Thread: [Beeframework-svn] SF.net SVN: beeframework:[6] trunk
Brought to you by:
b_hartmann,
m_plomer
From: <m_p...@us...> - 2010-08-11 12:18:51
|
Revision: 6 http://beeframework.svn.sourceforge.net/beeframework/?rev=6&view=rev Author: m_plomer Date: 2010-08-11 12:18:44 +0000 (Wed, 11 Aug 2010) Log Message: ----------- - copyright notices Modified Paths: -------------- trunk/framework/acl-default.xml trunk/framework/bee-aop-1.0.xsd trunk/framework/bee-beans-1.0.xsd trunk/framework/bee-security-1.0.xsd trunk/framework/bee-tx-1.0.xsd Added Paths: ----------- trunk/LICENSE trunk/NOTICE Added: trunk/LICENSE =================================================================== --- trunk/LICENSE (rev 0) +++ trunk/LICENSE 2010-08-11 12:18:44 UTC (rev 6) @@ -0,0 +1,177 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS \ No newline at end of file Added: trunk/NOTICE =================================================================== --- trunk/NOTICE (rev 0) +++ trunk/NOTICE 2010-08-11 12:18:44 UTC (rev 6) @@ -0,0 +1,12 @@ + + Bee Framework + Copyright 2008-2010 the original author or authors. + + This product is based on the Spring Framework for Java. It was ported and adapted to PHP + language specifics PHP between 2008-2010 by Michael Plomer and Benjamin Hartmann. More + information about Spring can be found at + http://www.springsource.org/about + + Annotations support is provided by the Addendum library for PHP, which is LGPL software + developed by Jan Suchal. The original software is available from + http://code.google.com/p/addendum/ Modified: trunk/framework/acl-default.xml =================================================================== --- trunk/framework/acl-default.xml 2010-08-04 19:04:03 UTC (rev 5) +++ trunk/framework/acl-default.xml 2010-08-11 12:18:44 UTC (rev 6) @@ -1,5 +1,19 @@ <?xml version="1.0" encoding="UTF-8"?> - +<!-- + * Copyright 2008-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +--> <beans xmlns="http://www.beeframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.beeframework.org/schema/beans http://www.beeframework.org/schema/beans/bee-beans-1.0.xsd"> Modified: trunk/framework/bee-aop-1.0.xsd =================================================================== --- trunk/framework/bee-aop-1.0.xsd 2010-08-04 19:04:03 UTC (rev 5) +++ trunk/framework/bee-aop-1.0.xsd 2010-08-11 12:18:44 UTC (rev 6) @@ -1,4 +1,19 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- + * Copyright 2008-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +--> <xsd:schema xmlns="http://www.beeframework.org/schema/aop" xmlns:xsd="http://www.w3.org/2001/XMLSchema" Modified: trunk/framework/bee-beans-1.0.xsd =================================================================== --- trunk/framework/bee-beans-1.0.xsd 2010-08-04 19:04:03 UTC (rev 5) +++ trunk/framework/bee-beans-1.0.xsd 2010-08-11 12:18:44 UTC (rev 6) @@ -1,13 +1,13 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> -<!-- - * Copyright 2008 the original author or authors. - * +<!-- + * Copyright 2008-2010 the original author or authors. + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Modified: trunk/framework/bee-security-1.0.xsd =================================================================== --- trunk/framework/bee-security-1.0.xsd 2010-08-04 19:04:03 UTC (rev 5) +++ trunk/framework/bee-security-1.0.xsd 2010-08-11 12:18:44 UTC (rev 6) @@ -1,4 +1,19 @@ <?xml version="1.0" encoding="utf-8"?> +<!-- + * Copyright 2008-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +--> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:security="http://www.beeframework.org/schema/security" elementFormDefault="qualified" targetNamespace="http://www.beeframework.org/schema/security"> Modified: trunk/framework/bee-tx-1.0.xsd =================================================================== --- trunk/framework/bee-tx-1.0.xsd 2010-08-04 19:04:03 UTC (rev 5) +++ trunk/framework/bee-tx-1.0.xsd 2010-08-11 12:18:44 UTC (rev 6) @@ -1,4 +1,19 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- + * Copyright 2008-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +--> <xsd:schema xmlns="http://www.beeframework.org/schema/tx" xmlns:xsd="http://www.w3.org/2001/XMLSchema" This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <m_p...@us...> - 2011-12-12 18:20:45
|
Revision: 11 http://beeframework.svn.sourceforge.net/beeframework/?rev=11&view=rev Author: m_plomer Date: 2011-12-12 18:20:38 +0000 (Mon, 12 Dec 2011) Log Message: ----------- Added Paths: ----------- trunk/tests/ trunk/tests/Bee/ trunk/tests/Bee/Annotations/ trunk/tests/Bee/Annotations/UtilsTest.php trunk/tests/Bee/Context/ trunk/tests/Bee/Context/AbstractTest.php trunk/tests/Bee/Context/Xml/ trunk/tests/Bee/Context/Xml/BeanDefinitionReaderTest-context.xml trunk/tests/Bee/Context/Xml/BeanDefinitionReaderTest.php trunk/tests/Bee/Utils/ trunk/tests/Bee/Utils/AntPathMatcherTest.php trunk/tests/Bee/Utils/StringsTest.php trunk/tests/bootstrap.php trunk/tests/phpunit.xml Added: trunk/tests/Bee/Annotations/UtilsTest.php =================================================================== --- trunk/tests/Bee/Annotations/UtilsTest.php (rev 0) +++ trunk/tests/Bee/Annotations/UtilsTest.php 2011-12-12 18:20:38 UTC (rev 11) @@ -0,0 +1,67 @@ +<?php +/* + * Copyright 2008-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * User: mp + * Date: 01.07.11 + * Time: 14:49 + */ + +class Bee_Annotations_UtilsTest /*extends PHPUnit_Framework_TestCase*/ { + + public function testFindInheritedAnnotation() { + + $class = new ReflectionClass('Bee_Annotations_UtilsTestChildAnnotatedClass'); + $method = $class->getMethod('testMethod'); + + $annot = Bee_Annotations_Utils::findAnnotation($method, 'Bee_Annotations_UtilsTestAnnotation1'); + +// $this->assertNotNull($annot, 'Annotation Bee_Annotations_UtilsTestAnnotation1 not found on Bee_Annotations_UtilsTestChildAnnotatedClass::testMethod()'); +// +// $this->assertEquals('parentAnnotation', $annot->value); + } +} + +class Bee_Annotations_UtilsTestAnnotation1 extends Annotation { + public $value; +} + +class Bee_Annotations_UtilsTestAnnotation2 extends Annotation { + public $value; +} + +class Bee_Annotations_UtilsTestParentAnnotatedClass { + + /** + * @return void + * + * @Bee_Annotations_UtilsTestAnnotation1(value = "parentAnnotation") + */ + public function testMethod() { + } +} + +class Bee_Annotations_UtilsTestChildAnnotatedClass extends Bee_Annotations_UtilsTestParentAnnotatedClass { + + /** + * @return void + * + * @Bee_Annotations_UtilsTestAnnotation2(value = "childAnnotation") + */ + public function testMethod() { + } +} Property changes on: trunk/tests/Bee/Annotations/UtilsTest.php ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/tests/Bee/Context/AbstractTest.php =================================================================== --- trunk/tests/Bee/Context/AbstractTest.php (rev 0) +++ trunk/tests/Bee/Context/AbstractTest.php 2011-12-12 18:20:38 UTC (rev 11) @@ -0,0 +1,103 @@ +<?php +/* + * Copyright 2008-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * User: mp + * Date: 06.07.11 + * Time: 18:53 + */ + +class Bee_Context_AbstractTest extends PHPUnit_Framework_TestCase { + + const BEAN_NAME_ARRAY_PARENT = 'arrayParent'; + const BEAN_NAME_ARRAY_CHILD_MERGED = 'arrayChildMerged'; + const BEAN_NAME_ARRAY_CHILD_NOT_MERGED = 'arrayChildNotMerged'; + + /** + * @var Bee_Context_Abstract + */ + private $context; + + protected function setUp() { + $this->context = new Bee_Context_AbstractTestStub('Bee_Context_AbstractTest'); + } + + /** + * @test + */ + public function beanDefinitionCount() { + $this->assertEquals(3, $this->context->getBeanDefinitionCount()); + } + + /** + * @test + */ + public function arrayMerged() { + $beanMerged = $this->context->getBean(self::BEAN_NAME_ARRAY_CHILD_MERGED); + $this->assertTrue(is_array($beanMerged)); + $this->assertEquals(4, count($beanMerged)); + } + + /** + * @test + */ + public function arrayNotMerged() { + $beanMerged = $this->context->getBean(self::BEAN_NAME_ARRAY_CHILD_NOT_MERGED); + $this->assertTrue(is_array($beanMerged)); + $this->assertEquals(2, count($beanMerged)); + } + + /** + * @test + */ + public function incomplete() { + $this->markTestIncomplete(); + } +} + +class Bee_Context_AbstractTestStub extends Bee_Context_Abstract { + + protected function loadBeanDefinitions() { + $this->registerArrayFactoryParent(); + + $this->registerBeanDefinition(Bee_Context_AbstractTest::BEAN_NAME_ARRAY_CHILD_MERGED, $this->createArrayFactoryChild(true)); + $this->registerBeanDefinition(Bee_Context_AbstractTest::BEAN_NAME_ARRAY_CHILD_NOT_MERGED, $this->createArrayFactoryChild(false)); + } + + private function registerArrayFactoryParent() { + $builder = Bee_Context_Support_BeanDefinitionBuilder::genericBeanDefinition('Bee_Context_Util_ArrayFactoryBean'); + $list = array( + 'keyA' => new Bee_Context_Config_TypedStringValue('valueA'), + 'keyB' => new Bee_Context_Config_TypedStringValue('valueB'), + 'keyC' => new Bee_Context_Config_TypedStringValue('valueC') + ); + $builder->addPropertyValue('sourceArray', new Bee_Context_Config_ArrayValue($list, false)); + $this->registerBeanDefinition(Bee_Context_AbstractTest::BEAN_NAME_ARRAY_PARENT, $builder->getBeanDefinition()); + } + + private function createArrayFactoryChild($merge) { + $builder = Bee_Context_Support_BeanDefinitionBuilder::genericBeanDefinition('Bee_Context_Util_ArrayFactoryBean'); + $list = array( + 'keyB' => new Bee_Context_Config_TypedStringValue('valueB_Child'), + 'keyD' => new Bee_Context_Config_TypedStringValue('valueD_Child'), + ); + $builder->setParentName(Bee_Context_AbstractTest::BEAN_NAME_ARRAY_PARENT) + ->addPropertyValue('sourceArray', new Bee_Context_Config_ArrayValue($list, $merge)); + + return $builder->getBeanDefinition(); + } +} Property changes on: trunk/tests/Bee/Context/AbstractTest.php ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/tests/Bee/Context/Xml/BeanDefinitionReaderTest-context.xml =================================================================== --- trunk/tests/Bee/Context/Xml/BeanDefinitionReaderTest-context.xml (rev 0) +++ trunk/tests/Bee/Context/Xml/BeanDefinitionReaderTest-context.xml 2011-12-12 18:20:38 UTC (rev 11) @@ -0,0 +1,49 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<beans xmlns="http://www.beeframework.org/schema/beans" + xmlns:util="http://www.beeframework.org/schema/util" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.beeframework.org/schema/beans http://www.beeframework.org/schema/beans/bee-beans-1.1.xsd + http://www.beeframework.org/schema/util http://www.beeframework.org/schema/beans/bee-utils-1.0.xsd" default-merge="true"> + + <bean name="referencedBean,alias1,alias2" class="Bee_Context_Util_ArrayFactoryBean" /> + + <util:array id="arrayFactory" scope="request"> + <value>Alpha</value> + <value>Bravo</value> + <value>Charlie</value> + <assoc-item key="d"> + <bean class="Bee_Context_Util_ArrayFactoryBean" /> + </assoc-item> + <ref bean="referencedBean" /> + </util:array> + + <util:array id="childArrayFactoryMergedTrue" scope="request" parent="arrayFactory" merge="true"> + <assoc-item key="d"> + <ref bean="referencedBean" /> + </assoc-item> + <value>Zulu</value> + </util:array> + + <util:array id="childArrayFactoryMergedDefault" scope="request" parent="arrayFactory" merge="default"> + <assoc-item key="d"> + <ref bean="referencedBean" /> + </assoc-item> + <value>Zulu</value> + </util:array> + + <util:array id="childArrayFactoryMergedFalse" scope="request" parent="arrayFactory" merge="false"> + <assoc-item key="d"> + <ref bean="referencedBean" /> + </assoc-item> + <value>Zulu</value> + </util:array> + + <util:array id="childArrayFactoryMergedNone" scope="request" parent="arrayFactory"> + <assoc-item key="d"> + <ref bean="referencedBean" /> + </assoc-item> + <value>Zulu</value> + </util:array> + +</beans> Property changes on: trunk/tests/Bee/Context/Xml/BeanDefinitionReaderTest-context.xml ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/tests/Bee/Context/Xml/BeanDefinitionReaderTest.php =================================================================== --- trunk/tests/Bee/Context/Xml/BeanDefinitionReaderTest.php (rev 0) +++ trunk/tests/Bee/Context/Xml/BeanDefinitionReaderTest.php 2011-12-12 18:20:38 UTC (rev 11) @@ -0,0 +1,141 @@ +<?php +/* + * Copyright 2008-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * User: mp + * Date: 03.07.11 + * Time: 19:18 + */ + +class Bee_Context_Xml_BeanDefinitionReaderTest extends PHPUnit_Framework_TestCase { + + /** + * @var Bee_Context_Config_BasicBeanDefinitionRegistry + */ + private static $registry; + + public static function setUpBeforeClass() { + self::$registry = new Bee_Context_Config_BasicBeanDefinitionRegistry(); + $reader = new Bee_Context_Xml_BeanDefinitionReader(self::$registry); + $reader->loadBeanDefinitions('Bee/Context/Xml/BeanDefinitionReaderTest-context.xml'); + } + + /** + * @test + */ + public function beanCount() { + $this->assertEquals(6, self::$registry->getBeanDefinitionCount()); + } + + /** + * @test + */ + public function beanDefinition() { + $this->assertTrue(self::$registry->containsBeanDefinition('arrayFactory')); + + $beanDefinition = self::$registry->getBeanDefinition('arrayFactory'); + + $this->assertInstanceOf('Bee_Context_Config_IBeanDefinition', $beanDefinition); + + $this->assertEquals('Bee_Context_Util_ArrayFactoryBean', $beanDefinition->getBeanClassName()); + + $propValues = $beanDefinition->getPropertyValues(); + + $this->assertTrue(is_array($propValues)); + + $sourceArrayProp = $propValues['sourceArray']; + $this->assertInstanceOf('Bee_Beans_PropertyValue', $sourceArrayProp); + + $this->assertEquals('sourceArray', $sourceArrayProp->getName()); + } + + /** + * @test + */ + public function arrayFactoryDef() { + $beanDefinition = self::$registry->getBeanDefinition('arrayFactory'); + $propValues = $beanDefinition->getPropertyValues(); + $sourceArrayProp = $propValues['sourceArray']; + + $arrayValue = $sourceArrayProp->getValue(); + + $this->assertArrayValueInstance($arrayValue, 5); + + $this->checkParentArrayContents($arrayValue); + + $this->assertInstanceOf('Bee_Context_Config_BeanDefinitionHolder', $arrayValue['d']); + } + + /** + * @param Bee_Context_Config_ArrayValue $arrayValue + * @return void + */ + private function checkParentArrayContents(Bee_Context_Config_ArrayValue $arrayValue) { + $this->assertTypedStringValue('Alpha', $arrayValue[0]); + $this->assertTypedStringValue('Bravo', $arrayValue[1]); + $this->assertTypedStringValue('Charlie', $arrayValue[2]); + $this->assertInstanceOf('Bee_Context_Config_RuntimeBeanReference', $arrayValue[3]); + } + + /** + * @test + */ + public function childArrayFactoryDefCheckMerge() { + $this->childArrayFactoryDefMerged('childArrayFactoryMergedTrue'); + $this->childArrayFactoryDefMerged('childArrayFactoryMergedDefault'); + $this->childArrayFactoryDefMerged('childArrayFactoryMergedNone'); + $this->childArrayFactoryDefNotMerged('childArrayFactoryMergedFalse'); + } + + private function childArrayFactoryDefMerged($beanName) { + $arrayValue = $this->getSourceArrayValueForArrayFactory($beanName); + $this->assertArrayValueInstance($arrayValue, 6); + $this->checkParentArrayContents($arrayValue); + $this->assertInstanceOf('Bee_Context_Config_RuntimeBeanReference', $arrayValue['d']); + } + + private function childArrayFactoryDefNotMerged($beanName) { + $arrayValue = $this->getSourceArrayValueForArrayFactory($beanName); + $this->assertArrayValueInstance($arrayValue, 2); + $this->assertInstanceOf('Bee_Context_Config_RuntimeBeanReference', $arrayValue['d']); + } + + private function getSourceArrayValueForArrayFactory($beanName) { + $beanDefinition = self::$registry->getBeanDefinition($beanName); + $propValues = $beanDefinition->getPropertyValues(); + $sourceArrayProp = $propValues['sourceArray']; + $this->assertInstanceOf('Bee_Beans_PropertyValue', $sourceArrayProp); + return $sourceArrayProp->getValue(); + } + + protected function assertTypedStringValue($stringValue, $propValue) { + $this->assertInstanceOf('Bee_Context_Config_TypedStringValue', $propValue); + $this->assertEquals($stringValue, $propValue->getValue()); + } + + protected function assertArrayValueInstance($arrayValue, $expectedSize) { + $this->assertInstanceOf('Bee_Context_Config_ArrayValue', $arrayValue); + $this->assertEquals($expectedSize, count($arrayValue)); + } + + /** + * @test + */ + public function incomplete() { + $this->markTestIncomplete(); + } +} \ No newline at end of file Property changes on: trunk/tests/Bee/Context/Xml/BeanDefinitionReaderTest.php ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/tests/Bee/Utils/AntPathMatcherTest.php =================================================================== --- trunk/tests/Bee/Utils/AntPathMatcherTest.php (rev 0) +++ trunk/tests/Bee/Utils/AntPathMatcherTest.php 2011-12-12 18:20:38 UTC (rev 11) @@ -0,0 +1,324 @@ +<?php +/* + * Copyright 2008-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * User: mp + * Date: 02.07.11 + * Time: 15:00 + */ +class Bee_Utils_AntPathMatcherTest extends PHPUnit_Framework_TestCase { + + /** + * @var Bee_Utils_AntPathMatcher + */ + private $pathMatcher; + + protected function setUp() { + $this->pathMatcher = new Bee_Utils_AntPathMatcher(); + } + + /** + * @test + * @dataProvider matchDataProvider + */ + public function match($pattern, $path, $result) { + $this->assertEquals($result, $this->pathMatcher->match($pattern, $path)); + } + + public function matchDataProvider() { + return array( + // test exact matching + array("test", "test", True), // #0 + array("/test", "/test", True), // #1 + array("/test.jpg", "test.jpg", False), // #2 + array("test", "/test", False), // #3 + array("/test", "test", False), // #4 + + // test matching with ?'s + array("t?st", "test", True), // #5 + array("??st", "test", True), // #6 + array("tes?", "test", True), // #7 + array("te??", "test", True), // #8 + array("?es?", "test", True), // #9 + array("tes?", "tes", False), // #10 + array("tes?", "testt", False), + array("tes?", "tsst", False), + + // test matchin with *'s + array("*", "test", True), + array("test*", "test", True), + array("test*", "testTest", True), // #15 + array("test/*", "test/Test", True), + array("test/*", "test/t", True), + array("test/*", "test/", True), + array("*test*", "AnothertestTest", True), + array("*test", "Anothertest", True), // #20 + array("*.*", "test.", True), + array("*.*", "test.test", True), + array("*.*", "test.test.test", True), + array("test*aaa", "testblaaaa", True), + array("test*", "tst", False), // #25 + array("test*", "tsttest", False), + array("test*", "test/", False), + array("test*", "test/t", False), + array("test/*", "test", False), + array("*test*", "tsttst", False), // #30 + array("*test", "tsttst", False), + array("*.*", "tsttst", False), + array("test*aaa", "test", False), + array("test*aaa", "testblaaab", False), + + // test matching with ?'s and /'s + array("/?", "/a", True), // #35 + array("/?/a", "/a/a", True), + array("/a/?", "/a/b", True), + array("/??/a", "/aa/a", True), + array("/a/??", "/a/bb", True), + array("/?", "/a", True), // #40 + + // test matching with **'s + array("/**", "/testing/testing", True), + array("/*/**", "/testing/testing", True), + array("/**/*", "/testing/testing", True), + array("/bla/**/bla", "/bla/testing/testing/bla", True), + array("/bla/**/bla", "/bla/testing/testing/bla/bla", True), // #45 + array("/**/test", "/bla/bla/test", True), + array("/bla/**/**/bla", "/bla/bla/bla/bla/bla/bla", True), + array("/bla*bla/test", "/blaXXXbla/test", True), + array("/*bla/test", "/XXXbla/test", True), + array("/bla*bla/test", "/blaXXXbl/test", False), // #50 + array("/*bla/test", "XXXblab/test", False), + array("/*bla/test", "XXXbl/test", False), + + array("/????", "/bala/bla", False), + array("/**/*bla", "/bla/bla/bla/bbb", False), + + array("/*bla*/**/bla/**", "/XXXblaXXXX/testing/testing/bla/testing/testing/", True), // #55 + array("/*bla*/**/bla/*", "/XXXblaXXXX/testing/testing/bla/testing", True), + array("/*bla*/**/bla/**", "/XXXblaXXXX/testing/testing/bla/testing/testing", True), + array("/*bla*/**/bla/**", "/XXXblaXXXX/testing/testing/bla/testing/testing.jpg", True), + + array("*bla*/**/bla/**", "XXXblaXXXX/testing/testing/bla/testing/testing/", True), + array("*bla*/**/bla/*", "XXXblaXXXX/testing/testing/bla/testing", True), // #60 + array("*bla*/**/bla/**", "XXXblaXXXX/testing/testing/bla/testing/testing", True), + array("*bla*/**/bla/*", "XXXblaXXXX/testing/testing/bla/testing/testing", False), + + array("/x/x/**/bla", "/x/x/x/", False), + + array("", "", True)//, + +// array("/{bla}.*", "/testing.html", True) // #65 + ); + } + + /** + * @test + * @dataProvider withMatchStartDataProvider + */ + public function withMatchStart($pattern, $path, $result) { + $this->assertEquals($result, $this->pathMatcher->matchStart($pattern, $path)); + } + + public function withMatchStartDataProvider() { + return array( + // test exact matching + array("test", "test", True), + array("/test", "/test", True), + array("/test.jpg", "test.jpg", False), + array("test", "/test", False), + array("/test", "test", False), + + // test matching with ?'s + array("t?st", "test", True), + array("??st", "test", True), + array("tes?", "test", True), + array("te??", "test", True), + array("?es?", "test", True), + array("tes?", "tes", False), + array("tes?", "testt", False), + array("tes?", "tsst", False), + + // test matchin with *'s + array("*", "test", True), + array("test*", "test", True), + array("test*", "testTest", True), + array("test/*", "test/Test", True), + array("test/*", "test/t", True), + array("test/*", "test/", True), + array("*test*", "AnothertestTest", True), + array("*test", "Anothertest", True), + array("*.*", "test.", True), + array("*.*", "test.test", True), + array("*.*", "test.test.test", True), + array("test*aaa", "testblaaaa", True), + array("test*", "tst", False), + array("test*", "test/", False), + array("test*", "tsttest", False), + array("test*", "test/", False), + array("test*", "test/t", False), + array("test/*", "test", True), + array("test/t*.txt", "test", True), + array("*test*", "tsttst", False), + array("*test", "tsttst", False), + array("*.*", "tsttst", False), + array("test*aaa", "test", False), + array("test*aaa", "testblaaab", False), + + // test matching with ?'s and /'s + array("/?", "/a", True), + array("/?/a", "/a/a", True), + array("/a/?", "/a/b", True), + array("/??/a", "/aa/a", True), + array("/a/??", "/a/bb", True), + array("/?", "/a", True), + + // test matching with **'s + array("/**", "/testing/testing", True), + array("/*/**", "/testing/testing", True), + array("/**/*", "/testing/testing", True), + array("test*/**", "test/", True), + array("test*/**", "test/t", True), + array("/bla/**/bla", "/bla/testing/testing/bla", True), + array("/bla/**/bla", "/bla/testing/testing/bla/bla", True), + array("/**/test", "/bla/bla/test", True), + array("/bla/**/**/bla", "/bla/bla/bla/bla/bla/bla", True), + array("/bla*bla/test", "/blaXXXbla/test", True), + array("/*bla/test", "/XXXbla/test", True), + array("/bla*bla/test", "/blaXXXbl/test", False), + array("/*bla/test", "XXXblab/test", False), + array("/*bla/test", "XXXbl/test", False), + + array("/????", "/bala/bla", False), + array("/**/*bla", "/bla/bla/bla/bbb", True), + + array("/*bla*/**/bla/**", "/XXXblaXXXX/testing/testing/bla/testing/testing/", True), + array("/*bla*/**/bla/*", "/XXXblaXXXX/testing/testing/bla/testing", True), + array("/*bla*/**/bla/**", "/XXXblaXXXX/testing/testing/bla/testing/testing", True), + array("/*bla*/**/bla/**", "/XXXblaXXXX/testing/testing/bla/testing/testing.jpg", True), + + array("*bla*/**/bla/**", "XXXblaXXXX/testing/testing/bla/testing/testing/", True), + array("*bla*/**/bla/*", "XXXblaXXXX/testing/testing/bla/testing", True), + array("*bla*/**/bla/**", "XXXblaXXXX/testing/testing/bla/testing/testing", True), + array("*bla*/**/bla/*", "XXXblaXXXX/testing/testing/bla/testing/testing", True), + + array("/x/x/**/bla", "/x/x/x/", True), + + array("", "", True) + ); + } + + /** + * @test + * @dataProvider uniqueDeliminatorDataProvider + */ + public function uniqueDeliminator($pattern, $path, $result) { + $this->pathMatcher->setPathSeparator("."); + $this->assertEquals($result, $this->pathMatcher->match($pattern, $path)); + } + + public function uniqueDeliminatorDataProvider() { + return array( + // test exact matching + array("test", "test", True), + array(".test", ".test", True), + array(".test/jpg", "test/jpg", False), + array("test", ".test", False), + array(".test", "test", False), + + // test matching with ?'s + array("t?st", "test", True), + array("??st", "test", True), + array("tes?", "test", True), + array("te??", "test", True), + array("?es?", "test", True), + array("tes?", "tes", False), + array("tes?", "testt", False), + array("tes?", "tsst", False), + + // test matchin with *'s + array("*", "test", True), + array("test*", "test", True), + array("test*", "testTest", True), + array("*test*", "AnothertestTest", True), + array("*test", "Anothertest", True), + array("*/*", "test/", True), + array("*/*", "test/test", True), + array("*/*", "test/test/test", True), + array("test*aaa", "testblaaaa", True), + array("test*", "tst", False), + array("test*", "tsttest", False), + array("*test*", "tsttst", False), + array("*test", "tsttst", False), + array("*/*", "tsttst", False), + array("test*aaa", "test", False), + array("test*aaa", "testblaaab", False), + + // test matching with ?'s and .'s + array(".?", ".a", True), + array(".?.a", ".a.a", True), + array(".a.?", ".a.b", True), + array(".??.a", ".aa.a", True), + array(".a.??", ".a.bb", True), + array(".?", ".a", True), + + // test matching with **'s + array(".**", ".testing.testing", True), + array(".*.**", ".testing.testing", True), + array(".**.*", ".testing.testing", True), + array(".bla.**.bla", ".bla.testing.testing.bla", True), + array(".bla.**.bla", ".bla.testing.testing.bla.bla", True), + array(".**.test", ".bla.bla.test", True), + array(".bla.**.**.bla", ".bla.bla.bla.bla.bla.bla", True), + array(".bla*bla.test", ".blaXXXbla.test", True), + array(".*bla.test", ".XXXbla.test", True), + array(".bla*bla.test", ".blaXXXbl.test", False), + array(".*bla.test", "XXXblab.test", False), + array(".*bla.test", "XXXbl.test", False) + ); + } + + /** + * @test + * @dataProvider extractPathWithinPatternDataProvider + */ + public function extractPathWithinPattern($pattern, $path, $result) { + $this->assertEquals($result, $this->pathMatcher->extractPathWithinPattern($pattern, $path)); + } + + public function extractPathWithinPatternDataProvider() { + return array ( + array("/docs/commit.html", "/docs/commit.html", ""), + + array("/docs/*", "/docs/cvs/commit", "cvs/commit"), + array("/docs/cvs/*.html", "/docs/cvs/commit.html", "commit.html"), + array("/docs/**", "/docs/cvs/commit", "cvs/commit"), + array("/docs/**/*.html", "/docs/cvs/commit.html", "cvs/commit.html"), + array("/docs/**/*.html", "/docs/commit.html", "commit.html"), + array("/*.html", "/commit.html", "commit.html"), + array("/*.html", "/docs/commit.html", "docs/commit.html"), + array("*.html", "/commit.html", "/commit.html"), + array("*.html", "/docs/commit.html", "/docs/commit.html"), + array("**/*.*", "/docs/commit.html", "/docs/commit.html"), + array("*", "/docs/commit.html", "/docs/commit.html"), + + array("/d?cs/*", "/docs/cvs/commit", "docs/cvs/commit"), + array("/docs/c?s/*.html", "/docs/cvs/commit.html", "cvs/commit.html"), + array("/d?cs/**", "/docs/cvs/commit", "docs/cvs/commit"), + array("/d?cs/**/*.html", "/docs/cvs/commit.html", "docs/cvs/commit.html") + ); + } +} Property changes on: trunk/tests/Bee/Utils/AntPathMatcherTest.php ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/tests/Bee/Utils/StringsTest.php =================================================================== --- trunk/tests/Bee/Utils/StringsTest.php (rev 0) +++ trunk/tests/Bee/Utils/StringsTest.php 2011-12-12 18:20:38 UTC (rev 11) @@ -0,0 +1,195 @@ +<?php +/* + * Copyright 2008-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * User: mp + * Date: 02.07.11 + * Time: 15:16 + */ + +class Bee_Utils_StringsTest extends PHPUnit_Framework_TestCase { + + /** + * @test + */ + public function hasLength() { + $this->assertTrue(Bee_Utils_Strings::hasLength(" ")); + $this->assertTrue(Bee_Utils_Strings::hasLength("abc ")); + + $this->assertFalse(Bee_Utils_Strings::hasLength("")); + $this->assertFalse(Bee_Utils_Strings::hasLength(null)); + } + + /** + * @test + * @expectedException Bee_Exceptions_TypeMismatch + */ + public function hasLengthTypeMismatch() { + Bee_Utils_Strings::hasLength(array("test")); // should throw Bee_Exceptions_TypeMismatch + } + + /** + * @test + */ + public function hasText() { + $blank = " "; + $this->assertFalse(Bee_Utils_Strings::hasText($blank)); + + $this->assertFalse(Bee_Utils_Strings::hasText(null)); + $this->assertFalse(Bee_Utils_Strings::hasText("")); + + $this->assertTrue(Bee_Utils_Strings::hasText("t")); + } + + /** + * @test + * @expectedException Bee_Exceptions_TypeMismatch + */ + public function hasTextTypeMismatch() { + Bee_Utils_Strings::hasText(array("test")); // should throw Bee_Exceptions_TypeMismatch + } + + /** + * @test + */ + public function tokenizeToArrayKeys() { + $sa = Bee_Utils_Strings::tokenizeToArrayKeys("a,b , ,c", ","); + $this->assertEquals(3, count($sa)); + $this->assertTrue($sa["a"] === true && $sa["b"] === true && $sa["c"] === true, "components are not correct"); + + $sa = Bee_Utils_Strings::tokenizeToArrayKeys("a,b , ,c", ",", true, false); + $this->assertEquals(4, count($sa)); + $this->assertTrue($sa["a"] === true && $sa["b"] === true && $sa[""] === true && $sa["c"] === true, "components are not correct"); + + $sa = Bee_Utils_Strings::tokenizeToArrayKeys("a,b ,c", ",", false, true); + $this->assertEquals(3, count($sa)); + $this->assertTrue($sa["a"] === true && $sa["b "] === true && $sa["c"] === true, "components are not correct"); + } + + /** + * @test + */ + public function tokenizeToArray() { + $sa = Bee_Utils_Strings::tokenizeToArray("a,b , ,c", ","); + $this->assertEquals(3, count($sa)); + $this->assertTrue($sa[0] === "a" && $sa[1] === "b" && $sa[2] === "c", "components are not correct"); + + $sa = Bee_Utils_Strings::tokenizeToArray("a,b , ,c", ",", true, false); + $this->assertEquals(4, count($sa)); + $this->assertTrue($sa[0] === "a" && $sa[1] === "b" && $sa[2] === "" && $sa[3] === "c", "components are not correct"); + + $sa = Bee_Utils_Strings::tokenizeToArray("a,b ,c", ",", false, true); + $this->assertEquals(3, count($sa)); + $this->assertTrue($sa[0] === "a" && $sa[1] === "b " && $sa[2] === "c", "components are not correct"); + } + + /** + * @test + */ + public function startsWith() { + $this->assertTrue(Bee_Utils_Strings::startsWith(null, null)); + $this->assertTrue(Bee_Utils_Strings::startsWith("", "")); + + $this->assertFalse(Bee_Utils_Strings::startsWith("", null)); + $this->assertFalse(Bee_Utils_Strings::startsWith("abcdef", null)); + $this->assertFalse(Bee_Utils_Strings::startsWith(null, "")); + $this->assertFalse(Bee_Utils_Strings::startsWith(null, "a")); + + $this->assertTrue(Bee_Utils_Strings::startsWith("abcdef", "a")); + $this->assertTrue(Bee_Utils_Strings::startsWith("abcdef", "ab")); + $this->assertTrue(Bee_Utils_Strings::startsWith("abcdef", "")); + $this->assertTrue(Bee_Utils_Strings::startsWith(" ", "")); + + $this->assertFalse(Bee_Utils_Strings::startsWith("abcdef", "bcdef")); + $this->assertFalse(Bee_Utils_Strings::startsWith("abcdef", " ")); + } + + /** + * @test + * @expectedException Bee_Exceptions_TypeMismatch + */ + public function startsWithSubjectNotString() { + Bee_Utils_Strings::startsWith(array(), "abcd"); + } + + /** + * @test + * @expectedException Bee_Exceptions_TypeMismatch + */ + public function startsWithPrefixNotString() { + Bee_Utils_Strings::startsWith("abcd", array()); + } + + /** + * @test + */ + public function stripPrefix() { + $this->assertEquals(null, Bee_Utils_Strings::stripPrefix(null, '')); + $this->assertEquals(null, Bee_Utils_Strings::stripPrefix(null, null)); + $this->assertEquals('', Bee_Utils_Strings::stripPrefix('', '')); + $this->assertEquals('', Bee_Utils_Strings::stripPrefix('', null)); + + $this->assertEquals('abcdef', Bee_Utils_Strings::stripPrefix('abcdef', '')); + $this->assertEquals('abcdef', Bee_Utils_Strings::stripPrefix('abcdef', 'bcd')); + $this->assertEquals('abcdef', Bee_Utils_Strings::stripPrefix('abcdef', 'def')); + $this->assertEquals('abcdef', Bee_Utils_Strings::stripPrefix('abcdef', 'xyz')); + + $this->assertEquals('', Bee_Utils_Strings::stripPrefix('', 'xyz')); + + $this->assertEquals('def', Bee_Utils_Strings::stripPrefix('abcdef', 'abc')); + $this->assertEquals('beeframework.org/', Bee_Utils_Strings::stripPrefix('http://beeframework.org/', 'http://')); + + } + + /** + * @test + */ + public function endsWith() { + $this->assertTrue(Bee_Utils_Strings::endsWith(null, null)); + $this->assertTrue(Bee_Utils_Strings::endsWith("", "")); + + $this->assertFalse(Bee_Utils_Strings::endsWith("", null)); + $this->assertFalse(Bee_Utils_Strings::endsWith("abcdef", null)); + $this->assertFalse(Bee_Utils_Strings::endsWith(null, "")); + $this->assertFalse(Bee_Utils_Strings::endsWith(null, "a")); + + $this->assertTrue(Bee_Utils_Strings::endsWith("abcdef", "f")); + $this->assertTrue(Bee_Utils_Strings::endsWith("abcdef", "ef")); + $this->assertTrue(Bee_Utils_Strings::endsWith("abcdef", "")); + $this->assertTrue(Bee_Utils_Strings::endsWith(" ", "")); + + $this->assertFalse(Bee_Utils_Strings::endsWith("abcdef", "abcde")); + $this->assertFalse(Bee_Utils_Strings::endsWith("abcdef", " ")); + } + + /** + * @test + * @expectedException Bee_Exceptions_TypeMismatch + */ + public function endsWithSubjectNotString() { + Bee_Utils_Strings::endsWith(array(), "abcd"); + } + + /** + * @test + * @expectedException Bee_Exceptions_TypeMismatch + */ + public function endsWithSuffixNotString() { + Bee_Utils_Strings::endsWith("abcd", array()); + } + +} \ No newline at end of file Property changes on: trunk/tests/Bee/Utils/StringsTest.php ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/tests/bootstrap.php =================================================================== --- trunk/tests/bootstrap.php (rev 0) +++ trunk/tests/bootstrap.php 2011-12-12 18:20:38 UTC (rev 11) @@ -0,0 +1,27 @@ +<?php +/* + * Copyright 2008-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * User: mp + * Date: 01.07.11 + * Time: 16:34 + */ + +require_once '../libs/addendum-0.4.1/annotations.php'; +require_once '../libs/log4php-2.1.0/Logger.php'; +require_once '../framework/potiscom/BeeFramework.php'; + Property changes on: trunk/tests/bootstrap.php ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/tests/phpunit.xml =================================================================== --- trunk/tests/phpunit.xml (rev 0) +++ trunk/tests/phpunit.xml 2011-12-12 18:20:38 UTC (rev 11) @@ -0,0 +1,8 @@ +<phpunit bootstrap="bootstrap.php" + colors="false" + convertErrorsToExceptions="true" + convertNoticesToExceptions="true" + convertWarningsToExceptions="true" + stopOnFailure="true"> + <!-- ... --> +</phpunit> Property changes on: trunk/tests/phpunit.xml ___________________________________________________________________ Added: svn:eol-style + native This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <m_p...@us...> - 2011-12-12 18:33:42
|
Revision: 12 http://beeframework.svn.sourceforge.net/beeframework/?rev=12&view=rev Author: m_plomer Date: 2011-12-12 18:33:36 +0000 (Mon, 12 Dec 2011) Log Message: ----------- Modified Paths: -------------- trunk/tests/bootstrap.php Property Changed: ---------------- trunk/libs/ Property changes on: trunk/libs ___________________________________________________________________ Added: svn:externals + log4php-2.1.0 https://svn.apache.org/repos/asf/logging/log4php/tags/apache-log4php-2.1.0/src/main/php Modified: trunk/tests/bootstrap.php =================================================================== --- trunk/tests/bootstrap.php 2011-12-12 18:20:38 UTC (rev 11) +++ trunk/tests/bootstrap.php 2011-12-12 18:33:36 UTC (rev 12) @@ -21,7 +21,7 @@ * Time: 16:34 */ -require_once '../libs/addendum-0.4.1/annotations.php'; +require_once '../libs/addendum-0.4.0/annotations.php'; require_once '../libs/log4php-2.1.0/Logger.php'; -require_once '../framework/potiscom/BeeFramework.php'; +require_once '../framework/BeeFramework.php'; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <m_p...@us...> - 2013-05-02 10:40:48
|
Revision: 25 http://sourceforge.net/p/beeframework/code/25 Author: m_plomer Date: 2013-05-02 10:40:45 +0000 (Thu, 02 May 2013) Log Message: ----------- - PHP 5.3 class loading - minor fixes Modified Paths: -------------- trunk/framework/Bee/Cache/Manager.php trunk/framework/Bee/Context/Xml/ReaderContext.php trunk/framework/Bee/MVC/View/Smarty3Adapter.php trunk/framework/BeeFramework.php Added Paths: ----------- trunk/composer.json Added: trunk/composer.json =================================================================== --- trunk/composer.json (rev 0) +++ trunk/composer.json 2013-05-02 10:40:45 UTC (rev 25) @@ -0,0 +1,28 @@ +{ + "name": "bee-framework/bee-framework", + "type": "library", + "description": "Bee Framework - PHP 5 DI/IoC application framework", + "keywords": ["framework"], + "homepage": "http://sourceforge.net/projects/beeframework/", + "license": "Apache License V2.0", + "authors": [ + { + "name": "Michael Plomer", + "email": "mic...@it..." + }, + { + "name": "Benjamin Hartmann" + } + ], + "require": { + "php": ">=5.2.3", + "niktux/addendum": "0.4.1", + "apache/log4php": "2.3.0" + }//, +// "autoload": { +// "classmap": [ +// "distribution/libs/Smarty.class.php", +// "distribution/libs/SmartyBC.class.php" +// ] +// } +} \ No newline at end of file Property changes on: trunk/composer.json ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Modified: trunk/framework/Bee/Cache/Manager.php =================================================================== --- trunk/framework/Bee/Cache/Manager.php 2013-05-02 10:34:07 UTC (rev 24) +++ trunk/framework/Bee/Cache/Manager.php 2013-05-02 10:40:45 UTC (rev 25) @@ -135,8 +135,9 @@ public static function &retrieveCachable(Bee_Cache_ICachableResource $resource, $returnInfoArray = false) { if(is_null(self::$provider)) { // no cache provider found, no caching or unsupported cache type installed - $data =& $resource->createContent(); - return $returnInfoArray ? array(self::INFO_NO_CACHE_KEY => true, self::INFO_CACHE_HIT_KEY => false, self::INFO_IN_CACHE_SINCE_KEY => false, self::INFO_DATA_KEY => $data) : $data; + $data =& $resource->createContent(); + $result = $returnInfoArray ? array(self::INFO_NO_CACHE_KEY => true, self::INFO_CACHE_HIT_KEY => false, self::INFO_IN_CACHE_SINCE_KEY => false, self::INFO_DATA_KEY => &$data) : $data; + return $result; } // caching supported, check if in cache and not stale @@ -197,4 +198,3 @@ return self::$provider->clearCache(); } } -?> \ No newline at end of file Modified: trunk/framework/Bee/Context/Xml/ReaderContext.php =================================================================== --- trunk/framework/Bee/Context/Xml/ReaderContext.php 2013-05-02 10:34:07 UTC (rev 24) +++ trunk/framework/Bee/Context/Xml/ReaderContext.php 2013-05-02 10:40:45 UTC (rev 25) @@ -47,7 +47,7 @@ Bee_Context_Config_IBeanDefinitionRegistry $registry, Bee_Context_Xml_Namespace_IHandlerResolver $namespaceHandlerResolver) { - $this->log = Logger::getLogger(__CLASS__); + $this->log = BeeFramework::getLoggerForClass(__CLASS__); $this->registry = $registry; $this->namespaceHandlerResolver = $namespaceHandlerResolver; @@ -87,4 +87,3 @@ $this->log->info($message); } } -?> \ No newline at end of file Modified: trunk/framework/Bee/MVC/View/Smarty3Adapter.php =================================================================== --- trunk/framework/Bee/MVC/View/Smarty3Adapter.php 2013-05-02 10:34:07 UTC (rev 24) +++ trunk/framework/Bee/MVC/View/Smarty3Adapter.php 2013-05-02 10:40:45 UTC (rev 25) @@ -15,7 +15,11 @@ * limitations under the License. */ -class Bee_MVC_View_Smarty3Adapter extends Smarty implements Bee_Context_Config_IInitializingBean { +/** + * Class Bee_MVC_View_Smarty3Adapter + * @deprecated probably not needed for Smarty3? + */ +class Bee_MVC_View_Smarty3Adapter extends Smarty /*implements Bee_Context_Config_IInitializingBean*/ { // /** // * @@ -92,5 +96,4 @@ $this->config_load($configFile); } } -} -?> \ No newline at end of file +} \ No newline at end of file Modified: trunk/framework/BeeFramework.php =================================================================== --- trunk/framework/BeeFramework.php 2013-05-02 10:34:07 UTC (rev 24) +++ trunk/framework/BeeFramework.php 2013-05-02 10:40:45 UTC (rev 25) @@ -171,7 +171,6 @@ foreach(self::getClassFileLocations($className) as $loc) { include $loc; - if (class_exists($className, false) || interface_exists($className, false)) { return true; } @@ -182,7 +181,7 @@ public static function getClassFileLocations($className) { return array( - str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php', + str_replace('_', DIRECTORY_SEPARATOR, str_replace('\\', DIRECTORY_SEPARATOR, $className)) . '.php', $className . '.php' ); } @@ -215,13 +214,13 @@ self::handleException($e); } } - - /** - * Convenience method, dispatches current request using the given dispatcher context. - * - * @param String $configLocation comma-separated string XML config files to load the bean definitions from - * @return void - */ + + /** + * Convenience method, dispatches current request using the given dispatcher context. + * + * @param Bee_IContext $ctx + * @return void + */ public static function dispatchRequestUsingContext(Bee_IContext $ctx) { try { Bee_Utils_Assert::notNull($ctx); @@ -340,6 +339,10 @@ public static function getProductionMode() { return self::$productionMode; } + + public static function getLoggerForClass($className) { + return Logger::getLogger(str_replace('_', '.', str_replace('\\', '.', $className))); + } } BeeFramework::init(); @@ -347,5 +350,4 @@ require_once dirname(__FILE__).'/Bee/Utils/ITypeDefinitions.php'; interface TYPES extends Bee_Utils_ITypeDefinitions { -} -?> \ No newline at end of file +} \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <m_p...@us...> - 2013-05-02 13:22:29
|
Revision: 27 http://sourceforge.net/p/beeframework/code/27 Author: m_plomer Date: 2013-05-02 13:22:26 +0000 (Thu, 02 May 2013) Log Message: ----------- - further PHP 5.3 related changes Modified Paths: -------------- trunk/framework/Bee/Annotations/Utils.php trunk/framework/Bee/Cache/Manager.php trunk/framework/Bee/Cache/Provider/File.php trunk/framework/Bee/Context/Xml/ReaderContext.php trunk/framework/Bee/Context/Xml.php trunk/framework/Bee/MVC/Controller/Multiaction/MethodNameResolver/AnnotationBased.php trunk/framework/Bee/MVC/Controller/Multiaction/RequestHandler.php trunk/framework/Bee/Security/Annotations/SecuredMethodDefinitionSource.php trunk/framework/Bee/Weaving/Enhancer.php trunk/tests/bootstrap.php Added Paths: ----------- trunk/framework/Bee/Framework.php trunk/framework/composer.json Removed Paths: ------------- trunk/composer.json trunk/framework/BeeFramework.php Deleted: trunk/composer.json =================================================================== --- trunk/composer.json 2013-05-02 10:50:42 UTC (rev 26) +++ trunk/composer.json 2013-05-02 13:22:26 UTC (rev 27) @@ -1,22 +0,0 @@ -{ - "name": "bee-framework/bee-framework", - "type": "library", - "description": "Bee Framework - PHP 5 DI/IoC application framework", - "keywords": ["framework"], - "homepage": "http://sourceforge.net/projects/beeframework/", - "license": "Apache License V2.0", - "authors": [ - { - "name": "Michael Plomer", - "email": "mic...@it..." - }, - { - "name": "Benjamin Hartmann" - } - ], - "require": { - "php": ">=5.2.3", - "niktux/addendum": "0.4.1", - "apache/log4php": "2.3.0" - } -} \ No newline at end of file Modified: trunk/framework/Bee/Annotations/Utils.php =================================================================== --- trunk/framework/Bee/Annotations/Utils.php 2013-05-02 10:50:42 UTC (rev 26) +++ trunk/framework/Bee/Annotations/Utils.php 2013-05-02 13:22:26 UTC (rev 27) @@ -15,6 +15,7 @@ * limitations under the License. */ +use Addendum\ReflectionAnnotatedClass; /** * User: mp * Date: Feb 19, 2010 Modified: trunk/framework/Bee/Cache/Manager.php =================================================================== --- trunk/framework/Bee/Cache/Manager.php 2013-05-02 10:50:42 UTC (rev 26) +++ trunk/framework/Bee/Cache/Manager.php 2013-05-02 13:22:26 UTC (rev 27) @@ -79,7 +79,7 @@ } private static function initProviderClass($providerClass) { - $loc = BeeFramework::getClassFileLocations($providerClass); + $loc = Bee_Framework::getClassFileLocations($providerClass); require_once $loc[0]; self::$provider = new $providerClass(); } @@ -191,7 +191,7 @@ } private static function getQualifiedKey($key) { - return (BeeFramework::getApplicationId()!==false ? BeeFramework::getApplicationId().'_' : '') . $key; + return (Bee_Framework::getApplicationId()!==false ? Bee_Framework::getApplicationId().'_' : '') . $key; } public static function clearCache() { Modified: trunk/framework/Bee/Cache/Provider/File.php =================================================================== --- trunk/framework/Bee/Cache/Provider/File.php 2013-05-02 10:50:42 UTC (rev 26) +++ trunk/framework/Bee/Cache/Provider/File.php 2013-05-02 13:22:26 UTC (rev 27) @@ -81,7 +81,7 @@ if (Bee_Utils_Strings::hasText($dir) && !preg_match('#'.DIRECTORY_SEPARATOR.'$#i', $dir)) { $dir .= DIRECTORY_SEPARATOR; } - $tmpName = $dir . $this->cacheFile . (BeeFramework::getApplicationId() ? '_'.BeeFramework::getApplicationId() : ''); + $tmpName = $dir . $this->cacheFile . (Bee_Framework::getApplicationId() ? '_'.Bee_Framework::getApplicationId() : ''); return $tmpName; } Modified: trunk/framework/Bee/Context/Xml/ReaderContext.php =================================================================== --- trunk/framework/Bee/Context/Xml/ReaderContext.php 2013-05-02 10:50:42 UTC (rev 26) +++ trunk/framework/Bee/Context/Xml/ReaderContext.php 2013-05-02 13:22:26 UTC (rev 27) @@ -47,7 +47,7 @@ Bee_Context_Config_IBeanDefinitionRegistry $registry, Bee_Context_Xml_Namespace_IHandlerResolver $namespaceHandlerResolver) { - $this->log = BeeFramework::getLoggerForClass(__CLASS__); + $this->log = Bee_Framework::getLoggerForClass(__CLASS__); $this->registry = $registry; $this->namespaceHandlerResolver = $namespaceHandlerResolver; Modified: trunk/framework/Bee/Context/Xml.php =================================================================== --- trunk/framework/Bee/Context/Xml.php 2013-05-02 10:50:42 UTC (rev 26) +++ trunk/framework/Bee/Context/Xml.php 2013-05-02 13:22:26 UTC (rev 27) @@ -80,7 +80,7 @@ } public function getModificationTimestamp() { - if(BeeFramework::getProductionMode()) { + if(Bee_Framework::getProductionMode()) { return 0; } if($this->modificationTimestamp === false) { Copied: trunk/framework/Bee/Framework.php (from rev 25, trunk/framework/BeeFramework.php) =================================================================== --- trunk/framework/Bee/Framework.php (rev 0) +++ trunk/framework/Bee/Framework.php 2013-05-02 13:22:26 UTC (rev 27) @@ -0,0 +1,351 @@ +<?php +/* + * Copyright 2008-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class Bee_Framework { + + const WEAVING_PACKAGE_PREFIX = 'Bee_'; + + const CLASS_FILE_CACHE_PREFIX = '__BeeClassFileCache_'; + + const GENERATED_CLASS_CODE_MARKER = '__CLASS_IS_GENERATED'; + + private static $beeHiveLocation; + + private static $applicationId = false; + + /** + * @var Bee_Weaving_IEnhancedClassesStore + */ + private static $enhancedClassesStore = null; + + /** + * todo: quick n dirty + * @var array + */ + private static $weavingExcludedClasses = array(); + + private static $weaveDuringClassloading = false; + + private static $missedClassNames = array(); + + private static $classFileMap; + + private static $productionMode = false; + + /** + * @param Bee_Weaving_IEnhancedClassesStore $enhancedClassesStore + */ + public static function setEnhancedClassesStore(Bee_Weaving_IEnhancedClassesStore $enhancedClassesStore) { + self::$enhancedClassesStore = $enhancedClassesStore; + } + + /** + * @return Bee_Weaving_IEnhancedClassesStore + */ + public static function getEnhancedClassesStore() { + return self::$enhancedClassesStore; + } + + public static function excludeFromWeaving($className) { + self::$weavingExcludedClasses[$className] = true; + } + + public static function setApplicationId($applicationId) { + self::$applicationId = $applicationId; + } + + public static function getApplicationId() { + return self::$applicationId; + } + + /** + * Main bootstrap method for the framework. Basically just initializes the framework classloader. + * + * @return void + */ + static function init() { + self::$beeHiveLocation = dirname(__FILE__); + self::addApplicationIncludePath(self::$beeHiveLocation); + + require_once dirname(__FILE__) . '/Cache/Manager.php'; + + spl_autoload_register(array(__CLASS__, 'autoload')); + + register_shutdown_function(array(__CLASS__, 'shutdown')); +// Bee_Cache_Manager::init(); + } + + public static function handleError($errno, $errstr, $errfile, $errline) { + error_log("HANDLING ERROR $errno"); + if((E_ERROR | E_RECOVERABLE_ERROR) & $errno) { + + error_log($errno .' : ' . $errstr); + throw new ErrorException($errstr, 0, $errno, $errfile, $errline); + } else if (E_ALL & ~E_NOTICE & ~E_WARNING & $errno) { + error_log($errno .' : ' . $errstr); + } + } + + /** + * Register application-specific include path with the framework classloader. + * + * @param String $includePath + * @return void + */ + public static function addApplicationIncludePath($includePath) { + $incPath = get_include_path(); + set_include_path($includePath . PATH_SEPARATOR . $incPath); + } + + + /** + * Main SPL autoloader function for the framework + * + * @param string $className + * @return boolean + */ + public static function autoload($className) { + + if (class_exists($className, false) || interface_exists($className, false)) { + return false; + } + + if(self::$productionMode) { + if(!is_array(self::$classFileMap)) { + self::$classFileMap = Bee_Cache_Manager::retrieve(self::CLASS_FILE_CACHE_PREFIX); + if(!is_array(self::$classFileMap)) { + self::$classFileMap = array(); + } + } + + if(array_key_exists($className, self::$classFileMap)) { + $cachedPath = self::$classFileMap[$className]; + if($cachedPath === self::GENERATED_CLASS_CODE_MARKER) { + return false; + } + + include $cachedPath; + if (class_exists($className, false) || interface_exists($className, false)) { + return false; + } + } + + if (class_exists($className)) { + array_push(self::$missedClassNames, $className); + } + // TODO: What to do if class-loading fails?? + } + + if(self::$enhancedClassesStore != null && !array_key_exists($className, self::$weavingExcludedClasses) && substr($className, 0, strlen(self::WEAVING_PACKAGE_PREFIX)) != self::WEAVING_PACKAGE_PREFIX) { + // possibly a woven class + + if(self::$enhancedClassesStore->loadClass($className)) { + return true; + } + + if(self::$weaveDuringClassloading) { + require_once dirname(__FILE__) . 'Bee/Weaving/Enhancer.php'; + + $enhancer = new Bee_Weaving_Enhancer($className); + if($enhancer->createEnhancedClass() !== false) { + return true; + } + } + } + + foreach(self::getClassFileLocations($className) as $loc) { + include $loc; + if (class_exists($className, false) || interface_exists($className, false)) { + return true; + } + } + + return false; + } + + public static function getClassFileLocations($className) { + return array( + str_replace('_', DIRECTORY_SEPARATOR, str_replace('\\', DIRECTORY_SEPARATOR, $className)) . '.php', + $className . '.php' + ); + } + + public static function shutdown() { + if(self::$productionMode) { + foreach(self::$missedClassNames as $missedClassName) { + $ref = new ReflectionClass($missedClassName); + self::$classFileMap[$missedClassName] = file_exists($ref->getFileName()) ? $ref->getFileName() : self::GENERATED_CLASS_CODE_MARKER; + } + Bee_Cache_Manager::store(self::CLASS_FILE_CACHE_PREFIX, self::$classFileMap); + } + + Bee_Cache_Manager::shutdown(); + } + + /** + * Convenience method, dispatches current request using a dispatcher context configured from the + * given set of XML config locations. + * + * @param String $configLocation comma-separated string XML config files to load the bean definitions from + * @return void + */ + public static function dispatchRequestUsingXmlContext($configLocation) { + try { + Bee_Utils_Assert::notNull($configLocation); + $ctx = new Bee_Context_Xml($configLocation); + self::dispatchRequestUsingContext($ctx); + } catch (Exception $e) { + self::handleException($e); + } + } + + /** + * Convenience method, dispatches current request using the given dispatcher context. + * + * @param Bee_IContext $ctx + * @return void + */ + public static function dispatchRequestUsingContext(Bee_IContext $ctx) { + try { + Bee_Utils_Assert::notNull($ctx); + $dp = new Bee_MVC_Dispatcher($ctx); + $dp->dispatch(); + } catch (Exception $e) { + self::handleException($e); + } + } + + public static function handleException(Exception $e) { + $topLevelMessage = $e->getMessage(); + + $js = '<script>'."\n"; + $js .= 'function toggle(event) {'."\n"; + + $js .= 'console.dir(event)'."\n"; + $js .= 'event.cancelBubble = true;'."\n"; + $js .= 'event.stopImmediatePropagation();'."\n"; + $js .= 'var ele = event.target.nextElementSibling;'."\n"; + $js .= 'if (ele.style.display == "none") {'."\n"; + $js .= 'ele.style.display = "block";'."\n"; + $js .= '} else {'."\n"; + $js .= 'ele.style.display = "none";'."\n"; + $js .= '}'."\n"; + $js .= '}'."\n"; + $js .= '</script>'."\n"; + + echo $js; + + + $excCnt = 0; + + while (!is_null($e)) { + $excCnt += 1; + echo '<div style="padding: 0 0 2px 0; margin: 0 2px 10px 2px; border: solid 1px #666;">'; + echo '<div style="background-color: #666; color: #fff; margin-bottom: 5px; padding: 5px; cursor: pointer;" onclick="javascript:toggle(event);">'.$excCnt.'. Exception: "'.get_class($e).'"</div>'; + + echo '<div>'; + echo '<div style="padding: 0 0 2px 0; margin: 10px; border: solid 1px #aaa; color: #aaa;">'; + echo '<div style="background-color: #aaa; color: #666; padding: 5px; cursor: pointer;" onclick="javascript:toggle(event);">Message</div>'; + echo '<div style="padding: 5px;">'; + echo $e->getMessage(); + echo '</div>'; + echo '</div>'; + + echo '<div style="padding: 0 0 2px 0; margin: 10px; border: solid 1px #aaa; color: #aaa;">'; + echo '<div style="background-color: #aaa; color: #666; padding: 5px; cursor: pointer;" onclick="javascript:toggle(event);">Stracktrace</div>'; + echo '<div style="padding: 5px; font-size: 10px; display: none;">'; + self::printArray($e->getTrace()); + echo '</div>'; + echo '</div>'; + echo '</div>'; + echo '</div>'; + + +// echo 'Root-Cause: '; + if ($e instanceof Bee_Exceptions_Base) { + $e = $e->getCause(); + } else { + $e = null; + } + + } + + error_log($topLevelMessage, E_USER_WARNING); + } + + private static function printSpaces($count) { + for ($i=0; $i<$count; $i++) { + echo ' '; + } + } + + public static function printArray($output, $level=0) { + if (is_array($output)) { + foreach ($output as $key => $value) { + self::printSpaces($level*4); + echo $key; + if (is_array($value)) { + echo '<br/>'; + } + self::printArray($value, $level+1); + } + } else { + self::printSpaces($level*4); + if (is_object($output)) { + echo 'Object - Class: '; + echo get_class($output); + } else { + echo $output; + } + echo '<br/>'; + } + if ($level==1) { + echo '<hr/>'; + } + } + + + /** + * The applicationName is an identifier that can be used + * to uniquely identify the application - e.g. in the + * SessionContext - even from a different entry page. + * + * @return String + */ + public static final function getApplicationName() { + return self::$applicationName; + } + + public static function setProductionMode($productionMode) { + self::$productionMode = $productionMode; + } + + public static function getProductionMode() { + return self::$productionMode; + } + + public static function getLoggerForClass($className) { + return Logger::getLogger(str_replace('_', '.', str_replace('\\', '.', $className))); + } +} + +Bee_Framework::init(); + +//require_once dirname(__FILE__) . '/Utils/ITypeDefinitions.php'; + +interface TYPES extends Bee_Utils_ITypeDefinitions { +} \ No newline at end of file Modified: trunk/framework/Bee/MVC/Controller/Multiaction/MethodNameResolver/AnnotationBased.php =================================================================== --- trunk/framework/Bee/MVC/Controller/Multiaction/MethodNameResolver/AnnotationBased.php 2013-05-02 10:50:42 UTC (rev 26) +++ trunk/framework/Bee/MVC/Controller/Multiaction/MethodNameResolver/AnnotationBased.php 2013-05-02 13:22:26 UTC (rev 27) @@ -14,6 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +use Addendum\ReflectionAnnotatedClass; /** * Method name resolver implementation based on Addendum Annotations. This is a very powerful implementation, capable of invoking different @@ -68,7 +69,7 @@ $delegateClassName = get_class($this->getController()->getDelegate()); - if(BeeFramework::getProductionMode()) { + if(Bee_Framework::getProductionMode()) { $this->methodResolvers = Bee_Cache_Manager::retrieve(self::CACHE_KEY_PREFIX.$delegateClassName); } @@ -110,7 +111,7 @@ } } - if(BeeFramework::getProductionMode()) { + if(Bee_Framework::getProductionMode()) { Bee_Cache_Manager::store(self::CACHE_KEY_PREFIX.$delegateClassName, $this->methodResolvers); } } Modified: trunk/framework/Bee/MVC/Controller/Multiaction/RequestHandler.php =================================================================== --- trunk/framework/Bee/MVC/Controller/Multiaction/RequestHandler.php 2013-05-02 10:50:42 UTC (rev 26) +++ trunk/framework/Bee/MVC/Controller/Multiaction/RequestHandler.php 2013-05-02 13:22:26 UTC (rev 27) @@ -14,6 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +use Addendum\Annotation; /** * Addendum annotation for the annotation-based method name resolver. Modified: trunk/framework/Bee/Security/Annotations/SecuredMethodDefinitionSource.php =================================================================== --- trunk/framework/Bee/Security/Annotations/SecuredMethodDefinitionSource.php 2013-05-02 10:50:42 UTC (rev 26) +++ trunk/framework/Bee/Security/Annotations/SecuredMethodDefinitionSource.php 2013-05-02 13:22:26 UTC (rev 27) @@ -14,6 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +use Addendum\ReflectionAnnotatedClass; /** * Created by IntelliJ IDEA. Modified: trunk/framework/Bee/Weaving/Enhancer.php =================================================================== --- trunk/framework/Bee/Weaving/Enhancer.php 2013-05-02 10:50:42 UTC (rev 26) +++ trunk/framework/Bee/Weaving/Enhancer.php 2013-05-02 13:22:26 UTC (rev 27) @@ -98,15 +98,15 @@ return $classNameToCreate; } - if(!BeeFramework::getEnhancedClassesStore()->hasStoredClass($classNameToCreate)) { + if(!Bee_Framework::getEnhancedClassesStore()->hasStoredClass($classNameToCreate)) { $incPaths = explode(PATH_SEPARATOR, get_include_path()); - foreach(BeeFramework::getClassFileLocations($templateClassName) as $loc) { + foreach(Bee_Framework::getClassFileLocations($templateClassName) as $loc) { foreach($incPaths as $incPath) { $classFile = $incPath . DIRECTORY_SEPARATOR . $loc; if(file_exists($classFile)) { $this->enhanceClass(file_get_contents($classFile)); - BeeFramework::getEnhancedClassesStore()->storeClass($classNameToCreate, $this->toSourceCode()); + Bee_Framework::getEnhancedClassesStore()->storeClass($classNameToCreate, $this->toSourceCode()); // file_put_contents($enhancedClassLocation, $this->toSourceCode()); break 2; } @@ -114,7 +114,7 @@ } } - if (BeeFramework::getEnhancedClassesStore()->loadClass($classNameToCreate)) { + if (Bee_Framework::getEnhancedClassesStore()->loadClass($classNameToCreate)) { return $classNameToCreate; } return false; Deleted: trunk/framework/BeeFramework.php =================================================================== --- trunk/framework/BeeFramework.php 2013-05-02 10:50:42 UTC (rev 26) +++ trunk/framework/BeeFramework.php 2013-05-02 13:22:26 UTC (rev 27) @@ -1,353 +0,0 @@ -<?php -/* - * Copyright 2008-2010 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -//require_once dirname(__FILE__).'/../libs/addendum/annotations.php'; - -class BeeFramework { - - const WEAVING_PACKAGE_PREFIX = 'Bee_'; - - const CLASS_FILE_CACHE_PREFIX = '__BeeClassFileCache_'; - - const GENERATED_CLASS_CODE_MARKER = '__CLASS_IS_GENERATED'; - - private static $beeHiveLocation; - - private static $applicationId = false; - - /** - * @var Bee_Weaving_IEnhancedClassesStore - */ - private static $enhancedClassesStore = null; - - /** - * todo: quick n dirty - * @var array - */ - private static $weavingExcludedClasses = array(); - - private static $weaveDuringClassloading = false; - - private static $missedClassNames = array(); - - private static $classFileMap; - - private static $productionMode = false; - - /** - * @param Bee_Weaving_IEnhancedClassesStore $enhancedClassesStore - */ - public static function setEnhancedClassesStore(Bee_Weaving_IEnhancedClassesStore $enhancedClassesStore) { - self::$enhancedClassesStore = $enhancedClassesStore; - } - - /** - * @return Bee_Weaving_IEnhancedClassesStore - */ - public static function getEnhancedClassesStore() { - return self::$enhancedClassesStore; - } - - public static function excludeFromWeaving($className) { - self::$weavingExcludedClasses[$className] = true; - } - - public static function setApplicationId($applicationId) { - self::$applicationId = $applicationId; - } - - public static function getApplicationId() { - return self::$applicationId; - } - - /** - * Main bootstrap method for the framework. Basically just initializes the framework classloader. - * - * @return void - */ - static function init() { - self::$beeHiveLocation = dirname(__FILE__); - self::addApplicationIncludePath(self::$beeHiveLocation); - - require_once dirname(__FILE__).'/Bee/Cache/Manager.php'; - - spl_autoload_register(array(__CLASS__, 'autoload')); - - register_shutdown_function(array(__CLASS__, 'shutdown')); -// Bee_Cache_Manager::init(); - } - - public static function handleError($errno, $errstr, $errfile, $errline) { - error_log("HANDLING ERROR $errno"); - if((E_ERROR | E_RECOVERABLE_ERROR) & $errno) { - - error_log($errno .' : ' . $errstr); - throw new ErrorException($errstr, 0, $errno, $errfile, $errline); - } else if (E_ALL & ~E_NOTICE & ~E_WARNING & $errno) { - error_log($errno .' : ' . $errstr); - } - } - - /** - * Register application-specific include path with the framework classloader. - * - * @param String $includePath - * @return void - */ - public static function addApplicationIncludePath($includePath) { - $incPath = get_include_path(); - set_include_path($includePath . PATH_SEPARATOR . $incPath); - } - - - /** - * Main SPL autoloader function for the framework - * - * @param string $className - * @return boolean - */ - public static function autoload($className) { - - if (class_exists($className, false) || interface_exists($className, false)) { - return false; - } - - if(self::$productionMode) { - if(!is_array(self::$classFileMap)) { - self::$classFileMap = Bee_Cache_Manager::retrieve(self::CLASS_FILE_CACHE_PREFIX); - if(!is_array(self::$classFileMap)) { - self::$classFileMap = array(); - } - } - - if(array_key_exists($className, self::$classFileMap)) { - $cachedPath = self::$classFileMap[$className]; - if($cachedPath === self::GENERATED_CLASS_CODE_MARKER) { - return false; - } - - include $cachedPath; - if (class_exists($className, false) || interface_exists($className, false)) { - return false; - } - } - - if (class_exists($className)) { - array_push(self::$missedClassNames, $className); - } - // TODO: What to do if class-loading fails?? - } - - if(self::$enhancedClassesStore != null && !array_key_exists($className, self::$weavingExcludedClasses) && substr($className, 0, strlen(self::WEAVING_PACKAGE_PREFIX)) != self::WEAVING_PACKAGE_PREFIX) { - // possibly a woven class - - if(self::$enhancedClassesStore->loadClass($className)) { - return true; - } - - if(self::$weaveDuringClassloading) { - require_once dirname(__FILE__).'Bee/Weaving/Enhancer.php'; - - $enhancer = new Bee_Weaving_Enhancer($className); - if($enhancer->createEnhancedClass() !== false) { - return true; - } - } - } - - foreach(self::getClassFileLocations($className) as $loc) { - include $loc; - if (class_exists($className, false) || interface_exists($className, false)) { - return true; - } - } - - return false; - } - - public static function getClassFileLocations($className) { - return array( - str_replace('_', DIRECTORY_SEPARATOR, str_replace('\\', DIRECTORY_SEPARATOR, $className)) . '.php', - $className . '.php' - ); - } - - public static function shutdown() { - if(self::$productionMode) { - foreach(self::$missedClassNames as $missedClassName) { - $ref = new ReflectionClass($missedClassName); - self::$classFileMap[$missedClassName] = file_exists($ref->getFileName()) ? $ref->getFileName() : self::GENERATED_CLASS_CODE_MARKER; - } - Bee_Cache_Manager::store(self::CLASS_FILE_CACHE_PREFIX, self::$classFileMap); - } - - Bee_Cache_Manager::shutdown(); - } - - /** - * Convenience method, dispatches current request using a dispatcher context configured from the - * given set of XML config locations. - * - * @param String $configLocation comma-separated string XML config files to load the bean definitions from - * @return void - */ - public static function dispatchRequestUsingXmlContext($configLocation) { - try { - Bee_Utils_Assert::notNull($configLocation); - $ctx = new Bee_Context_Xml($configLocation); - self::dispatchRequestUsingContext($ctx); - } catch (Exception $e) { - self::handleException($e); - } - } - - /** - * Convenience method, dispatches current request using the given dispatcher context. - * - * @param Bee_IContext $ctx - * @return void - */ - public static function dispatchRequestUsingContext(Bee_IContext $ctx) { - try { - Bee_Utils_Assert::notNull($ctx); - $dp = new Bee_MVC_Dispatcher($ctx); - $dp->dispatch(); - } catch (Exception $e) { - self::handleException($e); - } - } - - public static function handleException(Exception $e) { - $topLevelMessage = $e->getMessage(); - - $js = '<script>'."\n"; - $js .= 'function toggle(event) {'."\n"; - - $js .= 'console.dir(event)'."\n"; - $js .= 'event.cancelBubble = true;'."\n"; - $js .= 'event.stopImmediatePropagation();'."\n"; - $js .= 'var ele = event.target.nextElementSibling;'."\n"; - $js .= 'if (ele.style.display == "none") {'."\n"; - $js .= 'ele.style.display = "block";'."\n"; - $js .= '} else {'."\n"; - $js .= 'ele.style.display = "none";'."\n"; - $js .= '}'."\n"; - $js .= '}'."\n"; - $js .= '</script>'."\n"; - - echo $js; - - - $excCnt = 0; - - while (!is_null($e)) { - $excCnt += 1; - echo '<div style="padding: 0 0 2px 0; margin: 0 2px 10px 2px; border: solid 1px #666;">'; - echo '<div style="background-color: #666; color: #fff; margin-bottom: 5px; padding: 5px; cursor: pointer;" onclick="javascript:toggle(event);">'.$excCnt.'. Exception: "'.get_class($e).'"</div>'; - - echo '<div>'; - echo '<div style="padding: 0 0 2px 0; margin: 10px; border: solid 1px #aaa; color: #aaa;">'; - echo '<div style="background-color: #aaa; color: #666; padding: 5px; cursor: pointer;" onclick="javascript:toggle(event);">Message</div>'; - echo '<div style="padding: 5px;">'; - echo $e->getMessage(); - echo '</div>'; - echo '</div>'; - - echo '<div style="padding: 0 0 2px 0; margin: 10px; border: solid 1px #aaa; color: #aaa;">'; - echo '<div style="background-color: #aaa; color: #666; padding: 5px; cursor: pointer;" onclick="javascript:toggle(event);">Stracktrace</div>'; - echo '<div style="padding: 5px; font-size: 10px; display: none;">'; - self::printArray($e->getTrace()); - echo '</div>'; - echo '</div>'; - echo '</div>'; - echo '</div>'; - - -// echo 'Root-Cause: '; - if ($e instanceof Bee_Exceptions_Base) { - $e = $e->getCause(); - } else { - $e = null; - } - - } - - error_log($topLevelMessage, E_USER_WARNING); - } - - private static function printSpaces($count) { - for ($i=0; $i<$count; $i++) { - echo ' '; - } - } - - public static function printArray($output, $level=0) { - if (is_array($output)) { - foreach ($output as $key => $value) { - self::printSpaces($level*4); - echo $key; - if (is_array($value)) { - echo '<br/>'; - } - self::printArray($value, $level+1); - } - } else { - self::printSpaces($level*4); - if (is_object($output)) { - echo 'Object - Class: '; - echo get_class($output); - } else { - echo $output; - } - echo '<br/>'; - } - if ($level==1) { - echo '<hr/>'; - } - } - - - /** - * The applicationName is an identifier that can be used - * to uniquely identify the application - e.g. in the - * SessionContext - even from a different entry page. - * - * @return String - */ - public static final function getApplicationName() { - return self::$applicationName; - } - - public static function setProductionMode($productionMode) { - self::$productionMode = $productionMode; - } - - public static function getProductionMode() { - return self::$productionMode; - } - - public static function getLoggerForClass($className) { - return Logger::getLogger(str_replace('_', '.', str_replace('\\', '.', $className))); - } -} - -BeeFramework::init(); - -require_once dirname(__FILE__).'/Bee/Utils/ITypeDefinitions.php'; - -interface TYPES extends Bee_Utils_ITypeDefinitions { -} \ No newline at end of file Copied: trunk/framework/composer.json (from rev 26, trunk/composer.json) =================================================================== --- trunk/framework/composer.json (rev 0) +++ trunk/framework/composer.json 2013-05-02 13:22:26 UTC (rev 27) @@ -0,0 +1,27 @@ +{ + "name": "bee-framework/bee-framework", + "type": "library", + "description": "Bee Framework - PHP 5 DI/IoC application framework", + "keywords": ["framework"], + "homepage": "http://sourceforge.net/projects/beeframework/", + "license": "Apache License V2.0", + "authors": [ + { + "name": "Michael Plomer", + "email": "mic...@it..." + }, + { + "name": "Benjamin Hartmann" + } + ], + "require": { + "php": ">=5.2.3", + "niktux/addendum": "0.4.1", + "apache/log4php": "2.3.0" + }, + "autoload": { + "psr-0": { + "Bee": "framework/" + } + } +} \ No newline at end of file Property changes on: trunk/framework/composer.json ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Modified: trunk/tests/bootstrap.php =================================================================== --- trunk/tests/bootstrap.php 2013-05-02 10:50:42 UTC (rev 26) +++ trunk/tests/bootstrap.php 2013-05-02 13:22:26 UTC (rev 27) @@ -22,6 +22,6 @@ */ require_once '../libs/addendum-0.4.1/annotations.php'; -require_once '../libs/log4php-2.1.0/Logger.php'; -require_once '../framework/BeeFramework.php'; +require_once '../libs/apache-log4php-2.3.0/Logger.php'; +require_once '../framework/Bee/Framework.php'; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <m_p...@us...> - 2013-05-07 11:13:27
|
Revision: 30 http://sourceforge.net/p/beeframework/code/30 Author: m_plomer Date: 2013-05-07 11:13:24 +0000 (Tue, 07 May 2013) Log Message: ----------- - pdo ordering examples Modified Paths: -------------- trunk/framework/Bee/Framework.php trunk/framework/Bee/Persistence/Behaviors/Ordered/Strategy.php trunk/framework/Bee/Persistence/Pdo/Behaviors/GenericOrderedDelegate.php Added Paths: ----------- trunk/examples/ trunk/examples/classes/ trunk/examples/classes/Persistence/ trunk/examples/classes/Persistence/Pdo/ trunk/examples/classes/Persistence/Pdo/OrderedColorsDao.php trunk/examples/conf/ trunk/examples/conf/context.xml trunk/examples/conf/log4php.xml trunk/examples/db/ trunk/examples/index.php trunk/examples/logs/ Added: trunk/examples/classes/Persistence/Pdo/OrderedColorsDao.php =================================================================== --- trunk/examples/classes/Persistence/Pdo/OrderedColorsDao.php (rev 0) +++ trunk/examples/classes/Persistence/Pdo/OrderedColorsDao.php 2013-05-07 11:13:24 UTC (rev 30) @@ -0,0 +1,93 @@ +<?php +namespace Persistence\Pdo; + +use Bee\Persistence\Behaviors\Ordered\Strategy as OrderedStrategy; +use Bee\Persistence\Pdo\Behaviors\GenericOrderedDelegate; + +/* + * Copyright 2008-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * User: mp + * Date: 07.05.13 + * Time: 12:12 + */ + +class OrderedColorsDao { + + /** + * @var \Logger + */ + private static $log; + + /** + * @return \Logger + */ + protected static function getLog() { + if (!self::$log) { + self::$log = \Bee_Framework::getLoggerForClass(__CLASS__); + } + return self::$log; + } + + /** + * @var \PDO + */ + private $pdoConnection; + + /** + * @var OrderedStrategy + */ + private $orderedStrategy; + + public function __construct(\PDO $pdoConnection) { + self::getLog()->info('DAO constructed, got PDO connection'); + $this->pdoConnection = $pdoConnection; + $pdoOrderedDelagate = new GenericOrderedDelegate('ordered_colors', $pdoConnection); + $this->orderedStrategy = new OrderedStrategy($pdoOrderedDelagate); + } + + /** + * @return \Bee\Persistence\Behaviors\Ordered\Strategy + */ + public function getOrderedStrategy() { + return $this->orderedStrategy; + } + + public function addColor($colorName, $colorHex) { + self::getLog()->info("adding color ($colorName, $colorHex)"); + + $this->pdoConnection->beginTransaction(); + try { + + self::getLog()->debug('inserting'); + $insertStmt = $this->pdoConnection->prepare('INSERT INTO ordered_colors (name, hex_value) VALUES (:name, :hex_value)'); + $insertStmt->execute(array(':name' => $colorName, ':hex_value' => $colorHex)); + + $id = $this->pdoConnection->lastInsertId(); + self::getLog()->debug('moving to end of list'); + $pos = $this->orderedStrategy->moveToEnd($id); + + self::getLog()->debug("committing ($id, $colorName, $colorHex, $pos)"); + $this->pdoConnection->commit(); + return $id; + } catch(\Exception $e) { + self::getLog()->debug('exception caught', $e); + $this->pdoConnection->rollBack(); + throw $e; + } + } +} Added: trunk/examples/conf/context.xml =================================================================== --- trunk/examples/conf/context.xml (rev 0) +++ trunk/examples/conf/context.xml 2013-05-07 11:13:24 UTC (rev 30) @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="UTF-8"?> +<beans xmlns="http://www.beeframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:security="http://www.beeframework.org/schema/security" + xsi:schemaLocation="http://www.beeframework.org/schema/beans http://www.beeframework.org/schema/beans/bee-beans-1.2.xsd + http://www.beeframework.org/schema/security http://www.beeframework.org/schema/security/bee-security-1.0.xsd"> + + <!-- Persistence - PDO Connection --> + <bean id="pdoConnection" class="PDO"> + <!-- LOCAL DB --> + <constructor-arg index="0" value="sqlite:db/examples.sqlite" /> + <constructor-arg index="1" value="sa" /> + <constructor-arg index="2" value="" /> + </bean> + + <bean id="orderedColorsDao" class="Persistence\Pdo\OrderedColorsDao"> + <constructor-arg index="0" ref="pdoConnection" /> + </bean> + +</beans> Added: trunk/examples/conf/log4php.xml =================================================================== --- trunk/examples/conf/log4php.xml (rev 0) +++ trunk/examples/conf/log4php.xml 2013-05-07 11:13:24 UTC (rev 30) @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<configuration xmlns="http://logging.apache.org/log4php/"> + <appender name="default" class="LoggerAppenderFile"> + <layout class="LoggerLayoutPattern"> + <param name="conversionPattern" value="%date %logger %-5level %msg%n" /> + </layout> + <param name="file" value="logs/application.log" /> + <param name="append" value="true" /> + </appender> + <appender name="framework" class="LoggerAppenderFile"> + <layout class="LoggerLayoutPattern"> + <param name="conversionPattern" value="%date %logger %-5level %msg%n" /> + </layout> + <param name="file" value="logs/framework.log" /> + <param name="append" value="true" /> + </appender> + <root> + <appender_ref ref="default" /> + </root> + <logger name="Bee" additivity="false"> + <level value="warn" /> + <appender_ref ref="framework" /> + </logger> +</configuration> \ No newline at end of file Index: trunk/examples/db =================================================================== --- trunk/examples/db 2013-05-07 07:25:49 UTC (rev 29) +++ trunk/examples/db 2013-05-07 11:13:24 UTC (rev 30) Property changes on: trunk/examples/db ___________________________________________________________________ Added: svn:ignore ## -0,0 +1 ## +examples.sqlite Added: trunk/examples/index.php =================================================================== --- trunk/examples/index.php (rev 0) +++ trunk/examples/index.php 2013-05-07 11:13:24 UTC (rev 30) @@ -0,0 +1,61 @@ +<?php +/* + * Copyright 2008-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * User: mp + * Date: 07.05.13 + * Time: 12:25 + */ + +require_once '../framework/Bee/Framework.php'; + +// Verzeichnis mit Applikations-Klassen zum Classpath hinzufügen +Bee_Framework::addApplicationIncludePath('classes'); + +Bee_Framework::addApplicationIncludePath('../libs/apache-log4php-2.3.0'); +Bee_Framework::addApplicationIncludePath('../libs/apache-log4php-2.3.0/helpers'); +Bee_Framework::addApplicationIncludePath('../libs/apache-log4php-2.3.0/pattern'); +Bee_Framework::addApplicationIncludePath('../libs/apache-log4php-2.3.0/layouts'); +Bee_Framework::addApplicationIncludePath('../libs/apache-log4php-2.3.0/appenders'); +Bee_Framework::addApplicationIncludePath('../libs/apache-log4php-2.3.0/configurators'); +Bee_Framework::addApplicationIncludePath('../libs/apache-log4php-2.3.0/renderers'); + +Logger::configure('conf/log4php.xml'); + +$ctx = new Bee_Context_Xml('conf/context.xml'); + +$pdoConn = $ctx->getBean('pdoConnection'); +$pdoConn->exec('CREATE TABLE "ordered_colors" ( + "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, + "name" text NOT NULL, + "hex_value" text NOT NULL, + "pos" integer DEFAULT NULL, + UNIQUE (pos ASC) +)'); + +$dao = $ctx->getBean('orderedColorsDao'); + +$dao->addColor('Red', '#ff0000'); +$greenId = $dao->addColor('Green', '#00ff00'); +$dao->addColor('Blue', '#0000ff'); +$dao->addColor('Yellow', '#ffff00'); +$purpleId = $dao->addColor('Purple', '#ff00ff'); +$dao->addColor('Cyan', '#00ffff'); + +$dao->getOrderedStrategy()->moveAfter($greenId, $purpleId); + +//BeeFramework::dispatchRequestUsingSerializedContext('conf/context.serialized'); Index: trunk/examples/logs =================================================================== --- trunk/examples/logs 2013-05-07 07:25:49 UTC (rev 29) +++ trunk/examples/logs 2013-05-07 11:13:24 UTC (rev 30) Property changes on: trunk/examples/logs ___________________________________________________________________ Added: svn:ignore ## -0,0 +1 ## +*.log Modified: trunk/framework/Bee/Framework.php =================================================================== --- trunk/framework/Bee/Framework.php 2013-05-07 07:25:49 UTC (rev 29) +++ trunk/framework/Bee/Framework.php 2013-05-07 11:13:24 UTC (rev 30) @@ -78,7 +78,7 @@ * @return void */ static function init() { - self::$beeHiveLocation = dirname(__FILE__); + self::$beeHiveLocation = dirname(dirname(__FILE__)); self::addApplicationIncludePath(self::$beeHiveLocation); require_once dirname(__FILE__) . '/Cache/Manager.php'; Modified: trunk/framework/Bee/Persistence/Behaviors/Ordered/Strategy.php =================================================================== --- trunk/framework/Bee/Persistence/Behaviors/Ordered/Strategy.php 2013-05-07 07:25:49 UTC (rev 29) +++ trunk/framework/Bee/Persistence/Behaviors/Ordered/Strategy.php 2013-05-07 11:13:24 UTC (rev 30) @@ -29,29 +29,54 @@ */ private $delegate; + public function __construct(IDelegate $delgate) { + $this->delegate = $delgate; + } + /** * @param mixed $subject * @param mixed $ref * @param mixed $groupRestriction + * @return int */ public function moveBefore($subject, $ref, $groupRestriction = false) { - $this->moveRelative($subject, $ref, true, $groupRestriction); + return $this->moveRelative($subject, $ref, true, $groupRestriction); } /** * @param mixed $subject * @param mixed $ref * @param mixed $groupRestriction + * @return int */ - public function moveBehind($subject, $ref, $groupRestriction = false) { - $this->moveRelative($subject, $ref, false, $groupRestriction); + public function moveAfter($subject, $ref, $groupRestriction = false) { + return $this->moveRelative($subject, $ref, false, $groupRestriction); } /** * @param mixed $subject + * @param mixed $groupRestriction + * @return int + */ + public function moveToStart($subject, $groupRestriction = false) { + return $this->moveAfter($subject, false, $groupRestriction); + } + + /** + * @param mixed $subject + * @param mixed $groupRestriction + * @return int + */ + public function moveToEnd($subject, $groupRestriction = false) { + return $this->moveBefore($subject, false, $groupRestriction); + } + + /** + * @param mixed $subject * @param mixed $ref * @param bool $before * @param mixed $groupRestriction + * @return int */ public function moveRelative($subject, $ref, $before = true, $groupRestriction = false) { // determine previous position of subject @@ -83,5 +108,7 @@ $this->delegate->setPosition($subject, $newPos, $groupRestriction); } // that's all, folks! + + return $newPos; } } Modified: trunk/framework/Bee/Persistence/Pdo/Behaviors/GenericOrderedDelegate.php =================================================================== --- trunk/framework/Bee/Persistence/Pdo/Behaviors/GenericOrderedDelegate.php 2013-05-07 07:25:49 UTC (rev 29) +++ trunk/framework/Bee/Persistence/Pdo/Behaviors/GenericOrderedDelegate.php 2013-05-07 11:13:24 UTC (rev 30) @@ -167,9 +167,10 @@ $qryString = sprintf($newPos < $oldPos ? self::SHIFT_UP_QUERY_TEMPLATE : self::SHIFT_DOWN_QUERY_TEMPLATE, $this->getPosExpression(), $qryDomain, $this->getDomainRestrictionString($orderedEntity, $params, $restriction)); // if this is a single table update, add ORDER clause to avoid unique constraint violation - if (stripos($qryDomain, ' JOIN ') === false) { - $qryString .= ' ORDER BY ' . $this->getPosExpression() . ($newPos < $oldPos ? ' DESC' : ' ASC'); - } +// if (stripos($qryDomain, ' JOIN ') === false) { +// $qryString .= ' ORDER BY ' . $this->getPosExpression() . ($newPos < $oldPos ? ' DESC' : ' ASC'); +// } +// var_dump($qryString); $this->getPdo()->prepare($qryString)->execute($params); } @@ -178,7 +179,7 @@ * @param int $newPos * @param mixed $restriction */ - public function setPosition($orderedEntity, $newPos, $restriction) { + public function setPosition($orderedEntity, $newPos, $restriction = false) { $params = array(':newPos' => $newPos); $qryString = sprintf(self::SET_POS_QUERY_TEMPLATE, $this->getPosExpression(), $this->getQueryDomain(), $this->getIdentityRestrictionString($orderedEntity, $params), $this->getDomainRestrictionString($orderedEntity, $params, $restriction)); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <m_p...@us...> - 2013-05-07 13:23:29
|
Revision: 34 http://sourceforge.net/p/beeframework/code/34 Author: m_plomer Date: 2013-05-07 13:23:23 +0000 (Tue, 07 May 2013) Log Message: ----------- - intermediate commit: basic feature detection framework for PDO Modified Paths: -------------- trunk/examples/conf/log4php.xml trunk/framework/Bee/Persistence/Pdo/Behaviors/DelegateBase.php trunk/framework/Bee/Persistence/Pdo/Behaviors/GenericOrderedDelegate.php Added Paths: ----------- trunk/framework/Bee/Persistence/Pdo/FeatureDetector.php Modified: trunk/examples/conf/log4php.xml =================================================================== --- trunk/examples/conf/log4php.xml 2013-05-07 11:44:44 UTC (rev 33) +++ trunk/examples/conf/log4php.xml 2013-05-07 13:23:23 UTC (rev 34) @@ -18,7 +18,7 @@ <appender_ref ref="default" /> </root> <logger name="Bee" additivity="false"> - <level value="warn" /> + <level value="info" /> <appender_ref ref="framework" /> </logger> </configuration> \ No newline at end of file Modified: trunk/framework/Bee/Persistence/Pdo/Behaviors/DelegateBase.php =================================================================== --- trunk/framework/Bee/Persistence/Pdo/Behaviors/DelegateBase.php 2013-05-07 11:44:44 UTC (rev 33) +++ trunk/framework/Bee/Persistence/Pdo/Behaviors/DelegateBase.php 2013-05-07 13:23:23 UTC (rev 34) @@ -1,5 +1,8 @@ <?php namespace Bee\Persistence\Pdo\Behaviors; + +use Bee\Persistence\Pdo\FeatureDetector; + /* * Copyright 2008-2010 the original author or authors. * @@ -23,7 +26,7 @@ * Date: 05.05.13 * Time: 23:52 */ -abstract class DelegateBase { +abstract class DelegateBase extends FeatureDetector { /** * @var \PDO @@ -69,4 +72,12 @@ $res = $qry->fetch(\PDO::FETCH_NUM); return $res [0]; } + + /** + * @param string $feature + * @return bool + */ + protected function pdoSupportsFeature($feature) { + return self::supports($feature, $this->getPdo()); + } } Modified: trunk/framework/Bee/Persistence/Pdo/Behaviors/GenericOrderedDelegate.php =================================================================== --- trunk/framework/Bee/Persistence/Pdo/Behaviors/GenericOrderedDelegate.php 2013-05-07 11:44:44 UTC (rev 33) +++ trunk/framework/Bee/Persistence/Pdo/Behaviors/GenericOrderedDelegate.php 2013-05-07 13:23:23 UTC (rev 34) @@ -166,11 +166,12 @@ $qryDomain = $this->getQueryDomain(); $qryString = sprintf($newPos < $oldPos ? self::SHIFT_UP_QUERY_TEMPLATE : self::SHIFT_DOWN_QUERY_TEMPLATE, $this->getPosExpression(), $qryDomain, $this->getDomainRestrictionString($orderedEntity, $params, $restriction)); - // if this is a single table update, add ORDER clause to avoid unique constraint violation -// if (stripos($qryDomain, ' JOIN ') === false) { -// $qryString .= ' ORDER BY ' . $this->getPosExpression() . ($newPos < $oldPos ? ' DESC' : ' ASC'); -// } -// var_dump($qryString); + + // if this is a single table update, add ORDER clause to avoid unique constraint violation (if driver supports it) + if ($this->pdoSupportsFeature(self::FEATURE_ORDERED_UPDATE) && stripos($qryDomain, ' JOIN ') === false) { + $qryString .= ' ORDER BY ' . $this->getPosExpression() . ($newPos < $oldPos ? ' DESC' : ' ASC'); + } + $this->getPdo()->prepare($qryString)->execute($params); } Added: trunk/framework/Bee/Persistence/Pdo/FeatureDetector.php =================================================================== --- trunk/framework/Bee/Persistence/Pdo/FeatureDetector.php (rev 0) +++ trunk/framework/Bee/Persistence/Pdo/FeatureDetector.php 2013-05-07 13:23:23 UTC (rev 34) @@ -0,0 +1,82 @@ +<?php +namespace Bee\Persistence\Pdo; + /* + * Copyright 2008-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * User: mp + * Date: 07.05.13 + * Time: 14:42 + */ + +class FeatureDetector { + + const FEATURE_ORDERED_UPDATE = 'ORDERED_UPDATE'; + + private static $FEATURE_CACHE = array(); + + private static $DETECTORS; + + /** + * @var \Logger + */ + private static $log; + + /** + * @return \Logger + */ + protected static function getLog() { + if (!self::$log) { + self::$log = \Bee_Framework::getLoggerForClass(__CLASS__); + } + return self::$log; + } + + /** + * @param string $feature + * @param \PDO $pdoConnection + * @return bool + */ + public static function supports($feature, \PDO $pdoConnection) { + self::init(); + $connKey = spl_object_hash($pdoConnection); + if (!array_key_exists($connKey, self::$FEATURE_CACHE)) { + self::$FEATURE_CACHE[$connKey] = array(); + } + if (!array_key_exists($feature, self::$FEATURE_CACHE[$connKey])) { + $detector = self::$DETECTORS[$feature]; + $result = $detector($pdoConnection); + self::$FEATURE_CACHE[$connKey][$feature] = $result; + self::getLog()->info("PDO connection $connKey supports feature $feature : " . ($result ? "YES" : "NO")); + } + return self::$FEATURE_CACHE[$connKey][$feature]; + } + + private static function init() { + if (!self::$DETECTORS) { + self::$DETECTORS = array( + self::FEATURE_ORDERED_UPDATE => function (\PDO $pdoConnection) { + switch ($pdoConnection->getAttribute(\PDO::ATTR_DRIVER_NAME)) { + case 'mysql': + return true; + } + return false; + } + ); + } + } +} + This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <m_p...@us...> - 2013-05-21 14:20:18
|
Revision: 37 http://sourceforge.net/p/beeframework/code/37 Author: m_plomer Date: 2013-05-21 14:20:15 +0000 (Tue, 21 May 2013) Log Message: ----------- - updated ordered behavior with proper group handling Modified Paths: -------------- trunk/examples/classes/Persistence/Doctrine/OrderedColorsDao.php trunk/examples/classes/Persistence/Doctrine/OrderedColorsEntity.php trunk/examples/classes/Persistence/Pdo/OrderedColorsDao.php trunk/examples/classes/Persistence/Pdo/SimpleHierarchyDao.php trunk/examples/conf/context.xml trunk/examples/index.php trunk/framework/Bee/Persistence/Behaviors/Ordered/Strategy.php trunk/framework/Bee/Persistence/Doctrine/Behaviors/DelegateBase.php trunk/framework/Bee/Persistence/Doctrine/Behaviors/GenericOrderedDelegate.php trunk/framework/Bee/Persistence/Pdo/Behaviors/DelegateBase.php trunk/framework/Bee/Persistence/Pdo/Behaviors/GenericNestedSetDelegate.php trunk/framework/Bee/Persistence/Pdo/Behaviors/GenericOrderedDelegate.php trunk/framework/Bee/Persistence/Pdo/SimpleDaoBase.php Added Paths: ----------- trunk/framework/Bee/Persistence/Behaviors/AbstractFieldBasedDelegate.php Modified: trunk/examples/classes/Persistence/Doctrine/OrderedColorsDao.php =================================================================== --- trunk/examples/classes/Persistence/Doctrine/OrderedColorsDao.php 2013-05-20 19:06:48 UTC (rev 36) +++ trunk/examples/classes/Persistence/Doctrine/OrderedColorsDao.php 2013-05-21 14:20:15 UTC (rev 37) @@ -35,8 +35,9 @@ public function __construct(\Doctrine_Connection $conn) { $this->setDoctrineConnection($conn); - $pdoOrderedDelagate = new GenericOrderedDelegate(self::ENTITY_CLASS_NAME, $conn); - $this->orderedStrategy = new OrderedStrategy($pdoOrderedDelagate); + $delagate = new GenericOrderedDelegate(self::ENTITY_CLASS_NAME, $conn); + $delagate->setGroupFieldName('color_grp'); + $this->orderedStrategy = new OrderedStrategy($delagate); } /** @@ -57,19 +58,20 @@ }); } - public function addColor($colorName, $colorHex) { - self::getLog()->info("adding color ($colorName, $colorHex)"); - return $this->doInTransaction(function(OrderedColorsDao $dao, \Logger $log) use ($colorName, $colorHex) { + public function addColor($colorName, $colorHex, $grpId) { + self::getLog()->info("adding color ($colorName, $colorHex, $grpId)"); + return $this->doInTransaction(function(OrderedColorsDao $dao, \Logger $log) use ($colorName, $colorHex, $grpId) { $log->debug('inserting'); $entity = new OrderedColorsEntity(); $entity->setName($colorName); $entity->setHexValue($colorHex); + $entity->setColorGrp($grpId); $entity->save($dao->getDoctrineConnection()); $log->debug('moving to end of list'); $pos = $dao->getOrderedStrategy()->moveToEnd($entity); - $log->debug("committing ($entity->id, $colorName, $colorHex, $pos)"); + $log->debug("committing ($entity->id, $colorName, $colorHex, $grpId, $pos)"); return $entity; }); } Modified: trunk/examples/classes/Persistence/Doctrine/OrderedColorsEntity.php =================================================================== --- trunk/examples/classes/Persistence/Doctrine/OrderedColorsEntity.php 2013-05-20 19:06:48 UTC (rev 36) +++ trunk/examples/classes/Persistence/Doctrine/OrderedColorsEntity.php 2013-05-21 14:20:15 UTC (rev 37) @@ -1,20 +1,20 @@ <?php namespace Persistence\Doctrine; -/* - * Copyright 2008-2010 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ + /* + * Copyright 2008-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * User: mp @@ -31,46 +31,73 @@ $this->hasColumn('name', 'string', 255); $this->hasColumn('hex_value', 'string', 10); + $this->hasColumn('color_grp', 'int'); $this->hasColumn('pos', 'int'); + + $drvName = \Doctrine_Manager::connection()->getAttribute(\PDO::ATTR_DRIVER_NAME); + if($drvName == 'mysql') { + // sqlite does generally not support ordered updates + $this->index('grp_pos', array( + 'fields' => array( + 'color_grp', + 'pos' => array('sorting' => 'ASC') + ), + 'type' => 'unique', + )); + } } /** - * @param mixed $hexValue + * @param string $hexValue */ public function setHexValue($hexValue) { $this->hex_value = $hexValue; } /** - * @return mixed + * @return string */ public function getHexValue() { return $this->hex_value; } /** - * @param mixed $name + * @param string $name */ public function setName($name) { $this->name = $name; } /** - * @return mixed + * @return string */ public function getName() { return $this->name; } /** - * @param mixed $pos + * @param int $colorGrp */ + public function setColorGrp($colorGrp) { + $this->color_grp = $colorGrp; + } + + /** + * @return int + */ + public function getColorGrp() { + return $this->color_grp; + } + + /** + * @param int $pos + */ public function setPos($pos) { $this->pos = $pos; } /** - * @return mixed + * @return int */ public function getPos() { return $this->pos; Modified: trunk/examples/classes/Persistence/Pdo/OrderedColorsDao.php =================================================================== --- trunk/examples/classes/Persistence/Pdo/OrderedColorsDao.php 2013-05-20 19:06:48 UTC (rev 36) +++ trunk/examples/classes/Persistence/Pdo/OrderedColorsDao.php 2013-05-21 14:20:15 UTC (rev 37) @@ -26,7 +26,7 @@ * Date: 07.05.13 * Time: 12:12 */ - + class OrderedColorsDao extends SimpleDaoBase { /** @@ -36,20 +36,39 @@ public function __construct(\PDO $pdoConnection) { parent::__construct($pdoConnection); - $pdoOrderedDelagate = new GenericOrderedDelegate('ordered_colors_pdo', $pdoConnection); - $this->orderedStrategy = new OrderedStrategy($pdoOrderedDelagate); + $delagate = new GenericOrderedDelegate('ordered_colors_pdo', $pdoConnection); + $delagate->setGroupFieldName('color_grp'); + $this->orderedStrategy = new OrderedStrategy($delagate); } /** * */ public function createTable() { - $this->getPdoConnection()->exec('CREATE TABLE IF NOT EXISTS "ordered_colors_pdo" ( - "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, - "name" text NOT NULL, - "hex_value" text NOT NULL, - "pos" integer DEFAULT NULL)' - ); + $drvName = $this->getPdoConnection()->getAttribute(\PDO::ATTR_DRIVER_NAME); + switch ($drvName) { + case 'mysql': + $this->getPdoConnection()->exec('CREATE TABLE IF NOT EXISTS `ordered_colors_pdo` ( + id bigint(20) NOT NULL AUTO_INCREMENT, + name varchar(255) NOT NULL, + hex_value varchar(7) NOT NULL, + color_grp int(11) NOT NULL, + pos int(11) DEFAULT NULL, + PRIMARY KEY (id), + UNIQUE KEY grp_pos_idx (color_grp, pos)) + ENGINE=InnoDB CHARSET=utf8' + ); + break; + case 'sqlite': + $this->getPdoConnection()->exec('CREATE TABLE IF NOT EXISTS "ordered_colors_pdo" ( + "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, + "name" text NOT NULL, + "hex_value" text NOT NULL, + "color_grp" integer NOT NULL, + "pos" integer DEFAULT NULL)' + ); + break; + } } /** @@ -60,24 +79,24 @@ } public function deleteAllColors() { - $this->doInTransaction(function(OrderedColorsDao $dao, \Logger $log) { + $this->doInTransaction(function (OrderedColorsDao $dao, \Logger $log) { $log->debug('deleting all colors'); $dao->getPdoConnection()->exec('DELETE FROM ordered_colors_pdo'); }); } - public function addColor($colorName, $colorHex) { - self::getLog()->info("adding color ($colorName, $colorHex)"); - return $this->doInTransaction(function(OrderedColorsDao $dao, \Logger $log) use ($colorName, $colorHex) { + public function addColor($colorName, $colorHex, $grpId) { + self::getLog()->info("adding color ($colorName, $colorHex, $grpId)"); + return $this->doInTransaction(function (OrderedColorsDao $dao, \Logger $log) use ($colorName, $colorHex, $grpId) { $log->debug('inserting'); - $insertStmt = $dao->getPdoConnection()->prepare('INSERT INTO ordered_colors_pdo (name, hex_value) VALUES (:name, :hex_value)'); - $insertStmt->execute(array(':name' => $colorName, ':hex_value' => $colorHex)); + $insertStmt = $dao->getPdoConnection()->prepare('INSERT INTO ordered_colors_pdo (name, hex_value, color_grp) VALUES (:name, :hex_value, :grp_id)'); + $insertStmt->execute(array(':name' => $colorName, ':hex_value' => $colorHex, ':grp_id' => $grpId)); $id = $dao->getPdoConnection()->lastInsertId(); $log->debug('moving to end of list'); $pos = $dao->getOrderedStrategy()->moveToEnd($id); - $log->debug("committing ($id, $colorName, $colorHex, $pos)"); + $log->debug("committing ($id, $colorName, $colorHex, $grpId, $pos)"); return $id; }); Modified: trunk/examples/classes/Persistence/Pdo/SimpleHierarchyDao.php =================================================================== --- trunk/examples/classes/Persistence/Pdo/SimpleHierarchyDao.php 2013-05-20 19:06:48 UTC (rev 36) +++ trunk/examples/classes/Persistence/Pdo/SimpleHierarchyDao.php 2013-05-21 14:20:15 UTC (rev 37) @@ -35,27 +35,48 @@ public function __construct(\PDO $pdoConnection) { parent::__construct($pdoConnection); - $pdoNestedSetDelagate = new GenericNestedSetDelegate('simple_hierarchy', $pdoConnection); - $this->nestedSetStrategy = new NestedSetStrategy($pdoNestedSetDelagate); + $delagate = new GenericNestedSetDelegate('simple_hierarchy_pdo', $pdoConnection); + $delagate->setGroupFieldName('root_id'); + $this->nestedSetStrategy = new NestedSetStrategy($delagate); } /** * */ public function createTable() { - $this->getPdoConnection()->exec('CREATE TABLE IF NOT EXISTS "simple_hierarchy" ( - "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, - "name" text NOT NULL, - "lft" integer DEFAULT NULL, - "rgt" integer DEFAULT NULL, - "lvl" integer DEFAULT NULL)' - ); + $drvName = $this->getPdoConnection()->getAttribute(\PDO::ATTR_DRIVER_NAME); + switch ($drvName) { + case 'mysql': + $this->getPdoConnection()->exec('CREATE TABLE IF NOT EXISTS `simple_hierarchy_pdo` ( + id bigint(20) NOT NULL AUTO_INCREMENT, + name varchar(255) NOT NULL, + root_id int(11) NOT NULL, + lft int(11) DEFAULT NULL, + rgt int(11) DEFAULT NULL, + lvl int(11) DEFAULT NULL, + PRIMARY KEY (id), + UNIQUE KEY grp_lft (root_id, lft), + UNIQUE KEY grp_rgt (root_id, rgt)) + ENGINE=InnoDB CHARSET=utf8' + ); + break; + case 'sqlite': + $this->getPdoConnection()->exec('CREATE TABLE IF NOT EXISTS "simple_hierarchy_pdo" ( + "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, + "name" text NOT NULL, + "root_id" integer NOT NULL, + "lft" integer DEFAULT NULL, + "rgt" integer DEFAULT NULL, + "lvl" integer DEFAULT NULL)' + ); + break; + } } public function deleteAll() { $this->doInTransaction(function(SimpleHierarchyDao $dao, \Logger $log) { $log->debug('deleting all hierarchy entries'); - $dao->getPdoConnection()->exec('DELETE FROM simple_hierarchy'); + $dao->getPdoConnection()->exec('DELETE FROM simple_hierarchy_pdo'); }); } @@ -70,7 +91,7 @@ return $this->doInTransaction(function(SimpleHierarchyDao $dao, \Logger $log) use ($name) { $log->info("adding entry ($name)"); $log->debug('inserting'); - $insertStmt = $dao->getPdoConnection()->prepare('INSERT INTO simple_hierarchy (name) VALUES (:name)'); + $insertStmt = $dao->getPdoConnection()->prepare('INSERT INTO simple_hierarchy_pdo (name) VALUES (:name)'); $insertStmt->execute(array(':name' => $name)); $id = $dao->getPdoConnection()->lastInsertId(); Modified: trunk/examples/conf/context.xml =================================================================== --- trunk/examples/conf/context.xml 2013-05-20 19:06:48 UTC (rev 36) +++ trunk/examples/conf/context.xml 2013-05-21 14:20:15 UTC (rev 37) @@ -8,10 +8,10 @@ <!-- Persistence - PDO Connection --> <bean id="pdoConnection" class="PDO"> <!-- LOCAL DB --> - <constructor-arg index="0" value="sqlite:db/examples.sqlite" /> - <constructor-arg index="1" value="sa" /> - <!--<constructor-arg index="0" value="mysql:host=127.0.0.1;dbname=bee_test" />--> - <!--<constructor-arg index="1" value="root" />--> + <!--<constructor-arg index="0" value="sqlite:db/examples.sqlite" />--> + <!--<constructor-arg index="1" value="sa" />--> + <constructor-arg index="0" value="mysql:host=127.0.0.1;dbname=bee_test" /> + <constructor-arg index="1" value="root" /> <constructor-arg index="2" value="" /> </bean> Modified: trunk/examples/index.php =================================================================== --- trunk/examples/index.php 2013-05-20 19:06:48 UTC (rev 36) +++ trunk/examples/index.php 2013-05-21 14:20:15 UTC (rev 37) @@ -24,6 +24,8 @@ * Time: 12:25 */ +unlink('db/examples.sqlite'); + require_once '../framework/Bee/Framework.php'; require_once 'vendor/autoload.php'; @@ -51,13 +53,18 @@ $dao->createTable(); $dao->deleteAllColors(); -$redId = $dao->addColor('Red', '#ff0000'); -$greenId = $dao->addColor('Green', '#00ff00'); -$blueId = $dao->addColor('Blue', '#0000ff'); -$dao->addColor('Yellow', '#ffff00'); -$purpleId = $dao->addColor('Purple', '#ff00ff'); -$cyanId = $dao->addColor('Cyan', '#00ffff'); +$redId = $dao->addColor('Red', '#ff0000', 1); +$greenId = $dao->addColor('Green', '#00ff00', 1); +$blueId = $dao->addColor('Blue', '#0000ff', 1); +$dao->addColor('Yellow', '#ffff00', 1); +$purpleId = $dao->addColor('Purple', '#ff00ff', 1); +$cyanId = $dao->addColor('Cyan', '#00ffff', 1); +$redId2 = $dao->addColor('Red2', '#ff0000', 2); +$greenId2 = $dao->addColor('Green2', '#00ff00', 2); +$blueId2 = $dao->addColor('Blue2', '#0000ff', 2); +$yellowId2 = $dao->addColor('Yellow2', '#ffff00', 2); + $dao->doInTransaction(function(OrderedColorsDaoPdo $dao, \Logger $log) use ($greenId, $purpleId) { $dao->getOrderedStrategy()->moveAfter($greenId, $purpleId); }); @@ -86,13 +93,18 @@ $dao->createTable(); $dao->deleteAllColors(); -$redId = $dao->addColor('Red', '#ff0000'); -$greenId = $dao->addColor('Green', '#00ff00'); -$blueId = $dao->addColor('Blue', '#0000ff'); -$dao->addColor('Yellow', '#ffff00'); -$purpleId = $dao->addColor('Purple', '#ff00ff'); -$cyanId = $dao->addColor('Cyan', '#00ffff'); +$redId = $dao->addColor('Red', '#ff0000', 1); +$greenId = $dao->addColor('Green', '#00ff00', 1); +$blueId = $dao->addColor('Blue', '#0000ff', 1); +$dao->addColor('Yellow', '#ffff00', 1); +$purpleId = $dao->addColor('Purple', '#ff00ff', 1); +$cyanId = $dao->addColor('Cyan', '#00ffff', 1); +$redId2 = $dao->addColor('Red2', '#ff0000', 2); +$greenId2 = $dao->addColor('Green2', '#00ff00', 2); +$blueId2 = $dao->addColor('Blue2', '#0000ff', 2); +$yellowId2 = $dao->addColor('Yellow2', '#ffff00', 2); + $dao->doInTransaction(function(OrderedColorsDaoDoctrine $dao, \Logger $log) use ($greenId, $purpleId) { $dao->getOrderedStrategy()->moveAfter($greenId, $purpleId); }); Added: trunk/framework/Bee/Persistence/Behaviors/AbstractFieldBasedDelegate.php =================================================================== --- trunk/framework/Bee/Persistence/Behaviors/AbstractFieldBasedDelegate.php (rev 0) +++ trunk/framework/Bee/Persistence/Behaviors/AbstractFieldBasedDelegate.php 2013-05-21 14:20:15 UTC (rev 37) @@ -0,0 +1,85 @@ +<?php +namespace Bee\Persistence\Behaviors; +/* + * Copyright 2008-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +use Bee\Persistence\Pdo\FeatureDetector; + +/** + * User: mp + * Date: 21.05.13 + * Time: 10:19 + */ + +abstract class AbstractFieldBasedDelegate { + + /** + * @var string + */ + private $idFieldName = 'id'; + + /** + * @var string + */ + private $groupFieldName; + + /** + * @var string + */ + private $queryDomain; + + /** + * @param string $queryDomain + */ + public function __construct($queryDomain) { + \Bee_Utils_Assert::hasText($queryDomain, 'Query domain (table / entity name) required, must not be empty'); + $this->queryDomain = $queryDomain; + } + + /** + * @param string $idFieldName + */ + public function setIdFieldName($idFieldName) { + $this->idFieldName = $idFieldName; + } + + /** + * @return string + */ + public function getIdFieldName() { + return $this->idFieldName; + } + + /** + * @param string $domainFieldName + */ + public function setGroupFieldName($domainFieldName) { + $this->groupFieldName = $domainFieldName; + } + + /** + * @return string + */ + public function getGroupFieldName() { + return $this->groupFieldName; + } + + /** + * @return string + */ + public function getQueryDomain() { + return $this->queryDomain; + } +} Modified: trunk/framework/Bee/Persistence/Behaviors/Ordered/Strategy.php =================================================================== --- trunk/framework/Bee/Persistence/Behaviors/Ordered/Strategy.php 2013-05-20 19:06:48 UTC (rev 36) +++ trunk/framework/Bee/Persistence/Behaviors/Ordered/Strategy.php 2013-05-21 14:20:15 UTC (rev 37) @@ -97,6 +97,7 @@ * @return int */ public function moveRelative($subject, $ref, $before = true, $groupRestriction = false) { + // determine previous position of subject $oldPos = $this->delegate->getPosition($subject, $groupRestriction); @@ -113,10 +114,10 @@ } } else { // no, "move behind nothing" means "move to beginning", "move before nothing" means "move to the end" - $newPos = 0; + $newPos = 1; if ($before) { $maxPos = $this->delegate->getMaxPosition($subject, $groupRestriction); - $newPos = $maxPos !== false ? $maxPos + 1 : 0; + $newPos = $maxPos !== false ? $maxPos + 1 : 1; } } Modified: trunk/framework/Bee/Persistence/Doctrine/Behaviors/DelegateBase.php =================================================================== --- trunk/framework/Bee/Persistence/Doctrine/Behaviors/DelegateBase.php 2013-05-20 19:06:48 UTC (rev 36) +++ trunk/framework/Bee/Persistence/Doctrine/Behaviors/DelegateBase.php 2013-05-21 14:20:15 UTC (rev 37) @@ -15,7 +15,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +use Bee\Persistence\Behaviors\AbstractFieldBasedDelegate; use Bee\Persistence\Pdo\FeatureDetector; +use Bee\Persistence\Pdo\Utils; /** * User: mp @@ -23,29 +25,20 @@ * Time: 02:19 */ -class DelegateBase extends FeatureDetector { +class DelegateBase extends AbstractFieldBasedDelegate { + /** * @var \Doctrine_Connection */ private $doctrineConnection; /** - * @var string - */ - private $entityClass; - - /** - * @var string - */ - private $idFieldName = 'id'; - - /** * @param string $entityClass * @param \Doctrine_Connection $doctrineConnection * @return \Bee\Persistence\Doctrine\Behaviors\DelegateBase */ public function __construct($entityClass, \Doctrine_Connection $doctrineConnection) { - $this->entityClass = $entityClass; + parent::__construct($entityClass); $this->doctrineConnection = $doctrineConnection; } @@ -57,38 +50,17 @@ } /** - * @return string - */ - public function getEntityClass() { - return $this->entityClass; - } - - /** - * @param string $idFieldName - */ - public function setIdFieldName($idFieldName) { - $this->idFieldName = $idFieldName; - } - - /** - * @return string - */ - public function getIdFieldName() { - return $this->idFieldName; - } - - /** * @return \Doctrine_Query */ protected function getEntityBaseQuery() { - return $this->getDoctrineConnection()->createQuery()->from($this->entityClass); + return $this->getDoctrineConnection()->createQuery()->from($this->getQueryDomain()); } /** * @return \Doctrine_Query */ protected function getEntityUpdateBaseQuery() { - return $this->getDoctrineConnection()->createQuery()->update($this->entityClass); + return $this->getDoctrineConnection()->createQuery()->update($this->getQueryDomain()); } /** @@ -99,7 +71,7 @@ */ protected function addIdentityRestriction(\Doctrine_Query $qry, $orderedEntity) { if($orderedEntity instanceof \Doctrine_Record) { - $id = $orderedEntity->get($this->idFieldName); + $id = $orderedEntity->get($this->getIdFieldName()); } else if(is_numeric($orderedEntity)) { $id = $orderedEntity; } else { @@ -108,11 +80,34 @@ return $qry->addWhere('id = :id', array(':id' => $id)); } + protected function addGroupRestriction(\Doctrine_Query $qry, $orderedEntity, $restriction = false) { + if ($this->getGroupFieldName()) { + if ($restriction === false) { + $restriction = $this->getGroup($orderedEntity); + } + $this->doAddGroupRestriction($qry, $restriction); + } + return $qry; + } + + protected function doAddGroupRestriction(\Doctrine_Query $qry, $restriction = false) { + return $qry->addWhere($this->getGroupFieldName().' = :grp_id', array(':grp_id' => $restriction)); + } + /** * @param string $feature * @return bool */ protected function pdoSupportsFeature($feature) { - return self::supports($feature, $this->getDoctrineConnection()->getDbh()); + return FeatureDetector::supports($feature, $this->getDoctrineConnection()->getDbh()); } + + /** + * @param $entity + * @return mixed + */ + protected function getGroup($entity) { + $grpQry = $this->getDoctrineConnection()->createQuery()->select($this->getGroupFieldName())->from($this->getQueryDomain()); + return $this->addIdentityRestriction($grpQry, $entity)->fetchOne(array(), \Doctrine_Core::HYDRATE_SINGLE_SCALAR); + } } Modified: trunk/framework/Bee/Persistence/Doctrine/Behaviors/GenericOrderedDelegate.php =================================================================== --- trunk/framework/Bee/Persistence/Doctrine/Behaviors/GenericOrderedDelegate.php 2013-05-20 19:06:48 UTC (rev 36) +++ trunk/framework/Bee/Persistence/Doctrine/Behaviors/GenericOrderedDelegate.php 2013-05-21 14:20:15 UTC (rev 37) @@ -16,6 +16,7 @@ * limitations under the License. */ use Bee\Persistence\Behaviors\Ordered\IDelegate; +use Bee\Persistence\Pdo\FeatureDetector; use Bee\Persistence\Pdo\Utils; /** @@ -61,7 +62,7 @@ * @return int */ public function getMaxPosition($orderedEntity, $restriction = false) { - $qry = $this->addCustomRestricitons($this->getEntityBaseQuery($orderedEntity, $restriction), $restriction); + $qry = $this->addGroupRestriction($this->getEntityBaseQuery($orderedEntity, $restriction), $orderedEntity, $restriction); $result = $this->addMaxPositionSelect($qry)->fetchOne(array(), \Doctrine_Core::HYDRATE_SINGLE_SCALAR); return Utils::numericOrFalse($result); } @@ -76,7 +77,7 @@ public function shiftPosition($orderedEntity, $newPos, $oldPos, $restriction = false) { $params = array(); - $qry = $this->addCustomRestricitons($this->getEntityUpdateBaseQuery(), $restriction); + $qry = $this->addGroupRestriction($this->getEntityUpdateBaseQuery(), $orderedEntity, $restriction); if($oldPos !== false) { if($newPos !== false) { @@ -108,8 +109,8 @@ // if this is a single table update, add ORDER clause to avoid unique constraint violation (if driver supports it) - if ($oldPos !== false && $this->pdoSupportsFeature(self::FEATURE_ORDERED_UPDATE) /*&& stripos($qryDomain, ' JOIN ') === false*/) { - $qry->orderBy($this->getPosExpression() . ($newPos < $oldPos ? ' DESC' : ' ASC')); + if ($oldPos !== false && $this->pdoSupportsFeature(FeatureDetector::FEATURE_ORDERED_UPDATE) /*&& stripos($qryDomain, ' JOIN ') === false*/) { + $qry->orderBy($this->getPosExpression() . ($newPos !== false && ($newPos < $oldPos) ? ' DESC' : ' ASC')); } $qry->execute($params); @@ -121,7 +122,7 @@ * @param mixed $restriction */ public function setPosition($orderedEntity, $newPos, $restriction = false) { - $qry = $this->addCustomRestricitons($this->getEntityUpdateBaseQuery(), $restriction); + $qry = $this->addGroupRestriction($this->getEntityUpdateBaseQuery(), $orderedEntity, $restriction); $this->addIdentityRestriction($qry, $orderedEntity); $qry->set($this->getPosExpression(), is_null($newPos) ? 'NULL' : $newPos)->execute(); } @@ -134,7 +135,7 @@ protected function getIdentityBaseQuery($orderedEntity, $restriction = false) { $qry = $this->getEntityBaseQuery(); $this->addIdentityRestriction($qry, $orderedEntity); - return $this->addCustomRestricitons($qry, $restriction); + return $this->addGroupRestriction($qry, $orderedEntity, $restriction); } /** @@ -152,14 +153,4 @@ protected function addMaxPositionSelect(\Doctrine_Query $qry) { return $qry->select('MAX('.$this->getPosExpression().')'); } - - /** - * @param \Doctrine_Query $qry - * @param mixed $restriction - * @return \Doctrine_Query - */ - protected function addCustomRestricitons(\Doctrine_Query $qry, $restriction = false) { - // no default implementation - return $qry; - } } Modified: trunk/framework/Bee/Persistence/Pdo/Behaviors/DelegateBase.php =================================================================== --- trunk/framework/Bee/Persistence/Pdo/Behaviors/DelegateBase.php 2013-05-20 19:06:48 UTC (rev 36) +++ trunk/framework/Bee/Persistence/Pdo/Behaviors/DelegateBase.php 2013-05-21 14:20:15 UTC (rev 37) @@ -1,6 +1,7 @@ <?php namespace Bee\Persistence\Pdo\Behaviors; +use Bee\Persistence\Behaviors\AbstractFieldBasedDelegate; use Bee\Persistence\Pdo\FeatureDetector; use Bee\Persistence\Pdo\Utils; @@ -27,7 +28,7 @@ * Date: 05.05.13 * Time: 23:52 */ -abstract class DelegateBase extends FeatureDetector { +abstract class DelegateBase extends AbstractFieldBasedDelegate { const GROUP_QUERY_TEMPLATE = 'SELECT %1$s FROM %2$s WHERE %3$s'; @@ -37,28 +38,12 @@ private $pdo; /** - * @var string - */ - private $queryDomain; - - /** - * @var string - */ - private $idFieldName = 'id'; - - /** - * @var string - */ - private $groupFieldName; - - /** * @param string $queryDomain * @param \PDO $pdo * @return \Bee\Persistence\Pdo\Behaviors\DelegateBase */ public function __construct($queryDomain, \PDO $pdo) { - \Bee_Utils_Assert::hasText($queryDomain, 'Query domain (table name / table joins) required, must not be empty'); - $this->queryDomain = $queryDomain; + parent::__construct($queryDomain); $this->pdo = $pdo; } @@ -70,46 +55,11 @@ } /** - * @return string - */ - public function getQueryDomain() { - return $this->queryDomain; - } - - /** - * @param string $idFieldName - */ - public function setIdFieldName($idFieldName) { - $this->idFieldName = $idFieldName; - } - - /** - * @return string - */ - public function getIdFieldName() { - return $this->idFieldName; - } - - /** - * @param string $domainFieldName - */ - public function setGroupFieldName($domainFieldName) { - $this->groupFieldName = $domainFieldName; - } - - /** - * @return string - */ - public function getGroupFieldName() { - return $this->groupFieldName; - } - - /** * @param string $feature * @return bool */ protected function pdoSupportsFeature($feature) { - return self::supports($feature, $this->getPdo()); + return FeatureDetector::supports($feature, $this->getPdo()); } /** @@ -120,7 +70,7 @@ */ protected function getIdentityRestrictionString($entity, array &$params) { $params[':id'] = $entity; - return $this->idFieldName . ' = :id'; + return $this->getIdFieldName() . ' = :id'; } /** @@ -134,9 +84,7 @@ if ($this->getGroupFieldName()) { if ($restriction === false) { // determine group value - $grpParams = array(); - $qryString = sprintf(self::GROUP_QUERY_TEMPLATE, $this->getGroupFieldName(), $this->getQueryDomain(), $this->getIdentityRestrictionString($entity, $params)); - $restriction = Utils::fetchOne($this->getPdo()->prepare($qryString), $grpParams); + $restriction = $this->getGroup($entity); } $result = $this->doCreateRestrictionString($params, $restriction); } @@ -152,4 +100,15 @@ $params[':group_id'] = $restriction; return $this->getGroupFieldName() . ' = :group_id'; } + + /** + * @param $entity + * @return mixed + */ + protected function getGroup($entity) { + // determine group value + $params = array(); + $qryString = sprintf(self::GROUP_QUERY_TEMPLATE, $this->getGroupFieldName(), $this->getQueryDomain(), $this->getIdentityRestrictionString($entity, $params)); + return Utils::fetchOne($this->getPdo()->prepare($qryString), $params); + } } Modified: trunk/framework/Bee/Persistence/Pdo/Behaviors/GenericNestedSetDelegate.php =================================================================== --- trunk/framework/Bee/Persistence/Pdo/Behaviors/GenericNestedSetDelegate.php 2013-05-20 19:06:48 UTC (rev 36) +++ trunk/framework/Bee/Persistence/Pdo/Behaviors/GenericNestedSetDelegate.php 2013-05-21 14:20:15 UTC (rev 37) @@ -3,6 +3,7 @@ use Bee\Persistence\Behaviors\NestedSet\IDelegate; use Bee\Persistence\Behaviors\NestedSet\NodeInfo; +use Bee\Persistence\Pdo\FeatureDetector; use Bee\Persistence\Pdo\Utils; /* @@ -138,7 +139,7 @@ $domRes = $this->getDomainRestrictionString($nestedSetEntity, $params, $restriction); // order updates only if supported by the driver and not operating on a joined relation - $orderUpdate = $this->pdoSupportsFeature(self::FEATURE_ORDERED_UPDATE) && stripos($qryDomain, ' JOIN ') === false; + $orderUpdate = $this->pdoSupportsFeature(FeatureDetector::FEATURE_ORDERED_UPDATE) && stripos($qryDomain, ' JOIN ') === false; // update left positions $qryString = sprintf($qryTempl, $qryDomain, $this->leftFieldName, $domRes); Modified: trunk/framework/Bee/Persistence/Pdo/Behaviors/GenericOrderedDelegate.php =================================================================== --- trunk/framework/Bee/Persistence/Pdo/Behaviors/GenericOrderedDelegate.php 2013-05-20 19:06:48 UTC (rev 36) +++ trunk/framework/Bee/Persistence/Pdo/Behaviors/GenericOrderedDelegate.php 2013-05-21 14:20:15 UTC (rev 37) @@ -2,6 +2,7 @@ namespace Bee\Persistence\Pdo\Behaviors; use Bee\Persistence\Behaviors\Ordered\IDelegate; +use Bee\Persistence\Pdo\FeatureDetector; use Bee\Persistence\Pdo\Utils; /* @@ -69,7 +70,7 @@ /** * @param $orderedEntity * @param $restriction - * @return mixed + * @return int|bool */ public function getMaxPosition($orderedEntity, $restriction = false) { $params = array(); @@ -103,8 +104,8 @@ $this->getDomainRestrictionString($orderedEntity, $params, $restriction)); // if this is a single table update, add ORDER clause to avoid unique constraint violation (if driver supports it) - if ($oldPos !== false && $this->pdoSupportsFeature(self::FEATURE_ORDERED_UPDATE) && stripos($qryDomain, ' JOIN ') === false) { - $qryString .= ' ORDER BY ' . $this->getPosExpression() . ($newPos < $oldPos ? ' DESC' : ' ASC'); + if ($oldPos !== false && $this->pdoSupportsFeature(FeatureDetector::FEATURE_ORDERED_UPDATE) && stripos($qryDomain, ' JOIN ') === false) { + $qryString .= ' ORDER BY ' . $this->getPosExpression() . ($newPos !== false && ($newPos < $oldPos) ? ' DESC' : ' ASC'); } $this->getPdo()->prepare($qryString)->execute($params); Modified: trunk/framework/Bee/Persistence/Pdo/SimpleDaoBase.php =================================================================== --- trunk/framework/Bee/Persistence/Pdo/SimpleDaoBase.php 2013-05-20 19:06:48 UTC (rev 36) +++ trunk/framework/Bee/Persistence/Pdo/SimpleDaoBase.php 2013-05-21 14:20:15 UTC (rev 37) @@ -75,6 +75,5 @@ $this->pdoConnection->rollBack(); throw $e; } - } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <m_p...@us...> - 2013-06-28 14:49:47
|
Revision: 42 http://sourceforge.net/p/beeframework/code/42 Author: m_plomer Date: 2013-06-28 14:49:43 +0000 (Fri, 28 Jun 2013) Log Message: ----------- - Tree-based API of nested set behavior completed Modified Paths: -------------- trunk/examples/classes/Treetest/Node.php trunk/examples/classes/Treetest/TreeDao.php trunk/examples/index2.php trunk/framework/Bee/Persistence/Behaviors/NestedSet/IDelegate.php trunk/framework/Bee/Persistence/Behaviors/NestedSet/ITreeNode.php trunk/framework/Bee/Persistence/Behaviors/NestedSet/NodeInfo.php trunk/framework/Bee/Persistence/Behaviors/NestedSet/Strategy.php trunk/framework/Bee/Persistence/Behaviors/NestedSet/TreeStrategy.php trunk/framework/Bee/Persistence/Doctrine2/Behaviors/DelegateBase.php trunk/framework/Bee/Persistence/Doctrine2/Behaviors/GenericNestedSetDelegate.php trunk/framework/Bee/Persistence/Doctrine2/Log4PHPLogger.php trunk/framework/Bee/Persistence/Pdo/Behaviors/DelegateBase.php trunk/framework/Bee/Persistence/Pdo/Behaviors/GenericNestedSetDelegate.php trunk/tests/Bee/Persistence/Behaviors/NestedSet/DelegateMock.php trunk/tests/Bee/Persistence/Behaviors/NestedSet/TestTreeNode.php Modified: trunk/examples/classes/Treetest/Node.php =================================================================== --- trunk/examples/classes/Treetest/Node.php 2013-06-27 03:18:25 UTC (rev 41) +++ trunk/examples/classes/Treetest/Node.php 2013-06-28 14:49:43 UTC (rev 42) @@ -25,11 +25,7 @@ * * @Entity * @Table( - * name="tree_test", - * uniqueConstraints={ - * @UniqueConstraint(name="grp_lft", columns={"root_id", "lft"}), - * @UniqueConstraint(name="grp_rgt", columns={"root_id", "rgt"}) - * } + * name="tree_test" * ) */ class Node implements ITreeNode { @@ -50,7 +46,7 @@ /** * @var int - * @Column(name="root_id", type="integer", nullable=false) + * @Column(name="root_id", type="integer", nullable=true) */ private $rootId; @@ -84,9 +80,11 @@ /** * @param $name string + * @param null $rootId */ - public function __construct($name) { + public function __construct($name, $rootId = null) { $this->name = $name; + $this->rootId = $rootId; } /** @@ -166,18 +164,18 @@ return $this->rootId; } - /** - * @return ITreeNode + * @return ITreeNode[] */ - public function getParent() { - return $this->parent; + public function getChildren() { + return $this->children; } /** - * @return ITreeNode[] + * @param ITreeNode $child + * @return void */ - public function &getChildren() { - return $this->children; + public function appendChild(ITreeNode $child) { + array_push($this->children, $child); } } Modified: trunk/examples/classes/Treetest/TreeDao.php =================================================================== --- trunk/examples/classes/Treetest/TreeDao.php 2013-06-27 03:18:25 UTC (rev 41) +++ trunk/examples/classes/Treetest/TreeDao.php 2013-06-28 14:49:43 UTC (rev 42) @@ -28,15 +28,22 @@ class TreeDao extends DaoBase { + const ENTITY_CLASS_NAME = 'Treetest\Node'; + /** * @var NestedSetStrategy */ private $nestedSetStrategy; + /** + * @var GenericNestedSetDelegate + */ + private $nestedSetDelegate; + public function __construct(EntityManager $entityManager) { - $delagate = new GenericNestedSetDelegate($entityManager, 'Treetest\Node'); -// $delagate->setGroupFieldName('root_id'); - $this->nestedSetStrategy = new NestedSetStrategy($delagate); + $this->setEntityManager($entityManager); + $this->nestedSetDelegate = new GenericNestedSetDelegate($entityManager, self::ENTITY_CLASS_NAME); + $this->nestedSetStrategy = new NestedSetStrategy($this->nestedSetDelegate); } /** @@ -45,4 +52,22 @@ public function getNestedSetStrategy() { return $this->nestedSetStrategy; } + + public function loadTree($rootNodeIdOrEntity) { + if(!$rootNodeIdOrEntity instanceof Node) { + $rootNodeIdOrEntity = $this->getEntityManager()->find(self::ENTITY_CLASS_NAME, $rootNodeIdOrEntity); + } + + // obtain NodeInfo (left / right boundaries + group info) for the tree part rooted at given node + $rootNodeInfo = $this->nestedSetDelegate->getNodeInfo($rootNodeIdOrEntity); + + // construct our base query + $qb = $this->getEntityManager()->createQueryBuilder()->select('e')->from(self::ENTITY_CLASS_NAME, 'e'); + + // augment query with subtree limits + $this->nestedSetDelegate->augmentQueryWithSubtreeLimits($qb, $rootNodeInfo); + + // execute query and create tree structure from result + return $this->nestedSetStrategy->buildTreeStructure($qb->getQuery()->execute()); + } } Modified: trunk/examples/index2.php =================================================================== --- trunk/examples/index2.php 2013-06-27 03:18:25 UTC (rev 41) +++ trunk/examples/index2.php 2013-06-28 14:49:43 UTC (rev 42) @@ -22,54 +22,62 @@ */ use Treetest\Node; +use Bee\Persistence\Behaviors\NestedSet\ITreeNode; require_once('bootstrap.php'); -function addChild(&$children, Node $node) { +function addChild(ITreeNode $parent, Node $node) { global $entityManager; $entityManager->persist($node); - array_push($children, $node); + $parent->appendChild($node); } -$root = new Node('Root Node'); +$treeDao = $ctx->getBean('treeDao', 'Treetest\TreeDao'); + +$root = new Node('Root Node', 15); $entityManager->persist($root); -addChild($root->getChildren(), new Node('Child 1-1')); -addChild($root->getChildren(), new Node('Child 1-2')); +addChild($root, new Node('Child 1-1')); +addChild($root, new Node('Child 1-2')); $child13 = new Node('Child 1-3'); -addChild($root->getChildren(), $child13); +addChild($root, $child13); -addChild($child13->getChildren(), new Node('Child 1-3-1')); -addChild($child13->getChildren(), new Node('Child 1-3-2')); +addChild($child13, new Node('Child 1-3-1')); +addChild($child13, new Node('Child 1-3-2')); -$treeDao = $ctx->getBean('treeDao', 'Treetest\TreeDao'); - $treeDao->getNestedSetStrategy()->saveStructure($root); $entityManager->flush(); $entityManager->close(); +//exit(); + + // new EM instance $entityManager = $ctx->getBean('entityManager'); $c12 = $entityManager->getRepository('Treetest\Node')->findOneBy(array('name' => 'Child 1-2')); -addChild($c12->getChildren(), new Node('Child 1-2-1')); -addChild($c12->getChildren(), new Node('Child 1-2-2')); +addChild($c12, new Node('Child 1-2-1')); +addChild($c12, new Node('Child 1-2-2')); $treeDao->getNestedSetStrategy()->saveStructure($c12); $entityManager->flush(); $entityManager->close(); +//exit(); + // new EM instance $entityManager = $ctx->getBean('entityManager'); +//$entityManager = new \Doctrine\ORM\EntityManager(); + $c12 = $entityManager->getRepository('Treetest\Node')->findOneBy(array('name' => 'Child 1-2')); -//array_pop($c12->getChildren()); +$treeDao->getNestedSetStrategy()->saveStructure($c12); -$treeDao->getNestedSetStrategy()->saveStructure($c12); $entityManager->flush(); $entityManager->close(); +var_dump($treeDao->loadTree($root)); Modified: trunk/framework/Bee/Persistence/Behaviors/NestedSet/IDelegate.php =================================================================== --- trunk/framework/Bee/Persistence/Behaviors/NestedSet/IDelegate.php 2013-06-27 03:18:25 UTC (rev 41) +++ trunk/framework/Bee/Persistence/Behaviors/NestedSet/IDelegate.php 2013-06-28 14:49:43 UTC (rev 42) @@ -44,17 +44,23 @@ * @param NodeInfo $nodeInfo * @param bool|int $newLft * @param bool|int $newLvl - * @param mixed $restriction - * @return + * @return void */ - public function setPosition($nestedSetEntity, NodeInfo $nodeInfo, $newLft = false, $newLvl = false, $restriction = false); + public function setPosition($nestedSetEntity, NodeInfo $nodeInfo, $newLft = false, $newLvl = false); /** + * @param NodeInfo $parentNodeInfo + * @return void + */ + public function unsetChildGroupKeys(NodeInfo $parentNodeInfo); + + /** * @param mixed $nestedSetEntity * @param int $delta * @param int $lowerBoundIncl * @param int $upperBoundExcl - * @param mixed $restriction + * @param array $groupKey + * @return void */ - public function shift($nestedSetEntity, $delta, $lowerBoundIncl, $upperBoundExcl, $restriction = false); + public function shift($nestedSetEntity, $delta, $lowerBoundIncl, $upperBoundExcl, array $groupKey); } Modified: trunk/framework/Bee/Persistence/Behaviors/NestedSet/ITreeNode.php =================================================================== --- trunk/framework/Bee/Persistence/Behaviors/NestedSet/ITreeNode.php 2013-06-27 03:18:25 UTC (rev 41) +++ trunk/framework/Bee/Persistence/Behaviors/NestedSet/ITreeNode.php 2013-06-28 14:49:43 UTC (rev 42) @@ -25,12 +25,13 @@ interface ITreeNode { /** - * @return ITreeNode + * @return ITreeNode[] */ - public function getParent(); + public function getChildren(); /** - * @return ITreeNode[] + * @param ITreeNode $child + * @return void */ - public function getChildren(); + public function appendChild(ITreeNode $child); } Modified: trunk/framework/Bee/Persistence/Behaviors/NestedSet/NodeInfo.php =================================================================== --- trunk/framework/Bee/Persistence/Behaviors/NestedSet/NodeInfo.php 2013-06-27 03:18:25 UTC (rev 41) +++ trunk/framework/Bee/Persistence/Behaviors/NestedSet/NodeInfo.php 2013-06-28 14:49:43 UTC (rev 42) @@ -21,7 +21,6 @@ * Date: 07.05.13 * Time: 17:43 */ - class NodeInfo { const LEFT_KEY = 'lft'; @@ -43,6 +42,11 @@ */ public $lvl; + /** + * @var array + */ + public $groupKey; + public function __construct(array $tuple = null) { if(!is_null($tuple)) { $this->lft = is_numeric($tuple[self::LEFT_KEY]) ? $tuple[self::LEFT_KEY] : false; @@ -97,9 +101,21 @@ return $this->rgt > 0 && $this->lft > 0; } - function __toString() { - return "NodeInfo(lft:{$this->lft}|rgt:{$this->rgt}|lvl:{$this->lvl})"; + /** + * @return array + */ + public function getGroupKey() { + return $this->groupKey; } + /** + * @param array $groupKey + */ + public function setGroupKey($groupKey) { + $this->groupKey = $groupKey; + } + function __toString() { + return "NodeInfo(lft:{$this->lft}|rgt:{$this->rgt}|lvl:{$this->lvl}|group:[".implode(',', $this->groupKey)."])"; + } } Modified: trunk/framework/Bee/Persistence/Behaviors/NestedSet/Strategy.php =================================================================== --- trunk/framework/Bee/Persistence/Behaviors/NestedSet/Strategy.php 2013-06-27 03:18:25 UTC (rev 41) +++ trunk/framework/Bee/Persistence/Behaviors/NestedSet/Strategy.php 2013-06-28 14:49:43 UTC (rev 42) @@ -178,7 +178,7 @@ if ($subjectInfo->isInTree()) { // ... temporarily move it to a neutral position, so as to avoid any conflicts (e.g. SQL constraints) // (keep its original level for now) - $this->delegate->setPosition($subject, $subjectInfo, -$subjectInfo->getSpan(), $subjectInfo->lvl, $groupRestriction); + $this->delegate->setPosition($subject, $subjectInfo, -$subjectInfo->getSpan(), $subjectInfo->lvl); $subjectInfo->update(-$subjectInfo->getSpan(), $subjectInfo->lvl); } @@ -189,7 +189,7 @@ self::getLog()->debug("setting final position of subject to lft = $newLeft, lvl = $level"); // move subject to final position - $this->delegate->setPosition($subject, $subjectInfo, $newLeft, $level, $groupRestriction); + $this->delegate->setPosition($subject, $subjectInfo, $newLeft, $level); $subjectInfo->update($newLeft, $level); } @@ -210,10 +210,10 @@ } // store the subtree in the negative area (in case we do not want to delete it, but rather move it to a different tree) - $this->delegate->setPosition($subject, $subjectInfo, -$subjectInfo->getSpan(), 0, $groupRestriction); + $this->delegate->setPosition($subject, $subjectInfo, -$subjectInfo->getSpan(), 0); // restore numbering consistency - $this->delegate->shift($subject, -$subjectInfo->getSpan(), $subjectInfo->rgt + 1, false, $groupRestriction); + $this->delegate->shift($subject, -$subjectInfo->getSpan(), $subjectInfo->rgt + 1, false, $subjectInfo->getGroupKey()); } /** Modified: trunk/framework/Bee/Persistence/Behaviors/NestedSet/TreeStrategy.php =================================================================== --- trunk/framework/Bee/Persistence/Behaviors/NestedSet/TreeStrategy.php 2013-06-27 03:18:25 UTC (rev 41) +++ trunk/framework/Bee/Persistence/Behaviors/NestedSet/TreeStrategy.php 2013-06-28 14:49:43 UTC (rev 42) @@ -44,12 +44,13 @@ public function saveStructure(ITreeNode $structureRoot) { $rootNodeInfo = $this->nodeInfoCache->contains($structureRoot) ? $this->nodeInfoCache->offsetGet($structureRoot) : $this->delegate->getNodeInfo($structureRoot); + $this->delegate->unsetChildGroupKeys($rootNodeInfo); $oldNext = $rootNodeInfo->rgt + 1; - $next = $this->calculateNodeInfo($structureRoot, $rootNodeInfo->lft, $rootNodeInfo->lvl); + $next = $this->calculateNodeInfo($structureRoot, $rootNodeInfo->lft, $rootNodeInfo->lvl, $rootNodeInfo->getGroupKey()); $delta = $next - $oldNext; - $this->delegate->shift($structureRoot, $delta, $oldNext, false); + $this->delegate->shift($structureRoot, $delta, $oldNext, false, $rootNodeInfo->getGroupKey()); $myDelegate = $this->delegate; $this->walkTree($structureRoot, function(ITreeNode $currentNode, NodeInfo $nodeInfo) use ($myDelegate) { @@ -57,6 +58,11 @@ }); } + /** + * Walk the tree under $structureRoot iteratively in preorder and apply the given lambda $func to each node. + * @param ITreeNode $structureRoot + * @param $func + */ protected function walkTree(ITreeNode $structureRoot, $func) { $stack = array($structureRoot); while(count($stack) > 0) { @@ -72,9 +78,10 @@ * @param ITreeNode $currentNode * @param $lft * @param $lvl + * @param array $groupKey * @return mixed */ - protected function calculateNodeInfo(ITreeNode $currentNode, $lft, $lvl) { + protected function calculateNodeInfo(ITreeNode $currentNode, $lft, $lvl, array $groupKey) { $nodeInfo = new NodeInfo(); $this->nodeInfoCache->attach($currentNode, $nodeInfo); @@ -82,9 +89,10 @@ $nodeInfo->lft = $lft; $lft++; foreach($currentNode->getChildren() as $child) { - $lft = $this->calculateNodeInfo($child, $lft, $lvl + 1); + $lft = $this->calculateNodeInfo($child, $lft, $lvl + 1, $groupKey); } $nodeInfo->rgt = $lft; + $nodeInfo->setGroupKey($groupKey); return $nodeInfo->rgt + 1; } @@ -95,4 +103,46 @@ protected function getNodeInfoCache() { return $this->nodeInfoCache; } + + /** + * @param ITreeNode[] $nodesList + * @return ITreeNode + */ + public function buildTreeStructure(array $nodesList) { + $nodeStack = new \SplStack(); + + $lastNode = null; + $lastLevel = false; + + foreach ($nodesList as $node) { + $level = $this->delegate->getNodeInfo($node)->lvl; + + if ($lastLevel !== false) { + if ($level > $lastLevel) { + // dive exactly one level + // must be exactly 1 larger than last level (otherwise intermediate nodes are probably missing) + \Bee_Utils_Assert::isTrue($level == $lastLevel + 1, sprintf('Malformed nodes list, missing intermediate levels between %d and %d', $lastLevel, $level)); + // use last node as current parent + $nodeStack->push($lastNode); + } else { + // $lastLevel >= $level; emerge one or multiple levels + for ($i = $lastLevel; $i > $level; $i--) { + $nodeStack->pop(); + } + } + + // add to current parent (which must exist!!) + \Bee_Utils_Assert::isTrue(!$nodeStack->isEmpty(), sprintf('No current parent on level %d (if this happens on level 0, it usually means that your query returned multiple roots for this tree set)', $level)); + + $nodeStack->top()->appendChild($node); + } + + $lastLevel = $level; + $lastNode = $node; + } + + return $nodeStack->bottom(); + } + + } Modified: trunk/framework/Bee/Persistence/Doctrine2/Behaviors/DelegateBase.php =================================================================== --- trunk/framework/Bee/Persistence/Doctrine2/Behaviors/DelegateBase.php 2013-06-27 03:18:25 UTC (rev 41) +++ trunk/framework/Bee/Persistence/Doctrine2/Behaviors/DelegateBase.php 2013-06-28 14:49:43 UTC (rev 42) @@ -31,11 +31,18 @@ private $entityName; /** + * @var array + */ + private $groupKeyFields; + + /** * @param string $entityName + * @param array $groupKeyFields */ - public function __construct($entityName) { + public function __construct($entityName, array $groupKeyFields) { \Bee_Utils_Assert::hasText($entityName, 'Entity name required, must not be empty'); $this->entityName = $entityName; + $this->groupKeyFields = $groupKeyFields; } /** @@ -44,4 +51,11 @@ public function getEntityName() { return $this->entityName; } + + /** + * @return array + */ + public function getGroupKeyFields() { + return $this->groupKeyFields; + } } Modified: trunk/framework/Bee/Persistence/Doctrine2/Behaviors/GenericNestedSetDelegate.php =================================================================== --- trunk/framework/Bee/Persistence/Doctrine2/Behaviors/GenericNestedSetDelegate.php 2013-06-27 03:18:25 UTC (rev 41) +++ trunk/framework/Bee/Persistence/Doctrine2/Behaviors/GenericNestedSetDelegate.php 2013-06-28 14:49:43 UTC (rev 42) @@ -16,6 +16,7 @@ * limitations under the License. */ use Bee\Persistence\Behaviors\NestedSet\IDelegate; +use Bee\Persistence\Behaviors\NestedSet\ITreeNode; use Bee\Persistence\Behaviors\NestedSet\NodeInfo; use Doctrine\ORM\EntityManager; use Doctrine\ORM\QueryBuilder; @@ -25,7 +26,7 @@ * Date: 21.06.13 * Time: 16:01 */ - + class GenericNestedSetDelegate extends DelegateBase implements IDelegate { /** @@ -46,13 +47,13 @@ /** * @param EntityManager $entityManager * @param string $entityName + * @param array $rootKeyFields */ - public function __construct(EntityManager $entityManager, $entityName) { - parent::__construct($entityName); + public function __construct(EntityManager $entityManager, $entityName, array $rootKeyFields = array('rootId')) { + parent::__construct($entityName, $rootKeyFields); $this->setEntityManager($entityManager); } - /** * @param string $leftFieldName */ @@ -85,14 +86,30 @@ $result->lft = $bw->getPropertyValue($this->leftFieldName); $result->rgt = $bw->getPropertyValue($this->rightFieldName); $result->lvl = $bw->getPropertyValue($this->levelFieldName); - if(is_null($result->lft)) { + if (is_null($result->lft)) { $result->lft = 1; $result->lvl = 0; } + $result->setGroupKey($this->extractGroupKey($bw)); return $result; } /** + * @param mixed|\Bee_Beans_BeanWrapper $nestedSetEntityOrBeanWrapper + * @return array + */ + protected function extractGroupKey($nestedSetEntityOrBeanWrapper) { + if (!($nestedSetEntityOrBeanWrapper instanceof \Bee_Beans_BeanWrapper)) { + $nestedSetEntityOrBeanWrapper = new \Bee_Beans_BeanWrapper($nestedSetEntityOrBeanWrapper); + } + $groupKey = array(); + foreach ($this->getGroupKeyFields() as $groupFieldName) { + $groupKey[$groupFieldName] = $nestedSetEntityOrBeanWrapper->getPropertyValue($groupFieldName); + } + return $groupKey; + } + + /** * @param mixed $nestedSetEntity * @param mixed $restriction * @return NodeInfo @@ -106,41 +123,106 @@ * @param NodeInfo $nodeInfo * @param bool|int $newLft * @param bool|int $newLvl - * @param mixed $restriction */ - public function setPosition($nestedSetEntity, NodeInfo $nodeInfo, $newLft = false, $newLvl = false, $restriction = false) { + public function setPosition($nestedSetEntity, NodeInfo $nodeInfo, $newLft = false, $newLvl = false) { $bw = new \Bee_Beans_BeanWrapper($nestedSetEntity); $bw->setPropertyValue($this->leftFieldName, $nodeInfo->lft); $bw->setPropertyValue($this->rightFieldName, $nodeInfo->rgt); $bw->setPropertyValue($this->levelFieldName, $nodeInfo->lvl); + + $grpKey = $nodeInfo->getGroupKey(); + foreach ($this->getGroupKeyFields() as $groupKeyField) { + $bw->setPropertyValue($groupKeyField, $grpKey[$groupKeyField]); + } // todo: implement the other cases (i.e. for the non-tree strategy API) } /** + * @param NodeInfo $parentNodeInfo + * @return void + */ + public function unsetChildGroupKeys(NodeInfo $parentNodeInfo) { + $qb = $this->createUpdateBaseQueryBuilder($parentNodeInfo->getGroupKey()); + + // set group key to null... + foreach ($this->getGroupKeyFields() as $groupKeyField) { + $qb->set("e.$groupKeyField", 'NULL'); + } + + // .. on all children of the parent node given by the NodeInfo + $qb->andWhere("e.{$this->leftFieldName} > :parentLft") + ->setParameter('parentLft', $parentNodeInfo->lft) + ->andWhere("e.{$this->rightFieldName} < :parentRgt") + ->setParameter('parentRgt', $parentNodeInfo->rgt); + $qb->getQuery()->execute(); + } + + /** * @param mixed $nestedSetEntity * @param int $delta * @param int $lowerBoundIncl * @param int $upperBoundExcl - * @param mixed $restriction + * @param array $groupKey */ - public function shift($nestedSetEntity, $delta, $lowerBoundIncl, $upperBoundExcl, $restriction = false) { - $this->buildShiftQuery($this->leftFieldName, $delta, $lowerBoundIncl, $upperBoundExcl, $restriction)->execute(); - $this->buildShiftQuery($this->rightFieldName, $delta, $lowerBoundIncl, $upperBoundExcl, $restriction)->execute(); + public function shift($nestedSetEntity, $delta, $lowerBoundIncl, $upperBoundExcl, array $groupKey) { + $this->buildShiftQuery($this->leftFieldName, $delta, $lowerBoundIncl, $upperBoundExcl, $groupKey)->execute(); + $this->buildShiftQuery($this->rightFieldName, $delta, $lowerBoundIncl, $upperBoundExcl, $groupKey)->execute(); // todo: implement the other cases (i.e. for the non-tree strategy API) } /** + * @param QueryBuilder $qb + * @param NodeInfo $rootNodeInfo + * @param string $rootEntityAlias + * @param bool $maxLvl + */ + public function augmentQueryWithSubtreeLimits(QueryBuilder $qb, NodeInfo $rootNodeInfo, $rootEntityAlias = 'e', $maxLvl = false) { + if ($rootEntityAlias) { + $rootEntityAlias = $rootEntityAlias . '.'; + } + + // limit to subtree of this root node + $qb->andWhere("$rootEntityAlias{$this->leftFieldName} >= :limitLft") + ->setParameter('limitLft', $rootNodeInfo->lft) + ->andWhere("$rootEntityAlias{$this->rightFieldName} <= :limitRgt") + ->setParameter('limitRgt', $rootNodeInfo->rgt); + + // make sure we get only results from current group + $this->augmentQueryWithGroupLimits($qb, $rootNodeInfo->getGroupKey()); + + // apply max level restriction if needed + if ($maxLvl) { + $qb->andWhere("$rootEntityAlias{$this->leftFieldName} <= :maxLvl")->setParameter('maxLvl', $maxLvl); + } + + // proper ordering + $qb->orderBy("$rootEntityAlias{$this->leftFieldName}", 'ASC'); + } + + /** * @param string $fieldName * @param int $delta * @param int $lowerBoundIncl * @param int $upperBoundExcl - * @param mixed $restriction + * @param array $groupKey * @return \Doctrine\ORM\Query */ - protected function buildShiftQuery($fieldName, $delta, $lowerBoundIncl, $upperBoundExcl, $restriction = false) { - return $this->getEntityManager()->createQueryBuilder()->update($this->getEntityName(), 'e') - ->set('e.'.$fieldName, 'e.'.$fieldName .' + :delta')->setParameter('delta', $delta) - ->where('e.'.$fieldName . ' >= :lbIncl')->setParameter('lbIncl', $lowerBoundIncl)->getQuery(); -// ->orderBy('e.'.$fieldName, $delta > 0 ? 'DESC' : 'ASC')->getQuery(); + protected function buildShiftQuery($fieldName, $delta, $lowerBoundIncl, $upperBoundExcl, array $groupKey) { + $qb = $this->createUpdateBaseQueryBuilder($groupKey); + $qb->set("e.$fieldName", "e.$fieldName + :delta")->setParameter('delta', $delta) + ->andWhere("e.$fieldName >= :lbIncl")->setParameter('lbIncl', $lowerBoundIncl); + return $qb->getQuery(); } + + protected function createUpdateBaseQueryBuilder(array $groupKey) { + $qb = $this->getEntityManager()->createQueryBuilder()->update($this->getEntityName(), 'e'); + return $this->augmentQueryWithGroupLimits($qb, $groupKey); + } + + protected function augmentQueryWithGroupLimits(QueryBuilder $qb, array $groupKey) { + foreach ($this->getGroupKeyFields() as $groupFieldName) { + $qb->andWhere("e.$groupFieldName = :$groupFieldName")->setParameter($groupFieldName, $groupKey[$groupFieldName]); + } + return $qb; + } } Modified: trunk/framework/Bee/Persistence/Doctrine2/Log4PHPLogger.php =================================================================== --- trunk/framework/Bee/Persistence/Doctrine2/Log4PHPLogger.php 2013-06-27 03:18:25 UTC (rev 41) +++ trunk/framework/Bee/Persistence/Doctrine2/Log4PHPLogger.php 2013-06-28 14:49:43 UTC (rev 42) @@ -46,7 +46,7 @@ * @return void */ public function startQuery($sql, array $params = null, array $types = null) { - self::getLog()->trace('SQL : [' . $sql . '] PARAMS : [' . serialize($params) . '] TYPES: ['. serialize($types) . ']'); + self::getLog()->trace('SQL : [' . $sql . '] PARAMS : [' . implode(', ', $params) . '] TYPES: ['. implode(', ', $types) . ']'); $this->startTime = microtime(true); } Modified: trunk/framework/Bee/Persistence/Pdo/Behaviors/DelegateBase.php =================================================================== --- trunk/framework/Bee/Persistence/Pdo/Behaviors/DelegateBase.php 2013-06-27 03:18:25 UTC (rev 41) +++ trunk/framework/Bee/Persistence/Pdo/Behaviors/DelegateBase.php 2013-06-28 14:49:43 UTC (rev 42) @@ -79,9 +79,10 @@ * @param bool $restriction * @return string */ - protected function getDomainRestrictionString($entity, array &$params, $restriction = false) { + protected function getDomainRestrictionString($entity, array &$params, array $groupKey = array()) { $result = '1=1'; if ($this->getGroupFieldName()) { + //todo: fix this! if ($restriction === false) { // determine group value $restriction = $this->getGroup($entity); Modified: trunk/framework/Bee/Persistence/Pdo/Behaviors/GenericNestedSetDelegate.php =================================================================== --- trunk/framework/Bee/Persistence/Pdo/Behaviors/GenericNestedSetDelegate.php 2013-06-27 03:18:25 UTC (rev 41) +++ trunk/framework/Bee/Persistence/Pdo/Behaviors/GenericNestedSetDelegate.php 2013-06-28 14:49:43 UTC (rev 42) @@ -102,21 +102,20 @@ /** * @param mixed $nestedSetEntity * @param NodeInfo $nodeInfo - * @param int $newLft - * @param int $newLvl - * @param mixed $restriction + * @param bool|int $newLft + * @param bool|int $newLvl */ - public function setPosition($nestedSetEntity, NodeInfo $nodeInfo, $newLft = false, $newLvl = false, $restriction = false) { + public function setPosition($nestedSetEntity, NodeInfo $nodeInfo, $newLft = false, $newLvl = false) { if ($nodeInfo->hasStructure()) { $params = array(':pos_delta' => $newLft - $nodeInfo->lft, ':lvl_delta' => $newLvl - $nodeInfo->lvl, ':lft' => $nodeInfo->lft, ':rgt' => $nodeInfo->rgt); $qryString = sprintf(self::SET_POSITION_QUERY_TEMPLATE, $this->leftFieldName, $this->rightFieldName, $this->levelFieldName, - $this->getQueryDomain(), $this->getDomainRestrictionString($nestedSetEntity, $params, $restriction)); + $this->getQueryDomain(), $this->getDomainRestrictionString($nestedSetEntity, $params, $nodeInfo->getGroupKey())); } else { $params = array(':lft' => $newLft, ':rgt' => $newLft + $nodeInfo->getSpan() - 1, ':lvl' => $newLvl); $qryString = sprintf(self::SET_POSITION_QUERY_BY_ID_TEMPLATE, $this->leftFieldName, $this->rightFieldName, $this->levelFieldName, $this->getQueryDomain(), $this->getIdentityRestrictionString($nestedSetEntity, $params), - $this->getDomainRestrictionString($nestedSetEntity, $params, $restriction)); + $this->getDomainRestrictionString($nestedSetEntity, $params, $nodeInfo->getGroupKey())); } $this->getPdo()->prepare($qryString)->execute($params); } @@ -126,9 +125,9 @@ * @param int $delta * @param int $lowerBoundIncl * @param int $upperBoundExcl - * @param mixed $restriction + * @param array $groupKey */ - public function shift($nestedSetEntity, $delta, $lowerBoundIncl, $upperBoundExcl, $restriction = false) { + public function shift($nestedSetEntity, $delta, $lowerBoundIncl, $upperBoundExcl, array $groupKey) { $params = array(':delta' => $delta, ':lower_bound' => $lowerBoundIncl); if ($upperBoundExcl !== false) { $params[':upper_bound'] = $upperBoundExcl; @@ -136,7 +135,7 @@ $qryTempl = $upperBoundExcl !== false ? self::SHIFT_QUERY_TEMPLATE : self::SHIFT_QUERY_OPEN_TEMPLATE; $qryDomain = $this->getQueryDomain(); - $domRes = $this->getDomainRestrictionString($nestedSetEntity, $params, $restriction); + $domRes = $this->getDomainRestrictionString($nestedSetEntity, $params, $groupKey); // order updates only if supported by the driver and not operating on a joined relation $orderUpdate = $this->pdoSupportsFeature(FeatureDetector::FEATURE_ORDERED_UPDATE) && stripos($qryDomain, ' JOIN ') === false; Modified: trunk/tests/Bee/Persistence/Behaviors/NestedSet/DelegateMock.php =================================================================== --- trunk/tests/Bee/Persistence/Behaviors/NestedSet/DelegateMock.php 2013-06-27 03:18:25 UTC (rev 41) +++ trunk/tests/Bee/Persistence/Behaviors/NestedSet/DelegateMock.php 2013-06-28 14:49:43 UTC (rev 42) @@ -58,10 +58,9 @@ * @param NodeInfo $nodeInfo * @param bool|int $newLft * @param bool|int $newLvl - * @param mixed $restriction */ - public function setPosition($nestedSetEntity, NodeInfo $nodeInfo, $newLft = false, $newLvl = false, $restriction = false) { - array_push($this->protocol, sprintf('id=%s; lft=%d; rgt=%d; lvl=%d;', $nestedSetEntity->getId(), $nodeInfo->lft, $nodeInfo->rgt, $nodeInfo->lvl)); + public function setPosition($nestedSetEntity, NodeInfo $nodeInfo, $newLft = false, $newLvl = false) { + array_push($this->protocol, sprintf('id=%s; lft=%d; rgt=%d; lvl=%d; grp=[%s]', $nestedSetEntity->getId(), $nodeInfo->lft, $nodeInfo->rgt, $nodeInfo->lvl, implode(',', $nodeInfo->getGroupKey()))); } /** @@ -69,9 +68,17 @@ * @param int $delta * @param int $lowerBoundIncl * @param int $upperBoundExcl - * @param mixed $restriction + * @param array $groupKey */ - public function shift($nestedSetEntity, $delta, $lowerBoundIncl, $upperBoundExcl, $restriction = false) { - array_push($this->protocol, sprintf('delta=%d; %d<=lft/rgt%s;', $delta, $lowerBoundIncl, $upperBoundExcl !== false ? '<'.$upperBoundExcl : '')); + public function shift($nestedSetEntity, $delta, $lowerBoundIncl, $upperBoundExcl, array $groupKey) { + array_push($this->protocol, sprintf('delta=%d; %d<=lft/rgt%s; grp=[%s]', $delta, $lowerBoundIncl, $upperBoundExcl !== false ? '<'.$upperBoundExcl : '', implode(',', $groupKey))); } + + /** + * @param NodeInfo $parentNodeInfo + * @return void + */ + public function unsetChildGroupKeys(NodeInfo $parentNodeInfo) { + // TODO: Implement unsetChildGroupKeys() method. + } } Modified: trunk/tests/Bee/Persistence/Behaviors/NestedSet/TestTreeNode.php =================================================================== --- trunk/tests/Bee/Persistence/Behaviors/NestedSet/TestTreeNode.php 2013-06-27 03:18:25 UTC (rev 41) +++ trunk/tests/Bee/Persistence/Behaviors/NestedSet/TestTreeNode.php 2013-06-28 14:49:43 UTC (rev 42) @@ -40,33 +40,18 @@ private $children; /** + * @param array $id * @param TestTreeNode[] $children * @param array $nodeInfo + * @return \Bee\Persistence\Behaviors\NestedSet\TestTreeNode */ public function __construct($id, $children, array $nodeInfo) { parent::__construct($nodeInfo); $this->id = $id; $this->children = $children; - foreach($this->children as $child) { - $child->setParent($this); - } } /** - * @return ITreeNode - */ - public function getParent() { - return $this->parent; - } - - /** - * @param \Bee\Persistence\Behaviors\NestedSet\ITreeNode $parent - */ - public function setParent($parent) { - $this->parent = $parent; - } - - /** * @return ITreeNode[] */ public function getChildren() { @@ -79,4 +64,12 @@ public function getId() { return $this->id; } + + /** + * @param ITreeNode $child + * @return void + */ + public function appendChild(ITreeNode $child) { + array_push($this->children, $child); + } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <m_p...@us...> - 2013-06-28 17:29:49
|
Revision: 43 http://sourceforge.net/p/beeframework/code/43 Author: m_plomer Date: 2013-06-28 17:29:46 +0000 (Fri, 28 Jun 2013) Log Message: ----------- - removed proprietary parts from SF Removed Paths: ------------- trunk/examples/bootstrap.php trunk/examples/classes/Persistence/ trunk/examples/classes/Treetest/ trunk/examples/cli-config.php trunk/examples/composer.json trunk/examples/conf/ trunk/examples/index.php trunk/examples/index2.php trunk/framework/Bee/Persistence/Behaviors/ trunk/framework/Bee/Persistence/Doctrine/Behaviors/ trunk/framework/Bee/Persistence/Doctrine2/Behaviors/ trunk/framework/Bee/Persistence/Pdo/Behaviors/ trunk/tests/Bee/Persistence/Behaviors/ Deleted: trunk/examples/bootstrap.php =================================================================== --- trunk/examples/bootstrap.php 2013-06-28 14:49:43 UTC (rev 42) +++ trunk/examples/bootstrap.php 2013-06-28 17:29:46 UTC (rev 43) @@ -1,49 +0,0 @@ -<?php -/* - * Copyright 2008-2010 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * User: mp - * Date: 21.06.13 - * Time: 14:15 - */ - -unlink('db/examples.sqlite'); - -require_once '../framework/Bee/Framework.php'; -require_once 'vendor/autoload.php'; - -// Verzeichnis mit Applikations-Klassen zum Classpath hinzufügen -Bee_Framework::addApplicationIncludePath('classes'); - -Bee_Framework::addApplicationIncludePath('../libs/apache-log4php-2.3.0'); -Bee_Framework::addApplicationIncludePath('../libs/apache-log4php-2.3.0/helpers'); -Bee_Framework::addApplicationIncludePath('../libs/apache-log4php-2.3.0/pattern'); -Bee_Framework::addApplicationIncludePath('../libs/apache-log4php-2.3.0/layouts'); -Bee_Framework::addApplicationIncludePath('../libs/apache-log4php-2.3.0/appenders'); -Bee_Framework::addApplicationIncludePath('../libs/apache-log4php-2.3.0/configurators'); -Bee_Framework::addApplicationIncludePath('../libs/apache-log4php-2.3.0/renderers'); - -Logger::configure('conf/log4php.xml'); - -$ctx = new Bee_Context_Xml('conf/context.xml'); - -$conn = $ctx->getBean('pdoConnection'); - -$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); - -// obtaining the entity manager -$entityManager = $ctx->getBean('entityManager'); Deleted: trunk/examples/cli-config.php =================================================================== --- trunk/examples/cli-config.php 2013-06-28 14:49:43 UTC (rev 42) +++ trunk/examples/cli-config.php 2013-06-28 17:29:46 UTC (rev 43) @@ -1,26 +0,0 @@ -<?php -/* - * Copyright 2008-2010 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * User: mp - * Date: 21.06.13 - * Time: 14:40 - */ - -require_once "bootstrap.php"; - -$helperSet = $ctx->getBean('cliHelperSet'); Deleted: trunk/examples/composer.json =================================================================== --- trunk/examples/composer.json 2013-06-28 14:49:43 UTC (rev 42) +++ trunk/examples/composer.json 2013-06-28 17:29:46 UTC (rev 43) @@ -1,7 +0,0 @@ -{ - "require": { - "doctrine/orm": "~2.3@stable", - "doctrine/doctrine1": "~1.2@stable" - }, - "minimum-stability": "dev" -} \ No newline at end of file Deleted: trunk/examples/index.php =================================================================== --- trunk/examples/index.php 2013-06-28 14:49:43 UTC (rev 42) +++ trunk/examples/index.php 2013-06-28 17:29:46 UTC (rev 43) @@ -1,161 +0,0 @@ -<?php -/* - * Copyright 2008-2010 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * User: mp - * Date: 07.05.13 - * Time: 12:25 - */ - -require_once('bootstrap.php'); - -use Persistence\Pdo\SimpleHierarchyDao; -use Persistence\Pdo\OrderedColorsDao as OrderedColorsDaoPdo; -use Persistence\Doctrine\OrderedColorsDao as OrderedColorsDaoDoctrine; - -/* - * == EXAMPLE : Ordered Dao (PDO) ============================================= - */ -$dao = $ctx->getBean('orderedColorsDaoPdo'); - -$dao->createTable(); -$dao->deleteAllColors(); - -$redId = $dao->addColor('Red', '#ff0000', 1); -$greenId = $dao->addColor('Green', '#00ff00', 1); -$blueId = $dao->addColor('Blue', '#0000ff', 1); -$dao->addColor('Yellow', '#ffff00', 1); -$purpleId = $dao->addColor('Purple', '#ff00ff', 1); -$cyanId = $dao->addColor('Cyan', '#00ffff', 1); - -$redId2 = $dao->addColor('Red2', '#ff0000', 2); -$greenId2 = $dao->addColor('Green2', '#00ff00', 2); -$blueId2 = $dao->addColor('Blue2', '#0000ff', 2); -$yellowId2 = $dao->addColor('Yellow2', '#ffff00', 2); - -$dao->doInTransaction(function(OrderedColorsDaoPdo $dao, \Logger $log) use ($greenId, $purpleId) { - $dao->getOrderedStrategy()->moveAfter($greenId, $purpleId); -}); - -$dao->doInTransaction(function(OrderedColorsDaoPdo $dao, \Logger $log) use ($redId, $cyanId) { - $dao->getOrderedStrategy()->moveAfter($redId, $cyanId); -}); - -$dao->doInTransaction(function(OrderedColorsDaoPdo $dao, \Logger $log) use ($purpleId, $redId) { - $dao->getOrderedStrategy()->moveBefore($purpleId, $redId); -}); - -$dao->doInTransaction(function(OrderedColorsDaoPdo $dao, \Logger $log) use ($blueId) { - $dao->getOrderedStrategy()->remove($blueId); -}); - -$dao->doInTransaction(function(OrderedColorsDaoPdo $dao, \Logger $log) use ($redId) { - $dao->getOrderedStrategy()->remove($redId); -}); - -/* - * == EXAMPLE : Ordered Dao (Doctrine) ============================================= - */ -$dao = $ctx->getBean('orderedColorsDaoDoctrine'); - -$dao->createTable(); -$dao->deleteAllColors(); - -$redId = $dao->addColor('Red', '#ff0000', 1); -$greenId = $dao->addColor('Green', '#00ff00', 1); -$blueId = $dao->addColor('Blue', '#0000ff', 1); -$dao->addColor('Yellow', '#ffff00', 1); -$purpleId = $dao->addColor('Purple', '#ff00ff', 1); -$cyanId = $dao->addColor('Cyan', '#00ffff', 1); - -$redId2 = $dao->addColor('Red2', '#ff0000', 2); -$greenId2 = $dao->addColor('Green2', '#00ff00', 2); -$blueId2 = $dao->addColor('Blue2', '#0000ff', 2); -$yellowId2 = $dao->addColor('Yellow2', '#ffff00', 2); - -$dao->doInTransaction(function(OrderedColorsDaoDoctrine $dao, \Logger $log) use ($greenId, $purpleId) { - $dao->getOrderedStrategy()->moveAfter($greenId, $purpleId); -}); - -$dao->doInTransaction(function(OrderedColorsDaoDoctrine $dao, \Logger $log) use ($redId, $cyanId) { - $dao->getOrderedStrategy()->moveAfter($redId, $cyanId); -}); - -$dao->doInTransaction(function(OrderedColorsDaoDoctrine $dao, \Logger $log) use ($purpleId, $redId) { - $dao->getOrderedStrategy()->moveBefore($purpleId, $redId); -}); - -$dao->doInTransaction(function(OrderedColorsDaoDoctrine $dao, \Logger $log) use ($blueId) { - $dao->getOrderedStrategy()->remove($blueId); -}); - -$dao->doInTransaction(function(OrderedColorsDaoDoctrine $dao, \Logger $log) use ($redId) { - $dao->getOrderedStrategy()->remove($redId); -}); - -/* - * == EXAMPLE : NestedSet Dao ============================================= - */ -$dao = $ctx->getBean('simpleHierarchyDao'); - -$dao->createTable(); -$dao->deleteAll(); - -$id1 = $dao->addEntry('Entry 1'); -$id2 = $dao->addEntry('Entry 2'); -$id3 = $dao->addEntry('Entry 3'); -$id4 = $dao->addEntry('Entry 4'); -$id5 = $dao->addEntry('Entry 5'); -$id6 = $dao->addEntry('Entry 6'); -$id7 = $dao->addEntry('Entry 7'); -$id8 = $dao->addEntry('Entry 8'); -$id9 = $dao->addEntry('Entry 9'); - - -$dao->doInTransaction(function(SimpleHierarchyDao $dao, \Logger $log) use ($id9, $id1) { - $dao->getNestedSetStrategy()->moveBefore($id9, $id1); -}); - -$dao->doInTransaction(function(SimpleHierarchyDao $dao, \Logger $log) use ($id5, $id4) { - $dao->getNestedSetStrategy()->moveAsFirstChild($id5, $id4); -}); - -$dao->doInTransaction(function(SimpleHierarchyDao $dao, \Logger $log) use ($id6, $id4) { - $dao->getNestedSetStrategy()->moveAsFirstChild($id6, $id4); -}); - -$dao->doInTransaction(function(SimpleHierarchyDao $dao, \Logger $log) use ($id8, $id6) { - $dao->getNestedSetStrategy()->moveAsLastChild($id8, $id6); -}); - -$dao->doInTransaction(function(SimpleHierarchyDao $dao, \Logger $log) use ($id1, $id8) { - $dao->getNestedSetStrategy()->moveAfter($id1, $id8); -}); - -$dao->doInTransaction(function(SimpleHierarchyDao $dao, \Logger $log) use ($id6) { - $dao->getNestedSetStrategy()->remove($id6); -}); - -$dao->doInTransaction(function(SimpleHierarchyDao $dao, \Logger $log) use ($id6, $id9) { - $dao->getNestedSetStrategy()->moveAsLastChild($id6, $id9); -}); - -/* - * == END OF EXAMPLES ============================================= - */ - -echo 'DONE<hr/>'; Deleted: trunk/examples/index2.php =================================================================== --- trunk/examples/index2.php 2013-06-28 14:49:43 UTC (rev 42) +++ trunk/examples/index2.php 2013-06-28 17:29:46 UTC (rev 43) @@ -1,83 +0,0 @@ -<?php -/* - * Copyright 2008-2010 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * User: mp - * Date: 21.06.13 - * Time: 14:17 - */ - -use Treetest\Node; -use Bee\Persistence\Behaviors\NestedSet\ITreeNode; - -require_once('bootstrap.php'); - -function addChild(ITreeNode $parent, Node $node) { - global $entityManager; - $entityManager->persist($node); - $parent->appendChild($node); -} - -$treeDao = $ctx->getBean('treeDao', 'Treetest\TreeDao'); - -$root = new Node('Root Node', 15); -$entityManager->persist($root); - -addChild($root, new Node('Child 1-1')); -addChild($root, new Node('Child 1-2')); - -$child13 = new Node('Child 1-3'); -addChild($root, $child13); - -addChild($child13, new Node('Child 1-3-1')); -addChild($child13, new Node('Child 1-3-2')); - -$treeDao->getNestedSetStrategy()->saveStructure($root); - -$entityManager->flush(); -$entityManager->close(); - -//exit(); - - -// new EM instance -$entityManager = $ctx->getBean('entityManager'); - -$c12 = $entityManager->getRepository('Treetest\Node')->findOneBy(array('name' => 'Child 1-2')); - -addChild($c12, new Node('Child 1-2-1')); -addChild($c12, new Node('Child 1-2-2')); - -$treeDao->getNestedSetStrategy()->saveStructure($c12); -$entityManager->flush(); -$entityManager->close(); - -//exit(); - -// new EM instance -$entityManager = $ctx->getBean('entityManager'); -//$entityManager = new \Doctrine\ORM\EntityManager(); - -$c12 = $entityManager->getRepository('Treetest\Node')->findOneBy(array('name' => 'Child 1-2')); - -$treeDao->getNestedSetStrategy()->saveStructure($c12); - -$entityManager->flush(); -$entityManager->close(); - -var_dump($treeDao->loadTree($root)); - This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <m_p...@us...> - 2013-08-19 22:16:35
|
Revision: 53 http://sourceforge.net/p/beeframework/code/53 Author: m_plomer Date: 2013-08-19 22:16:31 +0000 (Mon, 19 Aug 2013) Log Message: ----------- - method-invocation extension for Context Modified Paths: -------------- trunk/framework/Bee/Context/Abstract.php trunk/framework/Bee/Context/Config/BeanDefinition/Abstract.php trunk/framework/Bee/Context/Config/BeanDefinition/Generic.php trunk/framework/Bee/Context/Config/IBeanDefinition.php trunk/framework/Bee/Context/Support/BeanUtils.php trunk/framework/Bee/Context/Xml/ParserDelegate.php trunk/framework/bee-beans-1.2.xsd Added Paths: ----------- trunk/framework/Bee/Beans/MethodInvocation.php trunk/framework/Bee/Context/Config/IMethodArguments.php trunk/framework/Bee/Context/Config/MethodArgumentsHolder.php Removed Paths: ------------- trunk/examples/vendor/ Added: trunk/framework/Bee/Beans/MethodInvocation.php =================================================================== --- trunk/framework/Bee/Beans/MethodInvocation.php (rev 0) +++ trunk/framework/Bee/Beans/MethodInvocation.php 2013-08-19 22:16:31 UTC (rev 53) @@ -0,0 +1,50 @@ +<?php +namespace Bee\Beans; +/* + * Copyright 2008-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +use Bee\Context\Config\IMethodArguments; +use Bee\Context\Config\MethodArgumentsHolder; +use Bee_Beans_PropertyValue; + +class MethodInvocation extends MethodArgumentsHolder implements IMethodArguments { + + /** + * @var string + */ + private $methodName; + + /** + * @param string $methodName + */ + function __construct($methodName) { + $this->methodName = $methodName; + } + + /** + * @param string $methodName + */ + public function setMethodName($methodName) { + $this->methodName = $methodName; + } + + /** + * @return string + */ + public function getMethodName() { + return $this->methodName; + } +} Modified: trunk/framework/Bee/Context/Abstract.php =================================================================== --- trunk/framework/Bee/Context/Abstract.php 2013-08-19 12:58:55 UTC (rev 52) +++ trunk/framework/Bee/Context/Abstract.php 2013-08-19 22:16:31 UTC (rev 53) @@ -1,4 +1,5 @@ <?php +use Bee\Beans\MethodInvocation; /* * Copyright 2008-2010 the original author or authors. * @@ -203,6 +204,7 @@ try { $this->applyPropertyValues($beanName, $beanDefinition, $instanceWrapper, $beanDefinition->getPropertyValues()); + $this->invokeMethods($beanName, $beanInstance, $beanDefinition->getMethodInvocations()); $exposedObject = $this->initializeBean($beanName, $beanInstance, $beanDefinition); } catch (Exception $ex) { if ($ex instanceof Bee_Context_BeanCreationException && $beanName === $ex->getBeanName()) { @@ -253,7 +255,7 @@ if (is_null($beanDefinition) || !$beanDefinition->isSynthetic()) { $wrappedBean = $this->applyBeanPostProcessorsBeforeInitialization($wrappedBean, $beanName); } - + try { $this->invokeInitMethods($beanName, $wrappedBean, $beanDefinition); } catch (Exception $ex) { @@ -412,15 +414,13 @@ return $beanClass->newInstanceArgs($this->createArgsArray($beanName, $beanDefinition)); } - - - private function createArgsArray($beanName, Bee_Context_Config_IBeanDefinition $beanDefinition) { + private function createArgsArray($beanName, \Bee\Context\Config\IMethodArguments $methodArguments) { // $typeConverter = null; // @todo: ??????????????????????????????????????????? // $valueResolver = new Bee_Context_BeanDefinitionValueResolver($this, $beanName, $beanDefinition, $typeConverter); - $valueResolver = new Bee_Context_BeanDefinitionValueResolver($this, $beanName, $beanDefinition); + $valueResolver = new Bee_Context_BeanDefinitionValueResolver($this, $beanName, $methodArguments); $args = array(); - foreach ($beanDefinition->getConstructorArgumentValues() as $propValue) { + foreach ($methodArguments->getConstructorArgumentValues() as $propValue) { // $value = $valueResolver->resolveValueIfNecessary('constructor/factory method argument', $propValue->getValue()); // $args[] = $typeConverter->convertIfNecessary($value, $propValue->getTypeName()); $args[] = $valueResolver->resolveValueIfNecessary('constructor/factory method argument', $propValue->getValue()); @@ -428,8 +428,6 @@ return $args; } - - /** * Apply the given property values, resolving any runtime references * to other beans in this context. @@ -459,6 +457,22 @@ } } + /** + * @param $beanName + * @param $beanInstance + * @param MethodInvocation[] $methodInvocations + */ + protected function invokeMethods($beanName, $beanInstance, array $methodInvocations = array()) { + foreach($methodInvocations as $methodInvocation) { + $method = array($beanInstance, $methodInvocation->getMethodName()); + if(!is_callable($method)) { + throw new Bee_Context_InvalidPropertyException($methodInvocation->getMethodName(), Bee_Utils_Types::getType($beanInstance), 'no such method found: '.$methodInvocation->getMethodName()); + } + // todo: validate method signature?? + call_user_func_array($method, $this->createArgsArray($beanName, $methodInvocation)); + } + } + abstract protected function loadBeanDefinitions(); /** @@ -858,6 +872,4 @@ function getModificationTimestamp() { return $this->context->getModificationTimestamp(); } -} - -?> \ No newline at end of file +} \ No newline at end of file Modified: trunk/framework/Bee/Context/Config/BeanDefinition/Abstract.php =================================================================== --- trunk/framework/Bee/Context/Config/BeanDefinition/Abstract.php 2013-08-19 12:58:55 UTC (rev 52) +++ trunk/framework/Bee/Context/Config/BeanDefinition/Abstract.php 2013-08-19 22:16:31 UTC (rev 53) @@ -14,6 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +use Bee\Beans\MethodInvocation; +use Bee\Context\Config\MethodArgumentsHolder; /** * Enter description here... @@ -21,7 +23,7 @@ * @author Benjamin Hartmann * @author Michael Plomer <mic...@it...> */ -abstract class Bee_Context_Config_BeanDefinition_Abstract implements Bee_Context_Config_IBeanDefinition { +abstract class Bee_Context_Config_BeanDefinition_Abstract extends MethodArgumentsHolder implements Bee_Context_Config_IBeanDefinition { /** * String representation of the scope that this bean should live in. @@ -56,21 +58,17 @@ */ private $dependsOn = array(); - /** * Enter description here... * - * @var Bee_Beans_PropertyValue[] + * @var Bee_Beans_PropertyValue[] array of PropertyValue instances */ - private $constructorArgumentValues = array(); - + private $propertyValues = array(); /** - * Enter description here... - * - * @var Bee_Beans_PropertyValue[] array of PropertyValue instances + * @var MethodInvocation[] */ - private $propertyValues = array(); + private $methodInvocations = array(); /** * Name of the factory bean, if this bean should be obtained by using another bean instance from the container as its factory. @@ -137,6 +135,7 @@ $this->setAbstract($original->isAbstract()); $this->setConstructorArgumentValues($original->getConstructorArgumentValues()); $this->setPropertyValues($original->getPropertyValues()); + $this->setMethodInvocations($original->getMethodInvocations()); $this->setDependsOn($original->getDependsOn()); $this->setInitMethodName($original->getInitMethodName()); $this->setEnforceInitMethod($original->isEnforceInitMethod()); @@ -159,12 +158,10 @@ return $this->beanClassName; } - public function setBeanClassName($beanClassName) { $this->beanClassName = $beanClassName; } - /** * Set if this bean is "abstract", i.e. not meant to be instantiated itself but * rather just serving as parent for concrete child bean definitions. @@ -199,42 +196,7 @@ public function setDependsOn(array $dependsOn) { $this->dependsOn = $dependsOn; } - - - public function getConstructorArgumentValues() { - return $this->constructorArgumentValues; - } - - - public function setConstructorArgumentValues(array $args) { - $this->constructorArgumentValues = $args; - } - - public function addConstructorArgumentValues(array $args) { - foreach($args as $arg) { - $this->addConstructorArgumentValue($arg); - } - } - - public function addConstructorArgumentValue(Bee_Beans_PropertyValue $arg) { - $idx = $arg->getName(); - if(!is_int($idx) || $idx < 0) { - trigger_error("Constructor argument index is not an integer or lower than 0 : $idx", E_USER_ERROR); - } else { - if(array_key_exists($idx, $this->constructorArgumentValues)) { - $this->mergePropertyValuesIfPossible($this->constructorArgumentValues[$idx], $arg); - } - $this->constructorArgumentValues[$idx] = $arg; - } - } - - private function mergePropertyValuesIfPossible (Bee_Beans_PropertyValue $parent, Bee_Beans_PropertyValue $child) { - $childValue = $child->getValue(); - if($childValue instanceof Bee_Context_Config_IMergeable && $childValue->getMergeEnabled() && $parent->getValue() instanceof Traversable) { - $childValue->merge($parent->getValue()); - } - } - + public function getPropertyValues() { return $this->propertyValues; } @@ -255,14 +217,44 @@ trigger_error("Property must have a name set", E_USER_ERROR); } else { if(array_key_exists($name, $this->propertyValues)) { - $this->mergePropertyValuesIfPossible($this->propertyValues[$name], $prop); + Bee_Context_Support_BeanUtils::mergePropertyValuesIfPossible($this->propertyValues[$name], $prop); } $this->propertyValues[$name] = $prop; } return $this; } - + /** + * @return MethodInvocation[] + */ + public function getMethodInvocations() { + return $this->methodInvocations; + } + + /** + * @param MethodInvocation[] $methodInvocations + */ + public function setMethodInvocations(array $methodInvocations) { + $this->methodInvocations = $methodInvocations; + } + + /** + * @param MethodInvocation[] $methodInvocations + */ + public function addMethodInvocations(array $methodInvocations) { + foreach($methodInvocations as $invocation) { + $this->addMethodInvocation($invocation); + } + } + + /** + * @param MethodInvocation $methodInvocation + * @return void + */ + public function addMethodInvocation(MethodInvocation $methodInvocation) { + array_push($this->methodInvocations, $methodInvocation); + } + public function getFactoryBeanName() { return $this->factoryBeanName; } @@ -389,6 +381,7 @@ $this->setAbstract($other->isAbstract()); $this->addConstructorArgumentValues($other->getConstructorArgumentValues()); $this->addPropertyValues($other->getPropertyValues()); + $this->addMethodInvocations($other->getMethodInvocations()); $this->addDependsOn($other->getDependsOn()); if(!is_null($other->getInitMethodName())) { @@ -404,6 +397,4 @@ $this->setSynthetic($other->isSynthetic()); } -} - -?> \ No newline at end of file +} \ No newline at end of file Modified: trunk/framework/Bee/Context/Config/BeanDefinition/Generic.php =================================================================== --- trunk/framework/Bee/Context/Config/BeanDefinition/Generic.php 2013-08-19 12:58:55 UTC (rev 52) +++ trunk/framework/Bee/Context/Config/BeanDefinition/Generic.php 2013-08-19 22:16:31 UTC (rev 53) @@ -14,6 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +use Bee\Beans\MethodInvocation; /** * Enter description here... @@ -74,5 +75,3 @@ echo '<hr/>'; } } - -?> \ No newline at end of file Modified: trunk/framework/Bee/Context/Config/IBeanDefinition.php =================================================================== --- trunk/framework/Bee/Context/Config/IBeanDefinition.php 2013-08-19 12:58:55 UTC (rev 52) +++ trunk/framework/Bee/Context/Config/IBeanDefinition.php 2013-08-19 22:16:31 UTC (rev 53) @@ -14,6 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +use Bee\Beans\MethodInvocation; /** * Enter description here... @@ -21,7 +22,7 @@ * @author Benjamin Hartmann * @author Michael Plomer <mic...@it...> */ -interface Bee_Context_Config_IBeanDefinition { +interface Bee_Context_Config_IBeanDefinition extends Bee\Context\Config\IMethodArguments { const SCOPE_CACHE = 'cache'; const SCOPE_SESSION = 'session'; @@ -35,7 +36,6 @@ */ public function getParentName(); - /** * Set the name of the parent definition of this bean definition, if any. * @@ -55,8 +55,6 @@ */ public function getBeanClassName(); - - /** * Override the bean class name of this bean definition. * <p>The class name can be modified during bean factory post-processing, @@ -67,8 +65,6 @@ */ public function setBeanClassName($beanClassName); - - /** * Return the factory bean name, if any. * @@ -76,8 +72,6 @@ */ public function getFactoryBeanName(); - - /** * Specify the factory bean to use, if any. * @@ -86,8 +80,6 @@ */ public function setFactoryBeanName($factoryBeanName); - - /** * Return a factory method, if any. * @@ -95,8 +87,6 @@ */ public function getFactoryMethodName(); - - /** * Specify a factory method, if any. This method will be invoked with * constructor arguments, or with no arguments if none are specified. @@ -110,8 +100,6 @@ */ public function setFactoryMethodName($factoryMethodName); - - /** * Override the target scope of this bean, specifying a new scope name. * @see #SCOPE_SINGLETON @@ -120,9 +108,7 @@ * @return String */ public function getScope(); - - - + /** * Enter description here... * @@ -130,28 +116,8 @@ * @return void */ public function setScope($scope); - - - - /** - * Return the constructor argument values for this bean. - * <p>The returned instance can be modified during bean factory post-processing. - * - * @return Bee_Beans_PropertyValue[] - */ - public function getConstructorArgumentValues(); - /** - * Enter description here... - * - * @param Bee_Beans_PropertyValue $arg - * @return void - */ - public function addConstructorArgumentValue(Bee_Beans_PropertyValue $arg); - - - /** * Return the property values to be applied to a new instance of the bean. * <p>The returned instance can be modified during bean factory post-processing. * @@ -159,7 +125,6 @@ */ public function getPropertyValues(); - /** * Add a PropertyValue object, replacing any existing one * for the corresponding property. @@ -169,17 +134,25 @@ * PropertyValues in a single statement */ public function addPropertyValue(Bee_Beans_PropertyValue $prop); - - + /** + * @return MethodInvocation[] + */ + public function getMethodInvocations(); + + /** + * @param MethodInvocation $methodInvocation + * @return void + */ + public function addMethodInvocation(MethodInvocation $methodInvocation); + + /** * Return whether this bean is "abstract", that is, not meant to be instantiated. * * @return boolean */ public function isAbstract(); - - /** * Enter description here... * @@ -187,8 +160,6 @@ */ public function getDependsOn(); - - /** * Enter description here... * @@ -196,8 +167,6 @@ */ public function setDependsOn(array $dependsOn); - - /** * Enter description here... * @@ -206,8 +175,6 @@ */ public function setInitMethodName($initMethodName); - - /** * Enter description here... * @@ -274,6 +241,4 @@ * @return boolean */ public function isSynthetic(); -} - -?> \ No newline at end of file +} \ No newline at end of file Added: trunk/framework/Bee/Context/Config/IMethodArguments.php =================================================================== --- trunk/framework/Bee/Context/Config/IMethodArguments.php (rev 0) +++ trunk/framework/Bee/Context/Config/IMethodArguments.php 2013-08-19 22:16:31 UTC (rev 53) @@ -0,0 +1,44 @@ +<?php +namespace Bee\Context\Config; +/* + * Copyright 2008-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +use Bee_Beans_PropertyValue; + +/** + * User: mp + * Date: 19.08.13 + * Time: 23:31 + */ + +interface IMethodArguments { + + /** + * Return the constructor argument values for this bean. + * <p>The returned instance can be modified during bean factory post-processing. + * + * @return Bee_Beans_PropertyValue[] + */ + public function getConstructorArgumentValues(); + + + /** + * Enter description here... + * + * @param Bee_Beans_PropertyValue $arg + * @return void + */ + public function addConstructorArgumentValue(Bee_Beans_PropertyValue $arg); +} Added: trunk/framework/Bee/Context/Config/MethodArgumentsHolder.php =================================================================== --- trunk/framework/Bee/Context/Config/MethodArgumentsHolder.php (rev 0) +++ trunk/framework/Bee/Context/Config/MethodArgumentsHolder.php 2013-08-19 22:16:31 UTC (rev 53) @@ -0,0 +1,73 @@ +<?php +namespace Bee\Context\Config; +/* + * Copyright 2008-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +use Bee_Beans_PropertyValue; +use Bee_Context_Support_BeanUtils; + +/** + * User: mp + * Date: 19.08.13 + * Time: 23:35 + */ + +class MethodArgumentsHolder implements IMethodArguments { + + /** + * Enter description here... + * + * @var Bee_Beans_PropertyValue[] + */ + private $constructorArgumentValues = array(); + + /** + * Return the constructor argument values for this bean. + * <p>The returned instance can be modified during bean factory post-processing. + * + * @return Bee_Beans_PropertyValue[] + */ + public function getConstructorArgumentValues() { + return $this->constructorArgumentValues; + } + + /** + * Enter description here... + * + * @param Bee_Beans_PropertyValue $arg + * @return void + */ + public function addConstructorArgumentValue(Bee_Beans_PropertyValue $arg) { + $idx = $arg->getName(); + if(!is_int($idx) || $idx < 0) { + trigger_error("Constructor argument index is not an integer or lower than 0 : $idx", E_USER_ERROR); + } else { + if(array_key_exists($idx, $this->constructorArgumentValues)) { + Bee_Context_Support_BeanUtils::mergePropertyValuesIfPossible($this->constructorArgumentValues[$idx], $arg); + } + $this->constructorArgumentValues[$idx] = $arg; + } + } + + public function setConstructorArgumentValues(array $args) { + $this->constructorArgumentValues = $args; + } + + public function addConstructorArgumentValues(array $args) { + foreach($args as $arg) { + $this->addConstructorArgumentValue($arg); + } + } +} Modified: trunk/framework/Bee/Context/Support/BeanUtils.php =================================================================== --- trunk/framework/Bee/Context/Support/BeanUtils.php 2013-08-19 12:58:55 UTC (rev 52) +++ trunk/framework/Bee/Context/Support/BeanUtils.php 2013-08-19 22:16:31 UTC (rev 53) @@ -24,4 +24,11 @@ } return $class->newInstanceArgs($args); } + + public static function mergePropertyValuesIfPossible (Bee_Beans_PropertyValue $parent, Bee_Beans_PropertyValue $child) { + $childValue = $child->getValue(); + if($childValue instanceof Bee_Context_Config_IMergeable && $childValue->getMergeEnabled() && $parent->getValue() instanceof Traversable) { + $childValue->merge($parent->getValue()); + } + } } Modified: trunk/framework/Bee/Context/Xml/ParserDelegate.php =================================================================== --- trunk/framework/Bee/Context/Xml/ParserDelegate.php 2013-08-19 12:58:55 UTC (rev 52) +++ trunk/framework/Bee/Context/Xml/ParserDelegate.php 2013-08-19 22:16:31 UTC (rev 53) @@ -59,6 +59,8 @@ const PROPERTY_ELEMENT = 'property'; + const METHOD_INVOCATION_ELEMENT = 'method-invocation'; + const REF_ELEMENT = 'ref'; const IDREF_ELEMENT = 'idref'; @@ -278,6 +280,7 @@ $this->parseConstructorArgElements($ele, $bd); $this->parsePropertyElements($ele, $bd); + $this->parseMethodInvocationElements($ele, $bd); // bd.setResource(this.readerContext.getResource()); // bd.setSource(extractSource(ele)); @@ -302,14 +305,14 @@ * Parse constructor-arg sub-elements of the given bean element. * * @param DOMElement $beanEle - * @param Bee_Context_Config_IBeanDefinition $bd + * @param Bee\Context\Config\IMethodArguments $argsHolder * @return void */ - public function parseConstructorArgElements(DOMElement $beanEle, Bee_Context_Config_IBeanDefinition $bd) { + public function parseConstructorArgElements(DOMElement $beanEle, Bee\Context\Config\IMethodArguments $argsHolder) { $nl = $beanEle->childNodes; foreach($nl as $node) { if ($node instanceof DOMElement && Bee_Utils_Dom::nodeNameEquals($node, self::CONSTRUCTOR_ARG_ELEMENT)) { - $this->parseConstructorArgElement($node, $bd); + $this->parseConstructorArgElement($node, $argsHolder); } } } @@ -331,24 +334,40 @@ } } - /** + * Parse method-invocation sub-elements of the given bean element. + * + * @param DOMElement $beanEle + * @param Bee_Context_Config_IBeanDefinition $bd + * @return void + */ + public function parseMethodInvocationElements(DOMElement $beanEle, Bee_Context_Config_IBeanDefinition $bd) { + $nl = $beanEle->childNodes; + foreach($nl as $node) { + if ($node instanceof DOMElement && Bee_Utils_Dom::nodeNameEquals($node, self::METHOD_INVOCATION_ELEMENT)) { + $this->parseMethodInvocationElement($node, $bd); + } + } + } + + + /** * Parse a constructor-arg element. */ - public function parseConstructorArgElement(DOMElement $ele, Bee_Context_Config_IBeanDefinition $bd) { + public function parseConstructorArgElement(DOMElement $ele, Bee\Context\Config\IMethodArguments $argsHolder) { $indexAttr = $ele->getAttribute(self::INDEX_ATTRIBUTE); if (Bee_Utils_Strings::hasLength($indexAttr) && is_numeric($indexAttr) && ($index = intval($indexAttr)) >= 0) { - $existingArgs = $bd->getConstructorArgumentValues(); + $existingArgs = $argsHolder->getConstructorArgumentValues(); if(isset($existingArgs[$index])) { $this->readerContext->error("Multiple occurrences of value $index for attribute 'index' of tag 'constructor-arg'", $ele); } else { try { array_push($this->parseState, "Constructor_Arg_Idx_$index"); - $value = $this->parsePropertyValue($ele, $bd, null); + $value = $this->parsePropertyValue($ele, $argsHolder, null); $valueHolder = new Bee_Beans_PropertyValue($index, $value); - $bd->addConstructorArgumentValue($valueHolder); + $argsHolder->addConstructorArgumentValue($valueHolder); array_pop($this->parseState); } catch (Exception $ex) { array_pop($this->parseState); @@ -364,7 +383,7 @@ * Parse a property element. */ public function parsePropertyElement(DOMElement $ele, Bee_Context_Config_IBeanDefinition $bd) { - + $propertyName = $ele->getAttribute(self::NAME_ATTRIBUTE); if (!Bee_Utils_Strings::hasText($propertyName)) { $this->readerContext->error("Tag 'property' must have a 'name' attribute", $ele); @@ -388,8 +407,31 @@ } } - /** + * Parse a property element. + */ + public function parseMethodInvocationElement(DOMElement $ele, Bee_Context_Config_IBeanDefinition $bd) { + + $methodName = $ele->getAttribute(self::NAME_ATTRIBUTE); + if (!Bee_Utils_Strings::hasText($methodName)) { + $this->readerContext->error("Tag 'method-invocation' must have a 'name' attribute", $ele); + return; + } + array_push($this->parseState, $methodName); + try { + $methodInvocation = new \Bee\Beans\MethodInvocation($methodName); + $this->parseConstructorArgElements($ele, $methodInvocation); + $bd->addMethodInvocation($methodInvocation); + + array_pop($this->parseState); + } catch (Exception $ex) { + array_pop($this->parseState); + throw $ex; + } + } + + + /** * Get the value of a property element. May be a list etc. * Also used for constructor arguments, "propertyName" being null in this case. */ Modified: trunk/framework/bee-beans-1.2.xsd =================================================================== --- trunk/framework/bee-beans-1.2.xsd 2013-08-19 12:58:55 UTC (rev 52) +++ trunk/framework/bee-beans-1.2.xsd 2013-08-19 22:16:31 UTC (rev 53) @@ -138,6 +138,7 @@ <xsd:choice minOccurs="0" maxOccurs="unbounded"> <xsd:element ref="constructor-arg"/> <xsd:element ref="property"/> + <xsd:element ref="method-invocation"/> <xsd:any namespace="##other" processContents="strict" minOccurs="0" maxOccurs="unbounded"/> </xsd:choice> </xsd:sequence> @@ -418,6 +419,21 @@ </xsd:annotation> </xsd:element> + <xsd:element name="method-invocation"> + <xsd:annotation> + <xsd:documentation><![CDATA[ + Bean definitions can have zero or more properties. + Property elements correspond to JavaBean setter methods exposed + by the bean classes. Spring supports primitives, references to other + beans in the same or related factories, lists, maps and properties. + ]]></xsd:documentation> + </xsd:annotation> + <xsd:complexType> + <xsd:choice minOccurs="0" maxOccurs="unbounded"> + </xsd:choice> + </xsd:complexType> + </xsd:element> + <xsd:element name="ref"> <xsd:annotation> <xsd:documentation><![CDATA[ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <m_p...@us...> - 2013-08-24 12:32:10
|
Revision: 59 http://sourceforge.net/p/beeframework/code/59 Author: m_plomer Date: 2013-08-24 12:32:07 +0000 (Sat, 24 Aug 2013) Log Message: ----------- - restructured libs - added Doctrine2 EnumType Modified Paths: -------------- trunk/framework/Bee/Persistence/Doctrine2/DaoBase.php Added Paths: ----------- trunk/framework/Bee/Persistence/Doctrine2/Types/ trunk/framework/Bee/Persistence/Doctrine2/Types/EnumType.php Removed Paths: ------------- trunk/libs/addendum-0.4.0/ trunk/libs/addendum-0.4.1/ trunk/libs/apache-log4php-2.3.0/ Property Changed: ---------------- trunk/ Index: trunk =================================================================== --- trunk 2013-08-19 22:44:55 UTC (rev 58) +++ trunk 2013-08-24 12:32:07 UTC (rev 59) Property changes on: trunk ___________________________________________________________________ Modified: svn:ignore ## -1 +1,3 ## .idea +vendor/** +composer.lock Modified: trunk/framework/Bee/Persistence/Doctrine2/DaoBase.php =================================================================== --- trunk/framework/Bee/Persistence/Doctrine2/DaoBase.php 2013-08-19 22:44:55 UTC (rev 58) +++ trunk/framework/Bee/Persistence/Doctrine2/DaoBase.php 2013-08-24 12:32:07 UTC (rev 59) @@ -1,5 +1,7 @@ <?php namespace Bee\Persistence\Doctrine2; +use Doctrine\ORM\Query; +use Doctrine\ORM\QueryBuilder; /** * User: mp @@ -17,13 +19,21 @@ * @internal param \Doctrine\ORM\QueryBuilder $query * @return array */ - public function executeListQuery(\Doctrine\ORM\QueryBuilder $queryBuilder, \Bee_Persistence_IRestrictionHolder $restrictionHolder = null, \Bee_Persistence_IOrderAndLimitHolder $orderAndLimitHolder = null, array $defaultOrderMapping) { + public function executeListQuery(\Doctrine\ORM\QueryBuilder $queryBuilder, \Bee_Persistence_IRestrictionHolder $restrictionHolder = null, \Bee_Persistence_IOrderAndLimitHolder $orderAndLimitHolder = null, array $defaultOrderMapping, $hydrationMode = null) { $this->applyFilterRestrictions($queryBuilder, $restrictionHolder); $this->applyOrderAndLimit($queryBuilder, $orderAndLimitHolder, $defaultOrderMapping); - return $queryBuilder->getQuery()->execute(); + return $this->getQueryFromBuilder($queryBuilder)->execute(null, $hydrationMode); } /** + * @param QueryBuilder $qb + * @return Query + */ + protected function getQueryFromBuilder(QueryBuilder $qb) { + return $qb->getQuery(); + } + + /** * @param \Doctrine\ORM\QueryBuilder $queryBuilder * @param \Bee_Persistence_IRestrictionHolder $restrictionHolder * @internal param \Doctrine\ORM\QueryBuilder $query @@ -87,7 +97,7 @@ $queryBuilder->setMaxResults($orderAndLimitHolder->getPageSize()); // TODO: build a performant count-query! This is simply bullshit! - $pageCount = ceil(count($queryBuilder->getQuery()->execute()) / $orderAndLimitHolder->getPageSize()); + $pageCount = ceil(count($this->getQueryFromBuilder($queryBuilder)->execute()) / $orderAndLimitHolder->getPageSize()); $orderAndLimitHolder->setPageCount($pageCount); if ($orderAndLimitHolder->getCurrentPage() > $pageCount) { Added: trunk/framework/Bee/Persistence/Doctrine2/Types/EnumType.php =================================================================== --- trunk/framework/Bee/Persistence/Doctrine2/Types/EnumType.php (rev 0) +++ trunk/framework/Bee/Persistence/Doctrine2/Types/EnumType.php 2013-08-24 12:32:07 UTC (rev 59) @@ -0,0 +1,39 @@ +<?php +namespace Bee\Persistence\Doctrine2\Types; +use Doctrine\DBAL\Platforms\AbstractPlatform; +use Doctrine\DBAL\Types\Type; + +/** + * Class EnumType + * @package Bee\Persistence\Doctrine2\Types + */ +abstract class EnumType extends Type +{ + protected $name; + protected $values = array(); + + public function getSqlDeclaration(array $fieldDeclaration, AbstractPlatform $platform) + { + $values = array_map(function($val) { return "'".$val."'"; }, $this->values); + + return "ENUM(".implode(", ", $values).") COMMENT '(DC2Type:".$this->name.")'"; + } + + public function convertToPHPValue($value, AbstractPlatform $platform) + { + return $value; + } + + public function convertToDatabaseValue($value, AbstractPlatform $platform) + { + if (!in_array($value, $this->values)) { + throw new \InvalidArgumentException("Invalid '".$this->name."' value."); + } + return $value; + } + + public function getName() + { + return $this->name; + } +} \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <m_p...@us...> - 2013-10-15 17:17:25
|
Revision: 100 http://sourceforge.net/p/beeframework/code/100 Author: m_plomer Date: 2013-10-15 17:17:20 +0000 (Tue, 15 Oct 2013) Log Message: ----------- - extracted PhpMailerWrapper base class out of SmartyMailer as a base class for PHPMailer based classes - added smarty and phpmailer as require-dev dependencies Modified Paths: -------------- trunk/composer.json trunk/framework/Bee/Utils/SmartyMailer.php Added Paths: ----------- trunk/framework/Bee/Utils/PhpMailerWrapper.php Modified: trunk/composer.json =================================================================== --- trunk/composer.json 2013-09-30 20:49:26 UTC (rev 99) +++ trunk/composer.json 2013-10-15 17:17:20 UTC (rev 100) @@ -21,6 +21,10 @@ "niktux/addendum": "0.4.1", "apache/log4php": "~2.3@stable" }, + "require-dev": { + "smarty/smarty": "~3.1@stable", + "phpmailer/phpmailer": "~5@stable" + }, "minimum-stability": "RC", "autoload": { "psr-0": { Added: trunk/framework/Bee/Utils/PhpMailerWrapper.php =================================================================== --- trunk/framework/Bee/Utils/PhpMailerWrapper.php (rev 0) +++ trunk/framework/Bee/Utils/PhpMailerWrapper.php 2013-10-15 17:17:20 UTC (rev 100) @@ -0,0 +1,350 @@ +<?php + +namespace Bee\Utils; + +use Bee_Utils_Strings; +use Exception; +use PHPMailer; + + +/** + * Class PhpMailerWrapper + * @package Bee\Utils + */ +class PhpMailerWrapper { + + /** + * Enter description here... + * + * @var string + */ + private $smtpHost; + + /** + * Enter description here... + * + * @var int + */ + private $smtpPort = 25; + + /** + * Enter description here... + * + * @var string + */ + private $smtpUsername; + + /** + * Enter description here... + * + * @var string + */ + private $smtpPassword; + + /** + * @var string + */ + private $smtpSecurity; + + /** + * Enter description here... + * + * @var string + */ + private $defaultSenderAddress; + + /** + * Enter description here... + * + * @var string + */ + private $defaultSenderName; + + /** + * @var string + */ + private $defaultRecipientAddress; + + /** + * @var string + */ + private $defaultRecipientName; + + /** + * @var string + */ + private $mailType = 'mail'; + + /** + * Enter description here... + * + * @return string + */ + public final function getSmtpHost() { + return $this->smtpHost; + } + + /** + * Enter description here... + * + * @param string $smtpHost + * @return void + */ + public final function setSmtpHost($smtpHost) { + $this->smtpHost = $smtpHost; + } + + /** + * Gets the SmtpPort + * + * @return int $smtpPort + */ + public function getSmtpPort() { + return $this->smtpPort; + } + + /** + * Sets the SmtpPort + * + * @param int $smtpPort + * @return void + */ + public function setSmtpPort($smtpPort) { + $this->smtpPort = $smtpPort; + } + + /** + * Enter description here... + * + * @return string + */ + public final function getSmtpUsername() { + return $this->smtpUsername; + } + + /** + * Enter description here... + * + * @param string $smtpUsername + * @return void + */ + public final function setSmtpUsername($smtpUsername) { + $this->smtpUsername = $smtpUsername; + } + + /** + * Gets the SmtpPassword + * + * @return string $smtpPassword + */ + public function getSmtpPassword() { + return $this->smtpPassword; + } + + /** + * Sets the SmtpPassword + * + * @param string $smtpPassword + * @return void + */ + public function setSmtpPassword($smtpPassword) { + $this->smtpPassword = $smtpPassword; + } + + /** + * Gets the SmtpSecurity + * + * @return string $smtpSecurity + */ + public function getSmtpSecurity() { + return $this->smtpSecurity; + } + + /** + * Sets the SmtpSecurity + * + * @param string $smtpSecurity + * @return void + */ + public function setSmtpSecurity($smtpSecurity) { + $this->smtpSecurity = $smtpSecurity; + } + + /** + * Enter description here... + * + * @return string + */ + public final function getDefaultSenderAddress() { + return $this->defaultSenderAddress; + } + + /** + * Enter description here... + * + * @param string $defaultSenderAddress + */ + public final function setDefaultSenderAddress($defaultSenderAddress) { + $this->defaultSenderAddress = $defaultSenderAddress; + } + + /** + * Enter description here... + * + * @return string + */ + public final function getDefaultSenderName() { + return $this->defaultSenderName; + } + + /** + * Enter description here... + * + * @param string $defaultSenderName + * @return void + */ + public final function setDefaultSenderName($defaultSenderName) { + $this->defaultSenderName = $defaultSenderName; + } + + /** + * Gets the DefaultRecipientAddress + * + * @return string $defaultRecipientAddress + */ + public function getDefaultRecipientAddress() { + return $this->defaultRecipientAddress; + } + + /** + * Sets the DefaultRecipientAddress + * + * @param string $defaultRecipientAddress + * @return void + */ + public function setDefaultRecipientAddress($defaultRecipientAddress) { + $this->defaultRecipientAddress = $defaultRecipientAddress; + } + + /** + * Gets the DefaultRecipientName + * + * @return string $defaultRecipientName + */ + public function getDefaultRecipientName() { + return $this->defaultRecipientName; + } + + /** + * Sets the DefaultRecipientName + * + * @param string $defaultRecipientName + * @return void + */ + public function setDefaultRecipientName($defaultRecipientName) { + $this->defaultRecipientName = $defaultRecipientName; + } + + /** + * Gets the MailType + * + * @return string $mailType + */ + public function getMailType() { + return $this->mailType; + } + + /** + * Sets the MailType + * + * @param string $mailType + * @return void + */ + public function setMailType($mailType) { + $this->mailType = $mailType; + } + + protected function createMailer($sender, $recipient, $charSet = 'UTF-8', $html = true) { + $phpMailer = new PHPMailer(true); + $phpMailer->CharSet = $charSet; + $phpMailer->IsHTML($html); + + // SET CONNECTION + switch ($this->getMailType()) { + case 'smtp' : + $phpMailer->IsSMTP(); + $phpMailer->Host = $this->getSmtpHost(); + $phpMailer->Port = intval($this->getSmtpPort()); + + if (Bee_Utils_Strings::hasText($this->getSmtpUsername())) { + $phpMailer->SMTPAuth = true; + $phpMailer->Username = $this->getSmtpUsername(); + $phpMailer->Password = $this->getSmtpPassword(); + + if (Bee_Utils_Strings::hasText($this->getSmtpSecurity())) { + $phpMailer->SMTPSecure = $this->getSmtpSecurity(); + } + } else { + } + break; + + case 'mail' : + $phpMailer->IsMail(); + break; + } + + + // SET RECIPIENT + if (is_null($recipient)) { + $recipient = array(); + $recipient['address'] = $this->getDefaultRecipientAddress(); + $recipient['name'] = $this->getDefaultRecipientName(); + } + + if (is_string($recipient)) { + $phpMailer->AddAddress($recipient); + + } else if (is_array($recipient)) { + if (!array_key_exists('address', $recipient)) { + throw new Exception('SmartyMailer failed: mailformed recipient. Field not found: "address"'); + } + + if (array_key_exists('name', $recipient)) { + $phpMailer->AddAddress($recipient['address'], $recipient['name']); + } else { + $phpMailer->AddAddress($recipient['address'], $recipient['name']); + } + + } else { + throw new Exception('SmartyMailer failed: mailformed recipient. Type-mismatch. Recipient must be either string or array, but is: "' . gettype($recipient) . '" instead.'); + } + + + // SET SENDER + if (is_null($sender)) { + $sender = array(); + $sender['address'] = $this->getDefaultSenderAddress(); + $sender['name'] = $this->getDefaultSenderName(); + } + + if (is_string($sender)) { + $phpMailer->SetFrom($sender); + + } else if (is_array($sender)) { + if (!array_key_exists('address', $sender)) { + throw new Exception('SmartyMailer failed: mailformed sender. Field not found: "address"'); + } + + if (array_key_exists('name', $sender)) { + $phpMailer->SetFrom($sender['address'], $sender['name']); + } else { + $phpMailer->SetFrom($sender['address'], $sender['name']); + } + + } else { + throw new Exception('SmartyMailer failed: mailformed sender. Type-mismatch. Sender must be either string or array, but is: "' . gettype($sender) . '" instead.'); + } + + return $phpMailer; + } +} \ No newline at end of file Modified: trunk/framework/Bee/Utils/SmartyMailer.php =================================================================== --- trunk/framework/Bee/Utils/SmartyMailer.php 2013-09-30 20:49:26 UTC (rev 99) +++ trunk/framework/Bee/Utils/SmartyMailer.php 2013-10-15 17:17:20 UTC (rev 100) @@ -14,12 +14,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +use Bee\Utils\PhpMailerWrapper; /** * @throws Exception * */ -class Bee_Utils_SmartyMailer { +class Bee_Utils_SmartyMailer extends PhpMailerWrapper { private $pluginDir; @@ -29,68 +30,7 @@ */ private $smarty; - /** - * Enter description here... - * - * @var String - */ - private $smtpHost; - - /** - * Enter description here... - * - * @var String - */ - private $smtpPort = 25; - - /** - * Enter description here... - * - * @var String - */ - private $smtpUsername; - - /** - * Enter description here... - * - * @var String - */ - private $smtpPassword; - /** - * @var string - */ - private $smtpSecurity; - - /** - * Enter description here... - * - * @var String - */ - private $defaultSenderAddress; - - /** - * Enter description here... - * - * @var String - */ - private $defaultSenderName; - - /** - * @var string - */ - private $defaultRecipientAddress; - - /** - * @var string - */ - private $defaultRecipientName; - - - private $mailType = 'mail'; - - - /** * @param $subjectTemplate * @param $bodyTemplate * @param array $model @@ -136,99 +76,19 @@ } - /** - * @param $subjectTemplate - * @param $bodyTemplate - * @param array $model - * @param mixed $recipient Either string ex...@ma... or array with keys "address" and optional "name" - * @param mixed $sender Either string ex...@ma... or array with keys "address" and optional "name" - * - * @return PHPMailer - */ + /** + * @param $subjectTemplate + * @param $bodyTemplate + * @param array $model + * @param mixed $recipient Either string ex...@ma... or array with keys "address" and optional "name" + * @param mixed $sender Either string ex...@ma... or array with keys "address" and optional "name" + * + * @throws Exception + * @return \PHPMailer + */ public function instantiatePhpMailer($subjectTemplate, $bodyTemplate, array $model, $recipient=null, $sender=null) { - $phpMailer = new PHPMailer(true); - $phpMailer->PluginDir = $this->getPluginDir(); - $phpMailer->CharSet = 'UTF-8'; - $phpMailer->IsHTML(true); + $phpMailer = $this->createMailer($sender, $recipient); - - // SET CONNECTION - switch ($this->getMailType()) { - case 'smtp' : - $phpMailer->IsSMTP(); - $phpMailer->Host = $this->getSmtpHost(); - $phpMailer->Port = intval($this->getSmtpPort()); - - if (Bee_Utils_Strings::hasText($this->getSmtpUsername())) { - $phpMailer->SMTPAuth = true; - $phpMailer->Username = $this->getSmtpUsername(); - $phpMailer->Password = $this->getSmtpPassword(); - - if (Bee_Utils_Strings::hasText($this->getSmtpSecurity())) { - $phpMailer->SMTPSecure = $this->getSmtpSecurity(); - } - } else { - } - break; - - case 'mail' : - $phpMailer->IsMail(); - break; - } - - - // SET RECIPIENT - if (is_null($recipient)) { - $recipient = array(); - $recipient['address'] = $this->getDefaultRecipientAddress(); - $recipient['name'] = $this->getDefaultRecipientName(); - } - - if (is_string($recipient)) { - $phpMailer->AddAddress($recipient); - - } else if (is_array($recipient)) { - if (!array_key_exists('address', $recipient)) { - throw new Exception('SmartyMailer failed: mailformed recipient. Field not found: "address"'); - } - - if (array_key_exists('name', $recipient)) { - $phpMailer->AddAddress($recipient['address'], $recipient['name']); - } else { - $phpMailer->AddAddress($recipient['address'], $recipient['name']); - } - - } else { - throw new Exception('SmartyMailer failed: mailformed recipient. Type-mismatch. Recipient must be either string or array, but is: "'.gettype($recipient).'" instead.'); - } - - - // SET SENDER - if (is_null($sender)) { - $sender = array(); - $sender['address'] = $this->getDefaultSenderAddress(); - $sender['name'] = $this->getDefaultSenderName(); - } - - if (is_string($sender)) { - $phpMailer->SetFrom($sender); - - } else if (is_array($sender)) { - if (!array_key_exists('address', $sender)) { - throw new Exception('SmartyMailer failed: mailformed sender. Field not found: "address"'); - } - - if (array_key_exists('name', $sender)) { - $phpMailer->SetFrom($sender['address'], $sender['name']); - } else { - $phpMailer->SetFrom($sender['address'], $sender['name']); - } - - } else { - throw new Exception('SmartyMailer failed: mailformed sender. Type-mismatch. Sender must be either string or array, but is: "'.gettype($sender).'" instead.'); - } - - // SET CONTENT $this->smarty->clearAllAssign(); foreach($model as $key => $value) { @@ -240,8 +100,6 @@ return $phpMailer; } - - //=== GETTERS & SETTERS ============================================================================================ /** * Gets the PluginDir @@ -278,194 +136,4 @@ public final function setSmarty(Smarty $smarty) { $this->smarty = $smarty; } - - /** - * Enter description here... - * - * @return String - */ - public final function getSmtpHost() { - return $this->smtpHost; - } - - /** - * Enter description here... - * - * @param String $smtpHost - * @return void - */ - public final function setSmtpHost($smtpHost) { - $this->smtpHost = $smtpHost; - } - - /** - * Gets the SmtpPort - * - * @return $smtpPort - */ - public function getSmtpPort() { - return $this->smtpPort; - } - - /** - * Sets the SmtpPort - * - * @param $smtpPort - * @return void - */ - public function setSmtpPort($smtpPort) { - $this->smtpPort = $smtpPort; - } - - /** - * Enter description here... - * - * @return String - */ - public final function getDefaultSenderAddress() { - return $this->defaultSenderAddress; - } - - /** - * Enter description here... - * - * @param String $defaultSenderAddress - */ - public final function setDefaultSenderAddress($defaultSenderAddress) { - $this->defaultSenderAddress = $defaultSenderAddress; - } - - /** - * Enter description here... - * - * @return String - */ - public final function getDefaultSenderName() { - return $this->defaultSenderName; - } - - /** - * Enter description here... - * - * @param String $defaultSenderName - * @return void - */ - public final function setDefaultSenderName($defaultSenderName) { - $this->defaultSenderName = $defaultSenderName; - } - - /** - * Enter description here... - * - * @return String - */ - public final function getSmtpUsername() { - return $this->smtpUsername; - } - - /** - * Enter description here... - * - * @param String $smtpUsername - * @return void - */ - public final function setSmtpUsername($smtpUsername) { - $this->smtpUsername = $smtpUsername; - } - - /** - * Gets the SmtpPassword - * - * @return $smtpPassword - */ - public function getSmtpPassword() { - return $this->smtpPassword; - } - - /** - * Sets the SmtpPassword - * - * @param $smtpPassword - * @return void - */ - public function setSmtpPassword($smtpPassword) { - $this->smtpPassword = $smtpPassword; - } - - /** - * Gets the SmtpSecurity - * - * @return $smtpSecurity - */ - public function getSmtpSecurity() { - return $this->smtpSecurity; - } - - /** - * Sets the SmtpSecurity - * - * @param $smtpSecurity - * @return void - */ - public function setSmtpSecurity($smtpSecurity) { - $this->smtpSecurity = $smtpSecurity; - } - - /** - * Gets the MailType - * - * @return String $mailType - */ - public function getMailType() { - return $this->mailType; - } - - /** - * Sets the MailType - * - * @param $mailType - * @return void - */ - public function setMailType($mailType) { - $this->mailType = $mailType; - } - - /** - * Gets the DefaultRecipientAddress - * - * @return $defaultRecipientAddress - */ - public function getDefaultRecipientAddress() { - return $this->defaultRecipientAddress; - } - - /** - * Sets the DefaultRecipientAddress - * - * @param $defaultRecipientAddress - * @return void - */ - public function setDefaultRecipientAddress($defaultRecipientAddress) { - $this->defaultRecipientAddress = $defaultRecipientAddress; - } - - /** - * Gets the DefaultRecipientName - * - * @return $defaultRecipientName - */ - public function getDefaultRecipientName() { - return $this->defaultRecipientName; - } - - /** - * Sets the DefaultRecipientName - * - * @param $defaultRecipientName - * @return void - */ - public function setDefaultRecipientName($defaultRecipientName) { - $this->defaultRecipientName = $defaultRecipientName; - } - } \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <m_p...@us...> - 2014-02-17 11:57:54
|
Revision: 139 http://sourceforge.net/p/beeframework/code/139 Author: m_plomer Date: 2014-02-17 11:57:50 +0000 (Mon, 17 Feb 2014) Log Message: ----------- - unicode normalizer -> composer compatibility Modified Paths: -------------- trunk/composer.json trunk/framework/Bee/Persistence/Doctrine/ManagerAugmenter.php trunk/framework/Bee/Text/Normalization/PEARNormalizer.php Modified: trunk/composer.json =================================================================== --- trunk/composer.json 2014-02-17 11:30:30 UTC (rev 138) +++ trunk/composer.json 2014-02-17 11:57:50 UTC (rev 139) @@ -1,4 +1,14 @@ { + "repositories": [ + { + "type": "composer", + "url": "http://dev.iter8.de/composer/" + }, + { + "type": "pear", + "url": "pear.php.net" + } + ], "name": "bee-framework/bee-framework", "type": "library", "description": "Bee Framework - PHP 5 DI/IoC application framework", @@ -19,7 +29,8 @@ "doctrine/orm": "~2.4@RC", "doctrine/doctrine1": "~1.2@stable", "niktux/addendum": "0.4.1", - "apache/log4php": "~2.3@stable" + "apache/log4php": "~2.3@stable", + "pear-pear/I18N_UnicodeNormalizer": "*@stable" }, "require-dev": { "smarty/smarty": "~3.1@stable", Modified: trunk/framework/Bee/Persistence/Doctrine/ManagerAugmenter.php =================================================================== --- trunk/framework/Bee/Persistence/Doctrine/ManagerAugmenter.php 2014-02-17 11:30:30 UTC (rev 138) +++ trunk/framework/Bee/Persistence/Doctrine/ManagerAugmenter.php 2014-02-17 11:57:50 UTC (rev 139) @@ -96,9 +96,9 @@ } public function afterPropertiesSet() { -// $this->doctrineManager->setAttribute(Doctrine::ATTR_USE_DQL_CALLBACKS, true); -// $this->doctrineManager->setAttribute(Doctrine::ATTR_AUTO_FREE_QUERY_OBJECTS, true); -// $this->doctrineManager->setAttribute(Doctrine::ATTR_QUOTE_IDENTIFIER, true); +// $this->doctrineManager->setAttribute(Doctrine_Core::ATTR_USE_DQL_CALLBACKS, true); +// $this->doctrineManager->setAttribute(Doctrine_Core::ATTR_AUTO_FREE_QUERY_OBJECTS, true); +// $this->doctrineManager->setAttribute(Doctrine_Core::ATTR_QUOTE_IDENTIFIER, true); if($this->queryCacheDriver) { $this->doctrineManager->setAttribute(Doctrine_Core::ATTR_QUERY_CACHE, $this->queryCacheDriver); Modified: trunk/framework/Bee/Text/Normalization/PEARNormalizer.php =================================================================== --- trunk/framework/Bee/Text/Normalization/PEARNormalizer.php 2014-02-17 11:30:30 UTC (rev 138) +++ trunk/framework/Bee/Text/Normalization/PEARNormalizer.php 2014-02-17 11:57:50 UTC (rev 139) @@ -23,7 +23,16 @@ class Bee_Text_Normalization_PEARNormalizer implements Bee_Text_Normalization_INormalizer { + private static $pearDataDir; + /** + * @param mixed $pearDataDir + */ + public static function setPearDataDir(mixed $pearDataDir) { + self::$pearDataDir = $pearDataDir; + } + + /** * @var I18N_UnicodeNormalizer */ private $normalizer; @@ -38,6 +47,6 @@ } public function __construct() { - $this->normalizer = new I18N_UnicodeNormalizer(); + $this->normalizer = new I18N_UnicodeNormalizer(self::$pearDataDir); } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <m_p...@us...> - 2014-07-01 07:51:05
|
Revision: 157 http://sourceforge.net/p/beeframework/code/157 Author: m_plomer Date: 2014-07-01 07:50:57 +0000 (Tue, 01 Jul 2014) Log Message: ----------- - Composer: fixed PEAR dependencies Modified Paths: -------------- trunk/composer.json trunk/framework/composer.json Modified: trunk/composer.json =================================================================== --- trunk/composer.json 2014-07-01 07:45:31 UTC (rev 156) +++ trunk/composer.json 2014-07-01 07:50:57 UTC (rev 157) @@ -26,16 +26,14 @@ ], "require": { "php": ">=5.3", + "smarty/smarty": "~3.1@stable", + "phpmailer/phpmailer": "~5@stable", "doctrine/orm": "~2.4@RC", "doctrine/doctrine1": "~1.2@stable", "niktux/addendum": "0.4.1", "apache/log4php": "~2.3@stable", - "pear-pear/I18N_UnicodeNormalizer": "*@stable" + "pear-pear.php.net/I18N_UnicodeNormalizer": "~1.0" }, - "require-dev": { - "smarty/smarty": "~3.1@stable", - "phpmailer/phpmailer": "~5@stable" - }, "minimum-stability": "RC", "autoload": { "psr-0": { Modified: trunk/framework/composer.json =================================================================== --- trunk/framework/composer.json 2014-07-01 07:45:31 UTC (rev 156) +++ trunk/framework/composer.json 2014-07-01 07:50:57 UTC (rev 157) @@ -26,7 +26,7 @@ "apache/log4php": "~2.3@stable" }, "require-dev": { - "pear-pear.php.net/I18N_UnicodeNormalizer": "*@stable" + "pear-pear.php.net/I18N_UnicodeNormalizer": "~1.0" }, "autoload": { "psr-0": { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <m_p...@us...> - 2014-07-01 15:18:24
|
Revision: 158 http://sourceforge.net/p/beeframework/code/158 Author: m_plomer Date: 2014-07-01 15:18:20 +0000 (Tue, 01 Jul 2014) Log Message: ----------- - MVC/Views: extended Redirect view Modified Paths: -------------- trunk/composer.json trunk/framework/Bee/MVC/IView.php trunk/framework/Bee/MVC/View/Redirect.php Added Paths: ----------- trunk/framework/Bee/MVC/IHttpStatusCodes.php Modified: trunk/composer.json =================================================================== --- trunk/composer.json 2014-07-01 07:50:57 UTC (rev 157) +++ trunk/composer.json 2014-07-01 15:18:20 UTC (rev 158) @@ -37,7 +37,7 @@ "minimum-stability": "RC", "autoload": { "psr-0": { - "Bee": "" + "Bee": "framework/" } } } \ No newline at end of file Added: trunk/framework/Bee/MVC/IHttpStatusCodes.php =================================================================== --- trunk/framework/Bee/MVC/IHttpStatusCodes.php (rev 0) +++ trunk/framework/Bee/MVC/IHttpStatusCodes.php 2014-07-01 15:18:20 UTC (rev 158) @@ -0,0 +1,430 @@ +<?php + +namespace Bee\MVC; + + +/** + * Interface IHttpStatusCodes - maps HTTP/1.1 status codes to symbolic names. Descriptions are taken from Wikipedia. + * + * @link http://en.wikipedia.org/wiki/List_of_HTTP_status_codes + * @package Bee\MVC + */ +interface IHttpStatusCodes { + + /** + * This means that the server has received the request headers, and that the client should proceed to send the + * request body (in the case of a request for which a body needs to be sent; for example, a POST request). If the + * request body is large, sending it to a server when a request has already been rejected based upon inappropriate + * headers is inefficient. To have a server check if the request could be accepted based on the request's headers + * alone, a client must send Expect: 100-continue as a header in its initial request and check if a 100 Continue + * status code is received in response before continuing (or receive 417 Expectation Failed and not continue). + */ + const HTTP_CONTINUE = 100; + + /** + * This means the requester has asked the server to switch protocols and the server is acknowledging that it will + * do so. + */ + const HTTP_SWITCHING_PROTOCOLS = 101; + + /** + * As a WebDAV request may contain many sub-requests involving file operations, it may take a long time to complete + * the request. This code indicates that the server has received and is processing the request, but no response is + * available yet. This prevents the client from timing out and assuming the request was lost. + */ + const HTTP_PROCESSING = 102; + + /** + * Standard response for successful HTTP requests. The actual response will depend on the request method used. In a + * GET request, the response will contain an entity corresponding to the requested resource. In a POST request the + * response will contain an entity describing or containing the result of the action. + */ + const HTTP_OK = 200; + + /** + * The request has been fulfilled and resulted in a new resource being created. + */ + const HTTP_CREATED = 201; + + /** + * The request has been accepted for processing, but the processing has not been completed. The request might or + * might not eventually be acted upon, as it might be disallowed when processing actually takes place. + */ + const HTTP_ACCEPTED = 202; + + /** + * The server successfully processed the request, but is returning information that may be from another source. + */ + const HTTP_NON_AUTHORITATIVE_INFORMATION = 203; + + /** + * The server successfully processed the request, but is not returning any content. Usually used as a response to a + * successful delete request. + */ + const HTTP_NO_CONTENT = 204; + + /** + * The server successfully processed the request, but is not returning any content. Unlike a 204 response, this + * response requires that the requester reset the document view. + */ + const HTTP_RESET_CONTENT = 205; + + /** + * The server is delivering only part of the resource due to a range header sent by the client. The range header is + * used by tools like wget to enable resuming of interrupted downloads, or split a download into multiple + * simultaneous streams. + */ + const HTTP_PARTIAL_CONTENT = 206; + + /** + * The message body that follows is an XML message and can contain a number of separate response codes, depending + * on how many sub-requests were made. + */ + const HTTP_MULTI_STATUS = 207; + + /** + * The members of a DAV binding have already been enumerated in a previous reply to this request, and are not being + * included again. + */ + const HTTP_ALREADY_REPORTED = 208; + + /** + * The server has fulfilled a GET request for the resource, and the response is a representation of the result of + * one or more instance-manipulations applied to the current instance. + */ + const HTTP_IM_USED = 226; + + + /** + * Indicates multiple options for the resource that the client may follow. It, for instance, could be used to + * present different format options for video, list files with different extensions, or word sense disambiguation. + */ + const HTTP_REDIRECT_MULTIPLE_CHOICES = 300; + + /** + * This and all future requests should be directed to the given URI. + */ + const HTTP_REDIRECT_MOVED_PERMANENTLY = 301; + + /** + * The HTTP/1.0 specification (RFC 1945) required the client to perform a temporary redirect (the original + * describing phrase was "Moved Temporarily"),[5] but popular browsers implemented 302 with the functionality of a + * 303 See Other. + */ + const HTTP_REDIRECT_FOUND = 302; + + /** + * The response to the request can be found under another URI using a GET method. When received in response to a + * POST (or PUT/DELETE), it should be assumed that the server has received the data and the redirect should be + * issued with a separate GET message. + */ + const HTTP_REDIRECT_SEE_OTHER = 303; + + /** + * Indicates that the resource has not been modified since the version specified by the request headers + * If-Modified-Since or If-Match. This means that there is no need to retransmit the resource, since the client + * still has a previously-downloaded copy. + */ + const HTTP_REDIRECT_NOT_MODIFIED = 304; + + /** + * The requested resource is only available through a proxy, whose address is provided in the response. Many HTTP + * clients (such as Mozilla and Internet Explorer) do not correctly handle responses with this status code, + * primarily for security reasons. + */ + const HTTP_REDIRECT_USE_PROXY = 305; + + /** + * In this case, the request should be repeated with another URI; however, future requests should still use the + * original URI. In contrast to how 302 was historically implemented, the request method is not allowed to be + * changed when reissuing the original request. For instance, a POST request should be repeated using another POST + * request. + */ + const HTTP_REDIRECT_TEMPORARY_REDIRECT = 307; + + /** + * The request, and all future requests should be repeated using another URI. 307 and 308 (as proposed) parallel the + * behaviours of 302 and 301, but do not allow the HTTP method to change. So, for example, submitting a form to a + * permanently redirected resource may continue smoothly. + */ + const HTTP_REDIRECT_PERMANENT_REDIRECT = 308; + + /** + * The request cannot be fulfilled due to bad syntax + */ + const HTTP_BAD_REQUEST = 400; + + /** + * Similar to 403 Forbidden, but specifically for use when authentication is required and has failed or has not yet + * been provided. The response must include a WWW-Authenticate header field containing a challenge applicable to the + * requested resource. + */ + const HTTP_UNAUTHORIZED = 401; + + /** + * Reserved for future use. The original intention was that this code might be used as part of some form of digital + * cash or micropayment scheme, but that has not happened, and this code is not usually used. + */ + const HTTP_PAYMENT_REQUIRED = 402; + + /** + * The request was a valid request, but the server is refusing to respond to it. Unlike a 401 Unauthorized response, + * authenticating will make no difference. + */ + const HTTP_FORBIDDEN = 403; + + /** + * The requested resource could not be found but may be available again in the future. Subsequent requests by the + * client are permissible. + */ + const HTTP_NOT_FOUND = 404; + + /** + * A request was made of a resource using a request method not supported by that resource; for example, using GET on + * a form which requires data to be presented via POST, or using PUT on a read-only resource. + */ + const HTTP_METHOD_NOT_ALLOWED = 405; + + /** + * The requested resource is only capable of generating content not acceptable according to the Accept headers sent + * in the request. + */ + const HTTP_NOT_ACCEPTABLE = 406; + + /** + * The client must first authenticate itself with the proxy. + */ + const HTTP_PROXY_AUTHENTICATION_REQUIRED = 407; + + /** + * The server timed out waiting for the request. According to HTTP specifications: "The client did not produce a + * request within the time that the server was prepared to wait. The client MAY repeat the request without + * modifications at any later time." + */ + const HTTP_REQUEST_TIMEOUT = 408; + + /** + * Indicates that the request could not be processed because of conflict in the request, such as an edit conflict + * in the case of multiple updates. + */ + const HTTP_CONFLICT = 409; + + /** + * Indicates that the resource requested is no longer available and will not be available again. This should be + * used when a resource has been intentionally removed and the resource should be purged. + */ + const HTTP_GONE = 410; + + /** + * The request did not specify the length of its content, which is required by the requested resource. + */ + const HTTP_LENGTH_REQUIRED = 411; + + /** + * The server does not meet one of the preconditions that the requester put on the request. + */ + const HTTP_PRECONDITION_FAILED = 412; + + /** + * The request is larger than the server is willing or able to process. + */ + const HTTP_REQUEST_ENTITY_TOO_LARGE = 413; + + /** + * The URI provided was too long for the server to process. Often the result of too much data being encoded as a + * query-string of a GET request, in which case it should be converted to a POST request. + */ + const HTTP_REQUEST_URI_TOO_LONG = 414; + + /** + * The request entity has a media type which the server or resource does not support. For example, the client + * uploads an image as image/svg+xml, but the server requires that images use a different format. + */ + const HTTP_UNSUPPORTED_MEDIA_TYPE = 415; + + /** + * The client has asked for a portion of the file, but the server cannot supply that portion. For example, if the + * client asked for a part of the file that lies beyond the end of the file. + */ + const HTTP_REQUESTED_RANGE_NOT_SATISFIABLE = 416; + + /** + * The server cannot meet the requirements of the Expect request-header field. + */ + const HTTP_EXPECTATION_FAILED = 417; + + /** + * Not a part of the HTTP standard, 419 Authentication Timeout denotes that previously valid authentication has + * expired. It is used as an alternative to 401 Unauthorized in order to differentiate from otherwise authenticated + * clients being denied access to specific server resources. + */ + const HTTP_AUTHENTICATION_TIMEOUT = 419; + + /** + * Not part of the HTTP standard, but defined by Spring in the HttpStatus class to be used when a method failed. + * This status code is deprecated by Spring. + */ + const HTTP_METHOD_FAILURE = 420; + + /** + * The request was well-formed but was unable to be followed due to semantic errors. + */ + const HTTP_UNPROCESSABLE_ENTITY = 422; + + /** + * The resource that is being accessed is locked. + */ + const HTTP_LOCKED = 423; + + /** + * The request failed due to failure of a previous request (e.g., a PROPPATCH). + */ + const HTTP_FAILED_DEPENDENCY = 424; + + /** + * The client should switch to a different protocol such as TLS/1.0. + */ + const HTTP_UPGRADE_REQUIRED = 426; + + /** + * The origin server requires the request to be conditional. Intended to prevent "the 'lost update' problem, where a + * client GETs a resource's state, modifies it, and PUTs it back to the server, when meanwhile a third party has + * modified the state on the server, leading to a conflict." + */ + const HTTP_PRECONDITION_REQUIRED = 428; + + /** + * The user has sent too many requests in a given amount of time. Intended for use with rate limiting schemes. + */ + const TOO_MANY_REQUESTS = 429; + + /** + * The server is unwilling to process the request because either an individual header field, or all the header + * fields collectively, are too large. + */ + const REQUEST_HEADER_FIELDS_TOO_LARGE = 431; + + /** + * Used in Nginx logs to indicate that the server has returned no information to the client and closed the + * connection (useful as a deterrent for malware). + */ + const NGINX_NO_RESPONSE = 444; + + /** + * A Microsoft extension. The request should be retried after performing the appropriate action.[14] + */ + const MICROSOFT_RETRY_WITH = 449; + + /** + * A Microsoft extension. This error is given when Windows Parental Controls are turned on and are blocking access + * to the given webpage.[15] + */ + const MICROSOFT_BLOCKED_BY_WINDOWS_PARENTAL_CONTROLS = 450; + + /** + * Defined in the internet draft "A New HTTP Status Code for Legally-restricted Resources".[16] Intended to be used + * when resource access is denied for legal reasons, e.g. censorship or government-mandated blocked access. A + * reference to the 1953 dystopian novel Fahrenheit 451, where books are outlawed.[17] + */ + const UNAVAILABLE_FOR_LEGAL_REASONS = 451; + + /** + * Used in Exchange ActiveSync if there either is a more efficient server to use or the server cannot access the + * users' mailbox. The client is supposed to re-run the HTTP Autodiscovery protocol to find a better suited server. + */ + const MICROSOFT_REDIRECT = 451; + + /** + * Nginx internal code similar to 431 but it was introduced earlier in version 0.9.4 (on January the 21th, 2011). + */ + const NGINX_REQUEST_HEADER_TOO_LARGE = 494; + + /** + * Nginx internal code used when SSL client certificate error occurred to distinguish it from 4XX in a log and an + * error page redirection. + */ + const NGINX_CERT_ERROR = 495; + + /** + * Nginx internal code used when client didn't provide certificate to distinguish it from 4XX in a log and an error + * page redirection. + */ + const NGINX_NO_CERT = 496; + + /** + * Nginx internal code used for the plain HTTP requests that are sent to HTTPS port to distinguish it from 4XX in a + * log and an error page redirection. + */ + const NGINX_HTTP_TO_HTTPS = 497; + + /** + * Used in Nginx logs to indicate when the connection has been closed by client while the server is still processing + * its request, making server unable to send a status code back.[22] + */ + const NGINX_CLIENT_CLOSED_REQUEST = 499; + + /** + * A generic error message, given when an unexpected condition was encountered and no more specific message is + * suitable. + */ + const INTERNAL_SERVER_ERROR = 500; + + /** + * The server either does not recognize the request method, or it lacks the ability to fulfill the request. Usually + * this implies future availability (e.g., a new feature of a web-service API). + */ + const NOT_IMPLEMENTED = 501; + + /** + * The server was acting as a gateway or proxy and received an invalid response from the upstream server. + */ + const BAD_GATEWAY = 502; + + /** + * The server is currently unavailable (because it is overloaded or down for maintenance). Generally, this is a + * temporary state. + */ + const SERVICE_UNAVAILABLE = 503; + + /** + * The server was acting as a gateway or proxy and did not receive a timely response from the upstream server. + */ + const GATEWAY_TIMEOUT = 504; + + /** + * The server does not support the HTTP protocol version used in the request. + */ + const HTTP_VERSION_NOT_SUPPORTED = 505; + + /** + * Transparent content negotiation for the request results in a circular reference. + */ + const VARIANT_ALSO_NEGOTIATES = 506; + + /** + * The server is unable to store the representation needed to complete the request. + */ + const INSUFFICIENT_STORAGE = 507; + + /** + * The server detected an infinite loop while processing the request (sent in lieu of 208 Already Reported). + */ + const LOOP_DETECTED = 508; + + /** + * This status code is not specified in any RFCs. Its use is unknown. + */ + const BANDWIDTH_LIMIT_EXCEEDED = 509; + + /** + * Further extensions to the request are required for the server to fulfill it. + */ + const NOT_EXTENDED = 510; + + /** + * The client needs to authenticate to gain network access. Intended for use by intercepting proxies used to control + * access to the network (e.g., "captive portals" used to require agreement to Terms of Service before granting full + * Internet access via a Wi-Fi hotspot). + */ + const NETWORK_AUTHENTICATION_REQUIRED = 511; +} \ No newline at end of file Modified: trunk/framework/Bee/MVC/IView.php =================================================================== --- trunk/framework/Bee/MVC/IView.php 2014-07-01 07:50:57 UTC (rev 157) +++ trunk/framework/Bee/MVC/IView.php 2014-07-01 15:18:20 UTC (rev 158) @@ -27,25 +27,22 @@ * @author Benjamin Hartmann */ interface Bee_MVC_IView { + /** * Return the content type of the view, if predetermined. * <p>Can be used to check the content type upfront, * before the actual rendering process. - * @return the content type string (optionally including a character set), + * @return string content type string (optionally including a character set), * or <code>null</code> if not predetermined. */ public function getContentType(); /** * Render the view given the specified model. - * <p>The first step will be preparing the request: In the JSP case, - * this would mean setting model objects as request attributes. - * The second step will be the actual rendering of the view, - * for example including the JSP via a RequestDispatcher. - * @param model associative array with name strings as keys and corresponding model + * + * @param array $model associative array with name strings as keys and corresponding model * objects as values (can also be omitted in case of empty model) * @throws Exception if rendering failed */ public function render(array $model = array()); -} -?> \ No newline at end of file +} \ No newline at end of file Modified: trunk/framework/Bee/MVC/View/Redirect.php =================================================================== --- trunk/framework/Bee/MVC/View/Redirect.php 2014-07-01 07:50:57 UTC (rev 157) +++ trunk/framework/Bee/MVC/View/Redirect.php 2014-07-01 15:18:20 UTC (rev 158) @@ -15,15 +15,50 @@ * limitations under the License. */ -class Bee_MVC_View_Redirect implements Bee_MVC_IView { +use Bee\MVC\IHttpStatusCodes; +/** + * Class Bee_MVC_View_Redirect - + */ +class Bee_MVC_View_Redirect implements Bee_MVC_IView, IHttpStatusCodes { + + const MODEL_KEY_REDIRECT_URL = 'redirectUrl'; + const MODEL_KEY_GET_PARAMS = 'getParams'; + + /** + * @var int + */ + private $statusCode = self::HTTP_REDIRECT_SEE_OTHER; + public function getContentType() { return false; } + /** + * @param int $statusCode + */ + public function setStatusCode($statusCode) { + $this->statusCode = $statusCode; + } + + /** + * @return int + */ + public function getStatusCode() { + return $this->statusCode; + } + public function render(array $model = array()) { - Bee_Utils_Assert::hasText($model['redirectUrl']); - header('Location: ' . $model['redirectUrl'], true, 303); + $redirectUrl = $model[self::MODEL_KEY_REDIRECT_URL]; + Bee_Utils_Assert::hasText($redirectUrl); + if (array_key_exists(self::MODEL_KEY_GET_PARAMS, $model)) { + $params = $model[self::MODEL_KEY_GET_PARAMS]; + Bee_Utils_Assert::isTrue(is_array($params), 'Bee_MVC_View_Redirect: getParams must be an array'); + array_walk($params, function (&$value, $key) { + $value = urlencode($key) . '=' . urlencode($value); + }); + $redirectUrl .= (strpos($redirectUrl, '?') !== false ? '&' : '?') . implode('&', $params); + } + header('Location: ' . $redirectUrl, true, $this->getStatusCode()); } -} -?> \ No newline at end of file +} \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <m_p...@us...> - 2014-07-08 16:41:35
|
Revision: 174 http://sourceforge.net/p/beeframework/code/174 Author: m_plomer Date: 2014-07-08 16:41:30 +0000 (Tue, 08 Jul 2014) Log Message: ----------- - MVC: parametrized URL patterns done Modified Paths: -------------- trunk/examples/classes/Test/Mvc/ParamTestDelegate.php trunk/examples/index.php trunk/framework/Bee/MVC/Controller/MultiActionController.php trunk/framework/Bee/MVC/Controller/Multiaction/AbstractAnnotationBasedResolver.php trunk/framework/Bee/MVC/Controller/Multiaction/HandlerMethodInvocator/AnnotationBasedInvocator.php trunk/framework/Bee/MVC/Controller/Multiaction/HandlerMethodInvocator/IInvocationResolver.php trunk/framework/Bee/MVC/Controller/Multiaction/HandlerMethodInvocator/RegexMappingInvocationResolver.php trunk/framework/Bee/MVC/Controller/Multiaction/RequestHandler.php Added Paths: ----------- trunk/framework/Bee/MVC/Controller/Multiaction/HandlerMethodInvocator/HandlerMethodMetadata.php trunk/framework/Bee/MVC/Controller/Multiaction/HandlerMethodInvocator/MethodInvocation.php trunk/framework/Bee/MVC/Controller/Multiaction/NoHandlerMethodFoundException.php trunk/framework/Bee/MVC/Controller/Multiaction/RequestHandlerMapping.php Modified: trunk/examples/classes/Test/Mvc/ParamTestDelegate.php =================================================================== --- trunk/examples/classes/Test/Mvc/ParamTestDelegate.php 2014-07-08 09:52:40 UTC (rev 173) +++ trunk/examples/classes/Test/Mvc/ParamTestDelegate.php 2014-07-08 16:41:30 UTC (rev 174) @@ -2,7 +2,8 @@ namespace Test\Mvc; use Bee_MVC_IHttpRequest; -use Test\MiscClass; +use Bee_MVC_ModelAndView; +use Test\MiscClass as MC; /** @@ -13,20 +14,30 @@ /** * - * @Bee_MVC_Controller_Multiaction_RequestHandler(httpMethod = "GET", pathPattern = "/**\/testParam/{paramA}/{paramB}") + * @param int $paramA + * @param Bee_MVC_IHttpRequest $request + * @param MC $paramB + * @param boolean $boolParam + * @param MC $testParam + * @param boolean $getParam + * @return bool + * @Bee_MVC_Controller_Multiaction_RequestHandler(httpMethod = "GET", pathPattern = "/**\/testParam/{0}/{2}/{boolParam}") */ - public function handleTestParams($paramA, MiscClass $paramB, Bee_MVC_IHttpRequest $request) { + public function handleTestParams($paramA, Bee_MVC_IHttpRequest $request, MC $paramB, $boolParam = false, $testParam = null, $getParam = false) { var_dump($paramA); var_dump($paramB); var_dump($request); - return true; + var_dump($boolParam); + var_dump($testParam); + var_dump($getParam); + return new Bee_MVC_ModelAndView(array('paramA' => $paramA, 'paramB' => $paramB, 'boolParam' => $boolParam), 'testview'); } /** * * @Bee_MVC_Controller_Multiaction_RequestHandler(httpMethod = "GET", pathPattern = "/**\/testParam/{paramA}/") */ - public function handleTestParams2(MiscClass $paramB, Bee_MVC_IHttpRequest $request) { + public function handleTestParams2(MC $paramB, Bee_MVC_IHttpRequest $request) { var_dump($paramB); var_dump($request); return true; Modified: trunk/examples/index.php =================================================================== --- trunk/examples/index.php 2014-07-08 09:52:40 UTC (rev 173) +++ trunk/examples/index.php 2014-07-08 16:41:30 UTC (rev 174) @@ -10,4 +10,5 @@ Bee_Cache_Manager::init(); +//Bee_Framework::setProductionMode(true); Bee_Framework::dispatchRequestUsingXmlContext(__DIR__.'/conf/context-mvc.xml'); \ No newline at end of file Modified: trunk/framework/Bee/MVC/Controller/MultiActionController.php =================================================================== --- trunk/framework/Bee/MVC/Controller/MultiActionController.php 2014-07-08 09:52:40 UTC (rev 173) +++ trunk/framework/Bee/MVC/Controller/MultiActionController.php 2014-07-08 16:41:30 UTC (rev 174) @@ -17,6 +17,7 @@ */ use Bee\MVC\Controller\Multiaction\IHandlerMethodInvocator; use Bee\MVC\Controller\Multiaction\IMethodNameResolver; +use Bee\MVC\Controller\Multiaction\NoHandlerMethodFoundException; use Bee_MVC_IHttpRequest; use Bee_Utils_Assert; use Bee_Utils_Reflection; @@ -95,7 +96,7 @@ // @todo: this might pose a security risk. introduce a set of allowed method names $method = new ReflectionMethod($this->delegate, $methodName); if (!$this->isHandlerMethod($method)) { - throw new Exception('No request handling method with name ' . $methodName . ' in class [' . Bee_Utils_Types::getType($this->delegate) . ']'); + throw new NoHandlerMethodFoundException('No request handling method with name ' . $methodName . ' in class [' . Bee_Utils_Types::getType($this->delegate) . ']'); } } return $method->invokeArgs($this->delegate, array($request)); Modified: trunk/framework/Bee/MVC/Controller/Multiaction/AbstractAnnotationBasedResolver.php =================================================================== --- trunk/framework/Bee/MVC/Controller/Multiaction/AbstractAnnotationBasedResolver.php 2014-07-08 09:52:40 UTC (rev 173) +++ trunk/framework/Bee/MVC/Controller/Multiaction/AbstractAnnotationBasedResolver.php 2014-07-08 16:41:30 UTC (rev 174) @@ -37,7 +37,7 @@ const AJAX_TYPE_FALSE_KEY = '_FALSE'; const AJAX_TYPE_ANY_KEY = '_ANY'; - const CACHE_KEY_PREFIX = 'BeeMethodNameResolverAnnotationCache_'; + const CACHE_KEY_PREFIX = 'BeeMethodResolverAnnotationCache_'; /** * @var Modified: trunk/framework/Bee/MVC/Controller/Multiaction/HandlerMethodInvocator/AnnotationBasedInvocator.php =================================================================== --- trunk/framework/Bee/MVC/Controller/Multiaction/HandlerMethodInvocator/AnnotationBasedInvocator.php 2014-07-08 09:52:40 UTC (rev 173) +++ trunk/framework/Bee/MVC/Controller/Multiaction/HandlerMethodInvocator/AnnotationBasedInvocator.php 2014-07-08 16:41:30 UTC (rev 174) @@ -1,5 +1,6 @@ <?php namespace Bee\MVC\Controller\Multiaction\HandlerMethodInvocator; + /* * Copyright 2008-2014 the original author or authors. * @@ -18,9 +19,12 @@ use Bee\Beans\PropertyEditor\PropertyEditorRegistry; use Bee\MVC\Controller\Multiaction\AbstractAnnotationBasedResolver; use Bee\MVC\Controller\Multiaction\IHandlerMethodInvocator; +use Bee_Cache_Manager; use Bee_Context_Config_IContextAware; +use Bee_Framework; use Bee_IContext; use Bee_MVC_IHttpRequest; +use Exception; /** * Class AnnotationBasedInvocator @@ -28,35 +32,82 @@ */ class AnnotationBasedInvocator extends AbstractAnnotationBasedResolver implements IHandlerMethodInvocator, Bee_Context_Config_IContextAware { + const DEFAULT_METHOD_CACHE_KEY_PREFIX = 'BeeDefaultHandlerMethodCache_'; + /** * @var PropertyEditorRegistry */ private $propertyEditorRegistry; /** + * @var MethodInvocation + */ + private $defaultMethodInvocation; + + /** + * @return array + */ + protected function getDefaultMethodInvocation() { + if (!is_array($this->defaultMethodInvocation)) { + // todo: fetch default invocation from cache or rebuild + + $ctrl = $this->getController(); + $delegateClassName = get_class($ctrl->getDelegate()); + + $cacheKey = self::DEFAULT_METHOD_CACHE_KEY_PREFIX . $delegateClassName.'::'.$ctrl->getDefaultMethodName(); + if (Bee_Framework::getProductionMode()) { + try { + $this->defaultMethodInvocation = Bee_Cache_Manager::retrieve($cacheKey); + } catch (Exception $e) { + $this->getLog()->debug('No cached default method invocation for "' . $delegateClassName . '::'. $ctrl->getDefaultMethodName() .'" found, annotation parsing required'); + } + } + + if (!$this->defaultMethodInvocation) { + $methodMeta = RegexMappingInvocationResolver::getCachedMethodMetadata(new \ReflectionMethod($delegateClassName, $ctrl->getDefaultMethodName())); + $this->defaultMethodInvocation = new MethodInvocation($methodMeta); + } + + if (Bee_Framework::getProductionMode()) { + Bee_Cache_Manager::store($cacheKey, $this->defaultMethodInvocation); + } + } + return $this->defaultMethodInvocation; + } + + /** * @param Bee_MVC_IHttpRequest $request * @return \Bee_MVC_ModelAndView */ public function invokeHandlerMethod(Bee_MVC_IHttpRequest $request) { + /** @var MethodInvocation $resolvedMethod */ $resolvedMethod = $this->resolveMethodForRequest($request); - /** @var \ReflectionMethod $method */ - $method = $resolvedMethod['method']; + if (is_null($resolvedMethod)) { + $resolvedMethod = $this->getDefaultMethodInvocation(); + } + $methodMeta = $resolvedMethod->getMethodMeta(); + $method = $methodMeta->getMethod(); $args = array(); - - foreach($method->getParameters() as $parameter) { + foreach ($method->getParameters() as $parameter) { $pos = $parameter->getPosition(); - $type = $resolvedMethod['typeMap'][$pos]; - if($type == 'Bee_MVC_IHttpRequest') { + $type = $methodMeta->getTypeMapping($pos); + if ($type == 'Bee_MVC_IHttpRequest') { $args[$pos] = $request; } else { $propEditor = $this->propertyEditorRegistry->getEditor($type); - $urlPos = $resolvedMethod['positionMap'][$pos]; - $args[$pos] = $propEditor->fromString($resolvedMethod['paramValues'][$urlPos]); + $posMap = $resolvedMethod->getUrlParameterPositions(); + $value = array_key_exists($pos, $posMap) ? $resolvedMethod->getParamValue($posMap[$pos]) : + (array_key_exists($parameter->getName(), $_REQUEST) ? $_REQUEST[$parameter->getName()] : null); + if (!is_null($value) || !$parameter->isOptional()) { + $args[$pos] = $propEditor->fromString($value); +// } else { +// $args[$pos] = null; + } } } - $method->invokeArgs($this->getController()->getDelegate(), $args); + return $method->invokeArgs($this->getController()->getDelegate(), $args); } /** Added: trunk/framework/Bee/MVC/Controller/Multiaction/HandlerMethodInvocator/HandlerMethodMetadata.php =================================================================== --- trunk/framework/Bee/MVC/Controller/Multiaction/HandlerMethodInvocator/HandlerMethodMetadata.php (rev 0) +++ trunk/framework/Bee/MVC/Controller/Multiaction/HandlerMethodInvocator/HandlerMethodMetadata.php 2014-07-08 16:41:30 UTC (rev 174) @@ -0,0 +1,134 @@ +<?php + +namespace Bee\MVC\Controller\Multiaction\HandlerMethodInvocator; + +use Bee\Utils\ITypeDefinitions; +use ReflectionClass; +use ReflectionMethod; + + +/** + * Class HandlerMethodMetadata + * @package Bee\MVC\Controller\Multiaction\HandlerMethodInvocator + */ +class HandlerMethodMetadata { + + const CLASS_USES_MATCH = '#^\s*use\s+((?:\w+\\\\)*(\w+))(?: as (\w+))?;\s*$#m'; + const DOCBLOCK_PARAM_TYPE_HINT_MATCH = '#\*\s+@param\s+([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)\s\$([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)#'; + + /** + * @var array + */ + private static $importMap = array(); + + /** + * @var ReflectionMethod + */ + private $method; + + /** + * @var + */ + private $typeMap; + + /** + * @var array + */ + private $requestParamPos; + + /** + * @var array + */ + private $parameterPositions; + + function __construct(ReflectionMethod $method) { + $this->method = $method; + + $typeNameMap = self::getDocBlockTypeHints($method); + $this->typeMap = array(); + $this->requestParamPos = array(); + $this->parameterPositions = array(); + + foreach ($method->getParameters() as $param) { + $typeName = array_key_exists($param->getName(), $typeNameMap) ? + $typeNameMap[$param->getName()] : + (!is_null($param->getClass()) ? $param->getClass()->getName() : ITypeDefinitions::STRING); + if ($typeName == 'Bee_MVC_IHttpRequest') { + $this->requestParamPos[$param->getPosition()] = true; + } + $this->typeMap[$param->getName()] = $typeName; + $this->typeMap[$param->getPosition()] = $typeName; + $this->parameterPositions[$param->getName()] = $param->getPosition(); + } + } + + /** + * @return ReflectionMethod + */ + public function getMethod() { + return $this->method; + } + + /** + * @return array + */ + public function getRequestParamPos() { + return $this->requestParamPos; + } + + /** + * @return mixed + */ + public function getTypeMap() { + return $this->typeMap; + } + + /** + * @param $pos + * @return mixed + */ + public function getTypeMapping($pos) { + return $this->typeMap[$pos]; + } + + /** + * @return array + */ + public function getParameterPositions() { + return $this->parameterPositions; + } + + /** + * @param ReflectionMethod $method + * @return array + */ + protected static function getDocBlockTypeHints(ReflectionMethod $method) { + $importMap = self::getImportMap($method->getDeclaringClass()); + $matches = array(); + preg_match_all(self::DOCBLOCK_PARAM_TYPE_HINT_MATCH, $method->getDocComment(), $matches); + $types = $matches[1]; + array_walk($types, function (&$value) use ($importMap) { + if (array_key_exists($value, $importMap)) { + $value = $importMap[$value]; + } + }); + return array_combine($matches[2], $types); + } + + /** + * @param ReflectionClass $class + * @return mixed + */ + protected static function getImportMap(ReflectionClass $class) { + $className = $class->getName(); + if (!array_key_exists($className, self::$importMap)) { + $fileContent = file_get_contents($class->getFileName()); + $matches = array(); + preg_match_all(self::CLASS_USES_MATCH, $fileContent, $matches, PREG_SET_ORDER); + foreach ($matches as $match) { + self::$importMap[$className][$match[count($match) - 1]] = $match[1]; + } + } + return self::$importMap[$className]; + } +} \ No newline at end of file Modified: trunk/framework/Bee/MVC/Controller/Multiaction/HandlerMethodInvocator/IInvocationResolver.php =================================================================== --- trunk/framework/Bee/MVC/Controller/Multiaction/HandlerMethodInvocator/IInvocationResolver.php 2014-07-08 09:52:40 UTC (rev 173) +++ trunk/framework/Bee/MVC/Controller/Multiaction/HandlerMethodInvocator/IInvocationResolver.php 2014-07-08 16:41:30 UTC (rev 174) @@ -22,5 +22,9 @@ * @package Bee\MVC\Controller\Multiaction\HandlerMethodInvocator */ interface IInvocationResolver { + /** + * @param Bee_MVC_IHttpRequest $request + * @return MethodInvocation + */ public function getInvocationDefinition(Bee_MVC_IHttpRequest $request); } \ No newline at end of file Added: trunk/framework/Bee/MVC/Controller/Multiaction/HandlerMethodInvocator/MethodInvocation.php =================================================================== --- trunk/framework/Bee/MVC/Controller/Multiaction/HandlerMethodInvocator/MethodInvocation.php (rev 0) +++ trunk/framework/Bee/MVC/Controller/Multiaction/HandlerMethodInvocator/MethodInvocation.php 2014-07-08 16:41:30 UTC (rev 174) @@ -0,0 +1,80 @@ +<?php +namespace Bee\MVC\Controller\Multiaction\HandlerMethodInvocator; +/* + * Copyright 2008-2014 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Class MethodInvocation + * @package Bee\MVC\Controller\Multiaction\HandlerMethodInvocator + */ +class MethodInvocation { + + /** + * @var HandlerMethodMetadata + */ + private $methodMeta; + + /** + * @var array + */ + private $paramValues; + + /** + * @var array + */ + private $urlParameterPositions; + + function __construct(HandlerMethodMetadata $methodMetadata, array $urlParameterPositions = array()) { + $this->methodMeta = $methodMetadata; + $this->urlParameterPositions = $urlParameterPositions; + } + + /** + * @return HandlerMethodMetadata + */ + public function getMethodMeta() { + return $this->methodMeta; + } + + /** + * @return array + */ + public function getUrlParameterPositions() { + return $this->urlParameterPositions; + } + + /** + * @return array + */ + public function getParamValues() { + return $this->paramValues; + } + + /** + * @param array $paramValues + */ + public function setParamValues(array $paramValues) { + $this->paramValues = $paramValues; + } + + /** + * @param $pos + * @return mixed + */ + public function getParamValue($pos) { + return $this->paramValues[$pos]; + } +} \ No newline at end of file Modified: trunk/framework/Bee/MVC/Controller/Multiaction/HandlerMethodInvocator/RegexMappingInvocationResolver.php =================================================================== --- trunk/framework/Bee/MVC/Controller/Multiaction/HandlerMethodInvocator/RegexMappingInvocationResolver.php 2014-07-08 09:52:40 UTC (rev 173) +++ trunk/framework/Bee/MVC/Controller/Multiaction/HandlerMethodInvocator/RegexMappingInvocationResolver.php 2014-07-08 16:41:30 UTC (rev 174) @@ -15,10 +15,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +use Addendum\ReflectionAnnotatedMethod; use Bee\Utils\AntPathToRegexTransformer; -use Bee\Utils\ITypeDefinitions; use Bee_MVC_IHttpRequest; -use ReflectionClass; use ReflectionMethod; /** @@ -28,65 +27,59 @@ class RegexMappingInvocationResolver implements IInvocationResolver { /** - * @var array + * @var HandlerMethodMetadata[] */ + private static $methodMetadataMap = array(); + + /** + * @var MethodInvocation[] + */ private $mappedMethods = array(); /** - * @param array|\ReflectionMethod[] $mapping + * @param array|ReflectionAnnotatedMethod[] $mapping */ public function __construct(array $mapping) { - foreach($mapping as $antPathPattern => $method) { - $paramTypes = array(); - $nameToPos = array(); - $fixedParamPos = array(); - foreach($method->getParameters() as $param) { - $typeName = $param->getClass(); - $typeName = $typeName instanceof ReflectionClass ? $typeName->getName() : null; - if(!\Bee_Utils_Strings::hasText($typeName)) { - // todo: derive primitive type names from @var annotations - $typeName = ITypeDefinitions::STRING; - } else if($typeName == 'Bee_MVC_IHttpRequest') { - $fixedParamPos[$param->getPosition()] = true; - } - $paramTypes[$param->getName()] = $typeName; - $paramTypes[$param->getPosition()] = $typeName; - $nameToPos[$param->getName()] = $param->getPosition(); - } - $positionMap = array(); - $regex = AntPathToRegexTransformer::getRegexForParametrizedPattern($antPathPattern, $paramTypes, $positionMap); - $positionMap = array_map(function ($value) use ($nameToPos) { + foreach ($mapping as $antPathPattern => $method) { + $methodMeta = new HandlerMethodMetadata($method); + + $urlParameterPositions = array(); + $regex = AntPathToRegexTransformer::getRegexForParametrizedPattern($antPathPattern, $methodMeta->getTypeMap(), $urlParameterPositions); + $nameToPos = $methodMeta->getParameterPositions(); + $urlParameterPositions = array_map(function ($value) use ($nameToPos) { return array_key_exists($value, $nameToPos) ? $nameToPos[$value] : $value; - }, $positionMap); + }, $urlParameterPositions); // positionMap should only contain numeric values, mapping from match position to parameter position - $positionMap = array_flip($positionMap); + $urlParameterPositions = array_flip($urlParameterPositions); // now from parameter pos to match pos - if(!array_key_exists($regex, $this->mappedMethods)) { - // todo: object? - $this->mappedMethods[$regex] = array( - 'method' => $method, - 'positionMap' => $positionMap, - 'requestParamPos' => $fixedParamPos, - 'typeMap' => $paramTypes - ); + if (!array_key_exists($regex, $this->mappedMethods)) { + $this->mappedMethods[$regex] = new MethodInvocation($methodMeta, $urlParameterPositions); } } } /** * @param Bee_MVC_IHttpRequest $request - * @return array + * @return MethodInvocation */ public function getInvocationDefinition(Bee_MVC_IHttpRequest $request) { $pathInfo = $request->getPathInfo(); - foreach($this->mappedMethods as $regex => $invocInfo) { + foreach ($this->mappedMethods as $regex => $invocInfo) { $matches = array(); - if(preg_match($regex, $pathInfo, $matches) === 1) { - return array_merge($invocInfo, array('paramValues' => $matches)); + if (preg_match($regex, $pathInfo, $matches) === 1) { + $invocInfo->setParamValues($matches); + return $invocInfo; } } - // todo: maybe throw exception? how do we determine if method could not be found? return null; } + + public static function getCachedMethodMetadata(ReflectionMethod $method) { + $methodFullName = $method->getDeclaringClass()->getName() .'::' . $method->getName(); + if(!array_key_exists($methodFullName, self::$methodMetadataMap)) { + self::$methodMetadataMap[$methodFullName] = new HandlerMethodMetadata($method); + } + return self::$methodMetadataMap[$methodFullName]; + } } \ No newline at end of file Added: trunk/framework/Bee/MVC/Controller/Multiaction/NoHandlerMethodFoundException.php =================================================================== --- trunk/framework/Bee/MVC/Controller/Multiaction/NoHandlerMethodFoundException.php (rev 0) +++ trunk/framework/Bee/MVC/Controller/Multiaction/NoHandlerMethodFoundException.php 2014-07-08 16:41:30 UTC (rev 174) @@ -0,0 +1,13 @@ +<?php + +namespace Bee\MVC\Controller\Multiaction; +use Exception; + + +/** + * Class NoHandlerMethodFoundException + * @package Bee\MVC\Controller\Multiaction + */ +class NoHandlerMethodFoundException extends Exception { + +} \ No newline at end of file Modified: trunk/framework/Bee/MVC/Controller/Multiaction/RequestHandler.php =================================================================== --- trunk/framework/Bee/MVC/Controller/Multiaction/RequestHandler.php 2014-07-08 09:52:40 UTC (rev 173) +++ trunk/framework/Bee/MVC/Controller/Multiaction/RequestHandler.php 2014-07-08 16:41:30 UTC (rev 174) @@ -23,7 +23,8 @@ * * @author Michael Plomer <mic...@it...> * - * @Target("method") + * @Annotation + * @Target("METHOD") */ class Bee_MVC_Controller_Multiaction_RequestHandler extends Annotation { public $httpMethod; Added: trunk/framework/Bee/MVC/Controller/Multiaction/RequestHandlerMapping.php =================================================================== --- trunk/framework/Bee/MVC/Controller/Multiaction/RequestHandlerMapping.php (rev 0) +++ trunk/framework/Bee/MVC/Controller/Multiaction/RequestHandlerMapping.php 2014-07-08 16:41:30 UTC (rev 174) @@ -0,0 +1,43 @@ +<?php +namespace Bee\MVC\Controller\Multiaction; +/* + * Copyright 2008-2014 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Class RequestHandlerMapping + * @package Bee\MVC\Controller\Multiaction + * + * @Annotation + * @Target({"METHOD"}) + */ +class RequestHandlerMapping { + + /** + * @var string + */ + public $httpMethod; + + /** + * @var string + */ + public $pathPattern; + + /** + * @var boolean + */ + public $ajax; + +} \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <m_p...@us...> - 2014-07-10 17:09:16
|
Revision: 176 http://sourceforge.net/p/beeframework/code/176 Author: m_plomer Date: 2014-07-10 17:09:13 +0000 (Thu, 10 Jul 2014) Log Message: ----------- - MVC: RegexMappingInvocationResolver - proper pattern ordering and test case Modified Paths: -------------- trunk/examples/classes/Test/Mvc/ParamTestDelegate.php trunk/examples/conf/context-mvc.xml trunk/framework/Bee/MVC/Controller/Multiaction/AbstractAnnotationBasedResolver.php trunk/framework/Bee/MVC/Controller/Multiaction/HandlerMethodInvocator/AnnotationBasedInvocator.php trunk/framework/Bee/MVC/Controller/Multiaction/HandlerMethodInvocator/MethodInvocation.php trunk/framework/Bee/MVC/Controller/Multiaction/HandlerMethodInvocator/RegexMappingInvocationResolver.php trunk/framework/Bee/Utils/AntPathToRegexTransformer.php trunk/tests/Bee/Context/AbstractTest.php trunk/tests/Bee/Utils/AntPathDataProvider.php Added Paths: ----------- trunk/tests/Bee/MVC/ trunk/tests/Bee/MVC/Controller/ trunk/tests/Bee/MVC/Controller/Multiaction/ trunk/tests/Bee/MVC/Controller/Multiaction/HandlerMethodInvocator/ trunk/tests/Bee/MVC/Controller/Multiaction/HandlerMethodInvocator/RegexMappingInvocationResolverTest.php trunk/tests/Bee/MVC/HttpRequestMock.php Modified: trunk/examples/classes/Test/Mvc/ParamTestDelegate.php =================================================================== --- trunk/examples/classes/Test/Mvc/ParamTestDelegate.php 2014-07-08 16:51:43 UTC (rev 175) +++ trunk/examples/classes/Test/Mvc/ParamTestDelegate.php 2014-07-10 17:09:13 UTC (rev 176) @@ -21,34 +21,65 @@ * @param MC $testParam * @param boolean $getParam * @return bool - * @Bee_MVC_Controller_Multiaction_RequestHandler(httpMethod = "GET", pathPattern = "/**\/testParam/{0}/{2}/{boolParam}") + * @Bee_MVC_Controller_Multiaction_RequestHandler(pathPattern = "/**\/ghi/*\/{0}/{2}/const/{boolParam}", httpMethod="GET") + * @Bee_MVC_Controller_Multiaction_RequestHandler(pathPattern = "/**\/{0}/{2}/{boolParam}", httpMethod="POST") */ public function handleTestParams($paramA, Bee_MVC_IHttpRequest $request, MC $paramB, $boolParam = false, $testParam = null, $getParam = false) { - var_dump($paramA); - var_dump($paramB); - var_dump($request); - var_dump($boolParam); - var_dump($testParam); - var_dump($getParam); + echo '<hr/>'. get_class($this) .'::'. __FUNCTION__ .'<hr/>'; +// var_dump($paramA); +// var_dump($paramB); +// var_dump($request); +// var_dump($boolParam); +// var_dump($testParam); +// var_dump($getParam); +// echo '<hr/>'; +// var_dump($this); return new Bee_MVC_ModelAndView(array('paramA' => $paramA, 'paramB' => $paramB, 'boolParam' => $boolParam), 'testview'); } /** * - * @Bee_MVC_Controller_Multiaction_RequestHandler(httpMethod = "GET", pathPattern = "/**\/testParam/{paramA}/") + * @param int $paramA + * @param Bee_MVC_IHttpRequest $request + * @param MC $paramB + * @param boolean $boolParam + * @param MC $testParam + * @param boolean $getParam + * @return bool + * @Bee_MVC_Controller_Multiaction_RequestHandler(pathPattern = "/**\/ttt/{0}/{2}/{boolParam}") */ + public function handleTestParams25($paramA, Bee_MVC_IHttpRequest $request, MC $paramB, $boolParam = false, $testParam = null, $getParam = false) { + echo '<hr/>'. get_class($this) .'::'. __FUNCTION__ .'<hr/>'; +// var_dump($paramA); +// var_dump($paramB); +// var_dump($request); +// var_dump($boolParam); +// var_dump($testParam); +// var_dump($getParam); +// echo '<hr/>'; +// var_dump($this); + return new Bee_MVC_ModelAndView(array('paramA' => $paramA, 'paramB' => $paramB, 'boolParam' => $boolParam), 'testview'); + } + + /** + * + * @Bee_MVC_Controller_Multiaction_RequestHandler(pathPattern = "/**\/testParam/{paramA}/") + */ public function handleTestParams2(MC $paramB, Bee_MVC_IHttpRequest $request) { - var_dump($paramB); - var_dump($request); + echo '<hr/>'. get_class($this) .'::'. __FUNCTION__ .'<hr/>'; +// var_dump($paramB); +// var_dump($request); return true; } /** * @param int $getParam * @return Bee_MVC_ModelAndView + * @Bee_MVC_Controller_Multiaction_RequestHandler(pathPattern = "/**") */ public function handleDefault($getParam = 1000) { - var_dump($getParam); + echo '<hr/>'. get_class($this) .'::'. __FUNCTION__ .'<hr/>'; +// var_dump($getParam); return new Bee_MVC_ModelAndView(array(), 'defaultview'); } } \ No newline at end of file Modified: trunk/examples/conf/context-mvc.xml =================================================================== --- trunk/examples/conf/context-mvc.xml 2014-07-08 16:51:43 UTC (rev 175) +++ trunk/examples/conf/context-mvc.xml 2014-07-10 17:09:13 UTC (rev 176) @@ -17,6 +17,7 @@ <array> <assoc-item key="/**/testClassic/**" value="classicController" /> <assoc-item key="/**/testParam/**" value="paramController" /> + <assoc-item key="/**/testParamSub/**" value="paramSubController" /> </array> </property> </bean> @@ -47,5 +48,14 @@ </property> </bean> + <bean id="paramSubController" parent="multiactionControllerTemplate"> + <property name="methodInvocator"> + <bean class="Bee\MVC\Controller\Multiaction\HandlerMethodInvocator\AnnotationBasedInvocator" scope="prototype"/> + </property> + <property name="delegate"> + <bean class="Test\Mvc\SubTestDelegate" /> + </property> + </bean> + <bean id="propertyEditor_Test_MiscClass" class="Test\MiscClassPropertyEditor" /> </beans> Modified: trunk/framework/Bee/MVC/Controller/Multiaction/AbstractAnnotationBasedResolver.php =================================================================== --- trunk/framework/Bee/MVC/Controller/Multiaction/AbstractAnnotationBasedResolver.php 2014-07-08 16:51:43 UTC (rev 175) +++ trunk/framework/Bee/MVC/Controller/Multiaction/AbstractAnnotationBasedResolver.php 2014-07-10 17:09:13 UTC (rev 176) @@ -113,12 +113,11 @@ if (!$this->delegates) { $classReflector = new ReflectionAnnotatedClass($delegateClassName); - /** @var ReflectionAnnotatedMethod[] $methods */ $methods = $classReflector->getMethods(ReflectionMethod::IS_PUBLIC); $mappings = array(); - foreach ($methods as $method) { - + foreach (array_reverse($methods) as $method) { + /** @var ReflectionAnnotatedMethod $method */ if (Bee_Utils_Reflection::isCallableRegularMethod($method)) { // is possible handler method, check for annotations Modified: trunk/framework/Bee/MVC/Controller/Multiaction/HandlerMethodInvocator/AnnotationBasedInvocator.php =================================================================== --- trunk/framework/Bee/MVC/Controller/Multiaction/HandlerMethodInvocator/AnnotationBasedInvocator.php 2014-07-08 16:51:43 UTC (rev 175) +++ trunk/framework/Bee/MVC/Controller/Multiaction/HandlerMethodInvocator/AnnotationBasedInvocator.php 2014-07-10 17:09:13 UTC (rev 176) @@ -102,8 +102,6 @@ (array_key_exists($parameter->getName(), $_REQUEST) ? $_REQUEST[$parameter->getName()] : null); if (!is_null($value) || !$parameter->isOptional()) { $args[$pos] = $propEditor->fromString($value); -// } else { -// $args[$pos] = null; } } } Modified: trunk/framework/Bee/MVC/Controller/Multiaction/HandlerMethodInvocator/MethodInvocation.php =================================================================== --- trunk/framework/Bee/MVC/Controller/Multiaction/HandlerMethodInvocator/MethodInvocation.php 2014-07-08 16:51:43 UTC (rev 175) +++ trunk/framework/Bee/MVC/Controller/Multiaction/HandlerMethodInvocator/MethodInvocation.php 2014-07-10 17:09:13 UTC (rev 176) @@ -28,6 +28,11 @@ private $methodMeta; /** + * @var string + */ + private $antPathPattern; + + /** * @var array */ private $paramValues; @@ -37,8 +42,9 @@ */ private $urlParameterPositions; - function __construct(HandlerMethodMetadata $methodMetadata, array $urlParameterPositions = array()) { + function __construct(HandlerMethodMetadata $methodMetadata, $antPathPattern = false, array $urlParameterPositions = array()) { $this->methodMeta = $methodMetadata; + $this->antPathPattern = $antPathPattern; $this->urlParameterPositions = $urlParameterPositions; } @@ -77,4 +83,11 @@ public function getParamValue($pos) { return $this->paramValues[$pos]; } + + /** + * @return string + */ + public function getAntPathPattern() { + return $this->antPathPattern; + } } \ No newline at end of file Modified: trunk/framework/Bee/MVC/Controller/Multiaction/HandlerMethodInvocator/RegexMappingInvocationResolver.php =================================================================== --- trunk/framework/Bee/MVC/Controller/Multiaction/HandlerMethodInvocator/RegexMappingInvocationResolver.php 2014-07-08 16:51:43 UTC (rev 175) +++ trunk/framework/Bee/MVC/Controller/Multiaction/HandlerMethodInvocator/RegexMappingInvocationResolver.php 2014-07-10 17:09:13 UTC (rev 176) @@ -1,5 +1,6 @@ <?php namespace Bee\MVC\Controller\Multiaction\HandlerMethodInvocator; + /* * Copyright 2008-2014 the original author or authors. * @@ -15,9 +16,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -use Addendum\ReflectionAnnotatedMethod; use Bee\Utils\AntPathToRegexTransformer; use Bee_MVC_IHttpRequest; +use Logger; use ReflectionMethod; /** @@ -26,10 +27,27 @@ */ class RegexMappingInvocationResolver implements IInvocationResolver { + const IGNORE_WILDCARD_TRAILING_PATTERN = '\\.[^/]*'; + /** + * @var Logger + */ + protected static $log; + + /** + * @return Logger + */ + protected static function getLog() { + if (!self::$log) { + self::$log = Logger::getLogger(get_called_class()); + } + return self::$log; + } + + /** * @var HandlerMethodMetadata[] */ - private static $methodMetadataMap = array(); + private static $methodMetadataMap; /** * @var MethodInvocation[] @@ -37,11 +55,11 @@ private $mappedMethods = array(); /** - * @param array|ReflectionAnnotatedMethod[] $mapping + * @param array|ReflectionMethod[] $mapping */ public function __construct(array $mapping) { foreach ($mapping as $antPathPattern => $method) { - $methodMeta = new HandlerMethodMetadata($method); + $methodMeta = self::getCachedMethodMetadata($method); $urlParameterPositions = array(); $regex = AntPathToRegexTransformer::getRegexForParametrizedPattern($antPathPattern, $methodMeta->getTypeMap(), $urlParameterPositions); @@ -53,9 +71,7 @@ $urlParameterPositions = array_flip($urlParameterPositions); // now from parameter pos to match pos - if (!array_key_exists($regex, $this->mappedMethods)) { - $this->mappedMethods[$regex] = new MethodInvocation($methodMeta, $urlParameterPositions); - } + $this->mappedMethods[$regex] = new MethodInvocation($methodMeta, $antPathPattern, $urlParameterPositions); } } @@ -65,21 +81,105 @@ */ public function getInvocationDefinition(Bee_MVC_IHttpRequest $request) { $pathInfo = $request->getPathInfo(); + $matchingPatterns = array(); foreach ($this->mappedMethods as $regex => $invocInfo) { $matches = array(); if (preg_match($regex, $pathInfo, $matches) === 1) { $invocInfo->setParamValues($matches); - return $invocInfo; +// return $invocInfo; + $matchingPatterns[$regex] = $invocInfo; } } + // sort matching patterns + if (self::getLog()->isDebugEnabled()) { + self::getLog()->debug('Found ' . count($matchingPatterns) . ' matching patterns for pathInfo "' . $pathInfo . '", trying to determine most specific match'); + } + + uksort($matchingPatterns, function ($patternA, $patternB) use ($matchingPatterns, $pathInfo) { + /** @var MethodInvocation[] $matchingPatterns */ + $matchA = $matchingPatterns[$patternA]; + $matchB = $matchingPatterns[$patternB]; + + $emptyMatches = 0; + $litLength = function ($carry, $item) use (&$emptyMatches) { + if ($carry === false) { + return $item; + } + if($item) { + if(substr($item, -1) == '/') { + $item = substr($item, 0, -1); + } + return preg_replace('#/'.preg_quote($item).'#', '', $carry, 1); + } + $emptyMatches++; + return $carry; + }; + $litA = array_reduce($matchA->getParamValues(), $litLength, false); + $litA = preg_replace('#//#', '/', $litA); + + $emptyMatches *= -1; + + $litB = array_reduce($matchB->getParamValues(), $litLength, false); + $litB = preg_replace('#//#', '/', $litB); + $litCountA = substr_count($litA, '/'); + $litCountB = substr_count($litB, '/'); + + if ($litCountA != $litCountB) { + return $litCountB - $litCountA; + } + + $resA = array_diff_key($matchA->getParamValues(), array_flip($matchA->getUrlParameterPositions()), array(0 => true)); + $resB = array_diff_key($matchB->getParamValues(), array_flip($matchB->getUrlParameterPositions()), array(0 => true)); + + $counter = function ($carry, $item) { + if (strlen($item) == 0) { + return $carry; + } + $count = substr_count($item, '/'); + return $carry + $count + (substr($item, -1) == '/' ? 0 : 1); + }; + $countA = array_reduce($resA, $counter, 0); + $countB = array_reduce($resB, $counter, 0); + + if ($countA != $countB) { + return $countA - $countB; + } + return -$emptyMatches; + }); + + if (self::getLog()->isDebugEnabled()) { + $matchingAntPaths = array_map(function (MethodInvocation $item) { + return $item->getAntPathPattern(); + }, $matchingPatterns); +// self::getLog()->debug('Sorted patterns for pathInfo "' . $pathInfo . '" are ' . implode("\n", array_keys($matchingPatterns))); + self::getLog()->debug('Sorted patterns for pathInfo "' . $pathInfo . '" are ' . "\n" . implode("\n", $matchingAntPaths)); + } + + if (count($matchingPatterns) > 0) { + return array_shift($matchingPatterns); + } + return null; } public static function getCachedMethodMetadata(ReflectionMethod $method) { - $methodFullName = $method->getDeclaringClass()->getName() .'::' . $method->getName(); - if(!array_key_exists($methodFullName, self::$methodMetadataMap)) { + $methodFullName = $method->getDeclaringClass()->getName() . '::' . $method->getName(); + if (!array_key_exists($methodFullName, self::$methodMetadataMap)) { self::$methodMetadataMap[$methodFullName] = new HandlerMethodMetadata($method); } return self::$methodMetadataMap[$methodFullName]; } + + public static function getWildcardCount($pattern) { + $len = strlen(self::IGNORE_WILDCARD_TRAILING_PATTERN); + if (substr($pattern, $len) == self::IGNORE_WILDCARD_TRAILING_PATTERN) { + $pattern = substr(self::IGNORE_WILDCARD_TRAILING_PATTERN, 0, -$len); + } + return substr_count($pattern, '[^/]*') + 2 * substr_count($pattern, '(?:[^/]+/)*') + 2 * substr_count($pattern, '.*'); + } + + public static function getPatternLength($pattern) { + $pattern = preg_replace('#\([^?].*?\)#', '#', $pattern); + return strlen($pattern); + } } \ No newline at end of file Modified: trunk/framework/Bee/Utils/AntPathToRegexTransformer.php =================================================================== --- trunk/framework/Bee/Utils/AntPathToRegexTransformer.php 2014-07-08 16:51:43 UTC (rev 175) +++ trunk/framework/Bee/Utils/AntPathToRegexTransformer.php 2014-07-10 17:09:13 UTC (rev 176) @@ -23,11 +23,11 @@ class AntPathToRegexTransformer { private static $SIMPLE_REPLACEMENTS = array( - '#\.#' => '\\.', - '#\*#' => '[^/]*', - '#\[\^/\]\*\[\^/\]\*/#' => '(?:[^/]+/)*', - '#\[\^/\]\*\[\^/\]\*#' => '.*', - '#(^|(?<=[^(]))\?#' => '[^/]' + '#\.#' => '\\.', // keep "." as literals + '#\*#' => '([^/]*)', // "*" matches any string that does not contain slashes + '#\(\[\^/\]\*\)\(\[\^/\]\*\)/#' => '((?:[^/]+/)*?)', // "**/" - replaced by "([^/]+)" above - matches 0:n path elements + '#\(\[\^/\]\*\)\(\[\^/\]\*\)#' => '(.*?)', + '#(^|(?<=[^(*]))\?#' => '[^/]' ); public static $TYPE_EXPRESSION_MAP = array( @@ -39,7 +39,7 @@ ITypeDefinitions::STRING => '[^/]+' ); - const PARAMETER_MATCH = '#{((?:\d+)|(?:[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*))}#'; + const PARAMETER_MATCH = '#(?:{((?:\d+)|(?:[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*))})|\(\(\[\^/\]\+/\)\*\?\)|\(.*?\)#'; /** * @param string $antPathPattern @@ -59,6 +59,10 @@ $result = self::getRegexForSimplePattern($antPathPattern); $matchPos = 1; return preg_replace_callback(self::PARAMETER_MATCH, function($matches) use ($parameterTypes, &$positionMap, &$matchPos) { + if(count($matches) == 1) { + $matchPos++; + return $matches[0]; + } $positionMap[$matchPos++] = $matches[1]; $typeName = $parameterTypes[$matches[1]]; if(!array_key_exists($typeName, AntPathToRegexTransformer::$TYPE_EXPRESSION_MAP)) { Modified: trunk/tests/Bee/Context/AbstractTest.php =================================================================== --- trunk/tests/Bee/Context/AbstractTest.php 2014-07-08 16:51:43 UTC (rev 175) +++ trunk/tests/Bee/Context/AbstractTest.php 2014-07-10 17:09:13 UTC (rev 176) @@ -1,6 +1,6 @@ <?php /* - * Copyright 2008-2010 the original author or authors. + * Copyright 2008-2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. Added: trunk/tests/Bee/MVC/Controller/Multiaction/HandlerMethodInvocator/RegexMappingInvocationResolverTest.php =================================================================== --- trunk/tests/Bee/MVC/Controller/Multiaction/HandlerMethodInvocator/RegexMappingInvocationResolverTest.php (rev 0) +++ trunk/tests/Bee/MVC/Controller/Multiaction/HandlerMethodInvocator/RegexMappingInvocationResolverTest.php 2014-07-10 17:09:13 UTC (rev 176) @@ -0,0 +1,205 @@ +<?php +namespace Bee\MVC\Controller\Multiaction\HandlerMethodInvocator; +/* + * Copyright 2008-2014 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +use Bee\MVC\HttpRequestMock; +use PHPUnit_Framework_TestCase; + +/** + * Class RegexMappingInvocationResolver + * @package Bee\MVC\Controller\Multiaction\HandlerMethodInvocator + */ +class RegexMappingInvocationResolverTest extends PHPUnit_Framework_TestCase { + + /** + * @test + * @dataProvider matchDataProvider + */ + public function testMapping(RegexMappingInvocationResolver $resolver, $pathInfo, $expectedAntPath, $expectedParams = array()) { + $request = new HttpRequestMock($pathInfo); + $invocation = $resolver->getInvocationDefinition($request); + $this->assertEquals($expectedAntPath, $invocation->getAntPathPattern()); + + $res = array_intersect_key($invocation->getParamValues(), array_flip($invocation->getUrlParameterPositions())); + $this->assertEquals($expectedParams, array_merge($res)); // param neu durchnummerieren + } + + + public function matchDataProvider() { + $testMapping = $this->provideTestRegexMappingInvocationResolver1(); + return array( + array($testMapping, '/complicated', '/complicated'), // # 00 + array($testMapping, '/complicated/', '/complicated/**'), + array($testMapping, '/complicated/hund', '/complicated/{string1}', array('hund')), + + array($testMapping, '/complicated/more/hund/complicator/hermelin/hase', '/complicated/more/{string1}/complicator/{string2}/**', array('hund', 'hermelin')), + array($testMapping, '/complicated/more/hund/complicator/hermelin/hase/dachs', '/complicated/more/{string1}/complicator/{string2}/**', array('hund', 'hermelin')), + + array($testMapping, + '/complicated/more/hund/complicator/hase', + '/complicated/more/{string1}/complicator/{string2}', + array('hund', 'hase')), // # 05 + array($testMapping, + '/complicated/more/complicator/hund', + '/complicated/more/**/complicator/{string2}', + array('hund')), + array($testMapping, + '/complicated/more/hund/hermelin/complicator/hase', + '/complicated/more/**/complicator/{string2}', + array('hase')), + array($testMapping, + '/hund/complicated/more/hund/complicator/hermelin/hase', + '/**/complicated/more/{string1}/complicator/{string2}/**', + array('hund', 'hermelin')), + array($testMapping, + '/x/complicated/more/complicator/hermelin/hase', + '/**/complicated/more/**/complicator/{string2}/**', + array('hermelin')), + array($testMapping, + '/hase/complicated/more/complicator/hermelin/x', + '/**/complicated/more/**/complicator/{string2}/**', + array('hermelin')), // # 10 + array($testMapping, + '/x/y/z/complicated/more/hund/complicator/hermelin/hase', + '/**/complicated/more/{string1}/complicator/{string2}/**', + array('hund', + 'hermelin')), + array($testMapping, + '/x/complicated/more/y/complicator/hermelin/hase', + '/**/complicated/more/{string1}/complicator/{string2}/**', + array('y', 'hermelin')), + array($testMapping, + '/complicated/more/x/y/z/complicator/hermelin/hase', + '/complicated/more/**/complicator/{string2}/**', + array('hermelin')), + array($testMapping, + '/complicated/more/x/y/z/compliment/hermelin/hase', + '/complicated/more/**/compl*/{string2}/**', + array('hermelin')), + + ); + } + + public function provideTestRegexMappingInvocationResolver1() { + $method = new \ReflectionMethod('Bee\MVC\Controller\Multiaction\HandlerMethodInvocator\HandlerMock', 'methodA'); + + $testPatterns1 = array(); + $testPatterns1['/complicated'] = $method; + $testPatterns1['/complicated/**'] = $method; + $testPatterns1['/complicated/more'] = $method; + $testPatterns1['/complicated/{string1}'] = $method; + $testPatterns1['/complicated/more/music'] = $method; + $testPatterns1['/complicated/more/{string1}/music'] = $method; + $testPatterns1['/complicated/more/{string1}/{string2}'] = $method; + $testPatterns1['/complicated/more/{string1}/{string2}/{string3}'] = $method; + $testPatterns1['/complicated/more/{string1}/complicator/{string2}'] = $method; + $testPatterns1['/complicated/{string1}/complicator/{string2}'] = $method; + $testPatterns1['/complicated/**/complicator/{string2}'] = $method; + $testPatterns1['/complicated/more/**/complicator/{string2}'] = $method; + $testPatterns1['/complicated/more/**'] = $method; + $testPatterns1['/complicated/{string1}/**'] = $method; + $testPatterns1['/complicated/more/music/**'] = $method; + $testPatterns1['/complicated/more/{string1}/music/**'] = $method; + $testPatterns1['/complicated/more/{string1}/{string2}/**'] = $method; + $testPatterns1['/complicated/more/{string1}/{string2}/{string3}/**'] = $method; + $testPatterns1['/complicated/more/{string1}/complicator/{string2}/**'] = $method; + $testPatterns1['/complicated/{string1}/complicator/{string2}/**'] = $method; + $testPatterns1['/complicated/**/complicator/{string2}/**'] = $method; + $testPatterns1['/complicated/more/**/complicator/{string2}/**'] = $method; + + $testPatterns1['/**/complicated'] = $method; + $testPatterns1['/**/complicated/**'] = $method; + $testPatterns1['/**/complicated/more'] = $method; + $testPatterns1['/**/complicated/{string1}'] = $method; + $testPatterns1['/**/complicated/more/music'] = $method; + $testPatterns1['/**/complicated/more/{string1}/music'] = $method; + $testPatterns1['/**/complicated/more/{string1}/{string2}'] = $method; + $testPatterns1['/**/complicated/more/{string1}/{string2}/{string3}'] = $method; + $testPatterns1['/**/complicated/more/{string1}/complicator/{string2}'] = $method; + $testPatterns1['/**/complicated/{string1}/complicator/{string2}'] = $method; + $testPatterns1['/**/complicated/**/complicator/{string2}'] = $method; + $testPatterns1['/**/complicated/more/**/complicator/{string2}'] = $method; + $testPatterns1['/**/complicated/more/**'] = $method; + $testPatterns1['/**/complicated/{string1}/**'] = $method; + $testPatterns1['/**/complicated/more/music/**'] = $method; + $testPatterns1['/**/complicated/more/{string1}/music/**'] = $method; + $testPatterns1['/**/complicated/more/{string1}/{string2}/**'] = $method; + $testPatterns1['/**/complicated/more/{string1}/{string2}/{string3}/**'] = $method; + $testPatterns1['/**/complicated/more/{string1}/complicator/{string2}/**'] = $method; + $testPatterns1['/**/complicated/{string1}/complicator/{string2}/**'] = $method; + $testPatterns1['/**/complicated/**/complicator/{string2}/**'] = $method; + $testPatterns1['/**/complicated/more/**/complicator/{string2}/**'] = $method; + + $testPatterns1['/**/more'] = $method; + $testPatterns1['/**/{string1}'] = $method; + $testPatterns1['/**/more/music'] = $method; + $testPatterns1['/**/more/{string1}/music'] = $method; + $testPatterns1['/**/more/{string1}/{string2}'] = $method; + $testPatterns1['/**/more/{string1}/{string2}/{string3}'] = $method; + $testPatterns1['/**/more/{string1}/complicator/{string2}'] = $method; + $testPatterns1['/**/{string1}/complicator/{string2}'] = $method; + $testPatterns1['/**/**/complicator/{string2}'] = $method; + $testPatterns1['/**/more/**/complicator/{string2}'] = $method; + $testPatterns1['/**/more/**'] = $method; + $testPatterns1['/**/{string1}/**'] = $method; + $testPatterns1['/**/more/music/**'] = $method; + $testPatterns1['/**/more/{string1}/music/**'] = $method; + $testPatterns1['/**/more/{string1}/{string2}/**'] = $method; + $testPatterns1['/**/more/{string1}/{string2}/{string3}/**'] = $method; + $testPatterns1['/**/more/{string1}/complicator/{string2}/**'] = $method; + $testPatterns1['/**/{string1}/complicator/{string2}/**'] = $method; + $testPatterns1['/**/complicator/{string2}/**'] = $method; + $testPatterns1['/**/more/**/complicator/{string2}/**'] = $method; + + $testPatterns1['/**'] = $method; + $testPatterns1['/*/more'] = $method; + $testPatterns1['/*/{string1}'] = $method; + $testPatterns1['/*/more/music'] = $method; + $testPatterns1['/*/more/{string1}/music'] = $method; + $testPatterns1['/*/more/{string1}/{string2}'] = $method; + $testPatterns1['/*/more/{string1}/{string2}/{string3}'] = $method; + $testPatterns1['/*/more/{string1}/complicator/{string2}'] = $method; + $testPatterns1['/*/{string1}/complicator/{string2}'] = $method; + $testPatterns1['/*/**/complicator/{string2}'] = $method; + $testPatterns1['/*/more/**/complicator/{string2}'] = $method; + $testPatterns1['/*/more/**'] = $method; + $testPatterns1['/*/{string1}/**'] = $method; + $testPatterns1['/*/more/music/**'] = $method; + $testPatterns1['/*/more/{string1}/music/**'] = $method; + $testPatterns1['/*/more/{string1}/{string2}/**'] = $method; + $testPatterns1['/*/more/{string1}/{string2}/{string3}/**'] = $method; + $testPatterns1['/*/more/{string1}/complicator/{string2}/**'] = $method; + $testPatterns1['/*/{string1}/complicator/{string2}/**'] = $method; + $testPatterns1['/*/complicator/{string2}/**'] = $method; + $testPatterns1['/*/more/**/complicator/{string2}/**'] = $method; + + $testPatterns1['/complicated/more/**/compl*/{string2}/**'] = $method; + + return new RegexMappingInvocationResolver($testPatterns1); + } +} + +class HandlerMock { + + /** + * @param string $string1 + * @param string $string2 + * @param string $string3 + */ + public function methodA($string1, $string2, $string3) { + + } +} \ No newline at end of file Added: trunk/tests/Bee/MVC/HttpRequestMock.php =================================================================== --- trunk/tests/Bee/MVC/HttpRequestMock.php (rev 0) +++ trunk/tests/Bee/MVC/HttpRequestMock.php 2014-07-10 17:09:13 UTC (rev 176) @@ -0,0 +1,118 @@ +<?php +namespace Bee\MVC; +use Bee_MVC_IHttpRequest; + +/** + * Class HttpRequestMock + * @package Bee\MVC + */ +class HttpRequestMock implements Bee_MVC_IHttpRequest { + + /** + * @var string + */ + private $pathInfo; + + /** + * @var string + */ + private $method; + + /** + * @var array + */ + private $parameters = array(); + + /** + * @var array + */ + private $headers = array(); + + /** + * @var bool + */ + private $ajax = false; + + /** + * @param $pathInfo + * @param $parameters + * @param $method + * @param $headers + * @param $ajax + */ + function __construct($pathInfo = '', array $parameters = array(), $method = 'GET', array $headers = array(), $ajax = false) { + $this->pathInfo = $pathInfo; + $this->parameters = $parameters; + $this->method = $method; + $this->headers = array_change_key_case($headers, CASE_UPPER); + $this->ajax = $ajax; + } + + + /** + * @return string + */ + public function getPathInfo() { + return $this->pathInfo; + } + + /** + * @return string + */ + public function getMethod() { + return $this->method; + } + + /** + * @param string $name + * @return bool + */ + public function hasParameter($name) { + return array_key_exists($name, $this->parameters); + } + + /** + * @param String $name + * @return String + */ + public function getParameter($name) { + return $this->hasParameter($name) ? $this->parameters[$name] : null; + } + + /** + * @return array + */ + public function getParameterNames() { + return array_keys($this->parameters); + } + + /** + * @param String $name + * @return String + */ + public function getHeader($name) { + $name = strtoupper($name); + return array_key_exists($name, $this->headers) ? $this->headers[$name] : false; + } + + /** + * @return array + */ + public function getHeaderNames() { + return array_keys($this->headers); + } + + /** + * @param array $params + */ + public function addParameters(array $params) { + $this->parameters = array_merge($this->parameters, $params); + } + + /** + * @return bool + */ + public function getAjax() { + return $this->ajax; + } +} \ No newline at end of file Modified: trunk/tests/Bee/Utils/AntPathDataProvider.php =================================================================== --- trunk/tests/Bee/Utils/AntPathDataProvider.php 2014-07-08 16:51:43 UTC (rev 175) +++ trunk/tests/Bee/Utils/AntPathDataProvider.php 2014-07-10 17:09:13 UTC (rev 176) @@ -104,6 +104,8 @@ array("/x/x/**/bla", "/x/x/x/", False), + array("/test/**", "/test", False), + array("", "", True)//, // array("/{bla}.*", "/testing.html", True) // #65 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <m_p...@us...> - 2014-09-26 14:04:24
|
Revision: 233 http://sourceforge.net/p/beeframework/code/233 Author: m_plomer Date: 2014-09-26 14:04:16 +0000 (Fri, 26 Sep 2014) Log Message: ----------- Context/Xml: added ability to decorate custom namespace beans with custom decorators - namespace fixes Modified Paths: -------------- trunk/framework/bee-beans-1.2.xsd trunk/framework/bee-util-1.0.xsd trunk/tests/Bee/Context/Xml/BeanDefinitionReaderTest-context.xml Modified: trunk/framework/bee-beans-1.2.xsd =================================================================== --- trunk/framework/bee-beans-1.2.xsd 2014-09-26 13:11:26 UTC (rev 232) +++ trunk/framework/bee-beans-1.2.xsd 2014-09-26 14:04:16 UTC (rev 233) @@ -325,6 +325,21 @@ </xsd:attribute> </xsd:attributeGroup> + <xsd:attributeGroup name="typedValueAttributes"> + <xsd:attribute name="value" type="xsd:string"> + <xsd:annotation> + <xsd:documentation> + <![CDATA[A short-cut alternative to a nested "<value>...</value>" element.]]></xsd:documentation> + </xsd:annotation> + </xsd:attribute> + <xsd:attribute name="type" type="xsd:string"> + <xsd:annotation> + <xsd:documentation><![CDATA[The type that the value attribute should be validated against and converted + to.]]></xsd:documentation> + </xsd:annotation> + </xsd:attribute> + </xsd:attributeGroup> + <xsd:element name="bean"> <xsd:annotation> <xsd:documentation source="java:org.springframework.beans.factory.config.BeanDefinition"><![CDATA[ @@ -670,12 +685,7 @@ <![CDATA[A short-cut alternative to a nested "<ref bean='...'/>".]]></xsd:documentation> </xsd:annotation> </xsd:attribute> - <xsd:attribute name="value" type="xsd:string"> - <xsd:annotation> - <xsd:documentation> - <![CDATA[A short-cut alternative to a nested "<value>...</value>" element.]]></xsd:documentation> - </xsd:annotation> - </xsd:attribute> + <xsd:attributeGroup ref="typedValueAttributes"/> </xsd:complexType> Modified: trunk/framework/bee-util-1.0.xsd =================================================================== --- trunk/framework/bee-util-1.0.xsd 2014-09-26 13:11:26 UTC (rev 232) +++ trunk/framework/bee-util-1.0.xsd 2014-09-26 14:04:16 UTC (rev 233) @@ -1,19 +1,20 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <xsd:schema xmlns="http://www.beeframework.org/schema/util" - xmlns:xsd="http://www.w3.org/2001/XMLSchema" - xmlns:beans="http://www.beeframework.org/schema/beans" - targetNamespace="http://www.beeframework.org/schema/util" - elementFormDefault="qualified" - attributeFormDefault="unqualified"> + xmlns:xsd="http://www.w3.org/2001/XMLSchema" + xmlns:beans="http://www.beeframework.org/schema/beans" + targetNamespace="http://www.beeframework.org/schema/util" + elementFormDefault="qualified" + attributeFormDefault="unqualified"> - <xsd:import namespace="http://www.beeframework.org/schema/beans" schemaLocation="http://www.beeframework.org/schema/beans/bee-beans-1.2.xsd"/> + <xsd:import namespace="http://www.beeframework.org/schema/beans" + schemaLocation="http://www.beeframework.org/schema/beans/bee-beans-1.2.xsd"/> - <xsd:annotation> - <xsd:documentation><![CDATA[ + <xsd:annotation> + <xsd:documentation><![CDATA[ Defines the configuration elements for misc context utilities. ]]></xsd:documentation> - </xsd:annotation> + </xsd:annotation> <xsd:element name="array"> <xsd:annotation> @@ -24,7 +25,7 @@ <xsd:complexType> <xsd:complexContent> <xsd:extension base="beans:identifiedType"> - <xsd:group ref="beans:arrayElements" /> + <xsd:group ref="beans:arrayElements"/> <xsd:attributeGroup ref="beans:commonBeanAttributes"/> <xsd:attributeGroup ref="beans:collectionBeanAttributes"/> </xsd:extension> @@ -34,18 +35,19 @@ <xsd:element name="value"> <xsd:annotation> - <xsd:documentation><![CDATA[ - Conveniently defines an array factory bean - ]]></xsd:documentation> + <xsd:documentation><![CDATA[Conveniently defines a value factory bean]]></xsd:documentation> </xsd:annotation> - <xsd:complexType mixed="true"> - <xsd:choice minOccurs="0" maxOccurs="unbounded"/> - <xsd:attribute name="type" type="xsd:string"> - <xsd:annotation> - <xsd:documentation><![CDATA[The type that the value attribute should be validated against and converted - to.]]></xsd:documentation> - </xsd:annotation> - </xsd:attribute> + <xsd:complexType> + <xsd:complexContent> + <xsd:extension base="beans:identifiedType"> + <xsd:sequence> + <xsd:element ref="beans:null" minOccurs="0" maxOccurs="1"/> + <xsd:any namespace="##other" processContents="strict" minOccurs="0" maxOccurs="unbounded"/> + </xsd:sequence> + <xsd:attributeGroup ref="beans:typedValueAttributes"/> + <xsd:attributeGroup ref="beans:commonBeanAttributes"/> + </xsd:extension> + </xsd:complexContent> </xsd:complexType> </xsd:element> Modified: trunk/tests/Bee/Context/Xml/BeanDefinitionReaderTest-context.xml =================================================================== --- trunk/tests/Bee/Context/Xml/BeanDefinitionReaderTest-context.xml 2014-09-26 13:11:26 UTC (rev 232) +++ trunk/tests/Bee/Context/Xml/BeanDefinitionReaderTest-context.xml 2014-09-26 14:04:16 UTC (rev 233) @@ -44,4 +44,6 @@ <assoc-item key="a" value="Zulu" /> </util:array> + <util:value type="int" id="tt" value="15"> + </util:value> </beans> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <m_p...@us...> - 2014-09-28 22:03:13
|
Revision: 239 http://sourceforge.net/p/beeframework/code/239 Author: m_plomer Date: 2014-09-28 22:03:01 +0000 (Sun, 28 Sep 2014) Log Message: ----------- Persistence: fixed bug in PaginationBase MVC: Dispatcher now accepts a MAV also from Interceptors, bypasses rest of chain and controller in that case Modified Paths: -------------- trunk/examples/classes/Test/Mvc/ClassicTestDelegate.php trunk/examples/classes/Test/Mvc/ParamTestDelegate.php trunk/examples/conf/views.xml trunk/examples/index.php trunk/framework/Bee/MVC/Dispatcher.php trunk/framework/Bee/Persistence/PaginationBase.php Modified: trunk/examples/classes/Test/Mvc/ClassicTestDelegate.php =================================================================== --- trunk/examples/classes/Test/Mvc/ClassicTestDelegate.php 2014-09-26 18:41:49 UTC (rev 238) +++ trunk/examples/classes/Test/Mvc/ClassicTestDelegate.php 2014-09-28 22:03:01 UTC (rev 239) @@ -13,10 +13,12 @@ /** * * @Bee_MVC_Controller_Multiaction_RequestHandler(httpMethod = "GET", pathPattern = "/**\/testClassic/**") + * @param Bee_MVC_IHttpRequest $request + * @return bool */ public function handleTestParams(Bee_MVC_IHttpRequest $request) { - var_dump($request); - return true; +// var_dump($request); + return new \Bee_MVC_ModelAndView(array('delegateName' => get_class($this)), 'testview'); } - +kk } \ No newline at end of file Modified: trunk/examples/classes/Test/Mvc/ParamTestDelegate.php =================================================================== --- trunk/examples/classes/Test/Mvc/ParamTestDelegate.php 2014-09-26 18:41:49 UTC (rev 238) +++ trunk/examples/classes/Test/Mvc/ParamTestDelegate.php 2014-09-28 22:03:01 UTC (rev 239) @@ -21,10 +21,11 @@ * @param MC $testParam * @param boolean $getParam * @return bool + * @Bee_MVC_Controller_Multiaction_RequestHandler(httpMethod = "GET", pathPattern = "/**\/testClassic/**") * @Bee_MVC_Controller_Multiaction_RequestHandler(pathPattern = "/**\/ghi/*\/{0}/{2}/const/{boolParam}", httpMethod="GET") * @Bee_MVC_Controller_Multiaction_RequestHandler(pathPattern = "/**\/{0}/{2}/{boolParam}", httpMethod="POST") */ - public function handleTestParams($paramA, Bee_MVC_IHttpRequest $request, MC $paramB, $boolParam = false, $testParam = null, $getParam = false) { + public function handleTestParams($paramA = null, Bee_MVC_IHttpRequest $request, MC $paramB, $boolParam = false, $testParam = null, $getParam = false) { echo '<hr/>'. get_class($this) .'::'. __FUNCTION__ .'<hr/>'; // var_dump($paramA); // var_dump($paramB); @@ -64,6 +65,9 @@ /** * * @Bee_MVC_Controller_Multiaction_RequestHandler(pathPattern = "/**\/testParam/{paramA}/") + * @param MC $paramB + * @param Bee_MVC_IHttpRequest $request + * @return bool */ public function handleTestParams2(MC $paramB, Bee_MVC_IHttpRequest $request) { echo '<hr/>'. get_class($this) .'::'. __FUNCTION__ .'<hr/>'; @@ -75,7 +79,7 @@ /** * @param int $getParam * @return Bee_MVC_ModelAndView - * @Bee_MVC_Controller_Multiaction_RequestHandler(pathPattern = "/**") + * @Bee_MVC_Controller_Multiaction_RequestHandler(pathPattern = "/**", httpMethod="GET") */ public function handleDefault($getParam = 1000) { echo '<hr/>'. get_class($this) .'::'. __FUNCTION__ .'<hr/>'; Modified: trunk/examples/conf/views.xml =================================================================== --- trunk/examples/conf/views.xml 2014-09-26 18:41:49 UTC (rev 238) +++ trunk/examples/conf/views.xml 2014-09-28 22:03:01 UTC (rev 239) @@ -3,4 +3,5 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.beeframework.org/schema/beans http://www.beeframework.org/schema/beans/bee-beans-1.2.xsd"> + <bean id="testview" class="Bee_MVC_View_JsonService" /> </beans> Modified: trunk/examples/index.php =================================================================== --- trunk/examples/index.php 2014-09-26 18:41:49 UTC (rev 238) +++ trunk/examples/index.php 2014-09-28 22:03:01 UTC (rev 239) @@ -11,4 +11,4 @@ Bee_Cache_Manager::init(); //Bee_Framework::setProductionMode(true); -Bee_Framework::dispatchRequestUsingXmlContext(__DIR__.'/conf/context-mvc.xml'); \ No newline at end of file +Bee_Framework::dispatchRequestUsingXmlContext(__DIR__.'/conf/context-newinterceptors.xml'); \ No newline at end of file Modified: trunk/framework/Bee/MVC/Dispatcher.php =================================================================== --- trunk/framework/Bee/MVC/Dispatcher.php 2014-09-26 18:41:49 UTC (rev 238) +++ trunk/framework/Bee/MVC/Dispatcher.php 2014-09-28 22:03:01 UTC (rev 239) @@ -262,25 +262,31 @@ $mav = null; $interceptors = array(); $handlerException = null; + $interceptorIndex = -1; try { - $mappedHandler = $this->handlerMapping->getHandler($request); $interceptors = $mappedHandler->getInterceptors(); $handler = $mappedHandler->getHandler(); -// $interceptorIndex = -1; - + $mav = null; for ($i = 0; $i < count($interceptors); $i++) { $interceptor = $interceptors[$i]; - if (!$interceptor->preHandle($request, $handler)) { + $interceptorResult = $interceptor->preHandle($request, $handler); + if (!$interceptorResult) { // $this->triggerAfterCompletion($handler, $interceptorIndex, $request, null); return; } -// $interceptorIndex = $i; + $interceptorIndex = $i; + if($interceptorResult instanceof Bee_MVC_ModelAndView) { + $mav = $interceptorResult; + break; + } } // @todo: introduce HandlerAdapter - $mav = $handler->handleRequest($request); + if(is_null($mav)) { + $mav = $handler->handleRequest($request); + } } catch (Exception $e) { $this->getLog()->warn('handler or interceptor exception caught, trying to resolve appropriate error view', $e); @@ -308,7 +314,7 @@ $interceptors = $this->handlerMapping->getInterceptors(); } // Apply postHandle methods of registered interceptors. - for ($i = count($interceptors) - 1; $i >= 0; $i--) { + for ($i = $interceptorIndex; $i >= 0; $i--) { $interceptor = $interceptors[$i]; $interceptor->postHandle($request, $handler, $mav); } Modified: trunk/framework/Bee/Persistence/PaginationBase.php =================================================================== --- trunk/framework/Bee/Persistence/PaginationBase.php 2014-09-26 18:41:49 UTC (rev 238) +++ trunk/framework/Bee/Persistence/PaginationBase.php 2014-09-28 22:03:01 UTC (rev 239) @@ -71,7 +71,6 @@ * @param $currentPage */ public function setCurrentPage($currentPage) { - $currentPage = $currentPage > $this->getPageCount() - 1 ? $this->getPageCount() - 1 : $currentPage; $currentPage = $currentPage < 0 ? 0 : $currentPage; $this->currentPage = $currentPage; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <m_p...@us...> - 2014-10-08 09:12:06
|
Revision: 244 http://sourceforge.net/p/beeframework/code/244 Author: m_plomer Date: 2014-10-08 09:12:00 +0000 (Wed, 08 Oct 2014) Log Message: ----------- removed previously deprecated Bee_MVC_Controller_MultiAction (replaced by Bee\MVC\Controller\MultiActionController) Modified Paths: -------------- trunk/examples/conf/context.xml trunk/framework/Bee/MVC/Controller/MultiActionController.php trunk/framework/Bee/MVC/Controller/MultiActionMultiDelegates.php Removed Paths: ------------- trunk/framework/Bee/MVC/Controller/MultiAction.php Modified: trunk/examples/conf/context.xml =================================================================== --- trunk/examples/conf/context.xml 2014-10-05 23:57:40 UTC (rev 243) +++ trunk/examples/conf/context.xml 2014-10-08 09:12:00 UTC (rev 244) @@ -23,7 +23,7 @@ <!-- METHOD NAME RESOLVER --> <bean id="methodNameResolver" class="Bee_MVC_Controller_Multiaction_MethodNameResolver_AnnotationBased" scope="prototype"/> - <bean id="multiactionControllerTemplate" class="Bee_MVC_Controller_MultiAction"> + <bean id="multiactionControllerTemplate" class="Bee\MVC\Controller\MultiActionController"> <property name="methodNameResolver" ref="methodNameResolver"/> </bean> Deleted: trunk/framework/Bee/MVC/Controller/MultiAction.php =================================================================== --- trunk/framework/Bee/MVC/Controller/MultiAction.php 2014-10-05 23:57:40 UTC (rev 243) +++ trunk/framework/Bee/MVC/Controller/MultiAction.php 2014-10-08 09:12:00 UTC (rev 244) @@ -1,34 +0,0 @@ -<?php -/* - * Copyright 2008-2014 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -use Bee\MVC\Controller\MultiActionController; - -/** - * The multiaction controller handles requests by delegating to method calls on a delegate object. The methods to be used are - * determined by the method name resolver. - * - * A handler method must take at least one argument, type-hinted to Bee_MVC_IHttpRequest, and return a Bee_MVC_ModelAndView. - * - * @see Bee_MVC_IHttpRequest - * @see Bee_MVC_ModelAndView - * - * @author Michael Plomer <mic...@it...> - * @author Benjamin Hartmann - * - * @deprecated replaced by \Bee\MVC\Controller\MultiActionController - */ -class Bee_MVC_Controller_MultiAction extends MultiActionController { -} Modified: trunk/framework/Bee/MVC/Controller/MultiActionController.php =================================================================== --- trunk/framework/Bee/MVC/Controller/MultiActionController.php 2014-10-05 23:57:40 UTC (rev 243) +++ trunk/framework/Bee/MVC/Controller/MultiActionController.php 2014-10-08 09:12:00 UTC (rev 244) @@ -19,6 +19,7 @@ use Bee\MVC\Controller\Multiaction\IMethodNameResolver; use Bee\MVC\Controller\Multiaction\NoHandlerMethodFoundException; use Bee_MVC_IHttpRequest; +use Bee_MVC_ModelAndView; use Bee_Utils_Assert; use Bee_Utils_Reflection; use Bee_Utils_Strings; @@ -67,10 +68,10 @@ private $methodNameResolver; protected function init() { - Bee_Utils_Assert::notNull($this->delegate, '\'delegate\' property is required in Bee_MVC_Controller_MultiAction'); + Bee_Utils_Assert::notNull($this->delegate, '\'delegate\' property is required in ' . __CLASS__); Bee_Utils_Assert::isTrue( !is_null($this->methodInvocator) || !is_null($this->methodNameResolver), - 'either \'methodInvocator\' or \'methodNameResolver\' property required in Bee_MVC_Controller_MultiAction' + 'either \'methodInvocator\' or \'methodNameResolver\' property required in ' . __CLASS__ ); } @@ -79,7 +80,7 @@ * * @param Bee_MVC_IHttpRequest $request * @throws Exception - * @return \Bee_MVC_ModelAndView + * @return Bee_MVC_ModelAndView */ protected function handleRequestInternally(Bee_MVC_IHttpRequest $request) { if(!is_null($this->methodInvocator)) { Modified: trunk/framework/Bee/MVC/Controller/MultiActionMultiDelegates.php =================================================================== --- trunk/framework/Bee/MVC/Controller/MultiActionMultiDelegates.php 2014-10-05 23:57:40 UTC (rev 243) +++ trunk/framework/Bee/MVC/Controller/MultiActionMultiDelegates.php 2014-10-08 09:12:00 UTC (rev 244) @@ -73,7 +73,7 @@ */ protected function init() { parent::init(); - Bee_Utils_Assert::notNull($this->delegateResolver, '\'methodNameResolver\' property is required in Bee_MVC_Controller_MultiAction'); + Bee_Utils_Assert::notNull($this->delegateResolver, '\'methodNameResolver\' property is required in ' . __CLASS__); } /** This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <m_p...@us...> - 2014-10-08 12:21:05
|
Revision: 245 http://sourceforge.net/p/beeframework/code/245 Author: m_plomer Date: 2014-10-08 12:21:00 +0000 (Wed, 08 Oct 2014) Log Message: ----------- fixed AntPathToRegexTransformer and RegexMappingInvocationResolver behavior on trailing /** patterns Modified Paths: -------------- trunk/framework/Bee/MVC/Controller/Multiaction/HandlerMethodInvocator/RegexMappingInvocationResolver.php trunk/framework/Bee/Utils/AntPathToRegexTransformer.php trunk/tests/Bee/MVC/Controller/Multiaction/HandlerMethodInvocator/RegexMappingInvocationResolverTest.php trunk/tests/Bee/Utils/AntPathDataProvider.php Modified: trunk/framework/Bee/MVC/Controller/Multiaction/HandlerMethodInvocator/RegexMappingInvocationResolver.php =================================================================== --- trunk/framework/Bee/MVC/Controller/Multiaction/HandlerMethodInvocator/RegexMappingInvocationResolver.php 2014-10-08 09:12:00 UTC (rev 244) +++ trunk/framework/Bee/MVC/Controller/Multiaction/HandlerMethodInvocator/RegexMappingInvocationResolver.php 2014-10-08 12:21:00 UTC (rev 245) @@ -1,5 +1,6 @@ <?php namespace Bee\MVC\Controller\Multiaction\HandlerMethodInvocator; + /* * Copyright 2008-2014 the original author or authors. * @@ -82,12 +83,11 @@ */ public function getInvocationDefinition(Bee_MVC_IHttpRequest $request) { $pathInfo = $request->getPathInfo(); + /** @var MethodInvocation[] $matchingPatterns */ $matchingPatterns = array(); foreach ($this->mappedMethods as $regex => $invocInfo) { - $matches = array(); if (preg_match($regex, $pathInfo, $matches) === 1) { $invocInfo->setParamValues($matches); -// return $invocInfo; $matchingPatterns[$regex] = $invocInfo; } } @@ -97,32 +97,31 @@ } uksort($matchingPatterns, function ($patternA, $patternB) use ($matchingPatterns, $pathInfo) { - /** @var MethodInvocation[] $matchingPatterns */ - $matchA = $matchingPatterns[$patternA]; - $matchB = $matchingPatterns[$patternB]; - $emptyMatches = 0; $litLength = function ($carry, $item) use (&$emptyMatches) { if ($carry === false) { return $item; } - if($item) { - if(substr($item, -1) == '/') { + if ($item) { + if (substr($item, -1) == '/') { $item = substr($item, 0, -1); } - return preg_replace('#/'.preg_quote($item).'#', '', $carry, 1); + return preg_replace('#/' . preg_quote($item) . '#', '', $carry, 1); } $emptyMatches++; return $carry; }; + + $matchA = $matchingPatterns[$patternA]; $litA = array_reduce($matchA->getParamValues(), $litLength, false); $litA = preg_replace('#//#', '/', $litA); + $litCountA = substr_count($litA, '/'); $emptyMatches *= -1; + $matchB = $matchingPatterns[$patternB]; $litB = array_reduce($matchB->getParamValues(), $litLength, false); $litB = preg_replace('#//#', '/', $litB); - $litCountA = substr_count($litA, '/'); $litCountB = substr_count($litB, '/'); if ($litCountA != $litCountB) { @@ -145,7 +144,10 @@ if ($countA != $countB) { return $countA - $countB; } - return -$emptyMatches; + if($emptyMatches != 0) { + return -$emptyMatches; + } + return strlen($matchA->getAntPathPattern()) - strlen($matchB->getAntPathPattern()); }); if (self::getLog()->isDebugEnabled()) { @@ -169,5 +171,4 @@ } return self::$methodMetadataMap[$methodFullName]; } - } \ No newline at end of file Modified: trunk/framework/Bee/Utils/AntPathToRegexTransformer.php =================================================================== --- trunk/framework/Bee/Utils/AntPathToRegexTransformer.php 2014-10-08 09:12:00 UTC (rev 244) +++ trunk/framework/Bee/Utils/AntPathToRegexTransformer.php 2014-10-08 12:21:00 UTC (rev 245) @@ -27,7 +27,8 @@ '#\*#' => '([^/]*)', // "*" matches any string that does not contain slashes '#\(\[\^/\]\*\)\(\[\^/\]\*\)/#' => '((?:[^/]+/)*?)', // "**/" - replaced by "([^/]+)" above - matches 0:n path elements '#\(\[\^/\]\*\)\(\[\^/\]\*\)#' => '(.*?)', - '#(^|(?<=[^(*]))\?#' => '[^/]' + '#(^|(?<=[^(*]))\?#' => '[^/]', + '#/\(\.\*\?\)$#' => '(?:/(.*?))??' ); public static $TYPE_EXPRESSION_MAP = array( @@ -80,4 +81,12 @@ $matches = array(); return !!preg_match(self::PARAMETER_MATCH, $antPathPattern, $matches); } + + public static function test($antPathPattern = '/**') { + foreach(self::$SIMPLE_REPLACEMENTS as $pattern => $replace) { + var_dump($antPathPattern); + $antPathPattern = preg_replace($pattern, $replace, $antPathPattern); + echo $antPathPattern . '<hr/>'; + } + } } \ No newline at end of file Modified: trunk/tests/Bee/MVC/Controller/Multiaction/HandlerMethodInvocator/RegexMappingInvocationResolverTest.php =================================================================== --- trunk/tests/Bee/MVC/Controller/Multiaction/HandlerMethodInvocator/RegexMappingInvocationResolverTest.php 2014-10-08 09:12:00 UTC (rev 244) +++ trunk/tests/Bee/MVC/Controller/Multiaction/HandlerMethodInvocator/RegexMappingInvocationResolverTest.php 2014-10-08 12:21:00 UTC (rev 245) @@ -36,6 +36,7 @@ public function testMapping(RegexMappingInvocationResolver $resolver, $pathInfo, $expectedAntPath, $expectedParams = array()) { $request = new HttpRequestMock($pathInfo); $invocation = $resolver->getInvocationDefinition($request); + $this->assertTrue(!is_null($invocation)); $this->assertEquals($expectedAntPath, $invocation->getAntPathPattern()); $res = array_intersect_key($invocation->getParamValues(), array_flip($invocation->getUrlParameterPositions())); @@ -94,7 +95,7 @@ '/complicated/more/x/y/z/compliment/hermelin/hase', '/complicated/more/**/compl*/{string2}/**', array('hermelin')), - + array($testMapping, '', '/**') ); } Modified: trunk/tests/Bee/Utils/AntPathDataProvider.php =================================================================== --- trunk/tests/Bee/Utils/AntPathDataProvider.php 2014-10-08 09:12:00 UTC (rev 244) +++ trunk/tests/Bee/Utils/AntPathDataProvider.php 2014-10-08 12:21:00 UTC (rev 245) @@ -103,10 +103,12 @@ array("*bla*/**/bla/*", "XXXblaXXXX/testing/testing/bla/testing/testing", False), array("/x/x/**/bla", "/x/x/x/", False), + array("/x/x/**/bla", "/x/x/bla", true), array("/test/**", "/test", true), - array("", "", True)//, + array("/**", "", true), + array("", "", true)//, // array("/{bla}.*", "/testing.html", True) // #65 ); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <m_p...@us...> - 2014-10-09 11:59:38
|
Revision: 255 http://sourceforge.net/p/beeframework/code/255 Author: m_plomer Date: 2014-10-09 11:59:29 +0000 (Thu, 09 Oct 2014) Log Message: ----------- - implemented request-based filtering of interceptors in AntPathHandlerMapping - omissions from previous namespace refactoring Modified Paths: -------------- trunk/framework/Bee/Annotations/Utils.php trunk/framework/Bee/MVC/HandlerMapping/AbstractHandlerMapping.php trunk/framework/Bee/MVC/HandlerMapping/AntPathHandlerMapping.php trunk/framework/Bee/Persistence/Pdo/IResultSetExtractor.php trunk/framework/Bee/Persistence/Pdo/IStatementCallback.php trunk/framework/Bee/Persistence/Pdo/RowMapper/SingleColumn.php trunk/framework/Bee/Persistence/Pdo/Template.php trunk/framework/Bee/Security/Acls/Pdo/AclService.php trunk/framework/Bee/Security/Annotations/Secured.php trunk/framework/Bee/Security/Annotations/SecuredMethodDefinitionSource.php trunk/framework/Bee/Security/Namespace/GlobalMethodSecurityBeanDefinitionParser.php trunk/framework/Bee/Security/Provider/DaoAuthentication.php trunk/tests/Bee/Annotations/UtilsTest.php Added Paths: ----------- trunk/framework/Bee/Persistence/Exception/DataAccessException.php Removed Paths: ------------- trunk/framework/Bee/Persistence/Exception/DataAccess.php Modified: trunk/framework/Bee/Annotations/Utils.php =================================================================== --- trunk/framework/Bee/Annotations/Utils.php 2014-10-09 02:29:34 UTC (rev 254) +++ trunk/framework/Bee/Annotations/Utils.php 2014-10-09 11:59:29 UTC (rev 255) @@ -1,6 +1,7 @@ <?php +namespace Bee\Annotations; /* - * Copyright 2008-2010 the original author or authors. + * Copyright 2008-2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,17 +15,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - use Addendum\ReflectionAnnotatedClass; use Addendum\ReflectionAnnotatedMethod; +use ReflectionMethod; + /** * User: mp * Date: Feb 19, 2010 * Time: 7:14:44 PM */ +class Utils { -class Bee_Annotations_Utils { - /** * Get a single {@link Annotation} of <code>annotationType</code> from the * supplied {@link Method}, traversing its super methods if no annotation @@ -33,7 +34,7 @@ * this explicitly. Tge * @param ReflectionMethod $method * @param $annotationClassName - * @return the annotation found, or <code>null</code> if none found + * @return mixed the annotation found, or <code>null</code> if none found */ public static function findAnnotation(ReflectionMethod $method, $annotationClassName) { $annotatedMethod = self::getReflectionAnnotatedMethodIfNecessary($method); Modified: trunk/framework/Bee/MVC/HandlerMapping/AbstractHandlerMapping.php =================================================================== --- trunk/framework/Bee/MVC/HandlerMapping/AbstractHandlerMapping.php 2014-10-09 02:29:34 UTC (rev 254) +++ trunk/framework/Bee/MVC/HandlerMapping/AbstractHandlerMapping.php 2014-10-09 11:59:29 UTC (rev 255) @@ -19,6 +19,7 @@ use Bee\IContext; use Bee\MVC\HandlerExecutionChain; use Bee\MVC\IController; +use Bee\MVC\IHandlerInterceptor; use Bee\MVC\IHandlerMapping; use Bee\MVC\IHttpRequest; use Exception; @@ -48,7 +49,7 @@ /** * Enter description here... * - * @var \Bee\MVC\IHandlerInterceptor[] + * @var IHandlerInterceptor[] */ private $interceptors = array(); @@ -81,7 +82,7 @@ /** * Enter description here... * - * @param \Bee\MVC\IHandlerInterceptor[] $interceptors + * @param IHandlerInterceptor[] $interceptors */ public function setInterceptors(array $interceptors) { $this->interceptors = $interceptors; @@ -90,7 +91,7 @@ /** * Enter description here... * - * @return \Bee\MVC\IHandlerInterceptor[] + * @return IHandlerInterceptor[] */ public function getInterceptors() { return $this->interceptors; @@ -112,11 +113,20 @@ } $hec = new HandlerExecutionChain($handlerBean); - $hec->addInterceptors($this->interceptors); + $hec->addInterceptors($this->filterInterceptors($request)); return $hec; } /** + * Default implementation returns unfiltered view of the interceptors collection. + * @param IHttpRequest $request + * @return IHandlerInterceptor[] + */ + protected function filterInterceptors(IHttpRequest $request) { + return $this->interceptors; + } + + /** * Resolves the actual controller bean name (may also return a controller instance directly) * @param IHttpRequest $request * @return mixed Modified: trunk/framework/Bee/MVC/HandlerMapping/AntPathHandlerMapping.php =================================================================== --- trunk/framework/Bee/MVC/HandlerMapping/AntPathHandlerMapping.php 2014-10-09 02:29:34 UTC (rev 254) +++ trunk/framework/Bee/MVC/HandlerMapping/AntPathHandlerMapping.php 2014-10-09 11:59:29 UTC (rev 255) @@ -15,6 +15,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +use Bee\MVC\IHandlerInterceptor; use Bee\MVC\IHttpRequest; use Bee\Utils\AntPathMatcher; use Bee\Utils\IPathMatcher; @@ -50,7 +51,7 @@ * @return IPathMatcher */ public function getPathMatcher() { - return $this->pathMatcher; + return $this->pathMatcher ?: ($this->pathMatcher = new AntPathMatcher()); } /** @@ -65,8 +66,7 @@ * @return mixed */ protected function getControllerBeanName(IHttpRequest $request) { - $pathInfo = $request->getPathInfo(); - return $this->getElementByMatchingArrayKey($pathInfo, $this->handlerMappings, $this->getDefaultControllerBeanName()); + return $this->getElementByMatchingArrayKey($request->getPathInfo(), $this->handlerMappings, $this->getDefaultControllerBeanName()); } /** @@ -82,7 +82,7 @@ // shortcut for direct path matches $result = $array[$path]; } else { - $matcher = is_null($this->pathMatcher) ? new AntPathMatcher() : $this->pathMatcher; + $matcher = $this->getPathMatcher(); foreach($array as $mapping => $element) { if($matcher->match($mapping, $path)) { // if(($matcher->isPattern($mapping) && $matcher->match($mapping, $pathInfo)) || Strings::startsWith($pathInfo, $mapping)) { @@ -94,4 +94,20 @@ } return $result; } + + /** + * @param IHttpRequest $request + * @return IHandlerInterceptor[] + */ + protected function filterInterceptors(IHttpRequest $request) { + $result = array(); + $pathInfo = $request->getPathInfo(); + $matcher = $this->getPathMatcher(); + foreach($this->getInterceptors() as $key => $interceptor) { + if(!is_string($key) || $key == $pathInfo || $matcher->match($key, $pathInfo)) { + $result[] = $interceptor; + } + } + return $result; + } } \ No newline at end of file Deleted: trunk/framework/Bee/Persistence/Exception/DataAccess.php =================================================================== --- trunk/framework/Bee/Persistence/Exception/DataAccess.php 2014-10-09 02:29:34 UTC (rev 254) +++ trunk/framework/Bee/Persistence/Exception/DataAccess.php 2014-10-09 11:59:29 UTC (rev 255) @@ -1,22 +0,0 @@ -<?php -/* - * Copyright 2008-2014 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -class Bee_Persistence_Exception_DataAccess extends Exception { - public function __construct($message, Exception $cause = null) { - parent::__construct($message, 0, $cause); - } -} Copied: trunk/framework/Bee/Persistence/Exception/DataAccessException.php (from rev 251, trunk/framework/Bee/Persistence/Exception/DataAccess.php) =================================================================== --- trunk/framework/Bee/Persistence/Exception/DataAccessException.php (rev 0) +++ trunk/framework/Bee/Persistence/Exception/DataAccessException.php 2014-10-09 11:59:29 UTC (rev 255) @@ -0,0 +1,25 @@ +<?php +namespace Bee\Persistence\Exception; +/* + * Copyright 2008-2014 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +use Exception; + +class DataAccessException extends Exception { + public function __construct($message, Exception $cause = null) { + parent::__construct($message, 0, $cause); + } +} Modified: trunk/framework/Bee/Persistence/Pdo/IResultSetExtractor.php =================================================================== --- trunk/framework/Bee/Persistence/Pdo/IResultSetExtractor.php 2014-10-09 02:29:34 UTC (rev 254) +++ trunk/framework/Bee/Persistence/Pdo/IResultSetExtractor.php 2014-10-09 11:59:29 UTC (rev 255) @@ -14,6 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +use Bee\Persistence\Exception\DataAccessException; /** * User: mp @@ -30,9 +31,7 @@ * (the extractor will typically be stateful in the latter case). * @throws PDOException if a PDOException is encountered getting column * values or navigating (that is, there's no need to catch PDOException) - * @throws Bee_Persistence_Exception_DataAccess in case of custom exceptions + * @throws DataAccessException in case of custom exceptions */ public function extractData(PDOStatement $rs); - -} -?> \ No newline at end of file +} \ No newline at end of file Modified: trunk/framework/Bee/Persistence/Pdo/IStatementCallback.php =================================================================== --- trunk/framework/Bee/Persistence/Pdo/IStatementCallback.php 2014-10-09 02:29:34 UTC (rev 254) +++ trunk/framework/Bee/Persistence/Pdo/IStatementCallback.php 2014-10-09 11:59:29 UTC (rev 255) @@ -14,6 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +use Bee\Persistence\Exception\DataAccessException; /** * User: mp @@ -44,9 +45,7 @@ * @param ps active JDBC PreparedStatement * @return a result object, or <code>null</code> if none * @throws PDOException - * @throws Bee_Persistence_Exception_DataAccess in case of custom exceptions + * @throws DataAccessException in case of custom exceptions */ public function doInPreparedStatement(PDOStatement $ps); - -} -?> \ No newline at end of file +} \ No newline at end of file Modified: trunk/framework/Bee/Persistence/Pdo/RowMapper/SingleColumn.php =================================================================== --- trunk/framework/Bee/Persistence/Pdo/RowMapper/SingleColumn.php 2014-10-09 02:29:34 UTC (rev 254) +++ trunk/framework/Bee/Persistence/Pdo/RowMapper/SingleColumn.php 2014-10-09 11:59:29 UTC (rev 255) @@ -14,6 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +use Bee\Persistence\Exception\DataAccessException; /** * User: mp @@ -26,9 +27,8 @@ public function mapRow(PDOStatement $rs, $rowNum) { $colCount = $rs->columnCount(); if($colCount != 1) { - throw new Bee_Persistence_Exception_DataAccess('Incorrect column count, is ' . $colCount . ', should be 1'); + throw new DataAccessException('Incorrect column count, is ' . $colCount . ', should be 1'); } return $rs->fetchColumn(); } -} -?> +} \ No newline at end of file Modified: trunk/framework/Bee/Persistence/Pdo/Template.php =================================================================== --- trunk/framework/Bee/Persistence/Pdo/Template.php 2014-10-09 02:29:34 UTC (rev 254) +++ trunk/framework/Bee/Persistence/Pdo/Template.php 2014-10-09 11:59:29 UTC (rev 255) @@ -15,6 +15,7 @@ * limitations under the License. */ use Bee\Framework; +use Bee\Persistence\Exception\DataAccessException; use Bee\Utils\Assert; /** @@ -86,7 +87,7 @@ new Bee_Persistence_Pdo_RowMapper_SingleColumn())); $count = count($results); if($count != 1) { - throw new Bee_Persistence_Exception_DataAccess('Incorrect result size, is ' .$count. ', expected 1'); + throw new DataAccessException('Incorrect result size, is ' .$count. ', expected 1'); } return $results[0]; } @@ -100,7 +101,7 @@ * @param pss object that knows how to set values on the prepared statement. * If this is null, the SQL will be assumed to contain no bind parameters. * @param rse object that will extract results. - * @return an arbitrary result object, as returned by the ResultSetExtractor + * @return mixed an arbitrary result object, as returned by the ResultSetExtractor * @throws DataAccessException if there is any problem */ public function query(Bee_Persistence_Pdo_IStatementCreator $psc, Bee_Persistence_Pdo_IStatementSetter $pss, @@ -158,7 +159,7 @@ // Release Connection early, to avoid potential connection pool deadlock // in the case when the exception translator hasn't been initialized yet. // $sql = $this->getSql($psc); - throw new Bee_Persistence_Exception_DataAccess('Bee_Persistence_Pdo_Template caught an exception', $ex); + throw new DataAccessException('Bee_Persistence_Pdo_Template caught an exception', $ex); // throw getExceptionTranslator().translate("PreparedStatementCallback", sql, ex); } } Modified: trunk/framework/Bee/Security/Acls/Pdo/AclService.php =================================================================== --- trunk/framework/Bee/Security/Acls/Pdo/AclService.php 2014-10-09 02:29:34 UTC (rev 254) +++ trunk/framework/Bee/Security/Acls/Pdo/AclService.php 2014-10-09 11:59:29 UTC (rev 255) @@ -14,6 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +use Bee\Persistence\Exception\DataAccessException; use Bee\Utils\Assert; /** @@ -211,7 +212,7 @@ try { return $this->pdoTemplate->queryScalarBySqlStringAndArgsArray(self::SELECT_OBJECT_IDENTITY_PRIMARY_KEY, array($oid->getType(), $oid->getIdentifier())); - } catch (Bee_Persistence_Exception_DataAccess $notFound) { + } catch (DataAccessException $notFound) { return null; } } @@ -419,5 +420,4 @@ return count($this->acl->getEntries()); } -} -?> +} \ No newline at end of file Modified: trunk/framework/Bee/Security/Annotations/Secured.php =================================================================== --- trunk/framework/Bee/Security/Annotations/Secured.php 2014-10-09 02:29:34 UTC (rev 254) +++ trunk/framework/Bee/Security/Annotations/Secured.php 2014-10-09 11:59:29 UTC (rev 255) @@ -1,6 +1,7 @@ <?php +namespace Bee\Security\Annotations; /* - * Copyright 2008-2010 the original author or authors. + * Copyright 2008-2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,6 +15,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +use Addendum\Annotation; /** * Created by IntelliJ IDEA. @@ -23,5 +25,4 @@ * To change this template use File | Settings | File Templates. */ -class Bee_Security_Annotations_Secured extends Annotation {} -?> +class Secured extends Annotation {} Modified: trunk/framework/Bee/Security/Annotations/SecuredMethodDefinitionSource.php =================================================================== --- trunk/framework/Bee/Security/Annotations/SecuredMethodDefinitionSource.php 2014-10-09 02:29:34 UTC (rev 254) +++ trunk/framework/Bee/Security/Annotations/SecuredMethodDefinitionSource.php 2014-10-09 11:59:29 UTC (rev 255) @@ -1,6 +1,7 @@ <?php +namespace Bee\Security\Annotations; /* - * Copyright 2008-2010 the original author or authors. + * Copyright 2008-2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +15,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +use Addendum\Annotation; use Addendum\ReflectionAnnotatedClass; +use Bee\Annotations\Utils; +use Bee_Security_ConfigAttributeDefinition; +use Bee_Security_Intercept_AbstractFallbackMethodDefinitionSource; +use ReflectionClass; +use ReflectionMethod; /** * Created by IntelliJ IDEA. @@ -24,9 +31,9 @@ * To change this template use File | Settings | File Templates. */ -class Bee_Security_Annotations_SecuredMethodDefinitionSource extends Bee_Security_Intercept_AbstractFallbackMethodDefinitionSource { +class SecuredMethodDefinitionSource extends Bee_Security_Intercept_AbstractFallbackMethodDefinitionSource { - const SECURED_ANNOTATION_CLASS_NAME = 'Bee_Security_Annotations_Secured'; + const SECURED_ANNOTATION_CLASS_NAME = 'Bee\Security\Annotations\Secured'; /** * @access protected @@ -51,7 +58,7 @@ * @return Bee_Security_ConfigAttributeDefinition */ protected function findAttributesForMethod(ReflectionMethod $method, $targetClassOrClassName) { - return $this->processAnnotation(Bee_Annotations_Utils::findAnnotation($method, self::SECURED_ANNOTATION_CLASS_NAME)); + return $this->processAnnotation(Utils::findAnnotation($method, self::SECURED_ANNOTATION_CLASS_NAME)); } /** @@ -67,10 +74,9 @@ * @return Bee_Security_ConfigAttributeDefinition */ private function processAnnotation(Annotation $a) { - if ($a == null || !($a instanceof Bee_Security_Annotations_Secured)) { + if ($a == null || !($a instanceof Secured)) { return null; } return new Bee_Security_ConfigAttributeDefinition($a->value); } } -?> Modified: trunk/framework/Bee/Security/Namespace/GlobalMethodSecurityBeanDefinitionParser.php =================================================================== --- trunk/framework/Bee/Security/Namespace/GlobalMethodSecurityBeanDefinitionParser.php 2014-10-09 02:29:34 UTC (rev 254) +++ trunk/framework/Bee/Security/Namespace/GlobalMethodSecurityBeanDefinitionParser.php 2014-10-09 11:59:29 UTC (rev 255) @@ -33,7 +33,7 @@ class Bee_Security_Namespace_GlobalMethodSecurityBeanDefinitionParser implements IBeanDefinitionParser { - const SECURED_METHOD_DEFINITION_SOURCE_CLASS = 'Bee_Security_Annotations_SecuredMethodDefinitionSource'; + const SECURED_METHOD_DEFINITION_SOURCE_CLASS = 'Bee\Security\Annotations\SecuredMethodDefinitionSource'; const ATT_USE_SECURED = 'secured-annotations'; const ATT_ACCESS_MGR = "access-decision-manager-ref"; Modified: trunk/framework/Bee/Security/Provider/DaoAuthentication.php =================================================================== --- trunk/framework/Bee/Security/Provider/DaoAuthentication.php 2014-10-09 02:29:34 UTC (rev 254) +++ trunk/framework/Bee/Security/Provider/DaoAuthentication.php 2014-10-09 11:59:29 UTC (rev 255) @@ -15,6 +15,8 @@ * limitations under the License. */ +use Bee\Persistence\Exception\DataAccessException; + class Bee_Security_Provider_DaoAuthentication extends Bee_Security_Provider_AbstractUserDetailsAuthentication { /** @@ -69,7 +71,7 @@ try { $loadedUser = $this->getUserDetailsService()->loadUserByUsername($username); - } catch (Bee_Persistence_Exception_DataAccess $repositoryProblem) { + } catch (DataAccessException $repositoryProblem) { throw new Bee_Security_Exception_Authentication($repositoryProblem->getMessage(), null, $repositoryProblem); } Modified: trunk/tests/Bee/Annotations/UtilsTest.php =================================================================== --- trunk/tests/Bee/Annotations/UtilsTest.php 2014-10-09 02:29:34 UTC (rev 254) +++ trunk/tests/Bee/Annotations/UtilsTest.php 2014-10-09 11:59:29 UTC (rev 255) @@ -1,6 +1,7 @@ <?php +namespace Bee\Annotations; /* - * Copyright 2008-2010 the original author or authors. + * Copyright 2008-2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,6 +16,7 @@ * limitations under the License. */ use Addendum\Annotation; +use ReflectionClass; /** * User: mp @@ -22,46 +24,46 @@ * Time: 14:49 */ -class Bee_Annotations_UtilsTest /*extends PHPUnit_Framework_TestCase*/ { +class UtilsTest /*extends PHPUnit_Framework_TestCase*/ { public function testFindInheritedAnnotation() { - $class = new ReflectionClass('Bee_Annotations_UtilsTestChildAnnotatedClass'); + $class = new ReflectionClass('UtilsTestChildAnnotatedClass'); $method = $class->getMethod('testMethod'); - $annot = Bee_Annotations_Utils::findAnnotation($method, 'Bee_Annotations_UtilsTestAnnotation1'); + $annot = Utils::findAnnotation($method, 'UtilsTestAnnotation1'); -// $this->assertNotNull($annot, 'Annotation Bee_Annotations_UtilsTestAnnotation1 not found on Bee_Annotations_UtilsTestChildAnnotatedClass::testMethod()'); +// $this->assertNotNull($annot, 'Annotation UtilsTestAnnotation1 not found on UtilsTestChildAnnotatedClass::testMethod()'); // // $this->assertEquals('parentAnnotation', $annot->value); } } -class Bee_Annotations_UtilsTestAnnotation1 extends Annotation { +class UtilsTestAnnotation1 extends Annotation { public $value; } -class Bee_Annotations_UtilsTestAnnotation2 extends Annotation { +class UtilsTestAnnotation2 extends Annotation { public $value; } -class Bee_Annotations_UtilsTestParentAnnotatedClass { +class UtilsTestParentAnnotatedClass { /** * @return void * - * @Bee_Annotations_UtilsTestAnnotation1(value = "parentAnnotation") + * @UtilsTestAnnotation1(value = "parentAnnotation") */ public function testMethod() { } } -class Bee_Annotations_UtilsTestChildAnnotatedClass extends Bee_Annotations_UtilsTestParentAnnotatedClass { +class UtilsTestChildAnnotatedClass extends UtilsTestParentAnnotatedClass { /** * @return void * - * @Bee_Annotations_UtilsTestAnnotation2(value = "childAnnotation") + * @UtilsTestAnnotation2(value = "childAnnotation") */ public function testMethod() { } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <m_p...@us...> - 2014-10-15 18:59:11
|
Revision: 258 http://sourceforge.net/p/beeframework/code/258 Author: m_plomer Date: 2014-10-15 18:59:03 +0000 (Wed, 15 Oct 2014) Log Message: ----------- - refactored DaoBase hierarchy - fixed parameteralignment in BeanCreationException::__construct() Added Paths: ----------- trunk/framework/Bee/Persistence/Doctrine2/GenericDaoBase.php trunk/framework/Bee/Persistence/Doctrine2/SimpleDao.php Property Changed: ---------------- trunk/libs/ Added: trunk/framework/Bee/Persistence/Doctrine2/GenericDaoBase.php =================================================================== --- trunk/framework/Bee/Persistence/Doctrine2/GenericDaoBase.php (rev 0) +++ trunk/framework/Bee/Persistence/Doctrine2/GenericDaoBase.php 2014-10-15 18:59:03 UTC (rev 258) @@ -0,0 +1,284 @@ +<?php +namespace Bee\Persistence\Doctrine2; + +use Bee\Persistence\IOrderAndLimitHolder; +use Bee\Persistence\IRestrictionHolder; +use Bee\Utils\Strings; +use Doctrine\ORM\QueryBuilder; +use UnexpectedValueException; + +/** + * Class GenericDaoBase + * @package Bee\Persistence\Doctrine2 + */ +abstract class GenericDaoBase extends DaoBase { + + const ALIAS_MATCHER = '#^([a-zA-Z0-9_]{2,})\.#'; + + /** + * @var callable + */ + private $idRestrictor; + + /** + * @var array + */ + private $aliases; + + /** + * @var array + * + * todo: this is only for one-time use during a request. should be ok for MOST cases... + */ + private $addedAliases = array(); + + /** + * @var array + */ + private $joins = array(); + + /** + * @var array + */ + private $restrictions = array(); + + /** + * @var array + */ + private $defaultOrderMapping = array(); + + /** + * @param mixed $id + * @throws UnexpectedValueException + * @return mixed + */ + public function getById($id) { + if(!is_callable($this->idRestrictor)) { + $idFields = $this->getIdFieldName(); + + $expectedDim = count($idFields); + $actualDim = count($id); + + // unpack single-valued id if necessary + if (is_array($id) && $actualDim === 1) { + $id = $id[0]; + } + + $baseEntityAlias = $this->getEntityAlias(); + if ($expectedDim > 1) { + // composite key + if ($actualDim === 1) { + $id = DaoUtils::explodeScalarId($id, $idFields); + } else if ($actualDim !== $expectedDim) { + throw new UnexpectedValueException('Dimension of given ID (' . count($id) . ') does not match expected dimension (' . count($idFields) . ').'); + } + + // here we can be sure that the dimensions match - both branches above would have thrown otherwise + $whereParts = array(); + array_walk($id, function ($value, $key) use ($baseEntityAlias, &$whereParts) { + $whereParts[] = $baseEntityAlias . '.' . $key . ' = ' . ':' . $key; + }); + + $where = implode(' AND ', $whereParts); + $this->idRestrictor = function(QueryBuilder $qb, $id) use ($where) { + $qb->where($where)->setParameters($id); + }; + } else { + $where = $baseEntityAlias . '.' . $idFields . ' = :id'; + $this->idRestrictor = function(QueryBuilder $qb, $id) use ($where) { + $qb->where($where)->setParameter('id', $id); + }; + } + } + + $this->idRestrictor($qb = $this->getBaseQuery(), $id); + return $this->getSingleResult($qb); + } + + /** + * @param IRestrictionHolder $restrictionHolder + * @param IOrderAndLimitHolder $orderAndLimitHolder + * @param array $defaultOrderMapping + * @return array + * + * @deprecated use executeListQuery() instead + */ + public function getList(IRestrictionHolder $restrictionHolder = null, IOrderAndLimitHolder $orderAndLimitHolder = null, array $defaultOrderMapping = null) { + return $this->executeListQuery($this->getBaseQuery(), $restrictionHolder, $orderAndLimitHolder, $defaultOrderMapping, null); + } + + /** + * @param string $expr + */ + protected function addAliasForExpression(QueryBuilder $queryBuilder, $expr) { + if(preg_match(self::ALIAS_MATCHER, $expr, $matches)) { + $this->addAlias($queryBuilder, $matches[1]); + } + } + + /** + * @param QueryBuilder $queryBuilder + * @param string $alias + */ + protected function addAlias(QueryBuilder $queryBuilder, $alias) { + if(!$this->containsAlias($alias)) { + $this->addedAliases[$alias] = true; + $this->addAliasForExpression($queryBuilder, $this->aliases[$alias]); + $queryBuilder->leftJoin($this->aliases[$alias], $alias); + } + } + + /** + * @param $alias + * @return boolean + */ + protected function containsAlias($alias) { + // todo: Alias presence could in theory also be detected by examining the query builders DQL parts. Feasibility / performance? + // pros: more thorough and consistent + // cons: more overhead? + return $alias == $this->getEntityAlias() || array_key_exists($alias, $this->addedAliases) || array_key_exists($alias, $this->getJoins()); + } + + public function executeListQuery(QueryBuilder $queryBuilder, IRestrictionHolder $restrictionHolder = null, IOrderAndLimitHolder $orderAndLimitHolder = null, array $defaultOrderMapping = null, $hydrationMode = null) { + if(!is_null($restrictionHolder)) { + if(Strings::hasText($restrictionHolder->getFilterString())) { + foreach($restrictionHolder->getFilterableFields() as $field) { + $this->addAliasForExpression($queryBuilder, $field); + } + } + if(count($restrictionHolder->getFieldRestrictions()) > 0) { + foreach($restrictionHolder->getFieldRestrictions() as $field => $value) { + $this->addAliasForExpression($queryBuilder, $field); + } + } + } + + if(!is_null($orderAndLimitHolder)) { + if(count($orderAndLimitHolder->getOrderMapping()) > 0) { + foreach($orderAndLimitHolder->getOrderMapping() as $field => $dir) { + $this->addAliasForExpression($queryBuilder, $field); + } + } + } + + return parent::executeListQuery($queryBuilder, $restrictionHolder, $orderAndLimitHolder, $defaultOrderMapping ?: $this->getDefaultOrderMapping(), $hydrationMode ?: $this->getHydrationMode()); + } + + /** + * @return QueryBuilder + */ + protected function getBaseQuery() { + $baseEntityAlias = $this->getEntityAlias(); +// $indexBy = count($this->getIdFieldName()) > 1 ? null : $baseEntityAlias . '.' . $this->getIdFieldName(); +// return $this->getEntityManager()->createQueryBuilder()->select($baseEntityAlias) +// ->from($this->getEntity(), $baseEntityAlias, $indexBy); + $qb = $this->getEntityManager()->createQueryBuilder()->select($baseEntityAlias)->from($this->getEntity(), $baseEntityAlias); + $this->addJoinsToBaseQuery($qb); + $this->addRestrictionsToBaseQuery($qb); + return $qb; + } + + /** + * @param QueryBuilder $q + */ + protected function addJoinsToBaseQuery(QueryBuilder $q) { + foreach($this->joins as $alias => $relation) { + $q->addSelect($alias)->leftJoin($relation, $alias); + } + } + + /** + * @param QueryBuilder $q + */ + protected function addRestrictionsToBaseQuery(QueryBuilder $q) { + foreach($this->restrictions as $restriction) { + $q->andWhere($restriction); + } + } + + /** + * @param QueryBuilder $qb + * @return mixed + */ + protected function getSingleResult(QueryBuilder $qb) { + $q = $this->getQueryFromBuilder($qb); + return $q->getSingleResult($this->getHydrationMode()); + } + + /** + * @return null|string + */ + protected function getHydrationMode() { + return null; + } + + /** + * @return string + */ + protected function getEntityAlias() { + return 'e'; + } + + /** + * @return mixed + */ + abstract protected function getIdFieldName(); + + /** + * @return string + */ + public abstract function getEntity(); + + // ================================================================================================================= + // == GETTERS & SETTERS ============================================================================================ + // ================================================================================================================= + + /** + * @return array + */ + public function getAliases() { + return $this->aliases; + } + + /** + * @param array $aliases + */ + public function setAliases(array $aliases) { + $this->aliases = $aliases; + } + + /** + * @param array $joins + */ + public function setJoins(array $joins) { + $this->joins = $joins; + } + + /** + * @return array + */ + public function getJoins() { + return $this->joins; + } + + /** + * @param array $restrictions + */ + public function setRestrictions(array $restrictions) { + $this->restrictions = $restrictions; + } + + /** + * @return array + */ + public function getDefaultOrderMapping() { + return $this->defaultOrderMapping; + } + + /** + * @param array $defaultOrderMapping + */ + public function setDefaultOrderMapping(array $defaultOrderMapping) { + $this->defaultOrderMapping = $defaultOrderMapping; + } +} \ No newline at end of file Added: trunk/framework/Bee/Persistence/Doctrine2/SimpleDao.php =================================================================== --- trunk/framework/Bee/Persistence/Doctrine2/SimpleDao.php (rev 0) +++ trunk/framework/Bee/Persistence/Doctrine2/SimpleDao.php 2014-10-15 18:59:03 UTC (rev 258) @@ -0,0 +1,87 @@ +<?php +namespace Bee\Persistence\Doctrine2; + +/** + * Class GenericDao - provides generic CRUD/L operations for a given entity class. The entity class name must be + * configured via the $entity property. + * + * @package Bee\Persistence\Doctrine2 + */ +class SimpleDao extends GenericDaoBase { + + /** + * @var string + */ + private $entity; + + /** + * @return string|array + */ + protected function getIdFieldName() { + $classMetadata = $this->getEntityManager()->getClassMetadata($this->getEntity()); + $idFields = $classMetadata->getIdentifierFieldNames(); + return count($idFields) > 1 ? $idFields : $idFields[0]; + } + + // ================================================================================================================= + // == CRUD operations : create / update ============================================================================ + // ================================================================================================================= + + /** + * @param mixed $entity + * @param bool $flush + * @return mixed + */ + public function persist($entity, $flush = true) { + $this->prePersist($entity); + $this->getEntityManager()->persist($entity); + $this->postPersist($entity); + if ($flush) { + $this->getEntityManager()->flush(); + } + return $entity; + } + + protected function prePersist($entity) { + } + + protected function postPersist($entity) { + } + + // ================================================================================================================= + // == CRUD operations : delete ===================================================================================== + // ================================================================================================================= + /** + * @param $entity + * @param bool $flush + * @return void + */ + public function delete($entity, $flush = true) { + $this->preDelete($entity); + $this->getEntityManager()->remove($entity); + if ($flush) { + $this->getEntityManager()->flush(); + } + } + + protected function preDelete($entity) { + } + + // ================================================================================================================= + // == GETTERS & SETTERS ============================================================================================ + // ================================================================================================================= + + /** + * @return string + */ + public function getEntity() { + return $this->entity; + } + + /** + * @param string $entity + */ + public function setEntity($entity) { + $this->entity = $entity; + } +} \ No newline at end of file Index: trunk/libs =================================================================== --- trunk/libs 2014-10-15 00:20:24 UTC (rev 257) +++ trunk/libs 2014-10-15 18:59:03 UTC (rev 258) Property changes on: trunk/libs ___________________________________________________________________ Modified: svn:externals ## -1,2 +1 ## -log4php-2.1.0 https://svn.apache.org/repos/asf/logging/log4php/tags/apache-log4php-2.1.0/src/main/php php-aop http://php-aop.googlecode.com/svn/trunk/aop This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <m_p...@us...> - 2014-10-15 19:49:22
|
Revision: 259 http://sourceforge.net/p/beeframework/code/259 Author: m_plomer Date: 2014-10-15 19:49:12 +0000 (Wed, 15 Oct 2014) Log Message: ----------- - fixed some tests Modified Paths: -------------- trunk/framework/Bee/MVC/Controller/Multiaction/HandlerMethodInvocator/RegexMappingInvocationResolver.php trunk/tests/Bee/Cache/Provider/AbstractSerializingTest.php trunk/tests/Bee/Cache/Provider/FileTest.php Modified: trunk/framework/Bee/MVC/Controller/Multiaction/HandlerMethodInvocator/RegexMappingInvocationResolver.php =================================================================== --- trunk/framework/Bee/MVC/Controller/Multiaction/HandlerMethodInvocator/RegexMappingInvocationResolver.php 2014-10-15 18:59:03 UTC (rev 258) +++ trunk/framework/Bee/MVC/Controller/Multiaction/HandlerMethodInvocator/RegexMappingInvocationResolver.php 2014-10-15 19:49:12 UTC (rev 259) @@ -48,7 +48,7 @@ /** * @var HandlerMethodMetadata[] */ - private static $methodMetadataMap; + private static $methodMetadataMap = array(); /** * @var MethodInvocation[] Modified: trunk/tests/Bee/Cache/Provider/AbstractSerializingTest.php =================================================================== --- trunk/tests/Bee/Cache/Provider/AbstractSerializingTest.php 2014-10-15 18:59:03 UTC (rev 258) +++ trunk/tests/Bee/Cache/Provider/AbstractSerializingTest.php 2014-10-15 19:49:12 UTC (rev 259) @@ -24,7 +24,7 @@ * Time: 15:16 */ -class Bee_Cache_Provider_AbstractSerializingTest extends PHPUnit_Framework_TestCase { +class AbstractSerializingTest extends PHPUnit_Framework_TestCase { // /** // * Initialize the cache provider if necessary. Called once per request, before the first cache access is made. @@ -79,7 +79,7 @@ private $provider; protected function setUp() { - $this->provider = new Bee_Cache_Provider_AbstractSerializingMock(array( + $this->provider = new AbstractSerializingMock(array( 'foo' => serialize('bar'), 'foo__ETIME__' => time() )); @@ -106,10 +106,10 @@ $value2 = array( 'level-1-1' => 'level-1-1 value', 'level-1-2' => 17, - 'level-1-3' => new stdClass(), + 'level-1-3' => new \stdClass(), 'level-1-4' => array( - 'level-2-1' => new stdClass(), - 'level-2-2' => new stdClass(), + 'level-2-1' => new \stdClass(), + 'level-2-2' => new \stdClass(), 'level-2-3' => 'level-2-3 value', 'level-2-3' => array( 'value-true' => true, Modified: trunk/tests/Bee/Cache/Provider/FileTest.php =================================================================== --- trunk/tests/Bee/Cache/Provider/FileTest.php 2014-10-15 18:59:03 UTC (rev 258) +++ trunk/tests/Bee/Cache/Provider/FileTest.php 2014-10-15 19:49:12 UTC (rev 259) @@ -1,4 +1,5 @@ <?php +namespace Bee\Cache\Provider; /* * Copyright 2008-2010 the original author or authors. * @@ -15,6 +16,7 @@ * limitations under the License. */ use Bee\Cache\IProvider; +use PHPUnit_Framework_TestCase; /** * User: mp @@ -22,7 +24,7 @@ * Time: 15:16 */ -class Bee_Cache_Provider_FileTest extends PHPUnit_Framework_TestCase { +class FileTest extends PHPUnit_Framework_TestCase { // /** // * Initialize the cache provider if necessary. Called once per request, before the first cache access is made. This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |