beeframework-svn Mailing List for Bee Framework (Page 6)
Brought to you by:
b_hartmann,
m_plomer
You can subscribe to this list here.
2010 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
(5) |
Sep
|
Oct
|
Nov
|
Dec
|
---|---|---|---|---|---|---|---|---|---|---|---|---|
2011 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(6) |
2013 |
Jan
|
Feb
|
Mar
|
Apr
(1) |
May
(12) |
Jun
(5) |
Jul
(6) |
Aug
(25) |
Sep
(25) |
Oct
(6) |
Nov
(29) |
Dec
|
2014 |
Jan
(2) |
Feb
(10) |
Mar
(2) |
Apr
(2) |
May
|
Jun
(5) |
Jul
(35) |
Aug
(9) |
Sep
(33) |
Oct
(30) |
Nov
(4) |
Dec
(1) |
2015 |
Jan
(3) |
Feb
(13) |
Mar
(13) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
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-07-08 16:51:52
|
Revision: 175 http://sourceforge.net/p/beeframework/code/175 Author: m_plomer Date: 2014-07-08 16:51:43 +0000 (Tue, 08 Jul 2014) Log Message: ----------- - MVC: parametrized URL patterns done Modified Paths: -------------- trunk/examples/classes/Test/Mvc/ParamTestDelegate.php trunk/examples/conf/context-mvc.xml Modified: trunk/examples/classes/Test/Mvc/ParamTestDelegate.php =================================================================== --- trunk/examples/classes/Test/Mvc/ParamTestDelegate.php 2014-07-08 16:41:30 UTC (rev 174) +++ trunk/examples/classes/Test/Mvc/ParamTestDelegate.php 2014-07-08 16:51:43 UTC (rev 175) @@ -42,4 +42,13 @@ var_dump($request); return true; } + + /** + * @param int $getParam + * @return Bee_MVC_ModelAndView + */ + public function handleDefault($getParam = 1000) { + 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:41:30 UTC (rev 174) +++ trunk/examples/conf/context-mvc.xml 2014-07-08 16:51:43 UTC (rev 175) @@ -23,7 +23,7 @@ <!-- METHOD NAME RESOLVER --> <bean id="multiactionControllerTemplate" class="Bee\MVC\Controller\MultiActionController"> - <property name="defaultMethodName" value="__INVALID__"/> + <property name="defaultMethodName" value="handleDefault"/> </bean> <!-- ++++++++++++++++++++++++++++++++++++++++++++++ --> 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-03 10:22:03
|
Revision: 170 http://sourceforge.net/p/beeframework/code/170 Author: m_plomer Date: 2014-07-03 10:21:54 +0000 (Thu, 03 Jul 2014) Log Message: ----------- - MVC: namespaced some core classes Modified Paths: -------------- trunk/framework/Bee/MVC/Dispatcher.php trunk/framework/Bee/MVC/HandlerMapping/AbstractHandlerMapping.php trunk/framework/Bee/MVC/IHandlerExceptionResolver.php trunk/framework/Bee/MVC/SimpleMappingExceptionResolver.php Modified: trunk/framework/Bee/MVC/Dispatcher.php =================================================================== --- trunk/framework/Bee/MVC/Dispatcher.php 2014-07-03 10:02:05 UTC (rev 169) +++ trunk/framework/Bee/MVC/Dispatcher.php 2014-07-03 10:21:54 UTC (rev 170) @@ -103,7 +103,7 @@ /** * The view resolver used by this dispatcher * - * @var IViewResolver + * @var Bee\MVC\IViewResolver */ private $viewResolver; @@ -116,7 +116,7 @@ /** * - * @var Bee_MVC_IHandlerExceptionResolver + * @var Bee\MVC\IHandlerExceptionResolver */ private $handlerExceptionResolver; @@ -220,7 +220,7 @@ } try { - $this->handlerExceptionResolver = $this->context->getBean(self::HANDLER_EXCEPTION_RESOLVER_NAME, 'Bee_MVC_IHandlerExceptionResolver'); + $this->handlerExceptionResolver = $this->context->getBean(self::HANDLER_EXCEPTION_RESOLVER_NAME, 'Bee\MVC\IHandlerExceptionResolver'); } catch (Bee_Context_NoSuchBeanDefinitionException $ex) { $this->getLog()->info('no exception resolver configured'); } Modified: trunk/framework/Bee/MVC/HandlerMapping/AbstractHandlerMapping.php =================================================================== --- trunk/framework/Bee/MVC/HandlerMapping/AbstractHandlerMapping.php 2014-07-03 10:02:05 UTC (rev 169) +++ trunk/framework/Bee/MVC/HandlerMapping/AbstractHandlerMapping.php 2014-07-03 10:21:54 UTC (rev 170) @@ -104,7 +104,7 @@ public function getHandler(Bee_MVC_IHttpRequest $request) { $controllerBeanName = $this->getControllerBeanName($request); $handlerBean = is_string($controllerBeanName) ? - $handlerBean = $this->context->getBean($controllerBeanName, 'IController') : + $handlerBean = $this->context->getBean($controllerBeanName, 'Bee\MVC\IController') : $controllerBeanName; if (!$handlerBean instanceof IController) { Modified: trunk/framework/Bee/MVC/IHandlerExceptionResolver.php =================================================================== --- trunk/framework/Bee/MVC/IHandlerExceptionResolver.php 2014-07-03 10:02:05 UTC (rev 169) +++ trunk/framework/Bee/MVC/IHandlerExceptionResolver.php 2014-07-03 10:21:54 UTC (rev 170) @@ -1,4 +1,5 @@ <?php +namespace Bee\MVC; /* * Copyright 2008-2014 the original author or authors. * @@ -14,16 +15,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -use Bee\MVC\IController; +use Bee_MVC_IHttpRequest; +use Exception; -interface Bee_MVC_IHandlerExceptionResolver { +interface IHandlerExceptionResolver { /** * * @param Bee_MVC_IHttpRequest $request * @param IController $handler * @param Exception $ex - * @return Bee_MVC_ModelAndView + * @return \Bee_MVC_ModelAndView */ public function resolveException(Bee_MVC_IHttpRequest $request, IController $handler = null, Exception $ex); } Modified: trunk/framework/Bee/MVC/SimpleMappingExceptionResolver.php =================================================================== --- trunk/framework/Bee/MVC/SimpleMappingExceptionResolver.php 2014-07-03 10:02:05 UTC (rev 169) +++ trunk/framework/Bee/MVC/SimpleMappingExceptionResolver.php 2014-07-03 10:21:54 UTC (rev 170) @@ -15,8 +15,9 @@ * limitations under the License. */ use Bee\MVC\IController; +use Bee\MVC\IHandlerExceptionResolver; -class Bee_MVC_SimpleMappingExceptionResolver implements Bee_MVC_IHandlerExceptionResolver { +class Bee_MVC_SimpleMappingExceptionResolver implements IHandlerExceptionResolver { const MODEL_HANDLER_EXCEPTION_KEY = 'handler_excpetion'; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <m_p...@us...> - 2014-07-03 10:02:13
|
Revision: 169 http://sourceforge.net/p/beeframework/code/169 Author: m_plomer Date: 2014-07-03 10:02:05 +0000 (Thu, 03 Jul 2014) Log Message: ----------- MVC SimpleMappingExceptionResolver: added logging Modified Paths: -------------- trunk/framework/Bee/MVC/SimpleMappingExceptionResolver.php Modified: trunk/framework/Bee/MVC/SimpleMappingExceptionResolver.php =================================================================== --- trunk/framework/Bee/MVC/SimpleMappingExceptionResolver.php 2014-07-03 09:13:10 UTC (rev 168) +++ trunk/framework/Bee/MVC/SimpleMappingExceptionResolver.php 2014-07-03 10:02:05 UTC (rev 169) @@ -21,6 +21,21 @@ const MODEL_HANDLER_EXCEPTION_KEY = 'handler_excpetion'; /** + * @var Logger + */ + protected $log; + + /** + * @return Logger + */ + protected function getLog() { + if (!$this->log) { + $this->log = Logger::getLogger(get_class($this)); + } + return $this->log; + } + + /** * * @var array */ @@ -73,6 +88,7 @@ * @return Bee_MVC_ModelAndView|bool */ public function resolveException(Bee_MVC_IHttpRequest $request, IController $handler = null, Exception $ex) { + $this->getLog()->info('Trying to map exception', $ex); $viewName = false; @@ -95,8 +111,10 @@ if (!$viewName && Bee_Utils_Strings::hasText($this->defaultErrorView)) { $viewName = $this->defaultErrorView; + $this->getLog()->debug('Resolving to default error view'); } + $this->getLog()->debug('Resolved error view: ' . $viewName); return $viewName ? new Bee_MVC_ModelAndView(array(self::MODEL_HANDLER_EXCEPTION_KEY => $ex), $viewName) : false; } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <m_p...@us...> - 2014-07-03 09:13:18
|
Revision: 168 http://sourceforge.net/p/beeframework/code/168 Author: m_plomer Date: 2014-07-03 09:13:10 +0000 (Thu, 03 Jul 2014) Log Message: ----------- - MVC: namespaced some core classes, updated copyright notice Modified Paths: -------------- trunk/framework/Bee/MVC/Controller/MultiActionController.php Modified: trunk/framework/Bee/MVC/Controller/MultiActionController.php =================================================================== --- trunk/framework/Bee/MVC/Controller/MultiActionController.php 2014-07-03 08:59:44 UTC (rev 167) +++ trunk/framework/Bee/MVC/Controller/MultiActionController.php 2014-07-03 09:13:10 UTC (rev 168) @@ -54,7 +54,7 @@ /** * Enter description here... * - * @var \Bee_MVC_Controller_Multiaction_IMethodNameResolver + * @var \Bee\MVC\Controller\Multiaction\IMethodNameResolver */ private $methodNameResolver; @@ -157,7 +157,7 @@ /** * Enter description here... * - * @param \Bee_MVC_Controller_Multiaction_IMethodNameResolver $methodNameResolver + * @param \Bee\MVC\Controller\Multiaction\IMethodNameResolver $methodNameResolver * @return void */ public final function setMethodNameResolver($methodNameResolver) { @@ -170,7 +170,7 @@ /** * Enter description here... * - * @return \Bee_MVC_Controller_Multiaction_IMethodNameResolver + * @return \Bee\MVC\Controller\Multiaction\IMethodNameResolver */ public function getMethodNameResolver() { return $this->methodNameResolver; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <m_p...@us...> - 2014-07-02 14:19:23
|
Revision: 165 http://sourceforge.net/p/beeframework/code/165 Author: m_plomer Date: 2014-07-02 14:19:15 +0000 (Wed, 02 Jul 2014) Log Message: ----------- - MVC MethodNameResolver: annotation-based - ajax flag introduced Modified Paths: -------------- trunk/framework/Bee/MVC/Controller/Multiaction/MethodNameResolver/AnnotationBased.php Modified: trunk/framework/Bee/MVC/Controller/Multiaction/MethodNameResolver/AnnotationBased.php =================================================================== --- trunk/framework/Bee/MVC/Controller/Multiaction/MethodNameResolver/AnnotationBased.php 2014-07-02 12:46:18 UTC (rev 164) +++ trunk/framework/Bee/MVC/Controller/Multiaction/MethodNameResolver/AnnotationBased.php 2014-07-02 14:19:15 UTC (rev 165) @@ -68,8 +68,7 @@ $this->init(); - $httpMethod = strtoupper($request->getMethod()); - + $httpMethod = $this->getMethodNameKey($request->getMethod()); $ajaxKeyPart = $this->getAjaxTypeKey($request->getAjax()); return $this->selectHandlerMethod(array( $httpMethod . $ajaxKeyPart, @@ -126,13 +125,8 @@ $annotations = $method->getAllAnnotations('Bee_MVC_Controller_Multiaction_RequestHandler'); foreach($annotations as $annotation) { - $httpMethod = strtoupper($annotation->httpMethod); - $ajax = filter_var($annotation->ajax, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE); - $ajax = $this->getAjaxTypeKey($ajax); - if(!Bee_Utils_Strings::hasText($httpMethod)) { - $httpMethod = self::DEFAULT_HTTP_METHOD_KEY; - } - $httpMethod .= $httpMethod . $ajax; + $httpMethod = $this->getMethodNameKey($annotation->httpMethod) . + $this->getAjaxTypeKey(filter_var($annotation->ajax, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE)); if(!array_key_exists($httpMethod, $mappings)) { $mappings[$httpMethod] = array(); } @@ -158,6 +152,14 @@ } /** + * @param $methodName + * @return string + */ + protected function getMethodNameKey($methodName) { + return Bee_Utils_Strings::hasText($methodName) ? strtoupper($methodName) : self::DEFAULT_HTTP_METHOD_KEY; + } + + /** * @param bool|null $ajax * @return string */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <m_p...@us...> - 2014-07-02 12:46:26
|
Revision: 164 http://sourceforge.net/p/beeframework/code/164 Author: m_plomer Date: 2014-07-02 12:46:18 +0000 (Wed, 02 Jul 2014) Log Message: ----------- - MVC MethodNameResolver: annotation-based - ajax flag introduced Modified Paths: -------------- trunk/framework/Bee/Annotations/Utils.php trunk/framework/Bee/MVC/Controller/Multiaction/MethodNameResolver/AnnotationBased.php trunk/framework/Bee/MVC/Controller/Multiaction/MethodNameResolver/AntPath.php trunk/framework/Bee/MVC/Controller/Multiaction/RequestHandler.php Modified: trunk/framework/Bee/Annotations/Utils.php =================================================================== --- trunk/framework/Bee/Annotations/Utils.php 2014-07-02 10:50:58 UTC (rev 163) +++ trunk/framework/Bee/Annotations/Utils.php 2014-07-02 12:46:18 UTC (rev 164) @@ -25,16 +25,16 @@ 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 - * can be found on the given method itself. - * <p>Annotations on methods are not inherited by default, so we need to handle - * this explicitly. Tge - * @param method the method to look for annotations on - * @param annotationType the annotation class to look for - * @return the annotation found, or <code>null</code> if none found - */ + /** + * Get a single {@link Annotation} of <code>annotationType</code> from the + * supplied {@link Method}, traversing its super methods if no annotation + * can be found on the given method itself. + * <p>Annotations on methods are not inherited by default, so we need to handle + * this explicitly. Tge + * @param ReflectionMethod $method + * @param $annotationClassName + * @return the annotation found, or <code>null</code> if none found + */ public static function findAnnotation(ReflectionMethod $method, $annotationClassName) { $annotatedMethod = self::getReflectionAnnotatedMethodIfNecessary($method); $annotation = $annotatedMethod->getAnnotation($annotationClassName); Modified: trunk/framework/Bee/MVC/Controller/Multiaction/MethodNameResolver/AnnotationBased.php =================================================================== --- trunk/framework/Bee/MVC/Controller/Multiaction/MethodNameResolver/AnnotationBased.php 2014-07-02 10:50:58 UTC (rev 163) +++ trunk/framework/Bee/MVC/Controller/Multiaction/MethodNameResolver/AnnotationBased.php 2014-07-02 12:46:18 UTC (rev 164) @@ -22,6 +22,8 @@ * * Handler methods in a delegate handler class must conform to the rules for handler methods for the multi action controller and be * annotated with <code>Bee_MVC_Controller_Multiaction_RequestHandler</code> annotations. + * + * todo: replace addendum annotation handling with Doctrine Annotations * * @see Bee_MVC_Controller_MultiAction * @see Bee_MVC_Controller_Multiaction_IMethodNameResolver @@ -32,37 +34,68 @@ class Bee_MVC_Controller_Multiaction_MethodNameResolver_AnnotationBased extends Bee_MVC_Controller_Multiaction_MethodNameResolver_Abstract { const DEFAULT_HTTP_METHOD_KEY = 'DEFAULT'; + const AJAX_TYPE_TRUE_KEY = '_TRUE'; + const AJAX_TYPE_FALSE_KEY = '_FALSE'; + const AJAX_TYPE_ANY_KEY = '_ANY'; const CACHE_KEY_PREFIX = 'BeeMethodNameResolverAnnotationCache_'; + /** + * @var Logger + */ + protected $log; + + /** + * @return Logger + */ + protected function getLog() { + if (!$this->log) { + $this->log = Logger::getLogger(get_class($this)); + } + return $this->log; + } + /** * @var Bee_MVC_Controller_Multiaction_MethodNameResolver_AntPath[] */ private $methodResolvers = false; + /** + * @param Bee_MVC_IHttpRequest $request + * @return string + */ public function getHandlerMethodName(Bee_MVC_IHttpRequest $request) { $this->init(); $httpMethod = strtoupper($request->getMethod()); - $handlerMethod = $this->getHandlerMethodInternal($httpMethod, $request); + $ajaxKeyPart = $this->getAjaxTypeKey($request->getAjax()); + return $this->selectHandlerMethod(array( + $httpMethod . $ajaxKeyPart, + $httpMethod . self::AJAX_TYPE_ANY_KEY, + self::DEFAULT_HTTP_METHOD_KEY . $ajaxKeyPart, + self::DEFAULT_HTTP_METHOD_KEY . self::AJAX_TYPE_ANY_KEY + ), $request); + } - if(is_null($handlerMethod)) { - $handlerMethod = $this->getHandlerMethodInternal(self::DEFAULT_HTTP_METHOD_KEY, $request); + /** + * @param array $possibleMethodKeys + * @param Bee_MVC_IHttpRequest $request + * @return string + */ + private function selectHandlerMethod(array $possibleMethodKeys, Bee_MVC_IHttpRequest $request) { + $result = null; + foreach($possibleMethodKeys as $methodKey) { + if(array_key_exists($methodKey, $this->methodResolvers)) { + $result = $this->methodResolvers[$methodKey]->getHandlerMethodName($request); + if(!is_null($result)) { + return $result; + } + } } - - return $handlerMethod; + return $result; } - - private function getHandlerMethodInternal($httpMethod, Bee_MVC_IHttpRequest $request) { - if(array_key_exists($httpMethod, $this->methodResolvers)) { - $resolver = $this->methodResolvers[$httpMethod]; - return $resolver->getHandlerMethodName($request); - } - return null; - } - protected function init() { if(!$this->methodResolvers) { @@ -73,12 +106,14 @@ try { $this->methodResolvers = Bee_Cache_Manager::retrieve(self::CACHE_KEY_PREFIX . $delegateClassName); } catch (Exception $e) { + $this->getLog()->debug('No cached method name resolvers for delegate "' . $delegateClassName . '" found, annotation parsing required'); } } if(!$this->methodResolvers) { $classReflector = new ReflectionAnnotatedClass($delegateClassName); + /** @var \Addendum\ReflectionAnnotatedMethod[] $methods */ $methods = $classReflector->getMethods(ReflectionMethod::IS_PUBLIC); $mappings = array(); @@ -87,13 +122,17 @@ if($this->getController()->isHandlerMethod($method)) { // is possible handler method, check for annotations + /** @var Bee_MVC_Controller_Multiaction_RequestHandler[] $annotations */ $annotations = $method->getAllAnnotations('Bee_MVC_Controller_Multiaction_RequestHandler'); foreach($annotations as $annotation) { $httpMethod = strtoupper($annotation->httpMethod); + $ajax = filter_var($annotation->ajax, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE); + $ajax = $this->getAjaxTypeKey($ajax); if(!Bee_Utils_Strings::hasText($httpMethod)) { $httpMethod = self::DEFAULT_HTTP_METHOD_KEY; } + $httpMethod .= $httpMethod . $ajax; if(!array_key_exists($httpMethod, $mappings)) { $mappings[$httpMethod] = array(); } @@ -102,9 +141,7 @@ $pathPattern = str_replace('*\/', '*/', $annotation->pathPattern); $mappings[$httpMethod][$pathPattern] = $method->getName(); } - } - } foreach($mappings as $method => $mapping) { @@ -119,5 +156,15 @@ } } } -} -?> \ No newline at end of file + + /** + * @param bool|null $ajax + * @return string + */ + protected function getAjaxTypeKey($ajax) { + if(is_null($ajax)) { + return self::AJAX_TYPE_ANY_KEY; + } + return $ajax ? self::AJAX_TYPE_TRUE_KEY : self::AJAX_TYPE_FALSE_KEY; + } +} \ No newline at end of file Modified: trunk/framework/Bee/MVC/Controller/Multiaction/MethodNameResolver/AntPath.php =================================================================== --- trunk/framework/Bee/MVC/Controller/Multiaction/MethodNameResolver/AntPath.php 2014-07-02 10:50:58 UTC (rev 163) +++ trunk/framework/Bee/MVC/Controller/Multiaction/MethodNameResolver/AntPath.php 2014-07-02 12:46:18 UTC (rev 164) @@ -77,4 +77,3 @@ return $handlerMethodName; } } -?> \ 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-02 10:50:58 UTC (rev 163) +++ trunk/framework/Bee/MVC/Controller/Multiaction/RequestHandler.php 2014-07-02 12:46:18 UTC (rev 164) @@ -28,5 +28,5 @@ class Bee_MVC_Controller_Multiaction_RequestHandler extends Annotation { public $httpMethod; public $pathPattern; + 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-02 10:51:01
|
Revision: 163 http://sourceforge.net/p/beeframework/code/163 Author: m_plomer Date: 2014-07-02 10:50:58 +0000 (Wed, 02 Jul 2014) Log Message: ----------- - MVC Dispatcher: introduced IRequestBuilder, DefaultRequestBuilder Modified Paths: -------------- trunk/framework/Bee/MVC/Dispatcher.php Modified: trunk/framework/Bee/MVC/Dispatcher.php =================================================================== --- trunk/framework/Bee/MVC/Dispatcher.php 2014-07-02 10:40:43 UTC (rev 162) +++ trunk/framework/Bee/MVC/Dispatcher.php 2014-07-02 10:50:58 UTC (rev 163) @@ -207,6 +207,8 @@ $this->requestBuilder = new DefaultRequestBuilder(); } + self::$currentRequest = $this->requestBuilder->buildRequestObject(); + $this->handlerMapping = $this->context->getBean(self::HANDLER_MAPPING_BEAN_NAME, 'Bee_MVC_IHandlerMapping'); $this->viewResolver = $this->context->getBean(self::VIEW_RESOLVER_BEAN_NAME, 'Bee_MVC_IViewResolver'); @@ -221,8 +223,6 @@ } catch (Bee_Context_NoSuchBeanDefinitionException $ex) { $this->getLog()->info('no exception resolver configured'); } - - self::$currentRequest = $this->requestBuilder->buildRequestObject(); } /** This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <m_p...@us...> - 2014-07-02 10:40:48
|
Revision: 162 http://sourceforge.net/p/beeframework/code/162 Author: m_plomer Date: 2014-07-02 10:40:43 +0000 (Wed, 02 Jul 2014) Log Message: ----------- - MVC Dispatcher: introduced IRequestBuilder, DefaultRequestBuilder Modified Paths: -------------- trunk/framework/Bee/MVC/Dispatcher.php Modified: trunk/framework/Bee/MVC/Dispatcher.php =================================================================== --- trunk/framework/Bee/MVC/Dispatcher.php 2014-07-02 09:43:40 UTC (rev 161) +++ trunk/framework/Bee/MVC/Dispatcher.php 2014-07-02 10:40:43 UTC (rev 162) @@ -201,7 +201,7 @@ } try { - $this->requestBuilder = $this->context->getBean(self::HANDLER_MAPPING_BEAN_NAME, '\Bee\MVC\IRequestBuilder'); + $this->requestBuilder = $this->context->getBean(self::REQUEST_BUILDER_BEAN_NAME, '\Bee\MVC\IRequestBuilder'); } catch (Bee_Context_NoSuchBeanDefinitionException $ex) { $this->getLog()->info('no RequestBuilder configured, using DefaultRequestBuilder'); $this->requestBuilder = new DefaultRequestBuilder(); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <m_p...@us...> - 2014-07-02 09:43:49
|
Revision: 161 http://sourceforge.net/p/beeframework/code/161 Author: m_plomer Date: 2014-07-02 09:43:40 +0000 (Wed, 02 Jul 2014) Log Message: ----------- - MVC Dispatcher: introduced IRequestBuilder, DefaultRequestBuilder - MVC/Views: RequestStoringRedirectView and RedirectedRequestBuilder Modified Paths: -------------- trunk/framework/Bee/Context/BeansException.php trunk/framework/Bee/MVC/DefaultRequestBuilder.php trunk/framework/Bee/MVC/Dispatcher.php trunk/framework/Bee/MVC/HttpRequest.php trunk/framework/Bee/MVC/IHttpRequest.php trunk/framework/Bee/MVC/IViewResolver.php trunk/framework/Bee/MVC/Redirect/AbstractRedirectStorage.php trunk/framework/Bee/MVC/Redirect/RedirectInfoStorage.php trunk/framework/Bee/MVC/Redirect/RedirectRequestStorage.php trunk/framework/Bee/MVC/Redirect/RedirectedRequestBuilder.php trunk/framework/Bee/MVC/SimpleMappingExceptionResolver.php trunk/framework/Bee/MVC/ViewResolver/Basic.php trunk/framework/Bee/MVC/ViewResolver/Loopback.php Added Paths: ----------- trunk/framework/Bee/MVC/Request/ trunk/framework/Bee/MVC/Request/DefaultAjaxDetectionStrategy.php trunk/framework/Bee/MVC/Request/IAjaxDetectionStrategy.php Modified: trunk/framework/Bee/Context/BeansException.php =================================================================== --- trunk/framework/Bee/Context/BeansException.php 2014-07-02 08:10:59 UTC (rev 160) +++ trunk/framework/Bee/Context/BeansException.php 2014-07-02 09:43:40 UTC (rev 161) @@ -23,5 +23,3 @@ */ class Bee_Context_BeansException extends Bee_Exceptions_Base { } - -?> \ No newline at end of file Modified: trunk/framework/Bee/MVC/DefaultRequestBuilder.php =================================================================== --- trunk/framework/Bee/MVC/DefaultRequestBuilder.php 2014-07-02 08:10:59 UTC (rev 160) +++ trunk/framework/Bee/MVC/DefaultRequestBuilder.php 2014-07-02 09:43:40 UTC (rev 161) @@ -1,9 +1,10 @@ <?php namespace Bee\MVC; +use Bee\MVC\Request\DefaultAjaxDetectionStrategy; +use Bee\MVC\Request\IAjaxDetectionStrategy; use Bee_MVC_HttpRequest; - /** * Class DefaultRequestBuilder * @package Bee\MVC @@ -11,9 +12,40 @@ class DefaultRequestBuilder implements IRequestBuilder { /** + * @var IAjaxDetectionStrategy + */ + private $ajaxDetectionStrategy; + + /** * @return \Bee_MVC_IHttpRequest */ public function buildRequestObject() { - return new Bee_MVC_HttpRequest(); + return $this->massageConstructedRequest(new Bee_MVC_HttpRequest()); } + + /** + * @param Bee_MVC_HttpRequest $request + * @return Bee_MVC_HttpRequest + */ + public function massageConstructedRequest(Bee_MVC_HttpRequest $request) { + $request->setAjax($this->getAjaxDetectionStrategy()->isAjaxRequest($request)); + return $request; + } + + /** + * @param IAjaxDetectionStrategy $ajaxDetectionStrategy + */ + public function setAjaxDetectionStrategy(IAjaxDetectionStrategy $ajaxDetectionStrategy) { + $this->ajaxDetectionStrategy = $ajaxDetectionStrategy; + } + + /** + * @return IAjaxDetectionStrategy + */ + public function getAjaxDetectionStrategy() { + if(is_null($this->ajaxDetectionStrategy)) { + $this->ajaxDetectionStrategy = new DefaultAjaxDetectionStrategy(); + } + return $this->ajaxDetectionStrategy; + } } \ No newline at end of file Modified: trunk/framework/Bee/MVC/Dispatcher.php =================================================================== --- trunk/framework/Bee/MVC/Dispatcher.php 2014-07-02 08:10:59 UTC (rev 160) +++ trunk/framework/Bee/MVC/Dispatcher.php 2014-07-02 09:43:40 UTC (rev 161) @@ -298,7 +298,7 @@ if ($mav instanceof Bee_MVC_ModelAndView) { $mav->addModelValue(Bee_MVC_Model::CURRENT_REQUEST_KEY, $request); - $this->resolveModelAndView($mav); + $this->resolveModelAndView($mav, $request); if(!is_null($handlerException) && !count($interceptors)) { // We were unable to resolve a handler and its interceptors due to an exception being thrown along @@ -319,8 +319,8 @@ } } - public function resolveModelAndView(Bee_MVC_ModelAndView $mav) { - $resolvedView = $this->viewResolver->resolveViewName($mav->getViewName()); + public function resolveModelAndView(Bee_MVC_ModelAndView $mav, Bee_MVC_IHttpRequest $request) { + $resolvedView = $this->viewResolver->resolveViewName($mav->getViewName(), $request); $mav->setResolvedView($resolvedView); if ($resolvedView instanceof Bee_MVC_View_Abstract) { $statics = $resolvedView->getStaticAttributes(); @@ -330,15 +330,15 @@ $model = array_merge($statics, $mav->getModel()); $mav->setModel($model); } - $this->resolveModelInternals($mav->getModel()); + $this->resolveModelInternals($mav->getModel(), $request); } - private function resolveModelInternals(array $model) { + private function resolveModelInternals(array $model, Bee_MVC_IHttpRequest $request) { foreach ($model as $modelElem) { if ($modelElem instanceof Bee_MVC_ModelAndView) { - $this->resolveModelAndView($modelElem); + $this->resolveModelAndView($modelElem, $request); } else if (is_array($modelElem)) { - $this->resolveModelInternals($modelElem); + $this->resolveModelInternals($modelElem, $request); } } } Modified: trunk/framework/Bee/MVC/HttpRequest.php =================================================================== --- trunk/framework/Bee/MVC/HttpRequest.php 2014-07-02 08:10:59 UTC (rev 160) +++ trunk/framework/Bee/MVC/HttpRequest.php 2014-07-02 09:43:40 UTC (rev 161) @@ -60,7 +60,12 @@ * @var array */ private $headerNames; - + + /** + * @var bool + */ + private $ajax; + public function __construct(array $parameters = null, $pathInfo = null, $method = null, array $headers = null) { if(is_null($headers)) { $headers = Bee_Utils_Env::getRequestHeaders(); @@ -195,4 +200,18 @@ } return new Bee_MVC_HttpRequest($params, $pathInfo, $method, $headers); } + + /** + * @param boolean $ajax + */ + public function setAjax($ajax) { + $this->ajax = $ajax; + } + + /** + * @return boolean + */ + public function getAjax() { + return $this->ajax; + } } Modified: trunk/framework/Bee/MVC/IHttpRequest.php =================================================================== --- trunk/framework/Bee/MVC/IHttpRequest.php 2014-07-02 08:10:59 UTC (rev 160) +++ trunk/framework/Bee/MVC/IHttpRequest.php 2014-07-02 09:43:40 UTC (rev 161) @@ -44,13 +44,14 @@ * @return String */ public function getMethod(); - - - /** - * Enter description here... - * - * @return bool - */ + + + /** + * Enter description here... + * + * @param string $name + * @return bool + */ public function hasParameter($name); /** @@ -99,4 +100,10 @@ // public function getParamArray(); public function addParameters(array $params); + + /** + * True if this is an AJAX request, false in case of a regular GET or POSTback. + * @return bool + */ + public function getAjax(); } \ No newline at end of file Modified: trunk/framework/Bee/MVC/IViewResolver.php =================================================================== --- trunk/framework/Bee/MVC/IViewResolver.php 2014-07-02 08:10:59 UTC (rev 160) +++ trunk/framework/Bee/MVC/IViewResolver.php 2014-07-02 09:43:40 UTC (rev 161) @@ -28,19 +28,17 @@ * @author Michael Plomer <mic...@it...> */ interface Bee_MVC_IViewResolver { - /** + /** * Resolve the given view by name. * <p>Note: To allow for ViewResolver chaining, a ViewResolver should * return <code>null</code> if a view with the given name is not defined in it. * However, this is not required: Some ViewResolvers will always attempt - * to build View objects with the given name, unable to return <code>null</code> + * to build View objects with the given name, unable to return <code>null</code> * (rather throwing an exception when View creation failed). - * @param String viewName name of the view to resolve + * @param String $viewName name of the view to resolve + * @param Bee_MVC_IHttpRequest $request * @return Bee_MVC_IView the IView object, or <code>null</code> if not found * (optional, to allow for ViewResolver chaining) - * @throws Exception if the view cannot be resolved - * (typically in case of problems creating an actual View object) */ - public function resolveViewName($viewName); + public function resolveViewName($viewName, Bee_MVC_IHttpRequest $request); } -?> \ No newline at end of file Modified: trunk/framework/Bee/MVC/Redirect/AbstractRedirectStorage.php =================================================================== --- trunk/framework/Bee/MVC/Redirect/AbstractRedirectStorage.php 2014-07-02 08:10:59 UTC (rev 160) +++ trunk/framework/Bee/MVC/Redirect/AbstractRedirectStorage.php 2014-07-02 09:43:40 UTC (rev 161) @@ -42,7 +42,8 @@ abstract protected function doStoreData(array $model); /** + * @param RedirectedRequestBuilder $requestBuilder * @return \Bee_MVC_IHttpRequest */ - abstract public function restoreRequestObject(); + abstract public function restoreRequestObject(RedirectedRequestBuilder $requestBuilder); } \ No newline at end of file Modified: trunk/framework/Bee/MVC/Redirect/RedirectInfoStorage.php =================================================================== --- trunk/framework/Bee/MVC/Redirect/RedirectInfoStorage.php 2014-07-02 08:10:59 UTC (rev 160) +++ trunk/framework/Bee/MVC/Redirect/RedirectInfoStorage.php 2014-07-02 09:43:40 UTC (rev 161) @@ -44,11 +44,12 @@ } /** + * @param RedirectedRequestBuilder $requestBuilder * @return \Bee_MVC_IHttpRequest */ - public function restoreRequestObject() { + public function restoreRequestObject(RedirectedRequestBuilder $requestBuilder) { $request = new Bee_MVC_HttpRequest(); $request->addParameters($this->storedData); - return $request; + return $requestBuilder->massageConstructedRequest($request); } } \ No newline at end of file Modified: trunk/framework/Bee/MVC/Redirect/RedirectRequestStorage.php =================================================================== --- trunk/framework/Bee/MVC/Redirect/RedirectRequestStorage.php 2014-07-02 08:10:59 UTC (rev 160) +++ trunk/framework/Bee/MVC/Redirect/RedirectRequestStorage.php 2014-07-02 09:43:40 UTC (rev 161) @@ -49,13 +49,14 @@ } /** + * @param RedirectedRequestBuilder $requestBuilder * @return \Bee_MVC_IHttpRequest */ - public function restoreRequestObject() { + public function restoreRequestObject(RedirectedRequestBuilder $requestBuilder) { $_GET = $this->getParams; $_POST = $this->postParams; $_REQUEST = $this->requestParams; $_SERVER = $this->serverVars; - return new \Bee_MVC_HttpRequest(null, null, null, $this->headers); + return $requestBuilder->massageConstructedRequest(new \Bee_MVC_HttpRequest(null, null, null, $this->headers)); } } \ No newline at end of file Modified: trunk/framework/Bee/MVC/Redirect/RedirectedRequestBuilder.php =================================================================== --- trunk/framework/Bee/MVC/Redirect/RedirectedRequestBuilder.php 2014-07-02 08:10:59 UTC (rev 160) +++ trunk/framework/Bee/MVC/Redirect/RedirectedRequestBuilder.php 2014-07-02 09:43:40 UTC (rev 161) @@ -1,7 +1,7 @@ <?php namespace Bee\MVC\Redirect; -use Bee\MVC\IRequestBuilder; +use Bee\MVC\DefaultRequestBuilder; /** * Class RedirectedRequestBuilder - restores a previously stored request from the session if applicable, or creates a @@ -9,7 +9,7 @@ * * @package Bee\MVC\Redirect */ -class RedirectedRequestBuilder implements IRequestBuilder { +class RedirectedRequestBuilder extends DefaultRequestBuilder { private $requestIdParamName = 'storedRequestId'; @@ -35,11 +35,11 @@ $id = $_GET[$this->requestIdParamName]; if(array_key_exists($id, $_SESSION) && ($storage = $_SESSION[$id]) instanceof AbstractRedirectStorage) { /** @var AbstractRedirectStorage $storage */ - return $storage->restoreRequestObject(); + return $storage->restoreRequestObject($this); } $this->throwNotFoundException($id); } - return new \Bee_MVC_HttpRequest(); + return parent::buildRequestObject(); } /** @@ -49,5 +49,4 @@ protected function throwNotFoundException($id) { throw new \Exception('Stored request with ID ' . $id . ' not found'); } - } \ No newline at end of file Added: trunk/framework/Bee/MVC/Request/DefaultAjaxDetectionStrategy.php =================================================================== --- trunk/framework/Bee/MVC/Request/DefaultAjaxDetectionStrategy.php (rev 0) +++ trunk/framework/Bee/MVC/Request/DefaultAjaxDetectionStrategy.php 2014-07-02 09:43:40 UTC (rev 161) @@ -0,0 +1,21 @@ +<?php + +namespace Bee\MVC\Request; +use Bee_MVC_IHttpRequest; + + +/** + * Class DefaultAjaxDetectionStrategy + * @package Bee\MVC\Request + */ +class DefaultAjaxDetectionStrategy implements IAjaxDetectionStrategy { + + /** + * Determine whether the given request represents an AJAX request or a regular GET / POSTback. + * @param Bee_MVC_IHttpRequest $request + * @return mixed + */ + public function isAjaxRequest(Bee_MVC_IHttpRequest $request) { + return $request->getHeader('X-Requested-With') == 'XMLHttpRequest'; + } +} \ No newline at end of file Added: trunk/framework/Bee/MVC/Request/IAjaxDetectionStrategy.php =================================================================== --- trunk/framework/Bee/MVC/Request/IAjaxDetectionStrategy.php (rev 0) +++ trunk/framework/Bee/MVC/Request/IAjaxDetectionStrategy.php 2014-07-02 09:43:40 UTC (rev 161) @@ -0,0 +1,18 @@ +<?php + +namespace Bee\MVC\Request; +use Bee_MVC_IHttpRequest; + +/** + * Interface IAjaxDetectionStrategy + * @package Bee\MVC\Request + */ +interface IAjaxDetectionStrategy { + + /** + * Determine whether the given request represents an AJAX request or a regular GET / POSTback. + * @param Bee_MVC_IHttpRequest $request + * @return mixed + */ + public function isAjaxRequest(Bee_MVC_IHttpRequest $request); +} \ No newline at end of file Modified: trunk/framework/Bee/MVC/SimpleMappingExceptionResolver.php =================================================================== --- trunk/framework/Bee/MVC/SimpleMappingExceptionResolver.php 2014-07-02 08:10:59 UTC (rev 160) +++ trunk/framework/Bee/MVC/SimpleMappingExceptionResolver.php 2014-07-02 09:43:40 UTC (rev 161) @@ -33,11 +33,6 @@ private $defaultErrorView; /** - * @var string - */ - private $ajaxViewNameSuffix = '.ajax'; - - /** * * @return array */ @@ -102,23 +97,6 @@ $viewName = $this->defaultErrorView; } - return $viewName ? new Bee_MVC_ModelAndView(array(self::MODEL_HANDLER_EXCEPTION_KEY => $ex), $this->modifyResolvedViewName($viewName, $request)) : false; + return $viewName ? new Bee_MVC_ModelAndView(array(self::MODEL_HANDLER_EXCEPTION_KEY => $ex), $viewName) : false; } - - /** - * @param $viewName - * @param Bee_MVC_IHttpRequest $request - * @return string - */ - protected function modifyResolvedViewName($viewName, Bee_MVC_IHttpRequest $request) { - return $this->isAjaxRequest($request) ? $viewName . $this->ajaxViewNameSuffix : $viewName; - } - - /** - * @param Bee_MVC_IHttpRequest $request - * @return bool - */ - protected function isAjaxRequest(Bee_MVC_IHttpRequest $request) { - return $request->getHeader('X-Requested-With') == 'XMLHttpRequest'; - } } Modified: trunk/framework/Bee/MVC/ViewResolver/Basic.php =================================================================== --- trunk/framework/Bee/MVC/ViewResolver/Basic.php 2014-07-02 08:10:59 UTC (rev 160) +++ trunk/framework/Bee/MVC/ViewResolver/Basic.php 2014-07-02 09:43:40 UTC (rev 161) @@ -18,20 +18,40 @@ /** * Basic implementation of the Bee_MVC_IViewResolver interface. Uses a Bee_IContext for view name resolution, looking up * beans of type Bee_MVC_IView by using the view name as bean name. - * + * * @author Benjamin Hartmann * @author Michael Plomer <mic...@it...> */ class Bee_MVC_ViewResolver_Basic implements Bee_MVC_IViewResolver { /** + * @var Logger + */ + protected $log; + + /** + * @return Logger + */ + protected function getLog() { + if (!$this->log) { + $this->log = Logger::getLogger(get_class($this)); + } + return $this->log; + } + + /** * Enter description here... * * @var Bee_IContext */ private $context; - + /** + * @var string + */ + private $ajaxViewNameSuffix = '.ajax'; + + /** * Enter description here... * * @param Bee_IContext $context @@ -40,7 +60,7 @@ public function setContext(Bee_IContext $context) { $this->context = $context; } - + /** * Enter description here... * @@ -49,10 +69,42 @@ public function getContext() { return $this->context; } - - public function resolveViewName($viewName) { + + /** + * @param String $viewName + * @param Bee_MVC_IHttpRequest $request + * @return Bee_MVC_IView|Object + */ + public function resolveViewName($viewName, Bee_MVC_IHttpRequest $request) { + $modifiedViewName = $this->modifyViewName($viewName, $request); + if ($modifiedViewName != $viewName) { + try { + return $this->getViewForName($viewName); + } catch (Bee_Context_BeansException $bex) { + if($this->getLog()->isDebugEnabled()) { + $this->getLog()->debug('Modified view name "' . $modifiedViewName . '" not found, trying base bean name "' . $viewName . '"', $bex); + } + } + } + return $this->getViewForName($viewName); + } + + /** + * @param string $viewName + * @return Bee_MVC_IView + */ + protected function getViewForName($viewName) { return $this->context->getBean($viewName, 'Bee_MVC_IView'); } -} -?> \ No newline at end of file + /** + * Modify the view name according to request specifics. By default, the suffix '.ajax' is appended to the view names + * for AJAX requests. Otherwise, the view name is left untouched. + * @param $viewName + * @param Bee_MVC_IHttpRequest $request + * @return string + */ + protected function modifyViewName($viewName, Bee_MVC_IHttpRequest $request) { + return $request->getAjax() ? $viewName . $this->ajaxViewNameSuffix : $viewName; + } +} \ No newline at end of file Modified: trunk/framework/Bee/MVC/ViewResolver/Loopback.php =================================================================== --- trunk/framework/Bee/MVC/ViewResolver/Loopback.php 2014-07-02 08:10:59 UTC (rev 160) +++ trunk/framework/Bee/MVC/ViewResolver/Loopback.php 2014-07-02 09:43:40 UTC (rev 161) @@ -1,18 +1,15 @@ <?php class Bee_MVC_ViewResolver_Loopback extends Bee_MVC_ViewResolver_Basic implements Bee_Context_Config_IContextAware{ - /** - * Callback that supplies the owning context to a bean instance. - * <p>Invoked after the population of normal bean properties - * but before an initialization callback such as - * {@link InitializingBean#afterPropertiesSet()} or a custom init-method. - * @param $context owning Context (never <code>null</code>). - * The bean can immediately call methods on the context. - */ + /** + * Callback that supplies the owning context to a bean instance. + * <p>Invoked after the population of normal bean properties + * but before an initialization callback such as + * {@link InitializingBean#afterPropertiesSet()} or a custom init-method. + * @param Bee_IContext $context owning context (never <code>null</code>). + * The bean can immediately call methods on the context. + */ public function setBeeContext(Bee_IContext $context) { $this->setContext($context); } - - } -?> \ 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-02 08:11:06
|
Revision: 160 http://sourceforge.net/p/beeframework/code/160 Author: m_plomer Date: 2014-07-02 08:10:59 +0000 (Wed, 02 Jul 2014) Log Message: ----------- - MVC Dispatcher: introduced IRequestBuilder, DefaultRequestBuilder - MVC/Views: RequestStoringRedirectView and RedirectedRequestBuilder Modified Paths: -------------- trunk/framework/Bee/MVC/Dispatcher.php trunk/framework/Bee/MVC/FilterChainProxy.php trunk/framework/Bee/MVC/HttpRequest.php trunk/framework/Bee/MVC/IFilter.php trunk/framework/Bee/MVC/View/Redirect.php trunk/framework/Bee/Security/Context/HttpSessionIntegrationFilter.php trunk/framework/Bee/Utils/HashManager.php Added Paths: ----------- trunk/framework/Bee/MVC/DefaultRequestBuilder.php trunk/framework/Bee/MVC/IRequestBuilder.php trunk/framework/Bee/MVC/Redirect/ trunk/framework/Bee/MVC/Redirect/AbstractRedirectStorage.php trunk/framework/Bee/MVC/Redirect/RedirectInfoStorage.php trunk/framework/Bee/MVC/Redirect/RedirectRequestStorage.php trunk/framework/Bee/MVC/Redirect/RedirectedRequestBuilder.php trunk/framework/Bee/MVC/View/RequestStoringRedirectView.php Added: trunk/framework/Bee/MVC/DefaultRequestBuilder.php =================================================================== --- trunk/framework/Bee/MVC/DefaultRequestBuilder.php (rev 0) +++ trunk/framework/Bee/MVC/DefaultRequestBuilder.php 2014-07-02 08:10:59 UTC (rev 160) @@ -0,0 +1,19 @@ +<?php + +namespace Bee\MVC; +use Bee_MVC_HttpRequest; + + +/** + * Class DefaultRequestBuilder + * @package Bee\MVC + */ +class DefaultRequestBuilder implements IRequestBuilder { + + /** + * @return \Bee_MVC_IHttpRequest + */ + public function buildRequestObject() { + return new Bee_MVC_HttpRequest(); + } +} \ No newline at end of file Modified: trunk/framework/Bee/MVC/Dispatcher.php =================================================================== --- trunk/framework/Bee/MVC/Dispatcher.php 2014-07-01 16:04:58 UTC (rev 159) +++ trunk/framework/Bee/MVC/Dispatcher.php 2014-07-02 08:10:59 UTC (rev 160) @@ -14,6 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +use Bee\MVC\DefaultRequestBuilder; /** * The dispatcher is the main entry point into an Bee MVC application. It acts as a front controller, i.e. it handles incoming @@ -41,6 +42,8 @@ */ class Bee_MVC_Dispatcher implements Bee_MVC_IFilterChain { + const REQUEST_BUILDER_BEAN_NAME = 'requestBuilder'; + const HANDLER_MAPPING_BEAN_NAME = 'handlerMapping'; const VIEW_RESOLVER_BEAN_NAME = 'viewResolver'; @@ -83,6 +86,10 @@ */ private $context; + /** + * @var \Bee\MVC\IRequestBuilder + */ + private $requestBuilder; /** * The handler mapping used by this dispatcher @@ -180,7 +187,26 @@ * @return void */ protected function init() { - self::$currentRequest = $this->buildRequestObject(); + if ($this->context->containsBean(Bee_MVC_Session_DispatcherAdapter::SESSION_HANDLER_NAME)) { + $this->getLog()->info('custom session handler configured, setting it as PHP session_set_save_handler()'); + $sessionAdapter = new Bee_MVC_Session_DispatcherAdapter($this->context); + session_set_save_handler( + array(&$sessionAdapter, "open"), + array(&$sessionAdapter, "close"), + array(&$sessionAdapter, "read"), + array(&$sessionAdapter, "write"), + array(&$sessionAdapter, "destroy"), + array(&$sessionAdapter, "gc") + ); + } + + try { + $this->requestBuilder = $this->context->getBean(self::HANDLER_MAPPING_BEAN_NAME, '\Bee\MVC\IRequestBuilder'); + } catch (Bee_Context_NoSuchBeanDefinitionException $ex) { + $this->getLog()->info('no RequestBuilder configured, using DefaultRequestBuilder'); + $this->requestBuilder = new DefaultRequestBuilder(); + } + $this->handlerMapping = $this->context->getBean(self::HANDLER_MAPPING_BEAN_NAME, 'Bee_MVC_IHandlerMapping'); $this->viewResolver = $this->context->getBean(self::VIEW_RESOLVER_BEAN_NAME, 'Bee_MVC_IViewResolver'); @@ -196,18 +222,7 @@ $this->getLog()->info('no exception resolver configured'); } - if ($this->context->containsBean(Bee_MVC_Session_DispatcherAdapter::SESSION_HANDLER_NAME)) { - $this->getLog()->info('custom session handler configured, setting it as PHP session_set_save_handler()'); - $sessionAdapter = new Bee_MVC_Session_DispatcherAdapter($this->context); - session_set_save_handler( - array(&$sessionAdapter, "open"), - array(&$sessionAdapter, "close"), - array(&$sessionAdapter, "read"), - array(&$sessionAdapter, "write"), - array(&$sessionAdapter, "destroy"), - array(&$sessionAdapter, "gc") - ); - } + self::$currentRequest = $this->requestBuilder->buildRequestObject(); } /** @@ -327,15 +342,6 @@ } } } - - /** - * Enter description here... - * - * @return Bee_MVC_HttpRequest - */ - private function buildRequestObject() { - return new Bee_MVC_HttpRequest(); - } } class B_DISPATCHER extends Bee_MVC_Dispatcher { Modified: trunk/framework/Bee/MVC/FilterChainProxy.php =================================================================== --- trunk/framework/Bee/MVC/FilterChainProxy.php 2014-07-01 16:04:58 UTC (rev 159) +++ trunk/framework/Bee/MVC/FilterChainProxy.php 2014-07-02 08:10:59 UTC (rev 160) @@ -75,15 +75,15 @@ */ private $currentPosition = 0; - /** - * @param Bee_MVC_IFilterChain $origFilterChain - * @param Bee_MVC_IFilter[] $filters - * @return void - */ + /** + * @param Bee_MVC_IFilterChain $origFilterChain + * @param Bee_MVC_IFilter[] $filters + */ public function __construct(Bee_MVC_IFilterChain $origFilterChain, array $filters) { $this->origFilterChain = $origFilterChain; $this->filters = $filters; } + public function doFilter(Bee_MVC_IHttpRequest $request) { if($this->currentPosition == sizeof($this->filters)) { $this->origFilterChain->doFilter($request); @@ -94,5 +94,4 @@ } } -} -?> \ No newline at end of file +} \ No newline at end of file Modified: trunk/framework/Bee/MVC/HttpRequest.php =================================================================== --- trunk/framework/Bee/MVC/HttpRequest.php 2014-07-01 16:04:58 UTC (rev 159) +++ trunk/framework/Bee/MVC/HttpRequest.php 2014-07-02 08:10:59 UTC (rev 160) @@ -103,17 +103,19 @@ } /** - * Returns the PATH_INFO (i.e. any additional path trailing the actual PHP file) + * Check whether the given parameter exists * - * @return string + * @param $name + * @return bool */ public function hasParameter($name) { return array_key_exists($name, $this->parameters); } /** - * Returns the PATH_INFO (i.e. any additional path trailing the actual PHP file) + * Returns the value of the given parameter, or null if no parameter with that name exists * + * @param string $name * @return string */ public function getParameter($name) { @@ -122,9 +124,14 @@ // $val = $val[0]; // } // return $val; - return array_key_exists($name, $this->parameters) ? $this->parameters[$name] : null; + return $this->hasParameter($name) ? $this->parameters[$name] : null; } + /** + * Set the value of the given parameter + * @param $name + * @param $value + */ public function setParameter($name, $value) { if(is_null($value)) { unset($this->parameters[$name]); @@ -162,9 +169,6 @@ } public function getHeaderNames() { - if(is_null($this->headerNames)) { - $this->headerNames = array_keys($this->headers); - } return $this->headerNames; } Modified: trunk/framework/Bee/MVC/IFilter.php =================================================================== --- trunk/framework/Bee/MVC/IFilter.php 2014-07-01 16:04:58 UTC (rev 159) +++ trunk/framework/Bee/MVC/IFilter.php 2014-07-02 08:10:59 UTC (rev 160) @@ -25,4 +25,3 @@ public function doFilter(Bee_MVC_IHttpRequest $request, Bee_MVC_IFilterChain $filterChain); } -?> \ No newline at end of file Added: trunk/framework/Bee/MVC/IRequestBuilder.php =================================================================== --- trunk/framework/Bee/MVC/IRequestBuilder.php (rev 0) +++ trunk/framework/Bee/MVC/IRequestBuilder.php 2014-07-02 08:10:59 UTC (rev 160) @@ -0,0 +1,16 @@ +<?php + +namespace Bee\MVC; + +/** + * Interface IRequestBuilder + * + * @package Bee\MVC + */ +interface IRequestBuilder { + + /** + * @return \Bee_MVC_IHttpRequest + */ + public function buildRequestObject(); +} \ No newline at end of file Added: trunk/framework/Bee/MVC/Redirect/AbstractRedirectStorage.php =================================================================== --- trunk/framework/Bee/MVC/Redirect/AbstractRedirectStorage.php (rev 0) +++ trunk/framework/Bee/MVC/Redirect/AbstractRedirectStorage.php 2014-07-02 08:10:59 UTC (rev 160) @@ -0,0 +1,48 @@ +<?php + +namespace Bee\MVC\Redirect; +use Bee\Utils\HashManager; +use Bee_MVC_IHttpRequest; + +/** + * Class AbstractRedirectStorage + * @package Bee\MVC\Redirect + */ +abstract class AbstractRedirectStorage { + + /** + * @var string + */ + private $id = false; + + /** + * @return string + */ + public function getId() { + if(!$this->id) { + $this->id = HashManager::createHash(); + } + return $this->id; + } + + /** + * @param array $model + * @return string + */ + public final function storeData(array $model = array()) { + $this->doStoreData($model); + $_SESSION[$this->getId()] = $this; + return $this->getId(); + } + + /** + * @param array $model + * @return mixed + */ + abstract protected function doStoreData(array $model); + + /** + * @return \Bee_MVC_IHttpRequest + */ + abstract public function restoreRequestObject(); +} \ No newline at end of file Added: trunk/framework/Bee/MVC/Redirect/RedirectInfoStorage.php =================================================================== --- trunk/framework/Bee/MVC/Redirect/RedirectInfoStorage.php (rev 0) +++ trunk/framework/Bee/MVC/Redirect/RedirectInfoStorage.php 2014-07-02 08:10:59 UTC (rev 160) @@ -0,0 +1,54 @@ +<?php + +namespace Bee\MVC\Redirect; +use Bee_MVC_HttpRequest; +use Bee_MVC_IHttpRequest; + + +/** + * Class RedirectInfoStorage + * @package Bee\MVC\View + */ +class RedirectInfoStorage extends AbstractRedirectStorage { + + /** + * @var array + */ + private $storeModelKeys = array(); + + /** + * @var array + */ + private $storedData; + + /** + * @param array $storeModelKeys + */ + public function setStoreModelKeys(array $storeModelKeys) { + $this->storeModelKeys = $storeModelKeys; + } + + /** + * @return array + */ + public function getStoreModelKeys() { + return $this->storeModelKeys; + } + + /** + * @param array $model + * @return mixed + */ + protected function doStoreData(array $model = array()) { + $this->storedData = array_intersect_key($model, array_fill_keys($this->storeModelKeys, true)); + } + + /** + * @return \Bee_MVC_IHttpRequest + */ + public function restoreRequestObject() { + $request = new Bee_MVC_HttpRequest(); + $request->addParameters($this->storedData); + return $request; + } +} \ No newline at end of file Added: trunk/framework/Bee/MVC/Redirect/RedirectRequestStorage.php =================================================================== --- trunk/framework/Bee/MVC/Redirect/RedirectRequestStorage.php (rev 0) +++ trunk/framework/Bee/MVC/Redirect/RedirectRequestStorage.php 2014-07-02 08:10:59 UTC (rev 160) @@ -0,0 +1,61 @@ +<?php + +namespace Bee\MVC\Redirect; +use Bee_MVC_IHttpRequest; +use Bee_Utils_Env; + + +/** + * Class RedirectRequestStorage + * @package Bee\MVC\View + */ +class RedirectRequestStorage extends AbstractRedirectStorage { + + /** + * @var array + */ + private $getParams; + + /** + * @var array + */ + private $postParams; + + /** + * @var array + */ + private $requestParams; + + /** + * @var array + */ + private $serverVars; + + /** + * @var array + */ + private $headers; + + /** + * @param array $model + * @return mixed + */ + protected function doStoreData(array $model = array()) { + $this->getParams = $_GET; + $this->postParams = $_POST; + $this->requestParams = $_REQUEST; + $this->serverVars = $_SERVER; + $this->headers = Bee_Utils_Env::getRequestHeaders(); + } + + /** + * @return \Bee_MVC_IHttpRequest + */ + public function restoreRequestObject() { + $_GET = $this->getParams; + $_POST = $this->postParams; + $_REQUEST = $this->requestParams; + $_SERVER = $this->serverVars; + return new \Bee_MVC_HttpRequest(null, null, null, $this->headers); + } +} \ No newline at end of file Added: trunk/framework/Bee/MVC/Redirect/RedirectedRequestBuilder.php =================================================================== --- trunk/framework/Bee/MVC/Redirect/RedirectedRequestBuilder.php (rev 0) +++ trunk/framework/Bee/MVC/Redirect/RedirectedRequestBuilder.php 2014-07-02 08:10:59 UTC (rev 160) @@ -0,0 +1,53 @@ +<?php + +namespace Bee\MVC\Redirect; +use Bee\MVC\IRequestBuilder; + +/** + * Class RedirectedRequestBuilder - restores a previously stored request from the session if applicable, or creates a + * default request otherwise. + * + * @package Bee\MVC\Redirect + */ +class RedirectedRequestBuilder implements IRequestBuilder { + + private $requestIdParamName = 'storedRequestId'; + + /** + * @param string $requestIdParamName + */ + public function setRequestIdParamName($requestIdParamName) { + $this->requestIdParamName = $requestIdParamName; + } + + /** + * @return string + */ + public function getRequestIdParamName() { + return $this->requestIdParamName; + } + + /** + * @return \Bee_MVC_IHttpRequest + */ + public function buildRequestObject() { + if(array_key_exists($this->requestIdParamName, $_GET)) { + $id = $_GET[$this->requestIdParamName]; + if(array_key_exists($id, $_SESSION) && ($storage = $_SESSION[$id]) instanceof AbstractRedirectStorage) { + /** @var AbstractRedirectStorage $storage */ + return $storage->restoreRequestObject(); + } + $this->throwNotFoundException($id); + } + return new \Bee_MVC_HttpRequest(); + } + + /** + * @param $id + * @throws \Exception + */ + protected function throwNotFoundException($id) { + throw new \Exception('Stored request with ID ' . $id . ' not found'); + } + +} \ No newline at end of file Modified: trunk/framework/Bee/MVC/View/Redirect.php =================================================================== --- trunk/framework/Bee/MVC/View/Redirect.php 2014-07-01 16:04:58 UTC (rev 159) +++ trunk/framework/Bee/MVC/View/Redirect.php 2014-07-02 08:10:59 UTC (rev 160) @@ -54,10 +54,7 @@ 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); + $redirectUrl .= (strpos($redirectUrl, '?') !== false ? '&' : '?') . http_build_query($params); } header('Location: ' . $redirectUrl, true, $this->getStatusCode()); } Added: trunk/framework/Bee/MVC/View/RequestStoringRedirectView.php =================================================================== --- trunk/framework/Bee/MVC/View/RequestStoringRedirectView.php (rev 0) +++ trunk/framework/Bee/MVC/View/RequestStoringRedirectView.php 2014-07-02 08:10:59 UTC (rev 160) @@ -0,0 +1,68 @@ +<?php + +namespace Bee\MVC\View; +use Bee\MVC\Redirect\AbstractRedirectStorage; +use Bee_MVC_View_Redirect; + +/** + * Class RequestStoringRedirectView + * @package Bee\MVC\View + */ +class RequestStoringRedirectView extends \Bee_MVC_View_Redirect { + + /** + * @var string + */ + private $requestIdParamName = 'requestId'; + + /** + * @var AbstractRedirectStorage[] + */ + private $stores = array(); + + /** + * @param string $requestIdParamName + */ + public function setRequestIdParamName($requestIdParamName) { + $this->requestIdParamName = $requestIdParamName; + } + + /** + * @return string + */ + public function getRequestIdParamName() { + return $this->requestIdParamName; + } + + /** + * @param array $stores + */ + public function setStores(array $stores) { + $this->stores = $stores; + } + + /** + * @return array + */ + public function getStores() { + return $this->stores; + } + + public function render(array $model = array()) { + $this->augmentModel($model); + $getParams = array_key_exists(self::MODEL_KEY_GET_PARAMS, $model) ? $model[self::MODEL_KEY_GET_PARAMS] : array(); + foreach($this->stores as $paramName => $store) { + $getParams[$paramName] = $store->storeData($model); + } + $model[self::MODEL_KEY_GET_PARAMS] = $getParams; + parent::render($model); + } + + /** + * Extension point for subclasses + * @param array $model + */ + protected function augmentModel(array &$model) { + // do nothing by default + } +} \ No newline at end of file Modified: trunk/framework/Bee/Security/Context/HttpSessionIntegrationFilter.php =================================================================== --- trunk/framework/Bee/Security/Context/HttpSessionIntegrationFilter.php 2014-07-01 16:04:58 UTC (rev 159) +++ trunk/framework/Bee/Security/Context/HttpSessionIntegrationFilter.php 2014-07-02 08:10:59 UTC (rev 160) @@ -69,4 +69,3 @@ } } -?> \ No newline at end of file Modified: trunk/framework/Bee/Utils/HashManager.php =================================================================== --- trunk/framework/Bee/Utils/HashManager.php 2014-07-01 16:04:58 UTC (rev 159) +++ trunk/framework/Bee/Utils/HashManager.php 2014-07-02 08:10:59 UTC (rev 160) @@ -57,8 +57,8 @@ return $row['hash']; } catch (Exception $e) { - $hash = $this->createHash(); - if ($this->persistHash($this->createHash(), $id, $group)) { + $hash = self::createHash(); + if ($this->persistHash(self::createHash(), $id, $group)) { return $hash; } return false; @@ -93,7 +93,10 @@ } } - private function createHash() { + /** + * @return mixed + */ + public static function createHash() { return preg_replace('/\./', 'b', uniqid('', true)); } 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 16:05:06
|
Revision: 159 http://sourceforge.net/p/beeframework/code/159 Author: m_plomer Date: 2014-07-01 16:04:58 +0000 (Tue, 01 Jul 2014) Log Message: ----------- - MVC/Views: extended Redirect view Modified Paths: -------------- trunk/framework/Bee/MVC/IHandlerExceptionResolver.php trunk/framework/Bee/MVC/SimpleMappingExceptionResolver.php Modified: trunk/framework/Bee/MVC/IHandlerExceptionResolver.php =================================================================== --- trunk/framework/Bee/MVC/IHandlerExceptionResolver.php 2014-07-01 15:18:20 UTC (rev 158) +++ trunk/framework/Bee/MVC/IHandlerExceptionResolver.php 2014-07-01 16:04:58 UTC (rev 159) @@ -25,6 +25,4 @@ * @return Bee_MVC_ModelAndView */ public function resolveException(Bee_MVC_IHttpRequest $request, Bee_MVC_IController $handler = null, Exception $ex); - } -?> \ No newline at end of file Modified: trunk/framework/Bee/MVC/SimpleMappingExceptionResolver.php =================================================================== --- trunk/framework/Bee/MVC/SimpleMappingExceptionResolver.php 2014-07-01 15:18:20 UTC (rev 158) +++ trunk/framework/Bee/MVC/SimpleMappingExceptionResolver.php 2014-07-01 16:04:58 UTC (rev 159) @@ -1,4 +1,5 @@ <?php + /* * Copyright 2008-2010 the original author or authors. * @@ -16,40 +17,45 @@ */ class Bee_MVC_SimpleMappingExceptionResolver implements Bee_MVC_IHandlerExceptionResolver { - + const MODEL_HANDLER_EXCEPTION_KEY = 'handler_excpetion'; - + /** - * + * * @var array */ private $exceptionMapping; - + /** - * + * * @var String */ private $defaultErrorView; - + /** - * + * @var string + */ + private $ajaxViewNameSuffix = '.ajax'; + + /** + * * @return array */ public final function getExceptionMapping() { return $this->exceptionMapping; } - + /** - * + * * @param array $exceptionMapping * @return void */ public final function setExceptionMapping(array $exceptionMapping) { $this->exceptionMapping = $exceptionMapping; } - + /** - * + * * @return String */ public final function getDefaultErrorView() { @@ -57,7 +63,7 @@ } /** - * + * * @param String $defaultErrorView * @return void */ @@ -65,24 +71,54 @@ $this->defaultErrorView = $defaultErrorView; } + /** + * @param Bee_MVC_IHttpRequest $request + * @param Bee_MVC_IController $handler + * @param Exception $ex + * @return Bee_MVC_ModelAndView|bool + */ public function resolveException(Bee_MVC_IHttpRequest $request, Bee_MVC_IController $handler = null, Exception $ex) { - $exceptionClass = get_class($ex); + $viewName = false; - if(is_array($this->exceptionMapping) && array_key_exists($exceptionClass, $this->exceptionMapping)) { - $viewName = $this->exceptionMapping[$exceptionClass]; + + // can the mapping be resolved directly? + if (is_array($this->exceptionMapping)) { + $exceptionClass = get_class($ex); + // can the mapping be resolved directly? + if (array_key_exists($exceptionClass, $this->exceptionMapping)) { + $viewName = $this->exceptionMapping[$exceptionClass]; + } else { + // try to find a mapping for a superclass + foreach ($this->exceptionMapping as $parentClass => $mappedSolution) { + if (is_subclass_of($exceptionClass, $parentClass)) { + $viewName = $mappedSolution; + break; + } + } + } } - if(!$viewName && Bee_Utils_Strings::hasText($this->defaultErrorView)) { + + if (!$viewName && Bee_Utils_Strings::hasText($this->defaultErrorView)) { $viewName = $this->defaultErrorView; } - - if($viewName) { - $model = array( - self::MODEL_HANDLER_EXCEPTION_KEY => $ex - ); - return new Bee_MVC_ModelAndView($model, $viewName); - } - return false; + + return $viewName ? new Bee_MVC_ModelAndView(array(self::MODEL_HANDLER_EXCEPTION_KEY => $ex), $this->modifyResolvedViewName($viewName, $request)) : false; } - + + /** + * @param $viewName + * @param Bee_MVC_IHttpRequest $request + * @return string + */ + protected function modifyResolvedViewName($viewName, Bee_MVC_IHttpRequest $request) { + return $this->isAjaxRequest($request) ? $viewName . $this->ajaxViewNameSuffix : $viewName; + } + + /** + * @param Bee_MVC_IHttpRequest $request + * @return bool + */ + protected function isAjaxRequest(Bee_MVC_IHttpRequest $request) { + return $request->getHeader('X-Requested-With') == 'XMLHttpRequest'; + } } -?> \ 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-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-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 07:45:33
|
Revision: 156 http://sourceforge.net/p/beeframework/code/156 Author: m_plomer Date: 2014-07-01 07:45:31 +0000 (Tue, 01 Jul 2014) Log Message: ----------- - MVC: fixed header names handling in HttpRequest - CORE: completely disabled autoloader for now (may return for loading proxies) - Composer: fixed PEAR dependencies Modified Paths: -------------- trunk/framework/Bee/Framework.php trunk/framework/Bee/MVC/HttpRequest.php trunk/framework/composer.json Modified: trunk/framework/Bee/Framework.php =================================================================== --- trunk/framework/Bee/Framework.php 2014-06-24 18:21:20 UTC (rev 155) +++ trunk/framework/Bee/Framework.php 2014-07-01 07:45:31 UTC (rev 156) @@ -83,7 +83,7 @@ require_once dirname(__FILE__) . '/Cache/Manager.php'; - spl_autoload_register(array(__CLASS__, 'autoload')); +// spl_autoload_register(array(__CLASS__, 'autoload')); register_shutdown_function(array(__CLASS__, 'shutdown')); // Bee_Cache_Manager::init(); @@ -117,6 +117,7 @@ * * @param string $className * @return boolean + * @deprecated */ public static function autoload($className) { Modified: trunk/framework/Bee/MVC/HttpRequest.php =================================================================== --- trunk/framework/Bee/MVC/HttpRequest.php 2014-06-24 18:21:20 UTC (rev 155) +++ trunk/framework/Bee/MVC/HttpRequest.php 2014-07-01 07:45:31 UTC (rev 156) @@ -157,11 +157,13 @@ } public function getHeader($name) { - return $this->headers[strtoupper($name)]; + $name = strtoupper($name); + return array_key_exists($name, $this->headers) ? $this->headers[$name] : false; } public function getHeaderNames() { if(is_null($this->headerNames)) { + $this->headerNames = array_keys($this->headers); } return $this->headerNames; } @@ -190,4 +192,3 @@ return new Bee_MVC_HttpRequest($params, $pathInfo, $method, $headers); } } -?> \ No newline at end of file Modified: trunk/framework/composer.json =================================================================== --- trunk/framework/composer.json 2014-06-24 18:21:20 UTC (rev 155) +++ trunk/framework/composer.json 2014-07-01 07:45:31 UTC (rev 156) @@ -23,9 +23,11 @@ "require": { "php": ">=5.3", "niktux/addendum": "0.4.1", - "apache/log4php": "~2.3@stable", - "pear-pear/I18N_UnicodeNormalizer": "*@stable" + "apache/log4php": "~2.3@stable" }, + "require-dev": { + "pear-pear.php.net/I18N_UnicodeNormalizer": "*@stable" + }, "autoload": { "psr-0": { "Bee": "" This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <m_p...@us...> - 2014-06-24 18:21:21
|
Revision: 155 http://sourceforge.net/p/beeframework/code/155 Author: m_plomer Date: 2014-06-24 18:21:20 +0000 (Tue, 24 Jun 2014) Log Message: ----------- misc changes Modified Paths: -------------- trunk/framework/Bee/Filesystem/MimeDetector.php trunk/framework/Bee/Persistence/Pdo/SimpleDaoBase.php Modified: trunk/framework/Bee/Filesystem/MimeDetector.php =================================================================== --- trunk/framework/Bee/Filesystem/MimeDetector.php 2014-06-18 13:10:26 UTC (rev 154) +++ trunk/framework/Bee/Filesystem/MimeDetector.php 2014-06-24 18:21:20 UTC (rev 155) @@ -20,10 +20,6 @@ private static $types; - private static function parseMimeTypeFile() { - - } - /** * Enter description here... * @@ -31,6 +27,12 @@ * @return String */ public static function detect($filename) { + // todo: +// $finfo = finfo_open(FILEINFO_MIME_TYPE); // return mime type ala mimetype extension +// foreach (glob("*") as $filename) { +// echo finfo_file($finfo, $filename) . "\n"; +// } +// finfo_close($finfo); if(is_null(self::$types)) { self::$types = Bee_Cache_Manager::retrieveCachable(new Bee_Filesystem_MimedictionaryCacheable()); } @@ -82,4 +84,3 @@ return $result; } } -?> \ No newline at end of file Modified: trunk/framework/Bee/Persistence/Pdo/SimpleDaoBase.php =================================================================== --- trunk/framework/Bee/Persistence/Pdo/SimpleDaoBase.php 2014-06-18 13:10:26 UTC (rev 154) +++ trunk/framework/Bee/Persistence/Pdo/SimpleDaoBase.php 2014-06-24 18:21:20 UTC (rev 155) @@ -16,6 +16,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +use PDO; /** * User: mp @@ -41,23 +42,35 @@ } /** - * @var \PDO + * @var PDO */ private $pdoConnection; - public function __construct(\PDO $pdoConnection) { - self::getLog()->info('DAO constructed, got PDO connection'); - $this->pdoConnection = $pdoConnection; + /** + * @param PDO $pdoConnection + */ + public function __construct(PDO $pdoConnection = null) { + if(!is_null($pdoConnection)) { + self::getLog()->info('DAO constructed, got PDO connection'); + $this->pdoConnection = $pdoConnection; + } } /** - * @return \PDO + * @return PDO */ public function getPdoConnection() { return $this->pdoConnection; } /** + * @param PDO $pdoConnection + */ + public function setPdoConnection(PDO $pdoConnection) { + $this->pdoConnection = $pdoConnection; + } + + /** * @param callback $func * @throws \Exception * @return mixed This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <m_p...@us...> - 2014-06-18 13:10:35
|
Revision: 154 http://sourceforge.net/p/beeframework/code/154 Author: m_plomer Date: 2014-06-18 13:10:26 +0000 (Wed, 18 Jun 2014) Log Message: ----------- tag latest changes Added Paths: ----------- tags/0.9.27/ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <m_p...@us...> - 2014-06-18 13:09:13
|
Revision: 153 http://sourceforge.net/p/beeframework/code/153 Author: m_plomer Date: 2014-06-18 13:09:08 +0000 (Wed, 18 Jun 2014) Log Message: ----------- - numeric-keys parameter introduced for arrays Modified Paths: -------------- trunk/framework/Bee/Context/Config/ArrayValue.php trunk/framework/Bee/Context/Xml/ParserDelegate.php Modified: trunk/framework/Bee/Context/Config/ArrayValue.php =================================================================== --- trunk/framework/Bee/Context/Config/ArrayValue.php 2014-06-18 12:24:38 UTC (rev 152) +++ trunk/framework/Bee/Context/Config/ArrayValue.php 2014-06-18 13:09:08 UTC (rev 153) @@ -35,10 +35,13 @@ private $associative = false; - public function __construct(array &$sourceArray, $mergeEnabled = false, $associative = false) { + private $numericKeys = false; + + public function __construct(array &$sourceArray, $mergeEnabled = false, $associative = false, $numericKeys = false) { $this->sourceArray =& $sourceArray; $this->mergeEnabled = $mergeEnabled; $this->associative = $associative; + $this->numericKeys = $numericKeys; } /** @@ -83,18 +86,23 @@ function merge(Traversable $parent) { $tmpArray = array(); $parentAssoc = $parent instanceof Bee_Context_Config_ArrayValue && $parent->associative; - foreach ($parent as $key => $value) { - if($parentAssoc) { - $tmpArray[$key] = $value; - } else { - array_push($tmpArray, $value); + if($parentAssoc && $this->associative && $parent->numericKeys && $this->numericKeys) { + $tmpArray = array_replace($parent->sourceArray, $this->sourceArray); + ksort($tmpArray); + } else { + foreach ($parent as $key => $value) { + if($parentAssoc) { + $tmpArray[$key] = $value; + } else { + array_push($tmpArray, $value); + } } - } - foreach ($this->sourceArray as $key => $value) { - if($this->associative) { - $tmpArray[$key] = $value; - } else { - array_push($tmpArray, $value); + foreach ($this->sourceArray as $key => $value) { + if($this->associative) { + $tmpArray[$key] = $value; + } else { + array_push($tmpArray, $value); + } } } $this->sourceArray =& $tmpArray; Modified: trunk/framework/Bee/Context/Xml/ParserDelegate.php =================================================================== --- trunk/framework/Bee/Context/Xml/ParserDelegate.php 2014-06-18 12:24:38 UTC (rev 152) +++ trunk/framework/Bee/Context/Xml/ParserDelegate.php 2014-06-18 13:09:08 UTC (rev 153) @@ -647,7 +647,7 @@ $this->readerContext->error('Must not combine \'assoc-item\' elements and other elements in the same \'array\' element!', $collectionEle); } } - return new Bee_Context_Config_ArrayValue($list, $this->parseMergeAttribute($collectionEle), $assoc); + return new Bee_Context_Config_ArrayValue($list, $this->parseMergeAttribute($collectionEle), $assoc, $numericKeys); } public function parseMergeAttribute(DOMElement $collectionElement) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <m_p...@us...> - 2014-06-18 12:24:41
|
Revision: 152 http://sourceforge.net/p/beeframework/code/152 Author: m_plomer Date: 2014-06-18 12:24:38 +0000 (Wed, 18 Jun 2014) Log Message: ----------- tagged latest changes Added Paths: ----------- tags/0.9.26/ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <m_p...@us...> - 2014-06-18 12:23:35
|
Revision: 151 http://sourceforge.net/p/beeframework/code/151 Author: m_plomer Date: 2014-06-18 12:23:30 +0000 (Wed, 18 Jun 2014) Log Message: ----------- - moved construction of current Request object from dispatch to init phase Modified Paths: -------------- trunk/framework/Bee/Context/Xml/IConstants.php trunk/framework/Bee/Context/Xml/ParserDelegate.php trunk/framework/Bee/Context/Xml.php trunk/framework/bee-beans-1.2.xsd Modified: trunk/framework/Bee/Context/Xml/IConstants.php =================================================================== --- trunk/framework/Bee/Context/Xml/IConstants.php 2014-04-11 13:07:06 UTC (rev 150) +++ trunk/framework/Bee/Context/Xml/IConstants.php 2014-06-18 12:23:30 UTC (rev 151) @@ -45,4 +45,5 @@ const KEY_ATTRIBUTE = 'key'; + const NUMERIC_KEYS_ATTRIBUTE = 'numeric-keys'; } Modified: trunk/framework/Bee/Context/Xml/ParserDelegate.php =================================================================== --- trunk/framework/Bee/Context/Xml/ParserDelegate.php 2014-04-11 13:07:06 UTC (rev 150) +++ trunk/framework/Bee/Context/Xml/ParserDelegate.php 2014-06-18 12:23:30 UTC (rev 151) @@ -625,6 +625,8 @@ public function parseArrayElement(DOMElement $collectionEle, Bee_Context_Config_IBeanDefinition $bd) { $defaultType = $collectionEle->getAttribute(self::VALUE_TYPE_ATTRIBUTE); + $numericKeys = $collectionEle->hasAttribute(self::NUMERIC_KEYS_ATTRIBUTE) ? filter_var($collectionEle->getAttribute(self::NUMERIC_KEYS_ATTRIBUTE), FILTER_VALIDATE_BOOLEAN) : false; + $assoc = false; $numeric = false; @@ -635,7 +637,7 @@ if (Bee_Utils_Dom::nodeNameEquals($ele, self::ASSOC_ITEM_ELEMENT)) { $assoc = true; list($key, $value) = $this->parseAssocItemElement($ele, $bd, $defaultType); - $list[$key] = $value; + $list[$numericKeys ? intval($key) : $key] = $value; } else { $numeric = true; array_push($list, $this->parsePropertySubElement($ele, $bd, $defaultType)); Modified: trunk/framework/Bee/Context/Xml.php =================================================================== --- trunk/framework/Bee/Context/Xml.php 2014-04-11 13:07:06 UTC (rev 150) +++ trunk/framework/Bee/Context/Xml.php 2014-06-18 12:23:30 UTC (rev 151) @@ -32,7 +32,8 @@ * Enter description here... * * @param String $locations - * @return void + * @param bool $callInitMethod + * @return \Bee_Context_Xml */ public function __construct($locations='', $callInitMethod=true) { parent::__construct($locations, false); @@ -111,5 +112,4 @@ return $registry; } -} -?> \ No newline at end of file +} \ No newline at end of file Modified: trunk/framework/bee-beans-1.2.xsd =================================================================== --- trunk/framework/bee-beans-1.2.xsd 2014-04-11 13:07:06 UTC (rev 150) +++ trunk/framework/bee-beans-1.2.xsd 2014-06-18 12:23:30 UTC (rev 151) @@ -318,6 +318,11 @@ <xsd:documentation><![CDATA[Default type for value elements]]></xsd:documentation> </xsd:annotation> </xsd:attribute> + <xsd:attribute name="numeric-keys" type="xsd:boolean"> + <xsd:annotation> + <xsd:documentation><![CDATA[Whether keys of assoc items should be interpreted as numeric]]></xsd:documentation> + </xsd:annotation> + </xsd:attribute> </xsd:attributeGroup> <xsd:element name="bean"> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <m_p...@us...> - 2014-04-11 13:07:08
|
Revision: 150 http://sourceforge.net/p/beeframework/code/150 Author: m_plomer Date: 2014-04-11 13:07:06 +0000 (Fri, 11 Apr 2014) Log Message: ----------- tagged latest change Added Paths: ----------- tags/0.9.25/ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <m_p...@us...> - 2014-04-11 13:02:09
|
Revision: 149 http://sourceforge.net/p/beeframework/code/149 Author: m_plomer Date: 2014-04-11 13:02:04 +0000 (Fri, 11 Apr 2014) Log Message: ----------- - moved construction of current Request object from dispatch to init phase Modified Paths: -------------- trunk/framework/Bee/MVC/Dispatcher.php Modified: trunk/framework/Bee/MVC/Dispatcher.php =================================================================== --- trunk/framework/Bee/MVC/Dispatcher.php 2014-03-06 16:26:30 UTC (rev 148) +++ trunk/framework/Bee/MVC/Dispatcher.php 2014-04-11 13:02:04 UTC (rev 149) @@ -180,6 +180,7 @@ * @return void */ protected function init() { + self::$currentRequest = $this->buildRequestObject(); $this->handlerMapping = $this->context->getBean(self::HANDLER_MAPPING_BEAN_NAME, 'Bee_MVC_IHandlerMapping'); $this->viewResolver = $this->context->getBean(self::VIEW_RESOLVER_BEAN_NAME, 'Bee_MVC_IViewResolver'); @@ -224,7 +225,7 @@ */ public function dispatch() { self::$currentDispatcher = $this; - self::$currentRequest = $this->buildRequestObject(); +// self::$currentRequest = $this->buildRequestObject(); if (!is_null($this->filterChainProxy)) { $this->filterChainProxy->doFilter(self::$currentRequest, $this); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <m_p...@us...> - 2014-03-06 16:26:33
|
Revision: 148 http://sourceforge.net/p/beeframework/code/148 Author: m_plomer Date: 2014-03-06 16:26:30 +0000 (Thu, 06 Mar 2014) Log Message: ----------- Added Paths: ----------- tags/0.9.24/ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <m_p...@us...> - 2014-03-06 16:23:49
|
Revision: 147 http://sourceforge.net/p/beeframework/code/147 Author: m_plomer Date: 2014-03-06 16:23:47 +0000 (Thu, 06 Mar 2014) Log Message: ----------- - HashManager added Added Paths: ----------- trunk/framework/Bee/Utils/HashManager.php Added: trunk/framework/Bee/Utils/HashManager.php =================================================================== --- trunk/framework/Bee/Utils/HashManager.php (rev 0) +++ trunk/framework/Bee/Utils/HashManager.php 2014-03-06 16:23:47 UTC (rev 147) @@ -0,0 +1,148 @@ +<?php + +namespace Bee\Utils; + +use PDO; +use Exception; + +class HashManager { + + /** + * @var HashManager + */ + private static $instance; + + /** + * @var PDO + */ + private $pdoConnection; + + /** + * @static + * @param \PDO $pdoConnection + * @return HashManager + */ + public static function getInstance(PDO $pdoConnection=null) { + if (is_null(self::$instance)) { + self::$instance = new HashManager($pdoConnection); + } + return self::$instance; + } + + private function __construct(PDO $pdoConnection) { + $this->pdoConnection = $pdoConnection; + } + + public function getHash($id, $group=null) { + try { + $stmt = 'SELECT * FROM `bee_hashes` WHERE `id` = :id'; + $params = array(); + $params['id'] = $id; + if (!is_null($group)) { + $stmt .= ' AND `group` = :grp'; + $params['grp'] = $group; + } else { + $stmt .= ' AND `group` IS NULL'; + } + + $stmt = $this->pdoConnection->prepare($stmt); + $stmt->execute($params); + if (!$row = $stmt->fetch(PDO::FETCH_ASSOC)) { + throw new Exception('hash not found'); + } + + if (!array_key_exists('hash', $row)) { + throw new Exception('row incomplete'); + } + return $row['hash']; + + } catch (Exception $e) { + $hash = $this->createHash(); + if ($this->persistHash($this->createHash(), $id, $group)) { + return $hash; + } + return false; + } + } + + public function getId($hash, $group=null) { + try { + $stmt = 'SELECT * FROM `bee_hashes` WHERE `hash` = :hash'; + $params = array(); + $params['hash'] = $hash; + if (!is_null($group)) { + $stmt .= ' AND `group` = :grp'; + $params['grp'] = $group; + } else { + $stmt .= ' AND `group` IS NULL'; + } + + $stmt = $this->pdoConnection->prepare($stmt); + $stmt->execute($params); + if (!$row = $stmt->fetch(PDO::FETCH_ASSOC)) { + throw new Exception('hash not found'); + } + + if (!array_key_exists('id', $row)) { + return false; + } + return $row['id']; + + } catch (Exception $e) { + return false; + } + } + + private function createHash() { + return preg_replace('/\./', 'b', uniqid('', true)); + } + + private function persistHash($hash, $id, $group=null) { + try { + $this->getPdoConnection()->beginTransaction(); + + $fields = '(`id`, `hash`'; + $values = '(:id, :hash'; + $params = array(); + $params['id'] = $id; + $params['hash'] = $hash; + if (!is_null($group)) { + $fields .= ', `group`'; + $values .= ', :grp'; + $params['grp'] = $group; + } + $fields .= ')'; + $values .= ')'; + + $stmt = 'INSERT INTO `bee_hashes` '.$fields.' VALUES '.$values; + + $stmt = $this->pdoConnection->prepare($stmt); + + if (!$stmt->execute($params)) { + throw new Exception('some exception'); + } + + $this->getPdoConnection()->commit(); + return true; + + + } catch (Exception $e) { + $this->getPdoConnection()->rollback(); + return false; + } + } + + /** + * @param PDO $pdoConnection + */ + public function setPdoConnection($pdoConnection) { + $this->pdoConnection = $pdoConnection; + } + + /** + * @return PDO + */ + public function getPdoConnection() { + return $this->pdoConnection; + } +} \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |