Passed
Push — main ( b663cc...120722 )
by Thierry
02:08
created

RegisterTrait::getPackageConfigKey()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
1
<?php
2
0 ignored issues
show
Coding Style introduced by
Missing file doc comment
Loading history...
3
namespace Jaxon\Di\Traits;
4
5
use Jaxon\App\CallableClass;
6
use Jaxon\App\Config\ConfigManager;
7
use Jaxon\App\Dialog\Library\DialogLibraryManager;
8
use Jaxon\App\I18n\Translator;
9
use Jaxon\App\View\ViewRenderer;
10
use Jaxon\Exception\SetupException;
11
use Jaxon\Plugin\AnnotationReaderInterface;
12
use Jaxon\Plugin\Request\CallableClass\CallableClassHelper;
13
use Jaxon\Plugin\Request\CallableClass\CallableObject;
14
use Jaxon\Plugin\Request\CallableClass\CallableRepository;
15
use Jaxon\Request\Call\Paginator;
16
use Jaxon\Request\Factory\Factory;
17
use Jaxon\Request\Factory\RequestFactory;
18
use Jaxon\Request\Handler\CallbackManager;
19
use Jaxon\Request\Target;
20
use Jaxon\Utils\Config\Config;
21
use ReflectionClass;
22
use ReflectionException;
23
24
use function call_user_func;
25
26
trait RegisterTrait
0 ignored issues
show
Coding Style introduced by
Missing doc comment for trait RegisterTrait
Loading history...
27
{
28
    /**
29
     * @param mixed $xRegisteredObject
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
30
     * @param array $aDiOptions
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
31
     *
32
     * @return void
33
     */
34
    private function setDiAttributes($xRegisteredObject, array $aDiOptions)
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines before function; 0 found
Loading history...
35
    {
36
        foreach($aDiOptions as $sName => $sClass)
37
        {
38
            // Set the protected attributes of the object
39
            $cSetter = function($xInjectedObject) use($sName) {
40
                // Warning: dynamic properties will be deprecated in PHP8.2.
41
                $this->$sName = $xInjectedObject;
42
            };
43
            // Can now access protected attributes
44
            call_user_func($cSetter->bindTo($xRegisteredObject, $xRegisteredObject), $this->get($sClass));
0 ignored issues
show
Bug introduced by
It seems like get() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

44
            call_user_func($cSetter->bindTo($xRegisteredObject, $xRegisteredObject), $this->/** @scrutinizer ignore-call */ get($sClass));
Loading history...
45
        }
46
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
47
48
    /**
49
     * Get a callable object when one of its method needs to be called
50
     *
51
     * @param CallableObject $xCallableObject
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
52
     * @param Target $xTarget
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Expected 9 spaces after parameter type; 1 found
Loading history...
53
     *
54
     * @return mixed
55
     */
56
    public function getRegisteredObject(CallableObject $xCallableObject, Target $xTarget)
57
    {
58
        // Set attributes from the DI container.
59
        // The class level DI options were set when creating the object instance.
60
        // We now need to set the method level DI options.
61
        $aDiOptions = $xCallableObject->getMethodDiOptions($xTarget->getMethodName());
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 8 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
62
        $xRegisteredObject = $this->g($xCallableObject->getClassName());
0 ignored issues
show
Bug introduced by
It seems like g() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

62
        /** @scrutinizer ignore-call */ 
63
        $xRegisteredObject = $this->g($xCallableObject->getClassName());
Loading history...
63
        $this->setDiAttributes($xRegisteredObject, $aDiOptions);
64
65
        // Set the Jaxon request target in the helper
66
        if($xRegisteredObject instanceof CallableClass)
67
        {
68
            // Set the protected attributes of the object
69
            $cSetter = function() use($xTarget) {
70
                $this->xCallableClassHelper->xTarget = $xTarget;
71
            };
72
            // Can now access protected attributes
73
            call_user_func($cSetter->bindTo($xRegisteredObject, $xRegisteredObject));
74
        }
75
        return $xRegisteredObject;
76
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
77
78
    /**
79
     * Register a callable class
80
     *
81
     * @param string $sClassName The callable class name
82
     * @param array $aOptions The callable object options
0 ignored issues
show
Coding Style introduced by
Expected 2 spaces after parameter type; 1 found
Loading history...
Coding Style introduced by
Expected 3 spaces after parameter name; 1 found
Loading history...
83
     *
84
     * @return void
85
     * @throws SetupException
86
     */
87
    public function registerCallableClass(string $sClassName, array $aOptions)
88
    {
89
        $sRequestFactory = $sClassName . '_RequestFactory';
90
        $sCallableObject = $sClassName . '_CallableObject';
91
        $sReflectionClass = $sClassName . '_ReflectionClass';
92
93
        // Prevent duplication
94
        if($this->h($sReflectionClass)) // It's important not to use the class name here.
0 ignored issues
show
Bug introduced by
It seems like h() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

94
        if($this->/** @scrutinizer ignore-call */ h($sReflectionClass)) // It's important not to use the class name here.
Loading history...
95
        {
96
            return;
97
        }
98
99
        // Make sure the registered class exists
100
        if(isset($aOptions['include']))
101
        {
102
            require_once($aOptions['include']);
103
        }
104
        // Register the reflection class
105
        try
106
        {
107
            $this->val($sReflectionClass, new ReflectionClass($sClassName));
0 ignored issues
show
Bug introduced by
It seems like val() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

107
            $this->/** @scrutinizer ignore-call */ 
108
                   val($sReflectionClass, new ReflectionClass($sClassName));
Loading history...
108
        }
109
        catch(ReflectionException $e)
110
        {
111
            $xTranslator = $this->g(Translator::class);
112
            $sMessage = $xTranslator->trans('errors.class.invalid', ['name' => $sClassName]);
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 4 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
113
            throw new SetupException($sMessage);
114
        }
115
116
        // Register the callable object
117
        $this->set($sCallableObject, function($di) use($sReflectionClass, $sClassName, $aOptions) {
0 ignored issues
show
Bug introduced by
It seems like set() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

117
        $this->/** @scrutinizer ignore-call */ 
118
               set($sCallableObject, function($di) use($sReflectionClass, $sClassName, $aOptions) {
Loading history...
118
            $xRepository = $di->g(CallableRepository::class);
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 7 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
119
            $aProtectedMethods = $xRepository->getProtectedMethods($sClassName);
120
            return new CallableObject($di, $di->g(AnnotationReaderInterface::class),
121
                $di->g($sReflectionClass), $aOptions, $aProtectedMethods);
122
        });
123
124
        // Register the request factory
125
        $this->set($sRequestFactory, function($di) use($sCallableObject) {
126
            $xConfigManager = $di->g(ConfigManager::class);
127
            $xCallable = $di->g($sCallableObject);
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 6 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
128
            $sJsClass = $xConfigManager->getOption('core.prefix.class') . $xCallable->getJsName() . '.';
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 7 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
129
            return new RequestFactory($sJsClass, $di->g(DialogLibraryManager::class), $di->g(Paginator::class));
130
        });
131
132
        // Register the user class, but only if the user didn't already.
133
        if(!$this->h($sClassName))
134
        {
135
            $this->set($sClassName, function($di) use($sReflectionClass) {
136
                return $this->make($di->g($sReflectionClass));
0 ignored issues
show
Bug introduced by
It seems like make() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

136
                return $this->/** @scrutinizer ignore-call */ make($di->g($sReflectionClass));
Loading history...
137
            });
138
        }
139
        // Initialize the user class instance
140
        $this->xLibContainer->extend($sClassName, function($xRegisteredObject)
141
            use($sCallableObject, $sClassName) {
142
            if($xRegisteredObject instanceof CallableClass)
143
            {
144
                $cSetter = function($di) use($sClassName) {
145
                    // Set the protected attributes of the object
146
                    $this->xCallableClassHelper = new CallableClassHelper($di, $sClassName);
0 ignored issues
show
Bug Best Practice introduced by
The property xCallableClassHelper does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
147
                    $this->response = $di->getResponse();
0 ignored issues
show
Bug Best Practice introduced by
The property response does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 13 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
148
                };
149
                // Can now access protected attributes
150
                call_user_func($cSetter->bindTo($xRegisteredObject, $xRegisteredObject), $this);
151
            }
152
153
            // Run the callbacks for class initialisation
154
            $aCallbacks = $this->g(CallbackManager::class)->getInitCallbacks();
155
            foreach($aCallbacks as $xCallback)
156
            {
157
                call_user_func($xCallback, $xRegisteredObject);
158
            }
159
160
            // Set attributes from the DI container.
161
            // The class level DI options are set when creating the object instance.
162
            // The method level DI options are set only when calling the method in the ajax request.
163
            /** @var CallableObject */
0 ignored issues
show
Coding Style introduced by
Block comments must be started with /*
Loading history...
164
            $xCallableObject = $this->g($sCallableObject);
165
            $this->setDiAttributes($xRegisteredObject, $xCallableObject->getClassDiOptions());
166
167
            return $xRegisteredObject;
168
        });
169
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
170
171
    /**
172
     * Get the callable object for a given class
173
     *
174
     * @param string $sClassName
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
175
     *
176
     * @return CallableObject
177
     */
178
    public function getCallableObject(string $sClassName): CallableObject
179
    {
180
        return $this->g($sClassName . '_CallableObject');
181
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
182
183
    /**
184
     * Get the request factory for a given class
185
     *
186
     * @param string $sClassName
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
187
     *
188
     * @return RequestFactory
189
     */
190
    public function getRequestFactory(string $sClassName): RequestFactory
191
    {
192
        return $this->g($sClassName . '_RequestFactory');
193
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
194
195
    /**
196
     * @param string $sClassName    The package class name
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 4 found
Loading history...
197
     *
198
     * @return string
199
     */
200
    private function getPackageConfigKey(string $sClassName): string
201
    {
202
        return $sClassName . '_config';
203
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
204
205
    /**
206
     * Register a package
207
     *
208
     * @param string $sClassName    The package class name
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 4 found
Loading history...
209
     * @param Config $xPkgConfig    The user provided package options
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 4 found
Loading history...
210
     *
211
     * @return void
212
     * @throws SetupException
213
     */
214
    public function registerPackage(string $sClassName, Config $xPkgConfig)
215
    {
216
        $sPkgConfigKey = $this->getPackageConfigKey($sClassName);
217
        $this->val($sPkgConfigKey, $xPkgConfig);
218
        // Register the user class, but only if the user didn't already.
219
        if(!$this->h($sClassName))
220
        {
221
            $this->set($sClassName, function() use($sClassName) {
222
                return $this->make($sClassName);
223
            });
224
        }
225
        $this->xLibContainer->extend($sClassName, function($xPackage) use($sPkgConfigKey) {
226
            $di = $this;
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 6 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
227
            $cSetter = function() use($di, $sPkgConfigKey) {
228
                // Set the protected attributes of the object
229
                $this->_init($di->g($sPkgConfigKey), $di->g(Factory::class), $di->g(ViewRenderer::class));
0 ignored issues
show
Bug introduced by
It seems like _init() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

229
                $this->/** @scrutinizer ignore-call */ 
230
                       _init($di->g($sPkgConfigKey), $di->g(Factory::class), $di->g(ViewRenderer::class));
Loading history...
230
                $this->init();
0 ignored issues
show
Bug introduced by
It seems like init() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

230
                $this->/** @scrutinizer ignore-call */ 
231
                       init();
Loading history...
231
            };
232
            // Can now access protected attributes
233
            call_user_func($cSetter->bindTo($xPackage, $xPackage));
234
            return $xPackage;
235
        });
236
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
237
238
    /**
239
     * Get the config of a package
240
     *
241
     * @param string $sClassName    The package class name
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 4 found
Loading history...
242
     *
243
     * @return Config
244
     */
245
    public function getPackageConfig(string $sClassName): Config
246
    {
247
        return $this->g($this->getPackageConfigKey($sClassName));
248
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 0 found
Loading history...
249
}
250