Changeset 1477
- Timestamp:
- 01/10/07 13:48:36 (2 years ago)
- Location:
- branches/david-execution_flow
- Files:
-
- 11 modified
-
src/config/AgaviOutputTypeConfigHandler.class.php (modified) (1 diff)
-
src/controller/AgaviController.class.php (modified) (8 diffs)
-
src/controller/AgaviExecutionContainer.class.php (modified) (9 diffs)
-
src/controller/AgaviOutputType.class.php (modified) (1 diff)
-
src/core/AgaviContext.class.php (modified) (2 diffs)
-
src/exception/AgaviException.class.php (modified) (1 diff)
-
src/filter/AgaviDispatchFilter.class.php (modified) (1 diff)
-
src/filter/AgaviExecutionFilter.class.php (modified) (3 diffs)
-
src/filter/AgaviSecurityFilter.class.php (modified) (2 diffs)
-
src/routing/AgaviRouting.class.php (modified) (5 diffs)
-
tests2/controller/ControllerTest.php (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
branches/david-execution_flow/src/config/AgaviOutputTypeConfigHandler.class.php
r1475 r1477 101 101 $code[] = implode("\n", array( 102 102 '$ot = new AgaviOutputType();', 103 '$ot->initialize($this->context, ' . var_export($outputType['parameters'], true) . ', ' . var_export($outputType ['renderers'], true) . ', ' . var_export($outputType['default_renderer'], true) . ', ' . var_export($outputType['exception_template'], true) . ');',103 '$ot->initialize($this->context, ' . var_export($outputType['parameters'], true) . ', ' . var_export($outputTypeName, true) . ', ' . var_export($outputType['renderers'], true) . ', ' . var_export($outputType['default_renderer'], true) . ', ' . var_export($outputType['exception_template'], true) . ');', 104 104 '$this->outputTypes["' . $outputTypeName . '"] = $ot;', 105 105 )); -
branches/david-execution_flow/src/controller/AgaviController.class.php
r1475 r1477 88 88 } else { 89 89 // maybe it's a sub-action with the last portion omitted 90 $actionName .= '/Index';90 $actionName .= ($actionName == '' ? '' : '/') . 'Index'; 91 91 $file = AgaviConfig::get('core.module_dir') . '/' . $moduleName . '/actions/' . $actionName . 'Action.class.php'; 92 92 if(is_readable($file)) { … … 126 126 * @since 0.11.0 127 127 */ 128 public function createExecutionContainer($moduleName , $actionName, array $parameters = array())128 public function createExecutionContainer($moduleName = null, $actionName = null, array $parameters = array()) 129 129 { 130 130 // create a new filter chain … … 152 152 $request = $this->context->getRequest(); 153 153 154 // match routes and set matched routes as request attributes155 $request->setAttribute('matchedRoutes', $this->context->getRouting()->execute(), 'org.agavi.routing');156 157 154 $request->setParameters($parameters); 158 159 // determine our module and action 160 $moduleName = $request->getParameter($request->getModuleAccessor()); 161 $actionName = $request->getParameter($request->getActionAccessor()); 162 155 156 // match routes and assign returned initial execution container 157 $container = $this->context->getRouting()->execute(); 158 159 $moduleName = $container->getModuleName(); 160 $actionName = $container->getActionName(); 161 163 162 if($moduleName == null) { 164 163 // no module has been specified 165 $moduleName = AgaviConfig::get('actions.default_module'); 166 $request->setParameter($request->getModuleAccessor(), $moduleName); 167 } 168 if($actionName == null) { 169 // no action has been specified 170 if($this->actionExists($moduleName, 'Index')) { 171 // an Index action exists 172 $actionName = 'Index'; 173 } else { 174 // use the default action 175 $actionName = AgaviConfig::get('actions.default_action'); 176 } 177 $request->setParameter($request->getActionAccessor(), $actionName); 178 } 179 180 $container = $this->createExecutionContainer($moduleName, $actionName); 164 $container->setModuleName(AgaviConfig::get('actions.default_module')); 165 $container->setActionName(AgaviConfig::get('actions.default_action')); 166 } 181 167 182 168 // create a new filter chain … … 186 172 187 173 $this->loadFilters($filterChain, 'global'); 188 174 189 175 // register the dispatch filter 190 176 $filterChain->register($this->filters['dispatch']); 191 177 192 178 // go, go, go! 193 179 $filterChain->execute($container); … … 196 182 197 183 } catch(Exception $e) { 198 if(isset($container) && $container instanceof AgaviExecutionContainer && ($response = $container->getResponse()) instanceof AgaviResponse) {199 AgaviException::printStackTrace($e, $this->context, $ response);184 if(isset($container) && $container instanceof AgaviExecutionContainer) { 185 AgaviException::printStackTrace($e, $this->context, $container); 200 186 } else { 201 187 AgaviException::printStackTrace($e, $this->context); … … 231 217 * @since 0.9.0 232 218 */ 233 public function getAction($moduleName, $actionName)219 public function createActionInstance($moduleName, $actionName) 234 220 { 235 221 static $loaded = array(); … … 293 279 * @since 0.9.0 294 280 */ 295 public function getView($moduleName, $viewName)281 public function createViewInstance($moduleName, $viewName) 296 282 { 297 283 static $loaded; … … 340 326 public function initialize(AgaviResponse $response, array $parameters = array()) 341 327 { 342 $this->max Forwards = isset($parameters['max_fowards']) ? $parameters['max_forwards'] : 20;328 $this->maxExecutions = isset($parameters['max_executions']) ? $parameters['max_executions'] : 20; 343 329 344 330 $this->response = $response; -
branches/david-execution_flow/src/controller/AgaviExecutionContainer.class.php
r1475 r1477 15 15 16 16 /** 17 * A container used for each forward() call that holds action information, the18 * response etc.17 * A container used for each action execution that holds neecessary information, 18 * such as the output type, the response etc. 19 19 * 20 20 * @package agavi … … 75 75 76 76 /** 77 * @var AgaviExecutionContainer The next container to execute. 78 */ 79 protected $next = null; 80 81 /** 77 82 * Initialize the container. This will create a response instance. 78 83 * … … 101 106 * 102 107 * This will create an instance of the action and merge in request parameters. 108 * 109 * This method returns a response. It is not necessarily the same response as 110 * the one of this container, but instead the one that contains the actual 111 * content that should be used for output etc, since the container's own 112 * response might be empty or invalid due to a "next" container that has been 113 * set and executed. 114 * 115 * @return AgaviResponse The "real" response. 103 116 * 104 117 * @author David Zuelke <dz@bitxtender.com> … … 164 177 $this->setActionName($actionName); 165 178 166 $this->actionInstance = $controller-> getAction($this->moduleName, $this->actionName);179 $this->actionInstance = $controller->createActionInstance($this->moduleName, $this->actionName); 167 180 168 181 // include the module configuration … … 250 263 251 264 // TODO. this will be pretty difficult, I guess... 252 $ controller->forward($moduleName, $actionName);265 $this->setNext($controller->createExecutionContainer($moduleName, $actionName)); 253 266 } 267 268 if($this->next !== null) { 269 return $this->next->execute(); 270 } else { 271 return $this->getResponse(); 272 } 254 273 } 255 274 … … 268 287 269 288 /** 270 * Retrieve this container's re ndered view presentation.289 * Retrieve this container's response instance. 271 290 * 272 291 * @return AgaviResponse The Response instance for this action. … … 281 300 282 301 /** 302 * Set a new response. 303 * 304 * @param AgaviResponse A new Response instance. 305 * 306 * @author David Zuelke <dz@bitxtender.com> 307 * @since 0.11.0 308 */ 309 public function setResponse(AgaviResponse $response) 310 { 311 $this->response = $response; 312 } 313 314 /** 283 315 * Retrieve the output type of this container. 284 316 * … … 291 323 { 292 324 return $this->outputType; 325 } 326 327 /** 328 * Set a different output type for this container. 329 * 330 * @param AgaviOutputType An output type object. 331 * 332 * @author David Zuelke <dz@bitxtender.com> 333 * @since 0.11.0 334 */ 335 public function setOutputType(AgaviOutputType $outputType) 336 { 337 $this->outputType = $outputType; 293 338 } 294 339 … … 424 469 $this->viewName = $viewName; 425 470 } 471 472 /** 473 * Check if a "next" container has been set. 474 * 475 * @return bool True, if a container for eventual execution has been set. 476 * 477 * @author David Zuelke <dz@bitxtender.com> 478 * @since 0.11.0 479 */ 480 public function hasNext() 481 { 482 return $this->next !== null; 483 } 484 485 /** 486 * Get the "next" container. 487 * 488 * @return AgaviExecutionContainer The "next" container, of null if unset. 489 * 490 * @author David Zuelke <dz@bitxtender.com> 491 * @since 0.11.0 492 */ 493 public function getNext() 494 { 495 return $this->next; 496 } 497 498 /** 499 * Set the container that should be executed once this one finished running. 500 * 501 * @param AgaviExcecutionContainer An execution container instance. 502 * 503 * @author David Zuelke <dz@bitxtender.com> 504 * @since 0.11.0 505 */ 506 public function setNext(AgaviExecutionContainer $container) 507 { 508 $this->next = $container; 509 } 510 511 /** 512 * Remove a possibly set "next" container. 513 * 514 * @return AgaviExecutionContainer The removed "next" container, or null 515 * if none had been set. 516 * 517 * @author David Zuelke <dz@bitxtender.com> 518 * @since 0.11.0 519 */ 520 public function clearNext() 521 { 522 $retval = $this->next; 523 $this->next = null; 524 return $retval; 525 } 426 526 } 427 527 -
branches/david-execution_flow/src/controller/AgaviOutputType.class.php
r1475 r1477 62 62 * @since 0.11.0 63 63 */ 64 public function initialize(AgaviContext $context, array $parameters, array $renderers, $defaultRenderer, $exceptionTemplate = null)64 public function initialize(AgaviContext $context, array $parameters, $name, array $renderers, $defaultRenderer, $exceptionTemplate = null) 65 65 { 66 66 $this->context = $context; 67 67 68 68 $this->parameters = $parameters; 69 70 $this->name = $name; 69 71 70 72 $this->renderers = $renderers; -
branches/david-execution_flow/src/core/AgaviContext.class.php
r1456 r1477 213 213 $profile = AgaviConfig::get('core.default_context'); 214 214 if($profile === null) { 215 throw new AgaviException('You must supply a n environment name to AgaviContext::getInstance() or set the name of the default environment to be used in the configuration directive "core.default_context".');215 throw new AgaviException('You must supply a context name to AgaviContext::getInstance() or set the name of the default context to be used in the configuration directive "core.default_context".'); 216 216 } 217 217 } … … 262 262 $this->name = $profile; 263 263 264 include(AgaviConfigCache::checkConfig(AgaviConfig::get('core.config_dir') . '/factories.xml', $profile)); 264 try { 265 include(AgaviConfigCache::checkConfig(AgaviConfig::get('core.config_dir') . '/factories.xml', $profile)); 266 } catch(Exception $e) { 267 AgaviException::printStackTrace($e, $this); 268 } 265 269 266 270 register_shutdown_function(array($this, 'shutdown')); -
branches/david-execution_flow/src/exception/AgaviException.class.php
r1436 r1477 43 43 * @since 0.9.0 44 44 */ 45 public static function printStackTrace(Exception $e, AgaviContext $context = null, Agavi Response $response= null)45 public static function printStackTrace(Exception $e, AgaviContext $context = null, AgaviExecutionContainer $container = null) 46 46 { 47 47 // discard any previous output waiting in the buffer 48 48 while(@ob_end_clean()); 49 49 50 // throw away any response data that might be there 51 if($context !== null && ($c = $context->getController()) !== null && $response !== null) { 52 if($response->isLocked()) { 53 // reponse is locked, so grab the output and discard it 54 ob_start(); 55 $response->send(); 56 ob_end_clean(); 57 } else { 58 // not locked, we can clear the response 59 $response->clear(); 60 } 61 } 62 63 if($context !== null && ($c = $context->getController()) !== null && ($oti = $c->getOutputTypeInfo()) !== null && isset($oti['exception_template'])) { 64 // an exception template was defined for this output type 65 include($oti['exception_template']); 50 if($context !== null && $container !== null && ($et = $container->getExceptionTemplate()) !== null) { 51 // an exception template was defined for the container's output type 52 include($et); 53 } elseif($container === null && ($c = $context->getController()) !== null && ($ot = $c->getOutputType() !== null) && ($et = $ot->getExceptionTemplate()) !== null) { 54 // an exception template was defined for the default output type and no container was given 55 include($et); 66 56 } elseif($context !== null && $tpl = AgaviConfig::get('exception.templates.' . $context->getName())) { 67 57 // a template was set for this context -
branches/david-execution_flow/src/filter/AgaviDispatchFilter.class.php
r1454 r1477 46 46 public function execute(AgaviFilterChain $filterChain, AgaviExecutionContainer $container) 47 47 { 48 $container-> execute();48 $container->setResponse($container->execute()); 49 49 } 50 50 } -
branches/david-execution_flow/src/filter/AgaviExecutionFilter.class.php
r1475 r1477 333 333 334 334 // get the view instance 335 $viewInstance = $controller-> getView($viewModule, $viewName);335 $viewInstance = $controller->createViewInstance($viewModule, $viewName); 336 336 337 337 // initialize the view … … 363 363 } 364 364 $key = $request->toggleLock(); 365 $ renderer= $viewInstance->$executeMethod($container);365 $next = $viewInstance->$executeMethod($container); 366 366 $request->toggleLock($key); 367 367 368 $attributes =& $viewInstance->getAttributes(); 369 370 $output = array(); 371 $nextOutput = null; 372 foreach($viewInstance->getLayers() as $layerName => $layer) { 373 foreach($layer->getSlots() as $slotName => $slotContainer) { 374 $slotContainer->execute(); 375 $response = $slotContainer->getResponse(); 376 if($response) { 377 // set the presentation data as a template attribute 378 $output[$name] = $response->getContent(); 379 // $response->merge($response->exportInfo()); 380 } else { 381 $output[$name] = null; 368 if($next instanceof AgaviExecutionContainer) { 369 $container->setNext($next); 370 } else { 371 $attributes =& $viewInstance->getAttributes(); 372 373 $output = array(); 374 $nextOutput = null; 375 foreach($viewInstance->getLayers() as $layerName => $layer) { 376 foreach($layer->getSlots() as $slotName => $slotContainer) { 377 $slotResponse = $slotContainer->execute(); 378 if($response) { 379 // set the presentation data as a template attribute 380 $output[$name] = $slotResponse->getContent(); 381 // $response->merge($response->exportInfo()); 382 } else { 383 $output[$name] = null; 384 } 382 385 } 386 $nextOutput = $layer->getRenderer()->render($layer, $attributes, $output); 387 $output = array(); 388 $output[$layerName] = $nextOutput; 383 389 } 384 $nextOutput = $layer->getRenderer()->render($layer, $attributes, $output); 385 $output = array(); 386 $output[$layerName] = $nextOutput; 387 } 388 $response->setContent($nextOutput); 390 $response->setContent($nextOutput); 391 } 389 392 } 390 393 … … 527 530 } 528 531 529 if($viewName !== AgaviView::NONE && !$controller->viewExists($viewModule, $viewName)) {530 // the requested view doesn't exist531 $file = AgaviConfig::get('core.module_dir') . '/' . $viewModule . '/views/' . $viewName . 'View.class.php';532 $error = 'Module "%s" does not contain the view "%sView" or the file "%s" is unreadable';533 $error = sprintf($error, $viewModule, $viewName, $file);534 throw new AgaviViewException($error);535 }536 537 532 return array($viewModule, $viewName); 538 533 } -
branches/david-execution_flow/src/filter/AgaviSecurityFilter.class.php
r1454 r1477 70 70 $filterChain->execute($container); 71 71 } else { 72 // the user doesn't have access, exit stage left72 // the user doesn't have access, set info regarding next action and leave 73 73 $request->setAttributes(array( 74 74 'requested_module' => $container->getModuleName(), 75 75 'requested_action' => $container->getActionName() 76 76 ), 'org.agavi.controller.forwards.secure'); 77 $cont roller->forward(new AgaviExecutionContainer(AgaviConfig::get('actions.secure_module'), AgaviConfig::get('actions.secure_action')));77 $container->setNext($controller->createExecutionContainer(AgaviConfig::get('actions.secure_module'), AgaviConfig::get('actions.secure_action'))); 78 78 } 79 79 … … 84 84 'requested_action' => $container->getActionName() 85 85 ), 'org.agavi.controller.forwards.login'); 86 $cont roller->forward(new AgaviExecutionContainer(AgaviConfig::get('actions.login_module'), AgaviConfig::get('actions.login_action')));86 $container->setNext($controller->createExecutionContainer(AgaviConfig::get('actions.login_module'), AgaviConfig::get('actions.login_action'))); 87 87 } 88 88 } -
branches/david-execution_flow/src/routing/AgaviRouting.class.php
r1410 r1477 483 483 public function execute() 484 484 { 485 $req = $this->context->getRequest(); 486 487 $container = $this->context->getController()->createExecutionContainer(); 488 $response = $container->getResponse(); 489 490 if(!AgaviConfig::get('core.use_routing', false) || count($this->routes) == 0) { 491 // routing disabled, determine module and action manually and bail out 492 $container->setModuleName($req->getParameter($req->getModuleAccessor())); 493 $container->setActionName($req->getParameter($req->getActionAccessor())); 494 495 return $container; 496 } 497 485 498 $matchedRoutes = array(); 486 487 if(!AgaviConfig::get('core.use_routing', false) || count($this->routes) == 0) {488 // routing disabled, bail out489 return $matchedRoutes;490 }491 492 $req = $this->context->getRequest();493 499 494 500 $input = $this->input; … … 501 507 $aa = $req->getActionAccessor(); 502 508 $requestMethod = $req->getMethod(); 503 504 // $routes = array_keys($this->routes);505 509 506 510 // get all top level routes … … 524 528 $cb = $opts['callback']; 525 529 $route['cb'] = new $cb(); 526 $route['cb']->initialize($ this->response, $route);530 $route['cb']->initialize($response, $route); 527 531 } 528 532 … … 635 639 // set the output type if necessary 636 640 if($ot !== null) { 637 $ this->context->getController()->setOutputType($ot);641 $container->setOutputType($ot); 638 642 } 639 643 … … 658 662 )); 659 663 } 664 665 $container->setModuleName($req->getParameter($ma)); 666 $container->setActionName($req->getParameter($aa)); 667 668 // set the list of matched route names as a request attribute 669 $req->setAttribute('matchedRoutes', $matchedRoutes, 'org.agavi.routing'); 670 660 671 // return a list of matched route names 661 return $ matchedRoutes;672 return $container; 662 673 } 663 674 -
branches/david-execution_flow/tests2/controller/ControllerTest.php
r1457 r1477 53 53 // TODO: check all other existing naming schemes for actions 54 54 55 $action = $this->_controller-> getAction('Test', 'Test');55 $action = $this->_controller->createActionInstance('Test', 'Test'); 56 56 $this->assertType('Test_TestAction', $action); 57 57 $this->assertType('AgaviAction', $action); 58 58 59 59 // TODO: this needs checking for errors 60 // $this->_controller-> getAction('Test', 'NonExistant');60 // $this->_controller->createActionInstance('Test', 'NonExistant'); 61 61 } 62 62

