Completed
Push — master ( f4fae9...d97ad7 )
by Mihail
09:18
created

App::buildExtendObject()   B

Complexity

Conditions 6
Paths 7

Size

Total Lines 17
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 6
Bugs 2 Features 1
Metric Value
c 6
b 2
f 1
dl 0
loc 17
rs 8.8571
cc 6
eloc 9
nc 7
nop 0
1
<?php
2
3
namespace Ffcms\Core;
4
5
use Ffcms\Core\Exception\ForbiddenException;
6
use Ffcms\Core\Exception\JsonException;
7
use Ffcms\Core\Exception\NativeException;
8
use Ffcms\Core\Exception\NotFoundException;
9
use Ffcms\Core\Exception\SyntaxException;
10
use Ffcms\Core\Helper\FileSystem\File;
11
use Ffcms\Core\Helper\Security;
12
use Ffcms\Core\Helper\Type\Obj;
13
use Ffcms\Core\Helper\Type\Str;
14
use Ffcms\Core\I18n\Translate;
15
use Ffcms\Core\Network\Request;
16
use Ffcms\Core\Network\Response;
17
use Ffcms\Core\Arch\View;
18
use Ffcms\Core\Debug\Manager as Debug;
19
use Ffcms\Core\Cache\MemoryObject;
20
21
/**
22
 * Class App - entry point for applications
23
 * @package Ffcms\Core
24
 */
25
class App
26
{
27
28
    /** @var \Ffcms\Core\Network\Request */
29
    public static $Request;
30
31
    /** @var \Ffcms\Core\Properties */
32
    public static $Properties;
33
34
    /** @var \Ffcms\Core\Network\Response */
35
    public static $Response;
36
37
    /** @var \Ffcms\Core\Alias */
38
    public static $Alias;
39
40
    /** @var \Ffcms\Core\Arch\View */
41
    public static $View;
42
43
    /** @var \Ffcms\Core\Debug\Manager|null */
44
    public static $Debug;
45
46
    /** @var \Ffcms\Core\Helper\Security */
47
    public static $Security;
48
49
    /** @var \Ffcms\Core\I18n\Translate */
50
    public static $Translate;
51
52
    /** @var \Ffcms\Core\Interfaces\iUser */
53
    public static $User;
54
55
    /** @var \Symfony\Component\HttpFoundation\Session\Session */
56
    public static $Session;
57
58
    /** @var \Illuminate\Database\Capsule\Manager */
59
    public static $Database;
60
61
    /** @var \Ffcms\Core\Cache\MemoryObject */
62
    public static $Memory;
63
64
    /** @var \Swift_Mailer */
65
    public static $Mailer;
66
67
    /** @var \Ffcms\Core\Interfaces\iCaptcha */
68
    public static $Captcha;
69
70
    /** @var \BasePhpFastCache */
71
    public static $Cache;
72
73
    private $services;
0 ignored issues
show
Unused Code introduced by
The property $services is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
74
75
76
    /**
77
     * Prepare entry-point services
78
     * @param array|null $services
79
     * @throws NativeException
80
     */
81
    public static function init(array $services = null)
82
    {
83
        // initialize default services - used in all apps type
84
        self::$Memory = MemoryObject::instance();
85
        self::$Properties = new Properties();
86
        self::$Request = Request::createFromGlobals();
87
        self::$Security = new Security();
88
        self::$Response = new Response();
89
        self::$View = new View();
90
        self::$Translate = new Translate();
91
        self::$Alias = new Alias();
92
93
        // check if debug is enabled and available for current session
94
        if (isset($services['Debug']) && $services['Debug'] === true && Debug::isEnabled() === true) {
95
            self::$Debug = new Debug();
96
        }
97
98
        $objects = App::$Properties->getAll('object');
99
        // pass dynamic initialization
100
        self::dynamicServicePrepare($services, $objects);
101
    }
102
103
    /**
104
     * Prepare dynamic services from object anonymous functions
105
     * @param array|null $services
106
     * @param null $objects
107
     * @throws NativeException
108
     */
109
    private static function dynamicServicePrepare(array $services = null, $objects = null)
110
    {
111
        // check if object configuration is passed
112
        if (!Obj::isArray($objects)) {
113
            throw new NativeException('Object configurations is not loaded: /Private/Config/Object.php');
114
        }
115
116
        // each all objects as service_name => service_instance()
117
        foreach ($objects as $name => $instance) {
0 ignored issues
show
Bug introduced by
The expression $objects of type null is not traversable.
Loading history...
118
            // check if definition of object is exist and services list contains it or is null to auto build
119
            if (property_exists(get_called_class(), $name) && $instance instanceof \Closure && (isset($services[$name]) || $services === null)) {
120
                if ($services[$name] === true || $services === null) { // initialize from configs
121
                    self::${$name} = $instance();
122
                } elseif (is_callable($services[$name])) { // raw initialization from App::run()
123
                    self::${$name} = $services[$name]();
124
                }
125
            }
126
        }
127
    }
128
129
    /**
130
     * Run applications and display output
131
     * @throws \DebugBar\DebugBarException
132
     */
133
    public static function run()
134
    {
135
        try {
136
            $callClass = null;
137
            $callMethod = 'action' . self::$Request->getAction();
138
139
            // founded callback injection alias
140
            if (self::$Request->getCallbackAlias() !== false) {
141
                $cName = self::$Request->getCallbackAlias();
142
                if (class_exists($cName)) {
143
                    $callClass = new $cName;
144
                } else {
145
                    throw new NotFoundException('Callback alias of class "' . App::$Security->strip_tags($cName) . '" is not founded');
0 ignored issues
show
Documentation introduced by
$cName is of type boolean, but the function expects a string|array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
146
                }
147
            } else { // typical parsing of native apps
148
                $cName = '\Apps\Controller\\' . env_name . '\\' . self::$Request->getController();
149
                $cPath = Str::replace('\\', '/', $cName) . '.php';
150
151
                // try to load controller
152
                if (File::exist($cPath)) {
153
                    File::inc($cPath, false, true);
154
                } else {
155
                    throw new NotFoundException('Controller not founded: {root}' . $cPath);
156
                }
157
                // try to initialize class object
158
                if (class_exists($cName)) {
159
                    $callClass = new $cName;
160
                } else {
161
                    throw new NotFoundException('App is not founded: "' . $cName . '. Pathway: {root}' . $cPath);
162
                }
163
            }
164
165
            // try to call method of founded callback class
166
            if (method_exists($callClass, $callMethod)) {
167
                $response = null;
168
                // param "id" is passed
169
                if (!Str::likeEmpty(self::$Request->getID())) {
170
                    // param "add" is passed
171
                    if (!Str::likeEmpty(self::$Request->getAdd())) {
172
                        $response = $callClass->$callMethod(self::$Request->getID(), self::$Request->getAdd());
173
                    } else {
174
                        $response = $callClass->$callMethod(self::$Request->getID());
175
                    }
176
                } else {
177
                    // no passed params is founded
178
                    $response = $callClass->$callMethod();
179
                }
180
181
                // work with returned response data
182
                if ($response !== null && Obj::isString($response) && method_exists($callClass, 'setResponse')) {
183
                    $callClass->setResponse($response);
184
                }
185
            } else {
186
                throw new NotFoundException('Method "' . $callMethod . '()" not founded in "' . get_class($callClass) . '"');
187
            }
188
        } catch (NotFoundException $e) {
189
            $e->display();
190
        } catch (ForbiddenException $e) {
191
            $e->display();
192
        } catch (SyntaxException $e) {
193
            $e->display();
194
        } catch (JsonException $e) {
195
            $e->display();
196
        } catch (NativeException $e) {
197
            $e->display();
198
        } catch(\Exception $e) { // catch all other exceptions
199
            (new NativeException($e->getMessage()))->display();
200
        }
201
    }
202
203
}