Slimore
  • Namespace
  • Class

Namespaces

  • None
  • Slimore
    • Cache
      • Exception
    • Captcha
    • Database
    • Debug
    • Http
    • Image
    • Log
    • Middleware
    • Mvc
    • Pagination
    • Upload

Classes

  • Slimore\Cache\File
  • Slimore\Captcha\Builder
  • Slimore\Database\Manager
  • Slimore\Debug\Simpler
  • Slimore\Http\Client
  • Slimore\Image\Gd
  • Slimore\Log\Writer
  • Slimore\Middleware\Exceptions
  • Slimore\Mvc\Application
  • Slimore\Mvc\Controller
  • Slimore\Mvc\Model
  • Slimore\Mvc\View
  • Slimore\Pagination\Paginator
  • Slimore\Upload\Uploader

Exceptions

  • Slimore\Cache\Exception\File
  • Slimore\Captcha\Exception
  • Slimore\Database\Exception
  • Slimore\Http\Exception
  • Slimore\Mvc\Exception
  • Slimore\Pagination\Exception
  • Slimore\Upload\Exception

Functions

  • arrayToObject
  • console
  • controller
  • ctl
  • currentUrl
  • decrypt
  • detectDevice
  • encrypt
  • fileFormatSize
  • getDirectoryItems
  • getDpi
  • hexToRGB
  • html
  • imageDataUrl
  • iPad
  • iPhone
  • iPod
  • isAndroid
  • isApache
  • isBlackberry
  • isChrome
  • isCli
  • isFirefox
  • isFreeBSD
  • isIE
  • isIIS
  • isJson
  • isLinux
  • isMacOSX
  • isMobile
  • isNginx
  • isOpera
  • isSafari
  • isTablet
  • isUnix
  • isUnixLike
  • isWebOS
  • isWindows
  • js
  • jsonToArray
  • linkTag
  • password
  • phoneMaskCode
  • randomCharacters
  • replaceDirSeparator
  • rgbToHex
  • script
  • shortUrl
  • style
  1 <?php
  2 
  3 /**
  4  * Slimore - The fully (H)MVC framework based on the Slim PHP framework.
  5  *
  6  * @author      Pandao <slimore@ipandao.com>
  7  * @copyright   2015 Pandao
  8  * @link        http://github.com/slimore/slimore
  9  * @license     MIT License https://github.com/slimore/slimore#license
 10  * @version     0.1.0
 11  * @package     Slimore\Mvc
 12  */
 13 
 14 namespace Slimore\Mvc;
 15 
 16 use \Slimore\Database\Manager            as DB;
 17 use \Illuminate\Container\Container      as Container;
 18 use \Illuminate\Events\Dispatcher        as Dispatcher;
 19 use \Slimore\Middleware\Exceptions       as ExceptionsMiddleware;
 20 
 21 /**
 22  * Class Application
 23  *
 24  * @author Pandao
 25  * @package Slimore\Mvc
 26  */
 27 
 28 class Application extends \Slim\Slim
 29 {
 30     /**
 31      * @var string
 32      */
 33     public $version  = '0.1.0';
 34 
 35     /**
 36      * @var array $defaults
 37      */
 38     protected $defaults = [
 39                             'path'               => '',
 40                             'baseURL'            => '',
 41                             'timezone'           => 'Asia/Shanghai',
 42                             'templates.path'     => '../app/views',
 43                             'cookies.encrypt'    => true,
 44                             'cookies.secret_key' => 'vadsfas',
 45                             'modules'            => [],
 46                             'defaultModule'      => '',
 47                             'disabledModules'    => '',
 48                             'template.suffix'    => '.php',
 49                             'x-framework-header' => true,
 50                             'mvcDirs'            => [
 51                                 'controller'     => 'controllers',
 52                                 'model'          => 'models',
 53                                 'view'           => 'views'
 54                             ],
 55                             'autoloads'          => [],
 56                             'defaultAutoloads'   => [
 57                                 '../app/controllers',
 58                                 '../app/models',
 59                             ],
 60                             'db'                 => []
 61                         ];
 62 
 63     /**
 64      * @var array $loadFiles
 65      */
 66 
 67     private $loadFiles = [];
 68 
 69     /**
 70      * @var string
 71      */
 72     public  $path;
 73 
 74     /**
 75      * @var string
 76      */
 77     public  $baseURL;
 78 
 79     /**
 80      * @var mixed
 81      */
 82     public  $db;
 83 
 84     /**
 85      * @var number
 86      */
 87     public  $startTime;
 88 
 89     /**
 90      * @var string
 91      */
 92     public  $moduleName = '';
 93 
 94     /**
 95      * @var string
 96      */
 97     public  $controllerName;
 98 
 99     /**
100      * @var string
101      */
102     public  $actionName;
103 
104     /**
105      * @var array
106      */
107     protected $routeInfo;
108 
109     /**
110      * Constructor
111      *
112      * @param array $settings null
113      */
114 
115     public function __construct(array $settings = null)
116     {
117         if (version_compare(phpversion(), '5.4.0', '<'))
118         {
119             throw new \RuntimeException('Slimore require PHP version >= 5.4.0');
120         }
121 
122         require __DIR__ . "/../Helper/Functions.php";
123 
124         $settings = array_merge ($this->defaults, $settings);
125 
126         if ($settings['x-framework-header'])
127         {
128             header('X-Framework-By: Slimore/' . $this->version);
129         }
130 
131         parent::__construct($settings);
132 
133         date_default_timezone_set($this->config('timezone'));
134 
135         $this->init();
136     }
137 
138     /**
139      * Application Initialization method
140      *
141      * @return void
142      */
143 
144     public function init()
145     {
146         $this->path    = $this->config('path');
147         $this->baseURL = $this->config('baseURL');
148 
149         $this->errorsHandle();
150         $this->autoloads();
151     }
152 
153     /**
154      * Override Slim run method
155      *
156      * @return void
157      */
158 
159     public function run()
160     {
161         set_error_handler(array('\Slim\Slim', 'handleErrors'));
162 
163         //Apply final outer middleware layers
164         if ($this->config('debug')) {
165             //Apply pretty exceptions only in debug to avoid accidental information leakage in production
166             $this->add(new \Slimore\Middleware\Exceptions());
167         }
168 
169         //Invoke middleware and application stack
170         $this->middleware[0]->call();
171 
172         //Fetch status, header, and body
173         list($status, $headers, $body) = $this->response->finalize();
174 
175         // Serialize cookies (with optional encryption)
176         \Slim\Http\Util::serializeCookies($headers, $this->response->cookies, $this->settings);
177 
178         //Send headers
179         if (headers_sent() === false) {
180             //Send status
181             if (strpos(PHP_SAPI, 'cgi') === 0) {
182                 header(sprintf('Status: %s', \Slim\Http\Response::getMessageForCode($status)));
183             } else {
184                 header(sprintf('HTTP/%s %s', $this->config('http.version'), \Slim\Http\Response::getMessageForCode($status)));
185             }
186 
187             //Send headers
188             foreach ($headers as $name => $value) {
189                 $hValues = explode("\n", $value);
190                 foreach ($hValues as $hVal) {
191                     header("$name: $hVal", false);
192                 }
193             }
194         }
195 
196         //Send body, but only if it isn't a HEAD request
197         if (!$this->request->isHead()) {
198             echo $body;
199         }
200 
201         $this->applyHook('slim.after');
202 
203         restore_error_handler();
204     }
205 
206     /**
207      * Errors / Exceptions handle
208      *
209      * @return void
210      */
211 
212     protected function errorsHandle()
213     {
214         $debug = $this->config('debug');
215 
216         error_reporting(($debug) ? E_ALL : E_ERROR & ~E_NOTICE);
217 
218         set_error_handler(function ($type, $message, $file, $line) {
219             throw new \ErrorException($message, 0, $type, $file, $line);
220         });
221 
222         set_exception_handler(function (\Exception $e) {
223 
224             $exception = new ExceptionsMiddleware;
225 
226             $log = $this->getLog(); // Force Slim to append log to env if not already
227             $env = $this->environment();
228             $env['slim.log'] = $log;
229             $env['slim.log']->error($e);
230 
231             $this->contentType('text/html');
232             $this->response()->status(500);
233 
234             echo $this->response()->body($exception->renderBody($env, $e));
235         });
236 
237         register_shutdown_function(function () {
238 
239             if ( !is_null($options = error_get_last()) )
240             {
241                 $title = 'Slimore Application Error Shutdown';
242 
243                 $html  = html($title, [
244                     '<meta http-equiv="X-UA-Compatible" content="IE=edge" />',
245                     '<meta name="renderer" content="webkit" />',
246                     '<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />',
247                     style([
248                         '*{margin:0;padding:0;}',
249                         'html {font-size: 62.5%;}',
250                         'html, body {max-width: 100%;width: 100%;}',
251                         'body {font-size: 1.4rem;font-family: "Microsoft Yahei", Helvetica, Tahoma, STXihei, arial,verdana,sans-serif;background:#fff;color:#555;}',
252                         'img {border: none;}',
253                         'pre, pre code {font-family:Consolas, arial,verdana,sans-serif;}',
254                         '#layout {padding: 6rem;}',
255                         '#main {margin: 0 auto;line-height: 1.5;}',
256                         '#main > h1 {font-size: 10rem;margin-bottom: 1rem;}',
257                         '#main > h3 {margin-bottom: 2rem; font-size: 1.8rem;}',
258                         '#main > h4 {margin-bottom: 1rem; font-size: 1.8rem;}',
259                         '#main pre {margin: 1.5rem 0;white-space: pre-wrap;word-wrap: break-word;}',
260                         '#main > p {white-space: pre-wrap;word-wrap: break-word;line-height: 1.3;margin-bottom: 0.6rem;}',
261                         '#main > p > strong {width: 7rem;display:inline-block;}',
262                         '.logo {text-align: left;border-top:1px solid #eee;margin-top: 5rem;padding: 3rem 0 0;color: #ccc;}',
263                         '.logo > h1 {font-weight: normal;font-size: 5rem;}',
264                         '.logo img {margin-left: -2rem;}',
265                         '.trace-line {padding: 0.3rem 0.6rem;margin-left:-0.6rem;-webkit-transition: background-color 300ms ease-out;transition: background-color 300ms ease-out;}',
266                         '.trace-line:hover {background:#fffccc;}'
267                     ])
268                 ], [
269                     '<div id="layout">',
270                     '<div id="main">',
271                     '<h1>:(</h1>',
272                     '<h3>' . $title . '</h3>',
273                     '<h4>Details :</h4>',
274                     '<p><strong>Type: </strong> ' . $options['type'] . '</p>',
275                     '<p><strong>Message: </strong> ' . $options['message'] . '</p>',
276                     '<p><strong>File: </strong> ' . $options['file'] . '</p>',
277                     '<p><strong>Line: </strong> ' . $options['line'] . '</p>',
278                     '<div class="logo">',
279                     '<h1>Slimore</h1>',
280                     '<p>The fully (H)MVC framework, based on the Slim PHP Framwork.</p>',
281                     '</div>',
282                     '</div>',
283                     '</div>'
284                 ]);
285 
286                 echo $html;
287 
288                 exit;
289             }
290 
291         });
292     }
293 
294     /**
295      * Configure the database and boot Eloquent
296      *
297      * @param array $configs null
298      * @param string $name default
299      * @param bool $enableQueryLog true
300      * @return mixed
301      */
302 
303     public function dbConnection(array $configs = null, $name = 'default', $enableQueryLog = true)
304     {
305         $db = new DB();
306 
307         $db->addConnection(($configs) ? $configs : $this->config('db'), $name);
308         $db->setEventDispatcher(new Dispatcher(new Container));
309         $db->setAsGlobal();
310         $db->bootEloquent();
311 
312         if ($enableQueryLog)
313         {
314             DB::connection()->enableQueryLog();
315         }
316 
317         $this->db = $db;
318 
319         return $db;
320     }
321 
322     /**
323      * Modules namespace route handle method
324      *
325      * @param string $namespace
326      * @param callable $callback
327      * @return void
328      */
329 
330     public function moduleNamespace($namespace, callable $callback)
331     {
332         if ( is_callable($callback) )
333         {
334             $callback($namespace, $this);
335         }
336     }
337 
338     /**
339      * Route controller handle
340      *
341      * @param string $controller
342      * @param callable $callback
343      * @param string $namespace
344      */
345 
346     public function controller($controller, callable $callback, $namespace = '')
347     {
348         if ( is_callable($callback) )
349         {
350             $callback(ucwords($controller) . 'Controller', $this, $namespace);
351         }
352     }
353 
354     /**
355      * Auto router method
356      *
357      * @param bool $stop false
358      * @return void
359      */
360 
361     public function autoRoute($stop = false)
362     {
363         if ($stop)
364         {
365             return $this;
366         }
367 
368         $app = self::getInstance();
369 
370         $app->get('(/)', 'IndexController:index');
371 
372         $app->get('/:action', function($action = 'index') use ($app) {
373 
374             if ( !class_exists('IndexController') )
375             {
376                 $app->notFound();
377                 return ;
378             }
379 
380             $this->controllerName = 'index';
381             $this->actionName     = $action;
382 
383             $controller = new \IndexController;
384 
385             if ( !method_exists($controller, $action) )
386             {
387                 $app->notFound();
388                 return ;
389             }
390 
391             $controller->$action();
392         });
393 
394         $app->get('/:controller/:action', function($controller = 'index', $action = 'index') use ($app) {
395 
396             $this->controllerName = $controller;
397             $this->actionName     = $action;
398 
399             $controller  = ucwords($controller) . 'Controller';
400 
401             if ( !class_exists($controller) )
402             {
403                 $app->notFound();
404                 return ;
405             }
406 
407             $controller = new $controller();
408 
409             if ( !method_exists($controller, $action) )
410             {
411                 $app->notFound();
412                 return ;
413             }
414 
415             $controller->$action();
416         });
417 
418         $app->get('/:module/:controller/:action', function($module, $controller = 'index', $action = 'index') use ($app) {
419             $this->moduleName     = $module;
420             $this->controllerName = $controller;
421             $this->actionName     = $action;
422 
423             $controller = ucwords($module) . '\Controllers\\' . ucwords($controller) . 'Controller';
424 
425             if ( !class_exists($controller) )
426             {
427                 $app->notFound();
428                 return ;
429             }
430 
431             $controller = new $controller();
432 
433             if ( !method_exists($controller, $action) )
434             {
435                 $app->notFound();
436                 return ;
437             }
438 
439             $controller->$action();
440         });
441     }
442 
443     /**
444      * Autoload callable method
445      *
446      * @param string $className
447      * @return void
448      */
449 
450     protected function __autoload($className)
451     {
452         // Single modules autoload
453 
454         foreach ($this->config('defaultAutoloads') as $key => $dir)
455         {
456             $fileName = $dir . DIRECTORY_SEPARATOR . $className . '.php';
457             $fileName = str_replace('\\', DIRECTORY_SEPARATOR, $fileName);
458 
459             if (file_exists($fileName) && !class_exists($className))
460             {
461                 $this->loadFiles[$className] = $fileName;
462 
463                 require $fileName;
464             }
465         }
466 
467         // Multi-Modules autoload
468 
469         $modules = array_merge([], $this->config('modules'));
470 
471         foreach ($modules as $key => $module)
472         {
473             $module = ($module == '') ? $module : $module . DIRECTORY_SEPARATOR;
474 
475             foreach ($this->config('mvcDirs') as $k => $mvc)
476             {
477                 $phpFile  = explode("\\", $className);
478                 $phpFile  = $phpFile[count($phpFile) - 1];
479                 $fileName = $this->path . str_replace('\\', DIRECTORY_SEPARATOR, strtolower(str_replace($phpFile, '', $className))). $phpFile . '.php';
480 
481                 if (file_exists($fileName) && !class_exists($className))
482                 {
483                     $this->loadFiles[$className] = $fileName;
484 
485                     require $fileName;
486                 }
487             }
488         }
489 
490         // User custom autoloads
491 
492         foreach ($this->config('autoloads') as $key => $dir)
493         {
494             $fileName = realpath($dir) . DIRECTORY_SEPARATOR . $className . '.php';
495             $fileName = str_replace('\\', DIRECTORY_SEPARATOR, $fileName);
496 
497             if (file_exists($fileName) && !class_exists($className))
498             {
499                 $this->loadFiles[$className] = $fileName;
500 
501                 require $fileName;
502             }
503         }
504     }
505 
506     /**
507      * SPL autoload register method
508      *
509      * @return void
510      */
511 
512     protected function autoloads()
513     {
514         spl_autoload_register(__CLASS__ . "::__autoload");
515     }
516 
517     /**
518      * Run time start
519      *
520      * @return number
521      */
522 
523     public function timeStart()
524     {
525         $now = explode(" ", microtime());
526         $this->startTime = $now[1] + $now[0];
527 
528         return $this->startTime;
529     }
530 
531     /**
532      * Run end time
533      *
534      * @param int $decimal 6
535      * @return number
536      */
537 
538     public function timeEnd($decimal = 6)
539     {
540         $now   = explode(" ", microtime());
541         $end   = $now[1] + $now[0];
542         $total = ($end - $this->startTime);
543 
544         return number_format($total, $decimal);
545     }
546 }
547 
Slimore API documentation generated by ApiGen