Advertisement
Geekimo

Exemple de code

Jul 18th, 2018
112
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 8.28 KB | None | 0 0
  1. <?php
  2.  
  3. namespace TCLib;
  4.  
  5. use TCLib\Config\ParameterBag;
  6. use TCLib\Utils as CoreUtils;
  7.  
  8. use Symfony\Component\HttpFoundation;
  9. use Symfony\Component\Routing;
  10. use Symfony\Component\HttpFoundation\Request;
  11. use Symfony\Component\Routing\RouteCollection;
  12. use Symfony\Component\Routing\Route;
  13. use Symfony\Component\Routing\Matcher\UrlMatcher;
  14. use Symfony\Component\Routing\RequestContext;
  15. use Symfony\Component\Yaml\Yaml;
  16.  
  17. abstract class Kernel {
  18.     public $version = '0.6a';
  19.     private $services = null,
  20.             $environment = null,
  21.             $modules = [],
  22.             $config = null;
  23.  
  24.     /**
  25.      * @param $environment (prod or dev)
  26.      * @throws KernelException
  27.      */
  28.     public function __construct($environment) {
  29.  
  30.         if(in_array($environment, array('prod', 'dev'))) {
  31.             $this->environment = $environment;
  32.         }
  33.         else {
  34.             throw new KernelException('$environment must be prod or dev when instantiating application.');
  35.         }
  36.  
  37.         $this->config = $this->loadConfiguration();
  38.  
  39.         $this->services = Services::getInstance();
  40.  
  41.         $this->services->register('kernel', $this);
  42.  
  43.         $this->services->register('config', $this->config);
  44.  
  45.         $modules = $this->registerModules();
  46.  
  47.         foreach($modules as $module) {
  48.             $this->modules[$module->getShortName()] = $module;
  49.             $module->onInitiate();
  50.         }
  51.  
  52.         // getting request
  53.         $request = Request::createFromGlobals();
  54.         $requestContext = new RequestContext();
  55.         $requestContext->fromRequest($request);
  56.         $this->services->register('request', $request);
  57.         $this->services->register('requestContext', $requestContext);
  58.  
  59.         //initializing response
  60.         $response = new HttpFoundation\Response();
  61.         $this->services->register('response', $response);
  62.  
  63.         // event dispatcher
  64.         $eventDispatcher = new EventDispatcher();
  65.         $this->services->register('event.dispatcher', $eventDispatcher);
  66.  
  67.         // templating
  68.  
  69.         $modulesRoutes = $this->getRoutesFromModules();
  70.  
  71.         $routes = new RouteCollection();
  72.  
  73.         Registry::set('routes', $routes);
  74.  
  75.         // hook for cms' to register own routes
  76.         array_map(function($module) use($routes) {
  77.             $module->registerDynamicRoutes($routes);
  78.         }, $modules);
  79.  
  80.         if(!empty($modulesRoutes)) {
  81.             // feeding collection with modules routes
  82.             foreach($modulesRoutes as $name => $configuration) {
  83.                 // resolving controller
  84.                 $configuration['_controller'] = $this->resolveController($configuration['_controller']);
  85.  
  86.                 // adding route to collection
  87.                 $routes->add($name, new Route($configuration['pattern'], $configuration));
  88.             }
  89.         }
  90.         else {
  91.             if($routes->count() < 1) {
  92.                 throw new KernelException('No routes defined.');
  93.             }
  94.         }
  95.         // all routes added, now we need to match one to the current request
  96.  
  97.         // matching request with a route
  98.         $matcher = new UrlMatcher($routes, $requestContext);
  99.         $this->services->register('urlMatcher', $matcher);
  100.        
  101.         array_map(function($module) {
  102.             $module->onRequest();
  103.         }, $modules);
  104.  
  105.         $this->matchAndExecuteRoute($requestContext->getPathInfo());
  106.     }
  107.  
  108.     private function matchAndExecuteRoute($path) {
  109.         $matcher = $this->services->get('urlMatcher');
  110.         $response = $this->services->get('response');
  111.  
  112.         try {
  113.  
  114.             $match = $matcher->match($path);
  115.             $controller = $match['_controller'];
  116.  
  117.             $controllerArgs = array_diff_key($match, ['pattern' => null, '_controller' => null, '_route' => null, $match['_route'] => null, 'requirements' => null]);
  118.         }
  119.         catch (Routing\Exception\ResourceNotFoundException $e) {
  120.             throw new Exceptions\Error404('No route matching.');
  121.         }
  122.  
  123.         //executing controller
  124.         $controller($controllerArgs);
  125.  
  126.         array_map(function($module) {
  127.             $module->onResponse();
  128.         }, $this->modules);
  129.  
  130.         // executing controller
  131.         $response->send();
  132.     }
  133.  
  134.     public function redirect($path, array $with = []) {
  135.         $this->services->get('view')->push($with);
  136.         $this->matchAndExecuteRoute($path);die;
  137.     }
  138.  
  139.     /**
  140.      * @return string environment type (prod or dev)
  141.      */
  142.     public function getEnv() {
  143.         return $this->environment;
  144.     }
  145.  
  146.     /**
  147.      * Returns an array with modules instances
  148.      * @return array
  149.      */
  150.     abstract function registerModules();
  151.  
  152.     /**
  153.      * Returns all modules routes
  154.      * @return array Each modules routes
  155.      */
  156.     private function getRoutesFromModules() {
  157.         $routes = [];
  158.         if(!empty($this->modules)) {
  159.             foreach($this->modules as $module) {
  160.                 $routes = array_merge($routes, $module->getRoutes());
  161.             }
  162.         }
  163.  
  164.         return $routes;
  165.     }
  166.  
  167.     /**
  168.      * Resolves a controller as a closures which returns an instance of the controller
  169.      * @param string $controller
  170.      * @return \Closure
  171.      * @throws KernelException
  172.      */
  173.     public function resolveController($controller) {
  174.         if(false === strpos($controller, ':')) {
  175.             throw new KernelException(sprintf('Controller "%s" is not resolvable.', $controller));
  176.         }
  177.  
  178.         $logicalName = explode(':', $controller);
  179.  
  180.         $class  = $this->resolveModule($logicalName[0]) . '\\Controller\\' . $logicalName[1] . 'Controller';
  181.         $method = $logicalName[2];
  182.  
  183.         if(!class_exists($class)) {
  184.             throw new KernelException(sprintf('Controller for %s does not exists.', $controller));
  185.         }
  186.  
  187.         return function($args = []) use($class, $method) {
  188.             return new $class($method, $args);
  189.         };
  190.     }
  191.  
  192.     /**
  193.      * Returns module if it exists
  194.      * @param $name Module name
  195.      * @return \TCLib\Module
  196.      * @throws KernelException
  197.      */
  198.     public function getModule($name) {
  199.         if(isset($this->modules[(string) $name])) {
  200.             return $this->modules[(string) $name];
  201.         }
  202.         else {
  203.             throw new KernelException(sprintf('Module "%s" is not registered or not exists.', (string) $name));
  204.         }
  205.     }
  206.  
  207.     /**
  208.      * Returns all modules
  209.      * @return array
  210.      */
  211.     public function getModules() {
  212.         return $this->modules;
  213.     }
  214.  
  215.     /**
  216.      * Resolves and returns module namespace
  217.      * @param $module Module Name
  218.      * @return string
  219.      * @throws KernelException
  220.      */
  221.     public function resolveModule($module) {
  222.         if(!isset($this->modules[$module])) {
  223.             throw new KernelException(sprintf('Module "%s" does not exists.', $module));
  224.         }
  225.  
  226.         return $this->modules[$module]->getNamespace();
  227.     }
  228.  
  229.     /**
  230.      * Load global configuration
  231.      * @return ParameterBag
  232.      */
  233.     private function loadConfiguration() {
  234.         $reflection = new \ReflectionClass($this);
  235.         $configFiles = glob(dirname($reflection->getFileName()) . DS . 'config' . DS . '*.yml');
  236.  
  237.         $config = [];
  238.  
  239.         foreach($configFiles as $configFile) {
  240.             $config = array_merge_recursive($config, Yaml::parse(file_get_contents($configFile)));
  241.         }
  242.  
  243.         return new ParameterBag($config);
  244.     }
  245.  
  246.     /**
  247.      * Returns global configuration
  248.      * @return null|ParameterBag
  249.      */
  250.     public function getConfig() {
  251.         return $this->config;
  252.     }
  253.  
  254.     /**
  255.      * Load each module configuration, eventually using a config key, and returns it
  256.      * @param string $key Optionnal. Config key to be returned by each module.
  257.      * @return array
  258.      */
  259.     public function getModulesConfiguration($key = null) {
  260.         $config = [];
  261.         foreach($this->modules as $module) {
  262.             $moduleConfig = $module->getConfig();
  263.             if(!is_null($key) && $moduleConfig->has($key)) {
  264.                 $config[$module->getShortName()] = $moduleConfig->get($key);
  265.             }
  266.             elseif(is_null($key)) {
  267.                 $config[$module->getShortName()] = $moduleConfig;
  268.             }
  269.         }
  270.  
  271.         return $config;
  272.     }
  273. }
  274.  
  275. class KernelException extends Exception {}
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement