Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <?php
- namespace TCLib;
- use TCLib\Config\ParameterBag;
- use TCLib\Utils as CoreUtils;
- use Symfony\Component\HttpFoundation;
- use Symfony\Component\Routing;
- use Symfony\Component\HttpFoundation\Request;
- use Symfony\Component\Routing\RouteCollection;
- use Symfony\Component\Routing\Route;
- use Symfony\Component\Routing\Matcher\UrlMatcher;
- use Symfony\Component\Routing\RequestContext;
- use Symfony\Component\Yaml\Yaml;
- abstract class Kernel {
- public $version = '0.6a';
- private $services = null,
- $environment = null,
- $modules = [],
- $config = null;
- /**
- * @param $environment (prod or dev)
- * @throws KernelException
- */
- public function __construct($environment) {
- if(in_array($environment, array('prod', 'dev'))) {
- $this->environment = $environment;
- }
- else {
- throw new KernelException('$environment must be prod or dev when instantiating application.');
- }
- $this->config = $this->loadConfiguration();
- $this->services = Services::getInstance();
- $this->services->register('kernel', $this);
- $this->services->register('config', $this->config);
- $modules = $this->registerModules();
- foreach($modules as $module) {
- $this->modules[$module->getShortName()] = $module;
- $module->onInitiate();
- }
- // getting request
- $request = Request::createFromGlobals();
- $requestContext = new RequestContext();
- $requestContext->fromRequest($request);
- $this->services->register('request', $request);
- $this->services->register('requestContext', $requestContext);
- //initializing response
- $response = new HttpFoundation\Response();
- $this->services->register('response', $response);
- // event dispatcher
- $eventDispatcher = new EventDispatcher();
- $this->services->register('event.dispatcher', $eventDispatcher);
- // templating
- $modulesRoutes = $this->getRoutesFromModules();
- $routes = new RouteCollection();
- Registry::set('routes', $routes);
- // hook for cms' to register own routes
- array_map(function($module) use($routes) {
- $module->registerDynamicRoutes($routes);
- }, $modules);
- if(!empty($modulesRoutes)) {
- // feeding collection with modules routes
- foreach($modulesRoutes as $name => $configuration) {
- // resolving controller
- $configuration['_controller'] = $this->resolveController($configuration['_controller']);
- // adding route to collection
- $routes->add($name, new Route($configuration['pattern'], $configuration));
- }
- }
- else {
- if($routes->count() < 1) {
- throw new KernelException('No routes defined.');
- }
- }
- // all routes added, now we need to match one to the current request
- // matching request with a route
- $matcher = new UrlMatcher($routes, $requestContext);
- $this->services->register('urlMatcher', $matcher);
- array_map(function($module) {
- $module->onRequest();
- }, $modules);
- $this->matchAndExecuteRoute($requestContext->getPathInfo());
- }
- private function matchAndExecuteRoute($path) {
- $matcher = $this->services->get('urlMatcher');
- $response = $this->services->get('response');
- try {
- $match = $matcher->match($path);
- $controller = $match['_controller'];
- $controllerArgs = array_diff_key($match, ['pattern' => null, '_controller' => null, '_route' => null, $match['_route'] => null, 'requirements' => null]);
- }
- catch (Routing\Exception\ResourceNotFoundException $e) {
- throw new Exceptions\Error404('No route matching.');
- }
- //executing controller
- $controller($controllerArgs);
- array_map(function($module) {
- $module->onResponse();
- }, $this->modules);
- // executing controller
- $response->send();
- }
- public function redirect($path, array $with = []) {
- $this->services->get('view')->push($with);
- $this->matchAndExecuteRoute($path);die;
- }
- /**
- * @return string environment type (prod or dev)
- */
- public function getEnv() {
- return $this->environment;
- }
- /**
- * Returns an array with modules instances
- * @return array
- */
- abstract function registerModules();
- /**
- * Returns all modules routes
- * @return array Each modules routes
- */
- private function getRoutesFromModules() {
- $routes = [];
- if(!empty($this->modules)) {
- foreach($this->modules as $module) {
- $routes = array_merge($routes, $module->getRoutes());
- }
- }
- return $routes;
- }
- /**
- * Resolves a controller as a closures which returns an instance of the controller
- * @param string $controller
- * @return \Closure
- * @throws KernelException
- */
- public function resolveController($controller) {
- if(false === strpos($controller, ':')) {
- throw new KernelException(sprintf('Controller "%s" is not resolvable.', $controller));
- }
- $logicalName = explode(':', $controller);
- $class = $this->resolveModule($logicalName[0]) . '\\Controller\\' . $logicalName[1] . 'Controller';
- $method = $logicalName[2];
- if(!class_exists($class)) {
- throw new KernelException(sprintf('Controller for %s does not exists.', $controller));
- }
- return function($args = []) use($class, $method) {
- return new $class($method, $args);
- };
- }
- /**
- * Returns module if it exists
- * @param $name Module name
- * @return \TCLib\Module
- * @throws KernelException
- */
- public function getModule($name) {
- if(isset($this->modules[(string) $name])) {
- return $this->modules[(string) $name];
- }
- else {
- throw new KernelException(sprintf('Module "%s" is not registered or not exists.', (string) $name));
- }
- }
- /**
- * Returns all modules
- * @return array
- */
- public function getModules() {
- return $this->modules;
- }
- /**
- * Resolves and returns module namespace
- * @param $module Module Name
- * @return string
- * @throws KernelException
- */
- public function resolveModule($module) {
- if(!isset($this->modules[$module])) {
- throw new KernelException(sprintf('Module "%s" does not exists.', $module));
- }
- return $this->modules[$module]->getNamespace();
- }
- /**
- * Load global configuration
- * @return ParameterBag
- */
- private function loadConfiguration() {
- $reflection = new \ReflectionClass($this);
- $configFiles = glob(dirname($reflection->getFileName()) . DS . 'config' . DS . '*.yml');
- $config = [];
- foreach($configFiles as $configFile) {
- $config = array_merge_recursive($config, Yaml::parse(file_get_contents($configFile)));
- }
- return new ParameterBag($config);
- }
- /**
- * Returns global configuration
- * @return null|ParameterBag
- */
- public function getConfig() {
- return $this->config;
- }
- /**
- * Load each module configuration, eventually using a config key, and returns it
- * @param string $key Optionnal. Config key to be returned by each module.
- * @return array
- */
- public function getModulesConfiguration($key = null) {
- $config = [];
- foreach($this->modules as $module) {
- $moduleConfig = $module->getConfig();
- if(!is_null($key) && $moduleConfig->has($key)) {
- $config[$module->getShortName()] = $moduleConfig->get($key);
- }
- elseif(is_null($key)) {
- $config[$module->getShortName()] = $moduleConfig;
- }
- }
- return $config;
- }
- }
- class KernelException extends Exception {}
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement