system.php 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  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. # delete username and password from uri
  92. $uri = $container['request']->getUri()->withUserInfo('');
  93. /********************************
  94. * ADD ASSET-FUNCTION FOR TWIG *
  95. ********************************/
  96. $container['assets'] = function($c) use ($uri)
  97. {
  98. return new \Typemill\Assets($uri->getBaseUrl());
  99. };
  100. /************************
  101. * DECIDE FOR SESSION *
  102. ************************/
  103. $session_segments = array('setup', 'tm/', 'api/', '/setup', '/tm/', '/api/');
  104. # let plugins add own segments for session, eg. to enable csrf for forms
  105. $client_segments = $dispatcher->dispatch('onSessionSegmentsLoaded', new OnSessionSegmentsLoaded([]))->getData();
  106. $session_segments = array_merge($session_segments, $client_segments);
  107. $path = $uri->getPath();
  108. $container['flash'] = false;
  109. $container['csrf'] = false;
  110. foreach($session_segments as $segment)
  111. {
  112. if(substr( $path, 0, strlen($segment) ) === $segment)
  113. {
  114. // configure session
  115. ini_set('session.cookie_httponly', 1 );
  116. ini_set('session.use_strict_mode', 1);
  117. if($uri->getScheme() == 'https')
  118. {
  119. ini_set('session.cookie_secure', 1);
  120. session_name('__Secure-typemill-session');
  121. }
  122. else
  123. {
  124. session_name('typemill-session');
  125. }
  126. // add csrf-protection
  127. $container['csrf'] = function ($c)
  128. {
  129. $guard = new \Slim\Csrf\Guard();
  130. $guard->setPersistentTokenMode(true);
  131. return $guard;
  132. };
  133. // add flash to container
  134. $container['flash'] = function ()
  135. {
  136. return new \Slim\Flash\Messages();
  137. };
  138. // start session
  139. session_start();
  140. }
  141. }
  142. /************************
  143. * LOAD TWIG VIEW *
  144. ************************/
  145. $container['view'] = function ($container) use ($uri)
  146. {
  147. $path = array($container->get('settings')['themePath'], $container->get('settings')['authorPath']);
  148. $view = new \Slim\Views\Twig( $path, [
  149. 'cache' => false,
  150. 'autoescape' => false,
  151. 'debug' => true
  152. ]);
  153. // Instantiate and add Slim specific extension
  154. $basePath = rtrim(str_ireplace('index.php', '', $uri->getBasePath()), '/');
  155. $view->addExtension(new Slim\Views\TwigExtension($container['router'], $basePath));
  156. $view->addExtension(new Twig_Extension_Debug());
  157. $view->addExtension(new Typemill\Extensions\TwigUserExtension());
  158. $view->addExtension(new Typemill\Extensions\TwigMarkdownExtension());
  159. $view->addExtension(new Typemill\Extensions\TwigMetaExtension());
  160. $view->addExtension(new Typemill\Extensions\TwigPagelistExtension());
  161. # use {{ base_url() }} in twig templates
  162. $view['base_url'] = $uri->getBaseUrl();
  163. $view['current_url'] = $uri->getPath();
  164. /* if session route, add flash messages and csrf-protection */
  165. if($container['flash'])
  166. {
  167. $view->getEnvironment()->addGlobal('flash', $container->flash);
  168. $view->addExtension(new Typemill\Extensions\TwigCsrfExtension($container['csrf']));
  169. }
  170. /* add asset-function to all views */
  171. $view->getEnvironment()->addGlobal('assets', $container->assets);
  172. /******************************
  173. * LOAD TRANSLATIONS *
  174. ******************************/
  175. $uri = $_SERVER['REQUEST_URI'];
  176. $base_path = $container['request']->getUri()->getBasePath();
  177. $uri = str_replace($base_path,'',$uri);
  178. $pieces = explode('/',$uri);
  179. if(isset($uri) && ($pieces[1] === 'tm' OR $pieces[1] === 'setup') )
  180. {
  181. // Admin environment labels
  182. $labels = Typemill\Translations::loadTranslations('admin');
  183. } else {
  184. // User environment labels
  185. // For now it is useless, but it will prove useful in the future
  186. $labels = Typemill\Translations::loadTranslations('user');
  187. }
  188. $view['translations'] = $labels;
  189. $view->addExtension(new Typemill\Extensions\TwigLanguageExtension( $labels ));
  190. return $view;
  191. };
  192. $container->dispatcher->dispatch('onTwigLoaded');
  193. /***************************
  194. * ADD NOT FOUND HANDLER *
  195. ***************************/
  196. $container['notFoundHandler'] = function($c)
  197. {
  198. return new \Typemill\Handlers\NotFoundHandler($c['view']);
  199. };
  200. /************************
  201. * ADD MIDDLEWARE *
  202. ************************/
  203. foreach($middleware as $pluginMiddleware)
  204. {
  205. $middlewareClass = $pluginMiddleware['classname'];
  206. $middlewareParams = $pluginMiddleware['params'];
  207. if(class_exists($middlewareClass))
  208. {
  209. $app->add(new $middlewareClass($middlewareParams));
  210. }
  211. }
  212. if($container['flash'])
  213. {
  214. $app->add(new \Typemill\Middleware\ValidationErrorsMiddleware($container['view']));
  215. $app->add(new \Typemill\Middleware\OldInputMiddleware($container['view']));
  216. $app->add($container->get('csrf'));
  217. }
  218. /************************
  219. * ADD ROUTES *
  220. ************************/
  221. require __DIR__ . '/Routes/Api.php';
  222. require __DIR__ . '/Routes/Web.php';