├── .gitignore ├── lib ├── lithe_IController.php ├── lithe_AbstractEmptyController.php ├── lithe_base.properties ├── lithe_Model.php ├── lithe_ControllerHandlerAdapter.php ├── lithe_Controller.php ├── lithe_base.context.php ├── lithe_ContextUtil.php └── lithe_BasicHandlerMapping.php ├── README └── LICENSE /.gitignore: -------------------------------------------------------------------------------- 1 | .buildpath 2 | .project 3 | .settings 4 | ._* 5 | -------------------------------------------------------------------------------- /lib/lithe_IController.php: -------------------------------------------------------------------------------- 1 | data[$key] = $value; 7 | } 8 | public function delete($key) { 9 | unset($this->data[$key]); 10 | } 11 | public function get($key) { 12 | return $this->data[$key]; 13 | } 14 | public function merge(array $data) { 15 | $this->data = array_merge_recursive($this->data, $data); 16 | } 17 | public function replace(array $data) { 18 | $this->data = $data; 19 | } 20 | public function export() { 21 | return $this->data; 22 | } 23 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2010, Dragonfly Development Inc 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, 8 | this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above copyright 10 | notice, this list of conditions and the following disclaimer in the 11 | documentation and/or other materials provided with the distribution. 12 | * Neither the name of Dragonfly Development Inc nor the names of its 13 | contributors may be used to endorse or promote products derived from 14 | this software without specific prior written permission. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 20 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 | POSSIBILITY OF SUCH DAMAGE. 27 | -------------------------------------------------------------------------------- /lib/lithe_ControllerHandlerAdapter.php: -------------------------------------------------------------------------------- 1 | setHttpRequestAndResponse($httpRequest, $httpResponse); 39 | } 40 | 41 | if ( is_assoc($uriParams) ) { $args[] = $uriParams; } 42 | else { $args = $uriParams; } 43 | 44 | $rv = call_user_func_array(array($handler, $method), $args); 45 | 46 | if ( $rv and $rv instanceof halo_ModelAndView ) { 47 | return $rv; 48 | } 49 | 50 | if ( $handler instanceof lithe_Controller ) { 51 | return $handler->generateHaloModelAndView(); 52 | } 53 | 54 | return $rv; 55 | 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /lib/lithe_Controller.php: -------------------------------------------------------------------------------- 1 | isDebugEnabled() ) { 73 | self::$LOGGER->debug('In constructor.'); 74 | } 75 | $this->model = $this->data = new lithe_Model(); 76 | } 77 | 78 | /** 79 | * Inform controller about Substrate context 80 | * @param $context 81 | */ 82 | public function informAboutContext(substrate_Context $context) { 83 | if ( self::$LOGGER->isDebugEnabled() ) { 84 | self::$LOGGER->debug('Informed of Substrate context startup.'); 85 | } 86 | $this->context = $context; 87 | } 88 | 89 | /** 90 | * Generate Halo's Model and View 91 | * @return halo_ModelAndView 92 | */ 93 | public function generateHaloModelAndView() { 94 | if ( $this->redirect ) { 95 | header('Location: ' . $this->redirect); 96 | return null; 97 | } 98 | $this->model->set('baseUri', $this->httpRequest->scriptPathRoot()); 99 | return new halo_ModelAndView($this->view ? $this->view : $this->defaultView, $this->model->export()); 100 | } 101 | 102 | /** 103 | * Set Halo's HTTP Request and HTTP Response objects 104 | * @param $httpRequest 105 | * @param $httpResponse 106 | */ 107 | public function setHttpRequestAndResponse(halo_HttpRequest $httpRequest, halo_HttpResponse $httpResponse) { 108 | $this->httpRequest = $httpRequest; 109 | $this->httpResponse = $httpResponse; 110 | } 111 | 112 | public function helper($name) { 113 | halo_HelperUtil::REGISTER_HELPER_NAME($this->httpRequest, $name); 114 | return halo_HelperUtil::MANAGER( 115 | $this->httpRequest, 116 | $this->httpResponse 117 | )->helper($name); 118 | } 119 | 120 | } 121 | 122 | lithe_Controller::$LOGGER = dd_logging_LogFactory::get('lithe_Controller'); 123 | -------------------------------------------------------------------------------- /lib/lithe_base.context.php: -------------------------------------------------------------------------------- 1 | import('halo_base.context.php'); 4 | 5 | /** 6 | * Lithe dispatcher 7 | * 8 | * The Lithe dispatcher is (currently) nothing special. 9 | * 10 | * It just masks Halo so "Lithe" users can be blissfully 11 | * unaware of Halo if they choose to be. 12 | */ 13 | $context->add('lithe.dispatcher', array( 14 | 'parent' => 'halo.dispatcher', 15 | )); 16 | 17 | /** 18 | * Lithe controller handler adapter 19 | */ 20 | $context->add('lithe.handlers.controllerHandlerAdapter', array( 21 | 'className' => 'lithe_ControllerHandlerAdapter', 22 | )); 23 | 24 | /** 25 | * Class loader for Lithe controllers 26 | */ 27 | $context->add('lithe.controllers.classLoader', array( 28 | 'className' => 'substrate_ResourceLocatorClassLoader', 29 | 'constructorArgs' => array( 30 | 'resourceLocator' => $context->ref('lithe.controllers.resourceLocator'), 31 | ), 32 | )); 33 | 34 | /** 35 | * Default handler mapping 36 | */ 37 | $context->add('lithe.handlers.defaultHandlerMapping', array( 38 | 'className' => 'lithe_BasicHandlerMapping', 39 | 'constructorArgs' => array( 40 | 'configuration' => $context->ref('lithe.controllers.configuration'), 41 | 'classLoader' => $context->ref('lithe.controllers.classLoader'), 42 | ), 43 | 'dependencies' => array( 44 | 'lithe.handlers.controllerHandlerAdapter', 45 | ), 46 | )); 47 | 48 | /** 49 | * Default parent controller 50 | */ 51 | $context->add('lithe.controllers.defaultParentController', array( 52 | 'className' => 'lithe_AbstractEmptyController', 53 | 'abstract' => true, 54 | )); 55 | 56 | /** 57 | * Lithe default view resolver 58 | */ 59 | $context->add('lithe.views.defaultViewResolver', array( 60 | 'className' => 'halo_view_ViewFactoryResourceViewResolver', 61 | 'constructorArgs' => array( 62 | 'viewFactory' => $context->ref('${lithe.views.default.viewFactoryStone}'), 63 | ), 64 | 'properties' => array( 65 | 'suffix' => '${lithe.views.default.suffix}', 66 | ), 67 | )); 68 | 69 | /** 70 | * Skittle view factory 71 | */ 72 | $context->add('lithe.views.skittle.viewFactory', array( 73 | 'className' => 'halo_view_skittle_SkittleViewFactory', 74 | 'constructorArgs' => array( 75 | 'resourceLocator' => $context->ref('lithe.views.resourceLocator'), 76 | ), 77 | )); 78 | 79 | /** 80 | * Configuration Helper Factory 81 | * 82 | * This gets us a URI helper that we can use to generate absolute 83 | * and cross site URIs. 84 | */ 85 | $context->add('lithe.helpers.configurationHelperFactory', array( 86 | 'className' => 'halo_helper_ConfigurationHelperFactory', 87 | 'constructorArgs' => array( 88 | 'configuration' => $context->ref('configuration'), 89 | ), 90 | 'lazyLoad' => false, 91 | )); 92 | 93 | /** 94 | * URI Helper Factory 95 | * 96 | * This gets us a URI helper that we can use to generate absolute 97 | * and cross site URIs. 98 | */ 99 | $context->add('lithe.helpers.uriHelperFactory', array( 100 | 'className' => 'halo_helper_UriHelperFactory', 101 | 'constructorArgs' => array( 102 | 'uriConfiguration' => $context->ref('lithe.uriConfiguration'), 103 | ), 104 | 'lazyLoad' => false, 105 | )); 106 | 107 | /** 108 | * URI Configuration 109 | * 110 | * We default to our app configuration instance. 111 | */ 112 | $context->set('lithe.uriConfiguration', array( 113 | 'className' => 'dd_uri_UriConfiguration', 114 | 'constructorArgs' => array( 115 | 'configuration' => $context->ref('configuration') 116 | ), 117 | )); 118 | -------------------------------------------------------------------------------- /lib/lithe_ContextUtil.php: -------------------------------------------------------------------------------- 1 | add('lithe.controllers.resourceLocator', array( 28 | 'className' => 'substrate_PathResourceLocator', 29 | 'constructorArgs' => array( 30 | 'paths' => $config['controllers'], 31 | ), 32 | )); 33 | } 34 | 35 | if ( isset($config['views']) ) { 36 | $context->add('lithe.views.resourceLocator', array( 37 | 'className' => 'substrate_PathResourceLocator', 38 | 'constructorArgs' => array( 39 | 'paths' => $config['views'], 40 | ), 41 | )); 42 | } 43 | 44 | } 45 | 46 | /** 47 | * Configure controller configuration 48 | * @param substrate_Context $context 49 | * @param array $paths 50 | */ 51 | static public function CONFIGURE_CONTROLLER_CONFIGURATION(substrate_Context $context, $paths) { 52 | $context->add('lithe.controllers.configuration', array( 53 | 'className' => 'dd_configuration_PropertiesConfiguration', 54 | 'constructorArgs' => array( 'locations' => $paths, ), 55 | )); 56 | } 57 | 58 | /** 59 | * Configure dependencies for the dispatcher 60 | * 61 | * Used to specify which stones should be initialized prior to the 62 | * dispatcher executing. 63 | * 64 | * @param substrate_Context $context 65 | * @param array $dependencies 66 | */ 67 | static public function CONFIGURE_DISPATCHER_DEPENDENCIES(substrate_Context $context, $dependencies = null) { 68 | 69 | if ( $dependencies and is_array($dependencies) ) { 70 | foreach ( $dependencies as $stoneName ) { 71 | $context->get($stoneName); 72 | } 73 | } 74 | 75 | } 76 | 77 | /** 78 | * Execute the dispatcher 79 | * @param substrate_Context $context 80 | * @param callback $beforeDoService 81 | * @param callback $afterDoService 82 | */ 83 | static public function DISPATCH(substrate_Context $context, $beforeDoService = null, $afterDoService = null) { 84 | 85 | // Get the Lithe dispatcher 86 | $dispatcher = $context->get('lithe.dispatcher'); 87 | 88 | $request = halo_DispatcherUtil::MAKE_HTTP_REQUEST($context); 89 | $response = halo_DispatcherUtil::MAKE_HTTP_RESPONSE(); 90 | 91 | if ( $beforeDoService ) { call_user_func($beforeDoService, $context, $request, $response); } 92 | 93 | // Do the service. 94 | $dispatcher->doService($request, $response); 95 | 96 | if ( $afterDoService ) { call_user_func($afterDoService, $context, $request, $response); } 97 | 98 | } 99 | 100 | /** 101 | * Get the URI params from an HTTP Request. 102 | * @param halo_HttpRequest $httpRequest 103 | * @return substrate_Context 104 | */ 105 | public static function GET_URI_PARAMS(halo_HttpRequest $httpRequest) { 106 | return $httpRequest->attribute(self::$URI_PARAMS_CONTEXT_KEY); 107 | } 108 | 109 | /** 110 | * Set the URI params for an HTTP Request. 111 | * @param halo_HttpRequest $httpRequest 112 | * @param array 113 | */ 114 | public static function SET_URI_PARAMS(halo_HttpRequest $httpRequest, $uriParams) { 115 | return $httpRequest->setAttribute(self::$URI_PARAMS_CONTEXT_KEY, $uriParams); 116 | } 117 | 118 | /** 119 | * Get the controller method from an HTTP Request. 120 | * @param halo_HttpRequest $httpRequest 121 | * @return substrate_Context 122 | */ 123 | public static function GET_CONTROLLER_METHOD(halo_HttpRequest $httpRequest) { 124 | return $httpRequest->attribute(self::$CONTROLLER_METHOD_CONTEXT_KEY); 125 | } 126 | 127 | /** 128 | * Set the controller method for an HTTP Request. 129 | * @param halo_HttpRequest $httpRequest 130 | * @param string 131 | */ 132 | public static function SET_CONTROLLER_METHOD(halo_HttpRequest $httpRequest, $method) { 133 | return $httpRequest->setAttribute(self::$CONTROLLER_METHOD_CONTEXT_KEY, $method); 134 | } 135 | 136 | } 137 | -------------------------------------------------------------------------------- /lib/lithe_BasicHandlerMapping.php: -------------------------------------------------------------------------------- 1 | configuration = $configuration; 34 | $this->classLoader = $classLoader; 35 | } 36 | 37 | /** 38 | * Try to find a handler for the request 39 | * @param halo_HttpRequest $httpRequest 40 | */ 41 | protected function getHandlerInternal(halo_HttpRequest $httpRequest) { 42 | 43 | $requestedUri = $httpRequest->requestedUri(); 44 | $requestedUri = preg_replace('/^\/*/', '', $requestedUri); 45 | 46 | if ( ! $requestedUri ) { 47 | if ( $this->configuration->get('lithe.controllers.defaultHandlerMapping.defaultController') ) { 48 | $requestedUri = $this->configuration->get('lithe.controllers.defaultHandlerMapping.defaultController'); 49 | } else { 50 | // We requested the root URI but we have no default 51 | // controller specified. Clearly we cannot handle 52 | // this request. 53 | return null; 54 | } 55 | } 56 | 57 | if ( self::$LOGGER->isDebugEnabled() ) { 58 | self::$LOGGER->debug('Checking to see if we can handle requested URI: [' . $requestedUri . ']'); 59 | } 60 | 61 | $uriParts = explode('/', $requestedUri); 62 | $method = null; 63 | $controller = array_shift($uriParts); 64 | 65 | if ( count($uriParts) > 0 ) { 66 | $method = array_shift($uriParts); 67 | if ( $method === '' ) $method = null; 68 | } 69 | 70 | if ( $method === null ) { 71 | $method = $this->configuration->get('lithe.controllers.defaultHandlerMapping.defaultMethod'); 72 | } 73 | 74 | $controllerClassName = 75 | $this->configuration->get('lithe.controllers.defaultHandlerMapping.classNamePrefix') . 76 | ucfirst($controller) . 77 | $this->configuration->get('lithe.controllers.defaultHandlerMapping.classNameSuffix'); 78 | 79 | $controllerStoneName = 80 | ( $this->configuration->get('lithe.controllers.defaultHandlerMapping.stoneNamePrefix') ? 81 | $this->configuration->get('lithe.controllers.defaultHandlerMapping.stoneNamePrefix') . ( 82 | preg_match('/[a-zA-Z]$/', $this->configuration->get('lithe.controllers.defaultHandlerMapping.stoneNamePrefix')) ? 83 | ucfirst($controller) : 84 | lcfirst($controller) 85 | ) : 86 | lcfirst($controller)) . 87 | $this->configuration->get('lithe.controllers.defaultHandlerMapping.stoneNameSuffix'); 88 | 89 | if ( self::$LOGGER->isDebugEnabled() ) { 90 | self::$LOGGER->debug('Controller: ' . $controllerClassName . '->' . $method . '(' . implode(', ', $uriParts) . ')'); 91 | self::$LOGGER->debug('Stone: ' . $controllerStoneName); 92 | self::$LOGGER->debug('URI Params: ' . print_r($uriParts, true)); 93 | } 94 | 95 | $context = halo_DispatcherUtil::GET_CONTEXT($httpRequest); 96 | 97 | $controllerObject = null; 98 | 99 | if ( $context->exists($controllerStoneName) ) { 100 | if ( self::$LOGGER->isDebugEnabled() ) { 101 | self::$LOGGER->debug('Found stone for this controller'); 102 | } 103 | $controllerObject = $context->get($controllerStoneName); 104 | } elseif ( $this->classLoader->load($controllerClassName) ) { 105 | if ( self::$LOGGER->isDebugEnabled() ) { 106 | self::$LOGGER->debug('Found class for this controller'); 107 | } 108 | $stone = $context->add(array( 109 | 'className' => $controllerClassName, 110 | 'parent' => $this->configuration->get('lithe.controllers.defaultHandlerMapping.defaultParent'), 111 | )); 112 | $controllerObject = $context->get($stone); 113 | } 114 | 115 | if ( $controllerObject !== null ) { 116 | lithe_ContextUtil::SET_URI_PARAMS($httpRequest, $uriParts); 117 | lithe_ContextUtil::SET_CONTROLLER_METHOD($httpRequest, $method); 118 | } 119 | 120 | return $controllerObject; 121 | 122 | } 123 | 124 | } 125 | 126 | lithe_BasicHandlerMapping::$LOGGER = dd_logging_LogFactory::get('lithe_BasicHandlerMapping'); 127 | --------------------------------------------------------------------------------