Application   A
last analyzed

Complexity

Total Complexity 24

Size/Duplication

Total Lines 147
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 9

Importance

Changes 4
Bugs 1 Features 1
Metric Value
wmc 24
c 4
b 1
f 1
lcom 2
cbo 9
dl 0
loc 147
rs 10

8 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 17 2
A getInstance() 0 8 2
A cache() 0 4 1
A session() 0 4 1
A redirect() 0 6 1
C run() 0 39 8
B handleMiddlewares() 0 27 6
A stripTraillingSlash() 0 8 3
1
<?php
2
3
namespace Core;
4
5
use Core\Exceptions\ExceptionHandler;
6
use DI\ContainerBuilder;
7
use Exception;
8
use Illuminate\Cache\CacheManager as CacheManager;
9
use Illuminate\Container\Container;
10
use Illuminate\Database\Capsule\Manager as Capsule;
11
use Illuminate\Events\Dispatcher;
12
use Symfony\Component\HttpFoundation\Session\Session;
13
14
class Application
15
{
16
    public $capsuleDb = [];
17
    public $cache , $session , $di;
0 ignored issues
show
Coding Style introduced by
It is generally advisable to only define one property per statement.

Only declaring a single property per statement allows you to later on add doc comments more easily.

It is also recommended by PSR2, so it is a common style that many people expect.

Loading history...
18
    private static $instance;
19
20
    public function __construct()
21
    {
22
        $di_builder = new ContainerBuilder();
23
        $di_builder->useAutowiring(true);
24
        $this->di = $di_builder->build();
25
        $this->session = new Session();
26
        try {
27
            $this->capsuleDb = new Capsule();
0 ignored issues
show
Documentation Bug introduced by
It seems like new \Illuminate\Database\Capsule\Manager() of type object<Illuminate\Database\Capsule\Manager> is incompatible with the declared type array of property $capsuleDb.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
28
            $this->capsuleDb->addConnection(Config::get('database.providers.pdo'));
29
            $this->capsuleDb->setEventDispatcher(new Dispatcher(new Container()));
30
            $this->capsuleDb->bootEloquent();
31
            $this->capsuleDb->setAsGlobal();
32
            $this->db = $this->capsuleDb->getConnection();
0 ignored issues
show
Bug introduced by
The property db does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
33
        } catch (\PDOException $exc) {
34
            die('Database '.Config::get('database.providers.pdo.database').' not found');
0 ignored issues
show
Coding Style Compatibility introduced by
The method __construct() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
35
        }
36
    }
37
38
    /**
39
     * @return Application
40
     */
41
    public static function getInstance()
42
    {
43
        if (!isset(self::$instance)) {
44
            self::$instance = new self();
45
        }
46
47
        return self::$instance;
48
    }
49
50
    /**
51
     * @return CacheManager
52
     */
53
    public function cache()
54
    {
55
        return $this->cache;
56
    }
57
58
    /**
59
     * @return Session
60
     */
61
    public function session()
62
    {
63
        return $this->session;
64
    }
65
66
    /**
67
     * @param $url
68
     *
69
     * @return mixed
70
     */
71
    public function redirect($url)
72
    {
73
        $url = str_replace('.', DS, $url);
74
75
        return header('location: /'.$url);
76
    }
77
78
    /**
79
     * @return bool|mixed
80
     */
81
    public function run()
82
    {
83
        try {
84
            date_default_timezone_set(Config::get('app.timezone'));
85
86
            static::stripTraillingSlash();
87
88
            $this->session()->start();
89
90
            Router::init();
91
92
            $routerParams = Router::getParams();
93
94
            $this->handleMiddlewares($routerParams);
95
96
            $controllerParams = [];
97
            foreach ($routerParams as $paramName => $paramValue) {
98
                if (substr($paramName, 0, 1) != '_') {
99
                    $controllerParams[$paramName] = $paramValue;
100
                }
101
            }
102
103
            if (isset($routerParams['_params']) && is_array($routerParams['_params'])) {
104
                foreach ($routerParams['_params'] as $paramName => $paramValue) {
105
                    $controllerParams[$paramName] = $paramValue;
106
                }
107
            }
108
            $controllerFullName = '\\App\\Controllers\\'.$routerParams['_controller'];
109
            try {
110
                return $this->di->call($controllerFullName.'::'.$routerParams['_method'], $controllerParams);
111
            } catch (Exception $e) {
112
                new ExceptionHandler($e);
113
            }
114
        } catch (Exception $e) {
115
            new ExceptionHandler($e);
116
        }
117
118
        return true;
119
    }
120
121
    /**
122
     * @param $routerParams
123
     */
124
    private function handleMiddlewares($routerParams)
125
    {
126
        if (array_key_exists('_middleware', $routerParams)) {
127
            $middlewaresList = [];
128
            foreach ($routerParams['_middleware'] as $middlewareGroup) {
129
                $configMiddleware = Config::get('middleware');
130
                if (isset($configMiddleware[$middlewareGroup])) {
131
                    $middlewaresList = array_merge($middlewaresList, $configMiddleware[$middlewareGroup]);
132
                }
133
            }
134
135
            $middlewaresList = array_reverse($middlewaresList);
136
            $middlewareObjects = [];
137
            $lastMiddleware = null;
138
139
            foreach ($middlewaresList as $middleware) {
140
                $md = new $middleware($lastMiddleware);
141
                $middlewareObjects[] = $md;
142
                $lastMiddleware = $md;
143
            }
144
145
            $middlewareObjects = array_reverse($middlewareObjects);
146
            if (isset($middlewareObjects[0])) {
147
                $middlewareObjects[0]->handle();
148
            }
149
        }
150
    }
151
152
    public static function stripTraillingSlash()
0 ignored issues
show
Coding Style introduced by
stripTraillingSlash uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
153
    {
154
        $urlParts = explode('?', $_SERVER['REQUEST_URI']);
155
        if ($urlParts[0] != '/') {
156
            $urlParts[0] = substr($urlParts[0], -1, 1) == '/' ? substr($urlParts[0], 0, -1) : $urlParts[0];
157
            $_SERVER['REQUEST_URI'] = implode('?', $urlParts);
158
        }
159
    }
160
}
161