system.php 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. <?php
  2. use Typemill\Events\OnSettingsLoaded;
  3. use Typemill\Events\OnPluginsLoaded;
  4. use Typemill\Events\OnSessionSegmentsLoaded;
  5. /****************************
  6. * HIDE ERRORS BY DEFAULT *
  7. ****************************/
  8. ini_set('display_errors', 0);
  9. ini_set('display_startup_errors', 0);
  10. error_reporting(E_ALL);
  11. /****************************
  12. * CREATE EVENT DISPATCHER *
  13. ****************************/
  14. $dispatcher = new \Symfony\Component\EventDispatcher\EventDispatcher();
  15. /************************
  16. * LOAD SETTINGS *
  17. ************************/
  18. $settings = Typemill\Settings::loadSettings();
  19. /****************************
  20. * HANDLE DISPLAY ERRORS *
  21. ****************************/
  22. if($settings['settings']['displayErrorDetails'])
  23. {
  24. ini_set('display_errors', 1);
  25. ini_set('display_startup_errors', 1);
  26. }
  27. /************************
  28. * INITIATE SLIM *
  29. ************************/
  30. $app = new \Slim\App($settings);
  31. /************************
  32. * GET SLIM CONTAINER *
  33. ************************/
  34. $container = $app->getContainer();
  35. /************************
  36. * LOAD & UPDATE PLUGINS *
  37. ************************/
  38. $plugins = new Typemill\Plugins();
  39. $pluginNames = $plugins->load();
  40. $pluginSettings = $routes = $middleware = array();
  41. foreach($pluginNames as $pluginName)
  42. {
  43. $className = $pluginName['className'];
  44. $name = $pluginName['name'];
  45. # check if plugin is in the settings already
  46. if(isset($settings['settings']['plugins'][$name]))
  47. {
  48. # if so, add the settings to temporary plugin settings
  49. $pluginSettings[$name] = $settings['settings']['plugins'][$name];
  50. # and delete them from original settings
  51. unset($settings['settings']['plugins'][$name]);
  52. }
  53. else
  54. {
  55. # if not, it is a new plugin. Add it and set active to false
  56. $pluginSettings[$name] = ['active' => false];
  57. # and set flag to refresh the settings
  58. $refreshSettings = true;
  59. }
  60. # if the plugin is activated, add routes/middleware and add plugin as event subscriber
  61. if($pluginSettings[$name]['active'])
  62. {
  63. $routes = $plugins->getNewRoutes($className, $routes);
  64. $middleware = $plugins->getNewMiddleware($className, $middleware);
  65. $dispatcher->addSubscriber(new $className($container));
  66. }
  67. }
  68. # if plugins in original settings are not empty now, then a plugin has been removed
  69. if(!empty($settings['settings']['plugins'])){ $refreshSettings = true; }
  70. # update the settings in all cases
  71. $settings['settings']['plugins'] = $pluginSettings;
  72. # if plugins have been added or removed
  73. if(isset($refreshSettings))
  74. {
  75. # update the settings in the container
  76. $container->get('settings')->replace($settings['settings']);
  77. # update stored settings file
  78. $refreshSettings = Typemill\settings::updateSettings($settings['settings']);
  79. }
  80. # dispatch the event onPluginsLoaded
  81. $dispatcher->dispatch('onPluginsLoaded', new OnPluginsLoaded($pluginNames));
  82. # dispatch settings event and get all setting-updates from plugins
  83. $dispatcher->dispatch('onSettingsLoaded', new OnSettingsLoaded($settings))->getData();
  84. /******************************
  85. * ADD DISPATCHER TO CONTAINER *
  86. ******************************/
  87. $container['dispatcher'] = function($container) use ($dispatcher)
  88. {
  89. return $dispatcher;
  90. };
  91. /********************************
  92. * ADD ASSET-FUNCTION FOR TWIG *
  93. ********************************/
  94. $container['assets'] = function($c)
  95. {
  96. return new \Typemill\Assets($c['request']->getUri()->getBaseUrl());
  97. };
  98. /************************
  99. * DECIDE FOR SESSION *
  100. ************************/
  101. $session_segments = array('setup', 'tm/', 'api/', '/setup', '/tm/', '/api/');
  102. # let plugins add own segments for session, eg. to enable csrf for forms
  103. $client_segments = $dispatcher->dispatch('onSessionSegmentsLoaded', new OnSessionSegmentsLoaded([]))->getData();
  104. $session_segments = array_merge($session_segments, $client_segments);
  105. $path = $container['request']->getUri()->getPath();
  106. $container['flash'] = false;
  107. $container['csrf'] = false;
  108. foreach($session_segments as $segment)
  109. {
  110. if(substr( $path, 0, strlen($segment) ) === $segment)
  111. {
  112. // configure session
  113. ini_set('session.cookie_httponly', 1 );
  114. ini_set('session.use_strict_mode', 1);
  115. if($container['request']->getUri()->getScheme() == 'https')
  116. {
  117. ini_set('session.cookie_secure', 1);
  118. session_name('__Secure-typemill-session');
  119. }
  120. else
  121. {
  122. session_name('typemill-session');
  123. }
  124. // add csrf-protection
  125. $container['csrf'] = function ($c)
  126. {
  127. $guard = new \Slim\Csrf\Guard();
  128. $guard->setPersistentTokenMode(true);
  129. return $guard;
  130. };
  131. // add flash to container
  132. $container['flash'] = function ()
  133. {
  134. return new \Slim\Flash\Messages();
  135. };
  136. // start session
  137. session_start();
  138. }
  139. }
  140. /************************
  141. * LOAD TWIG VIEW *
  142. ************************/
  143. $container['view'] = function ($container)
  144. {
  145. $path = array($container->get('settings')['themePath'], $container->get('settings')['authorPath']);
  146. $view = new \Slim\Views\Twig( $path, [
  147. 'cache' => false,
  148. 'autoescape' => false,
  149. 'debug' => true
  150. ]);
  151. // Instantiate and add Slim specific extension
  152. $basePath = rtrim(str_ireplace('index.php', '', $container['request']->getUri()->getBasePath()), '/');
  153. $view->addExtension(new Slim\Views\TwigExtension($container['router'], $basePath));
  154. $view->addExtension(new Twig_Extension_Debug());
  155. $view->addExtension(new Typemill\Extensions\TwigUserExtension());
  156. $view->addExtension(new Typemill\Extensions\TwigMarkdownExtension());
  157. $view->addExtension(new Typemill\Extensions\TwigMetaExtension());
  158. $view->addExtension(new Typemill\Extensions\TwigPagelistExtension());
  159. /* use {{ base_url() }} in twig templates */
  160. $view['base_url'] = $container['request']->getUri()->getBaseUrl();
  161. $view['current_url'] = $container['request']->getUri()->getPath();
  162. /* if session route, add flash messages and csrf-protection */
  163. if($container['flash'])
  164. {
  165. $view->getEnvironment()->addGlobal('flash', $container->flash);
  166. $view->addExtension(new Typemill\Extensions\TwigCsrfExtension($container['csrf']));
  167. }
  168. /* add asset-function to all views */
  169. $view->getEnvironment()->addGlobal('assets', $container->assets);
  170. /******************************
  171. * LOAD TRANSLATIONS *
  172. ******************************/
  173. $uri = $_SERVER['REQUEST_URI'];
  174. if(isset($uri) && (strpos($uri,'/tm/') !== false OR strpos($uri,'/setup') !== false))
  175. {
  176. // Admin environment labels
  177. $labels = Typemill\Translations::loadTranslations('admin');
  178. } else {
  179. // User environment labels
  180. // For now it is useless, but it will prove useful in the future
  181. $labels = Typemill\Translations::loadTranslations('user');
  182. }
  183. $container['translations'] = $labels;
  184. $view['translations'] = $labels;
  185. $view->addExtension(new Typemill\Extensions\TwigLanguageExtension( $labels ));
  186. return $view;
  187. };
  188. $container->dispatcher->dispatch('onTwigLoaded');
  189. /***************************
  190. * ADD NOT FOUND HANDLER *
  191. ***************************/
  192. $container['notFoundHandler'] = function($c)
  193. {
  194. return new \Typemill\Handlers\NotFoundHandler($c['view']);
  195. };
  196. /************************
  197. * ADD MIDDLEWARE *
  198. ************************/
  199. foreach($middleware as $pluginMiddleware)
  200. {
  201. $middlewareClass = $pluginMiddleware['classname'];
  202. $middlewareParams = $pluginMiddleware['params'];
  203. if(class_exists($middlewareClass))
  204. {
  205. $app->add(new $middlewareClass($middlewareParams));
  206. }
  207. }
  208. if($container['flash'])
  209. {
  210. $app->add(new \Typemill\Middleware\ValidationErrorsMiddleware($container['view']));
  211. $app->add(new \Typemill\Middleware\OldInputMiddleware($container['view']));
  212. $app->add($container->get('csrf'));
  213. }
  214. /************************
  215. * ADD ROUTES *
  216. ************************/
  217. require __DIR__ . '/Routes/Api.php';
  218. require __DIR__ . '/Routes/Web.php';