Passed
Push — master ( d2ebdc...958928 )
by Bogdan
05:05
created

JsSandboxServiceProvider   C

Complexity

Total Complexity 12

Size/Duplication

Total Lines 202
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 27

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
wmc 12
lcom 1
cbo 27
dl 0
loc 202
ccs 0
cts 94
cp 0
rs 5
c 0
b 0
f 0

7 Methods

Rating   Name   Duplication   Size   Complexity  
A register() 0 8 1
A registerIsolateAndContext() 0 10 1
B registerCallbackGuard() 0 38 6
A registerFunctionCallHandler() 0 8 1
A registerWrapper() 0 54 1
B registerExtractor() 0 41 1
B provides() 0 32 1
1
<?php declare(strict_types=1);
2
3
/*
4
 * This file is part of the pinepain/js-sandbox PHP library.
5
 *
6
 * Copyright (c) 2016-2017 Bogdan Padalko <[email protected]>
7
 *
8
 * Licensed under the MIT license: http://opensource.org/licenses/MIT
9
 *
10
 * For the full copyright and license information, please view the
11
 * LICENSE file that was distributed with this source or visit
12
 * http://opensource.org/licenses/MIT
13
 */
14
15
16
namespace Pinepain\JsSandbox\Laravel;
17
18
19
use Illuminate\Contracts\Container\Container;
20
use Illuminate\Support\ServiceProvider;
21
use InvalidArgumentException;
22
use Pinepain\JsSandbox\Extractors\Extractor;
23
use Pinepain\JsSandbox\Extractors\ExtractorDefinitionBuilder;
24
use Pinepain\JsSandbox\Extractors\ExtractorDefinitionBuilderInterface;
25
use Pinepain\JsSandbox\Extractors\ExtractorInterface;
26
use Pinepain\JsSandbox\Extractors\ExtractorsCollection;
27
use Pinepain\JsSandbox\Extractors\ExtractorsCollectionInterface;
28
use Pinepain\JsSandbox\Extractors\ObjectComponents\ExtractorsObjectStore;
29
use Pinepain\JsSandbox\Extractors\ObjectComponents\ExtractorsObjectStoreInterface;
30
use Pinepain\JsSandbox\Extractors\PlainExtractors\ArrayExtractor;
31
use Pinepain\JsSandbox\Extractors\PlainExtractors\AssocExtractor;
32
use Pinepain\JsSandbox\Extractors\PlainExtractors\BoolExtractor;
33
use Pinepain\JsSandbox\Extractors\PlainExtractors\DateExtractor;
34
use Pinepain\JsSandbox\Extractors\PlainExtractors\DateTimeExtractor;
35
use Pinepain\JsSandbox\Extractors\PlainExtractors\FunctionExtractor;
36
use Pinepain\JsSandbox\Extractors\PlainExtractors\InstanceExtractor;
37
use Pinepain\JsSandbox\Extractors\PlainExtractors\NullExtractor;
38
use Pinepain\JsSandbox\Extractors\PlainExtractors\NumberExtractor;
39
use Pinepain\JsSandbox\Extractors\PlainExtractors\ObjectExtractor;
40
use Pinepain\JsSandbox\Extractors\PlainExtractors\PrimitiveExtractor;
41
use Pinepain\JsSandbox\Extractors\PlainExtractors\RawExtractor;
42
use Pinepain\JsSandbox\Extractors\PlainExtractors\RegExpExtractor;
43
use Pinepain\JsSandbox\Extractors\PlainExtractors\ScalarExtractor;
44
use Pinepain\JsSandbox\Extractors\PlainExtractors\StringExtractor;
45
use Pinepain\JsSandbox\Extractors\PlainExtractors\UndefinedExtractor;
46
use Pinepain\JsSandbox\Specs\Builder\BindingSpecBuilder;
47
use Pinepain\JsSandbox\Specs\Builder\BindingSpecBuilderInterface;
48
use Pinepain\JsSandbox\Specs\Builder\FunctionSpecBuilder;
49
use Pinepain\JsSandbox\Specs\Builder\FunctionSpecBuilderInterface;
50
use Pinepain\JsSandbox\Specs\Builder\ObjectSpecBuilder;
51
use Pinepain\JsSandbox\Specs\Builder\ObjectSpecBuilderInterface;
52
use Pinepain\JsSandbox\Specs\Builder\ParameterSpecBuilder;
53
use Pinepain\JsSandbox\Specs\Builder\ParameterSpecBuilderInterface;
54
use Pinepain\JsSandbox\Specs\Builder\PropertySpecBuilder;
55
use Pinepain\JsSandbox\Specs\Builder\PropertySpecBuilderInterface;
56
use Pinepain\JsSandbox\Specs\ObjectSpecsCollection;
57
use Pinepain\JsSandbox\Specs\ObjectSpecsCollectionInterface;
58
use Pinepain\JsSandbox\Wrappers\ArrayWrapper;
59
use Pinepain\JsSandbox\Wrappers\CallbackGuards\CallbackGuard;
60
use Pinepain\JsSandbox\Wrappers\CallbackGuards\CallbackGuardInterface;
61
use Pinepain\JsSandbox\Wrappers\CallbackGuards\DebugCallbackGuard;
62
use Pinepain\JsSandbox\Wrappers\CallbackGuards\DevCallbackGuard;
63
use Pinepain\JsSandbox\Wrappers\FunctionComponents\ArgumentsExtractor;
64
use Pinepain\JsSandbox\Wrappers\FunctionComponents\ArgumentsExtractorInterface;
65
use Pinepain\JsSandbox\Wrappers\FunctionComponents\FunctionCallHandler;
66
use Pinepain\JsSandbox\Wrappers\FunctionComponents\FunctionCallHandlerInterface;
67
use Pinepain\JsSandbox\Wrappers\FunctionComponents\FunctionExceptionHandler;
68
use Pinepain\JsSandbox\Wrappers\FunctionComponents\FunctionExceptionHandlerInterface;
69
use Pinepain\JsSandbox\Wrappers\FunctionComponents\FunctionWrappersCache;
70
use Pinepain\JsSandbox\Wrappers\FunctionComponents\FunctionWrappersCacheInterface;
71
use Pinepain\JsSandbox\Wrappers\FunctionComponents\ReturnValueSetter;
72
use Pinepain\JsSandbox\Wrappers\FunctionComponents\ReturnValueSetterInterface;
73
use Pinepain\JsSandbox\Wrappers\FunctionWrapper;
74
use Pinepain\JsSandbox\Wrappers\ObjectComponents\PropertiesHandler;
75
use Pinepain\JsSandbox\Wrappers\ObjectComponents\PropertiesHandlerInterface;
76
use Pinepain\JsSandbox\Wrappers\ObjectComponents\WrappersObjectStore;
77
use Pinepain\JsSandbox\Wrappers\ObjectComponents\WrappersObjectStoreInterface;
78
use Pinepain\JsSandbox\Wrappers\ObjectWrapper;
79
use Pinepain\JsSandbox\Wrappers\PrimitiveWrapper;
80
use Pinepain\JsSandbox\Wrappers\Wrapper;
81
use Pinepain\JsSandbox\Wrappers\WrapperInterface;
82
use Pinepain\ObjectMaps\ObjectBiMap;
83
use Pinepain\ObjectMaps\ObjectMap;
84
use V8\Context;
85
use V8\Isolate;
86
87
88
class JsSandboxServiceProvider extends ServiceProvider
89
{
90
    protected $defer = true;
91
92
    public function register()
93
    {
94
        $this->registerIsolateAndContext();
95
        $this->registerCallbackGuard();
96
        $this->registerFunctionCallHandler();
97
        $this->registerWrapper();
98
        $this->registerExtractor();
99
    }
100
101
    protected function registerIsolateAndContext()
102
    {
103
        $this->app->singleton(Isolate::class, function (/*Container $app*/) {
104
            return new Isolate();
105
        });
106
107
        $this->app->singleton(Context::class, function (Container $app) {
108
            return new Context($app->make(Isolate::class));
109
        });
110
    }
111
112
    protected function registerCallbackGuard()
113
    {
114
115
        $config = $this->app->make('config');
116
117
        $guards = [
118
            'prod'  => CallbackGuard::class,
119
            'dev'   => DevCallbackGuard::class,
120
            'debug' => DebugCallbackGuard::class,
121
        ];
122
123
        $guard = $config->get('js_sandbox.guard', 'auto');
124
125
        if ('auto' == $guard) {
126
            if ($config->get('app.debug')) {
127
                if ($this->app->environment('production')) {
0 ignored issues
show
Unused Code introduced by
The call to Application::environment() has too many arguments starting with 'production'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
128
                    $guard = 'debug';
129
                } else {
130
                    $guard = 'dev';
131
                }
132
            } else {
133
                if ($this->app->environment('production')) {
0 ignored issues
show
Unused Code introduced by
The call to Application::environment() has too many arguments starting with 'production'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
134
                    $guard = 'prod';
135
                } else {
136
                    $guard = 'debug';
137
                }
138
            }
139
        }
140
141
        if (!isset($guards[$guard])) {
142
            $expected = '[\'auto\', \'' . implode('\', \'', array_keys($guards)) . '\']';
143
            throw new InvalidArgumentException("Invalid guard mode specified: expected one of {$expected}, '$guard' given instead");
144
        }
145
146
147
        $this->app->singleton(CallbackGuardInterface::class, $guards[$guard]);
148
149
    }
150
151
    protected function registerFunctionCallHandler()
152
    {
153
        $this->app->singleton(ArgumentsExtractorInterface::class, ArgumentsExtractor::class);
154
        $this->app->singleton(FunctionExceptionHandlerInterface::class, FunctionExceptionHandler::class);
155
        $this->app->singleton(ReturnValueSetterInterface::class, ReturnValueSetter::class);
156
157
        $this->app->singleton(FunctionCallHandlerInterface::class, FunctionCallHandler::class);
158
    }
159
160
    protected function registerWrapper()
161
    {
162
        $function_wrappers_map = new ObjectMap(ObjectMap::WEAK_VALUE);
163
164
        $this->app->singleton(ObjectSpecsCollectionInterface::class, ObjectSpecsCollection::class);
165
        $this->app->singleton(FunctionWrappersCacheInterface::class, function () use ($function_wrappers_map) {
166
            new FunctionWrappersCache($function_wrappers_map);
167
        });
168
169
        $object_store_map = new ObjectBiMap();
170
171
        // $this->app->when(WrappersObjectStore::class)
0 ignored issues
show
Unused Code Comprehensibility introduced by
55% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
172
        //           ->needs(ObjectMapInterface::class)
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
173
        //           ->give(function () use ($object_store_map) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
63% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
174
        //               return $object_store_map;
175
        //           });
176
        //
177
        // $this->app->when(ExtractorsObjectStoreInterface::class)
0 ignored issues
show
Unused Code Comprehensibility introduced by
55% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
178
        //           ->needs(ObjectMapInterface::class)
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
179
        //           ->give(function () use ($object_store_map) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
63% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
180
        //               return $object_store_map->values();
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
181
        //           });
182
        //
183
        // $this->app->singleton(WrappersObjectStoreInterface::class, WrappersObjectStore::class);
0 ignored issues
show
Unused Code Comprehensibility introduced by
53% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
184
        // $this->app->singleton(ExtractorsObjectStoreInterface::class, ExtractorsObjectStore::class);
0 ignored issues
show
Unused Code Comprehensibility introduced by
53% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
185
186
        $this->app->instance(WrappersObjectStoreInterface::class, new WrappersObjectStore($object_store_map));
187
        $this->app->instance(ExtractorsObjectStoreInterface::class, new ExtractorsObjectStore($object_store_map->values()));
188
189
        $this->app->singleton(PropertiesHandlerInterface::class, PropertiesHandler::class);
190
191
        $this->app->singleton(WrapperInterface::class, function (Container $app) {
192
193
            $wrapper = new Wrapper();
194
195
            $primitive_wrapper = $app->make(PrimitiveWrapper::class);
196
197
            $array_wrapper = $app->make(ArrayWrapper::class);
198
            $array_wrapper->setWrapper($wrapper);
199
200
            $function_wrapper = $app->make(FunctionWrapper::class);
201
            $function_wrapper->setWrapper($wrapper);
202
203
            $object_wrapper = $app->make(ObjectWrapper::class);
204
            $object_wrapper->setWrapper($wrapper);
205
206
            $wrapper->setPrimitiveWrapper($primitive_wrapper);
207
            $wrapper->setArrayWrapper($array_wrapper);
208
            $wrapper->setFunctionWrapper($function_wrapper);
209
            $wrapper->setObjectWrapper($object_wrapper);
210
211
            return $wrapper;
212
        });
213
    }
214
215
    protected function registerExtractor()
216
    {
217
        $this->app->singleton(ExtractorDefinitionBuilderInterface::class, ExtractorDefinitionBuilder::class);
218
        $this->app->singleton(PropertySpecBuilderInterface::class, PropertySpecBuilder::class);
219
        $this->app->singleton(ParameterSpecBuilderInterface::class, ParameterSpecBuilder::class);
220
        $this->app->singleton(FunctionSpecBuilderInterface::class, FunctionSpecBuilder::class);
221
        $this->app->singleton(BindingSpecBuilderInterface::class, BindingSpecBuilder::class);
222
        $this->app->singleton(ObjectSpecBuilderInterface::class, ObjectSpecBuilder::class);
223
224
        $this->app->singleton(ExtractorInterface::class, Extractor::class);
225
226
        $this->app->singleton(ExtractorsCollectionInterface::class, function (Container $app) {
227
228
            $collection = new ExtractorsCollection();
229
230
            // TODO: register basic extractor
231
232
            $collection->put('raw', $raw = new RawExtractor());
233
            $collection->put('array', $array = new ArrayExtractor());
234
            $collection->put('primitive', $primitive = new PrimitiveExtractor());
235
236
            $collection->put('string', $string = new StringExtractor());
237
            $collection->put('number', $number = new NumberExtractor());
238
            $collection->put('bool', $bool = new BoolExtractor());
239
            $collection->put('null', $null = new NullExtractor());
240
            $collection->put('undefined', $undefined = new UndefinedExtractor());
241
242
            $collection->put('regexp', $regexp = new RegExpExtractor());
243
            $collection->put('date', $date = new DateExtractor());
244
            $collection->put('datetime', $datetime = new DateTimeExtractor());
245
            $collection->put('object', $object = new ObjectExtractor());
246
            $collection->put('function', $function = new FunctionExtractor());
247
            $collection->put('instance', $instance = $app->make(InstanceExtractor::class));
248
249
            $collection->put('assoc', $assoc = new AssocExtractor());
250
            $collection->put('scalar', $scalar = new ScalarExtractor($string, $number, $bool, $null, $undefined));
251
252
            return $collection;
253
        });
254
255
    }
256
257
    public function provides()
258
    {
259
        return [
260
            Isolate::class,
261
            Context::class,
262
263
            CallbackGuardInterface::class,
264
265
            ArgumentsExtractorInterface::class,
266
            FunctionExceptionHandlerInterface::class,
267
            ReturnValueSetterInterface::class,
268
            FunctionCallHandlerInterface::class,
269
270
            ObjectSpecsCollectionInterface::class,
271
            FunctionWrappersCacheInterface::class,
272
            WrappersObjectStoreInterface::class,
273
            PropertiesHandlerInterface::class,
274
            WrapperInterface::class,
275
276
            ExtractorDefinitionBuilderInterface::class,
277
            PropertySpecBuilderInterface::class,
278
            ParameterSpecBuilderInterface::class .
279
            FunctionSpecBuilderInterface::class,
280
            BindingSpecBuilderInterface::class,
281
            ObjectSpecBuilderInterface::class,
282
283
            ExtractorsCollectionInterface::class,
284
            ExtractorsObjectStoreInterface::class,
285
            ExtractorInterface::class,
286
287
        ];
288
    }
289
}
290