예제 #1
0
 /**
  * @covers addSubscriber
  */
 public function testSuscriber()
 {
     $this->dispatcher->addSubscriber(new Sample2Listener());
     $expected = 'executed Sample2Listener::onBeforeLogin(1, 2, 3)';
     $expected .= 'executed Sample2Listener::onBeforeLogin2(1, 2, 3)';
     $expected .= 'executed Sample2Listener::onAfterLogin(1, 2, 3)';
     $this->expectOutputString($expected);
     $this->dispatcher->dispatch('system.before_login', new Event(array(1, 2, 3)));
     $this->dispatcher->dispatch('system.after_login', new Event(array(1, 2, 3)));
 }
예제 #2
0
 /**
  * handle the http user request
  *
  * @param \Alchemy\Application $app
  * @param \Alchemy\Component\Http\Request $request user http request
  * @return \Alchemy\Component\Http\JsonResponse|\Alchemy\Component\Http\Response
  */
 public function handle(Request $request, Application $app = null)
 {
     $this->request = $request;
     try {
         // init services providers
         /** @var \Alchemy\Service\ServiceProviderInterface $providers */
         $providers = $app->getServiceProviders();
         foreach ($providers as $provider) {
             $provider->init($app);
         }
         /*
          * "EVENT" KernelEvents::REQUEST using GetResponse Event
          *
          * This event can be used by an application to filter a request before
          * ever all kernel logic being executed, listeners for this event should
          * be registered outside framework logic (should be on application logic).
          */
         if ($this->dispatcher->hasListeners(KernelEvents::REQUEST)) {
             $event = new GetResponseEvent($this, $request, $app);
             $this->dispatcher->dispatch(KernelEvents::REQUEST, $event);
             if ($event->hasResponse()) {
                 //var_dump($event->getResponse()); die("ee");
                 $event = new FilterResponseEvent($this, $request, $event->getResponse());
                 $this->dispatcher->dispatch(KernelEvents::RESPONSE, $event);
                 return $event->getResponse();
             }
         }
         /*
          * try match the url request with a defined route.
          * it any route match the current url a ResourceNotFoundException
          * will be thrown.
          */
         $params = $this->mapper->match($request);
         $uriParams = $params["params"];
         // prepare request params.
         $params = $this->prepareRequestParams(array($params["mapped"], $request->query->all(), $request->request->all()));
         // add prepared params to request as attributes.
         $request->attributes->add($params);
         // resolve controller
         try {
             $controller = $this->resolver->getController($request);
         } catch (\Exception $exception) {
             /*
              * Detailed exception types are only for development environments
              * if the current is a non dev environment just overrides the current exception with
              * a ResourceNotFoundException exception
              */
             if ($this->config->get('env.type') !== 'dev') {
                 $exception = new ResourceNotFoundException($request->getPathInfo());
             }
             throw $exception;
         }
         if (!$controller) {
             throw new ResourceNotFoundException($request->getPathInfo());
         }
         // setting default annotations namespace
         $this->annotationReader->setDefaultNamespace('\\Alchemy\\Annotation\\');
         // seeting annotation reader target
         $this->annotationReader->setTarget($params['_controllerClass'], $params['_controllerMethod']);
         $arguments = $this->resolver->getArguments($app, $request, $controller);
         //"EVENT" FILTER_CONTROLLER
         if ($this->dispatcher->hasListeners(KernelEvents::FILTER_CONTROLLER)) {
             $event = new FilterControllerEvent($this, $controller, $request);
             $this->dispatcher->dispatch(KernelEvents::FILTER_CONTROLLER, $event);
             // getting controller; this can be the same or other filtered controller
             $controller = $event->getController();
         }
         //"EVENT" BEFORE_CONTROLLER
         if ($this->dispatcher->hasListeners(KernelEvents::BEFORE_CONTROLLER)) {
             $event = new ControllerEvent($this, $controller, $arguments, $request);
             $this->dispatcher->dispatch(KernelEvents::BEFORE_CONTROLLER, $event);
         }
         // Execute controller action
         $response = call_user_func_array($controller, $arguments);
         // check returned value by method is a array
         if (is_array($response)) {
             // set controller view data object
             foreach ($response as $key => $value) {
                 $controller[0]->view->{$key} = $value;
             }
         }
         // getting controller's data.
         $controllerData = (array) $controller[0]->view;
         if (!($response instanceof Response || $response instanceof JsonResponse)) {
             if ($this->annotationReader->getAnnotation('JsonResponse')) {
                 $controllerData = $response;
                 $response = new JsonResponse();
                 $response->setData($controllerData);
             } else {
                 $response = new Response();
             }
         }
         //"EVENT" AFTER_CONTROLLER
         if ($this->dispatcher->hasListeners(KernelEvents::AFTER_CONTROLLER)) {
             if (!isset($event) || !$event instanceof ControllerEvent) {
                 $event = new ControllerEvent($this, $controller, $arguments, $request);
             }
             $event->setResponse($response);
             $this->dispatcher->dispatch(KernelEvents::AFTER_CONTROLLER, $event);
         }
         // handling view
         $view = $this->handleView($params['_controllerClass'], $params['_controllerMethod'], $controllerData, $this->annotationReader->getAnnotation('View'));
         // handling meta ui
         if ($this->annotationReader->getAnnotation('ServeUi')) {
             $view = $this->handleMetaUi($controllerData, $this->annotationReader->getAnnotation('ServeUi'), $view, $request);
         }
         // if there is a view adapter instance, get its contents and set to response content
         if (!empty($view)) {
             foreach ($uriParams as $keyParam => $valParam) {
                 $view->assign($keyParam, $valParam);
             }
             //"EVENT" VIEW dispatch all KernelEvents::VIEW events
             if ($this->dispatcher->hasListeners(KernelEvents::VIEW)) {
                 $event = new ViewEvent($this, $view, $request, $this->annotationReader, $app);
                 $this->dispatcher->dispatch(KernelEvents::VIEW, $event);
                 $view = $event->getView();
             }
             $response->setContent($view->getOutput());
         }
     } catch (ResourceNotFoundException $e) {
         $exceptionHandler = new Exception\Handler();
         if ($request->isXmlHttpRequest()) {
             $response = new JsonResponse();
             $response->setData(array('success' => false, 'message' => $e->getMessage()));
         } else {
             $response = new Response($exceptionHandler->getOutput($e), 404);
         }
     } catch (\Exception $e) {
         //            echo $e->getMessage();
         //            echo "<br><pre>";
         //            echo $e->getTraceAsString();
         //            die;
         $exceptionHandler = new Exception\Handler();
         if ($request->isXmlHttpRequest()) {
             $response = new JsonResponse();
             $response->setData(array('success' => false, 'message' => $e->getMessage()));
         } else {
             $response = new Response($exceptionHandler->getOutput($e), 500);
         }
     }
     if ($this->annotationReader->hasTarget()) {
         $responseAnnotation = $this->annotationReader->getAnnotation('Response');
     } else {
         $responseAnnotation = null;
     }
     // dispatch a response event
     $this->dispatcher->dispatch(KernelEvents::RESPONSE, new FilterResponseEvent($this, $request, $response, $responseAnnotation));
     return $response;
 }
예제 #3
0
 /**
  * Construct application object
  * @param array $conf
  * @throws \Exception
  * @internal param \Alchemy\Contains $config all app configuration
  */
 public function init($conf = array())
 {
     defined('DS') || define('DS', DIRECTORY_SEPARATOR);
     $app = $this;
     $this['logger'] = null;
     $this['config'] = function () use($conf, $app) {
         $config = new Config();
         $config->load($conf);
         if (!$config->exists('phpalchemy.root_dir')) {
             $config->set('phpalchemy.root_dir', realpath(__DIR__ . '/../'));
         }
         if (!empty($app->appDir)) {
             $config->set('app.root_dir', $app->getAppDir());
         }
         return $config;
     };
     // load configuration ini files
     $this->loadAppConfigurationFiles();
     // apply configurated php settings
     $this->applyPhpSettings();
     $this['autoloader'] = function () {
         return new ClassLoader();
     };
     $this['yaml'] = function () {
         return new Yaml();
     };
     $this['annotation'] = function () use($app) {
         return new NotojReader();
         //return new Annotations($app['config']);
     };
     $this['mapper'] = function () use($app) {
         $config = $app['config'];
         $routesDir = $config->get('app.root_dir') . DS . 'config' . DS;
         if (file_exists($routesDir . 'routes.php')) {
             $mapper = (include $routesDir . 'routes.php');
         } elseif (file_exists($routesDir . 'routes.yaml')) {
             $mapper = new Mapper($app['yaml']);
             $mapper->setCacheDir($config->get('app.cache_dir'));
             $mapper->loadFrom($routesDir . 'routes.yaml');
         } else {
             throw new \Exception("Application Error: No routes found for this app.\n" . "You need create & configure 'config/routes.yaml'");
         }
         return $mapper;
     };
     //TODO $this['exception_handler'] = $this->share(function () {
     //     return new ExceptionHandler();
     // });
     $this['dispatcher'] = function () use($app) {
         $dispatcher = new EventDispatcher();
         $dispatcher->addSubscriber($app);
         // subscribing events
         $dispatcher->addSubscriber(new EventListener\ResponseListener($app['config']->get('templating.charset')));
         //TODO $dispatcher->addSubscriber(new LocaleListener($app['locale'], $urlMatcher));
         return $dispatcher;
     };
     $this['resolver'] = function () use($app) {
         return new ControllerResolver($app, $app['logger']);
     };
     $this['ui_reader_factory'] = function () use($app) {
         return new ReaderFactory();
     };
     $this['ui_parser'] = function () use($app) {
         return new Parser();
     };
     /** @var \Alchemy\Component\UI\Engine */
     $this['ui_engine'] = function () use($app) {
         return new Engine($app['ui_reader_factory'], $app['ui_parser']);
     };
     $this['assetsHandler'] = function () use($app) {
         return new WebAssets\Bundle();
     };
     /** @var \Alchemy\Kernel\Kernel */
     $this['kernel'] = function () use($app) {
         return new Kernel($app['dispatcher'], $app['mapper'], $app['resolver'], $app['config'], $app['annotation'], $app['ui_engine'], $app['assetsHandler']);
     };
     // registering the aplication namespace to SPL ClassLoader
     $this['autoloader']->register($this['config']->get('app.name'), $this['config']->get('app.app_root_dir'));
     // registering the aplication Extend folder to SPL ClassLoader (if folder was created)
     if (is_dir($this['config']->get('app.root_dir') . DIRECTORY_SEPARATOR . 'Extend')) {
         $this['autoloader']->register($this['config']->get('app.name') . '/Extend', $this['config']->get('app.root_dir') . DIRECTORY_SEPARATOR . 'Extend');
     }
     $this['exception_handler'] = function () use($app) {
         return new ExceptionHandler();
     };
 }