Application.php 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. <?php
  2. /**
  3. * Pimf
  4. *
  5. * @copyright Copyright (c) Gjero Krsteski (http://krsteski.de)
  6. * @license http://krsteski.de/new-bsd-license New BSD License
  7. */
  8. namespace Pimf;
  9. use Pimf\Util\String as Str;
  10. /**
  11. * Provides a facility for applications which provides reusable resources,
  12. * common-based bootstrapping and dependency checking.
  13. *
  14. * @package Pimf
  15. * @author Gjero Krsteski <[email protected]>
  16. *
  17. */
  18. final class Application
  19. {
  20. const VERSION = '1.8.6';
  21. /**
  22. * Mechanism used to do some initial config before a Application runs.
  23. *
  24. * @param array $conf The array of configuration options.
  25. * @param array $server Array of information such as headers, paths, and script locations.
  26. *
  27. * @return boolean|null
  28. */
  29. public static function bootstrap(array $conf, array $server = array())
  30. {
  31. $problems = array();
  32. try {
  33. ini_set('default_charset', $conf['encoding']);
  34. date_default_timezone_set($conf['timezone']);
  35. self::registerLocalEnvironment($conf, $server);
  36. self::setupErrorHandling($conf);
  37. self::loadPdoDriver($conf);
  38. self::loadRoutes($conf['app']['routeable'], BASE_PATH . 'app/' . $conf['app']['name'] . '/routes.php');
  39. self::loadListeners(BASE_PATH . 'app/' . $conf['app']['name'] . '/events.php');
  40. } catch (\Exception $exception) {
  41. $problems[] = $exception->getMessage();
  42. }
  43. self::reportIf($problems, PHP_VERSION);
  44. }
  45. /**
  46. * Please bootstrap first, than run the application!
  47. *
  48. * Run a application, let application accept a request, route the request,
  49. * dispatch to controller/action, render response and return response to client finally.
  50. *
  51. * @param array $get Array of variables passed to the current script via the URL parameters.
  52. * @param array $post Array of variables passed to the current script via the HTTP POST method.
  53. * @param array $cookie Array of variables passed to the current script via HTTP Cookies.
  54. *
  55. * @throws \LogicException If application not bootstrapped.
  56. * @return void
  57. */
  58. public static function run(array $get, array $post, array $cookie)
  59. {
  60. $cli = array();
  61. if (Sapi::isCli()) {
  62. $cli = Cli::parse((array)Registry::get('env')->argv);
  63. if (count($cli) < 1 || isset($cli['list'])) {
  64. Cli::absorb();
  65. exit(0);
  66. }
  67. }
  68. $conf = Registry::get('conf');
  69. $prefix = Str::ensureTrailing('\\', $conf['app']['name']);
  70. $repository = BASE_PATH . 'app/' . $conf['app']['name'] . '/Controller';
  71. if (isset($cli['controller']) && $cli['controller'] == 'core') {
  72. $prefix = 'Pimf\\';
  73. $repository = BASE_PATH . 'pimf-framework/core/Pimf/Controller';
  74. }
  75. $resolver = new Resolver(new Request($get, $post, $cookie, $cli), $repository, $prefix);
  76. $sessionized = (Sapi::isWeb() && $conf['session']['storage'] !== '');
  77. if ($sessionized) {
  78. Session::load();
  79. }
  80. $pimf = $resolver->process();
  81. if ($sessionized) {
  82. Session::save();
  83. Cookie::send();
  84. }
  85. $pimf->render();
  86. }
  87. /**
  88. * @param array $conf
  89. * @param array $server
  90. */
  91. private static function registerLocalEnvironment(array $conf, array $server)
  92. {
  93. Registry::set('conf', $conf);
  94. Registry::set('env', new Environment($server));
  95. Registry::set('logger', new Logger($conf['bootstrap']['local_temp_directory']));
  96. Registry::get('logger')->init();
  97. }
  98. /**
  99. * @param array $conf
  100. */
  101. private static function setupErrorHandling(array $conf)
  102. {
  103. if ($conf['environment'] == 'testing') {
  104. error_reporting(E_ALL | E_STRICT);
  105. } else {
  106. set_exception_handler(
  107. function ($exception) {
  108. Error::exception($exception);
  109. }
  110. );
  111. set_error_handler(
  112. function ($code, $error, $file, $line) {
  113. Error::native($code, $error, $file, $line);
  114. }
  115. );
  116. register_shutdown_function(
  117. function () {
  118. Error::shutdown();
  119. }
  120. );
  121. error_reporting(-1);
  122. }
  123. }
  124. /**
  125. * @param array $conf
  126. */
  127. private static function loadPdoDriver(array $conf)
  128. {
  129. $dbConf = $conf[$conf['environment']]['db'];
  130. if (is_array($dbConf) && $conf['environment'] != 'testing') {
  131. Registry::set('em', new EntityManager(Pdo\Factory::get($dbConf), $conf['app']['name']));
  132. }
  133. }
  134. /**
  135. * @param boolean $routeable
  136. * @param string $routes Path to routes definition file.
  137. */
  138. private static function loadRoutes($routeable, $routes)
  139. {
  140. if ($routeable === true && file_exists($routes)) {
  141. Registry::set('router', new Router());
  142. foreach ((array)(include $routes) as $route) {
  143. Registry::get('router')->map($route);
  144. }
  145. }
  146. }
  147. /**
  148. * @param string $events Path to event listeners
  149. */
  150. private static function loadListeners($events)
  151. {
  152. if (file_exists($events)) {
  153. include_once $events;
  154. }
  155. }
  156. /**
  157. * @param array $problems
  158. * @param float $version
  159. * @param bool $die
  160. *
  161. * @return array|void
  162. */
  163. private static function reportIf(array $problems, $version, $die = true)
  164. {
  165. if (version_compare($version, 5.3) == -1) {
  166. $problems[] = 'You have PHP ' . $version . ' and you need 5.3 or higher!';
  167. }
  168. if (!empty($problems)) {
  169. return ($die === true) ? die(implode(PHP_EOL . PHP_EOL, $problems)) : $problems;
  170. }
  171. }
  172. /**
  173. * PIMF Application can not be cloned.
  174. */
  175. private function __clone() { }
  176. /**
  177. * Stopping the PHP process for PHP-FastCGI users to speed up some PHP queries.
  178. */
  179. public static function finish()
  180. {
  181. if (function_exists('fastcgi_finish_request')) {
  182. fastcgi_finish_request();
  183. }
  184. }
  185. }