Completed
Pull Request — master (#66)
by Marko
02:32
created

Scene::prepareAssets()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 5
ccs 4
cts 4
cp 1
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 3
nc 2
nop 0
crap 2
1
<?php
2
/** @formatter:off
3
 * ******************************************************************
4
 * Created by   Marko Kungla on Jun 20, 2016 - 9:01:22 PM
5
 * Contact      [email protected]
6
 * @copyright   2016 Marko Kungla - https://github.com/mkungla
7
 * @license     The MIT License (MIT)
8
 *
9
 * @category       AframeVR
10
 * @package        aframe-php
11
 *
12
 * Lang         PHP (php version >= 7)
13
 * Encoding     UTF-8
14
 * File         Scene.php
15
 * Code format  PSR-2 and 12
16
 * @link        https://github.com/mkungla/aframe-php
17
 * @issues      https://github.com/mkungla/aframe-php/issues
18
 * ********************************************************************
19
 * Contributors:
20
 * @author Marko Kungla <[email protected]>
21
 * ********************************************************************
22
 * Comments:
23
 * @formatter:on */
24
namespace AframeVR\Core;
25
26
use \AframeVR\Extras\Primitives;
27
use \AframeVR\Core\Entity;
28
use \AframeVR\Core\DOM\AframeDOMDocument;
29
use \AframeVR\Core\Assets;
30
use \AframeVR\Core\Exceptions\BadComponentCallException;
31
use \AframeVR\Core\Helpers\EntityChildrenFactory;
32
33
final class Scene
34
{
35
    /* All scenes can use primitives */
36
    use Primitives;
37
38
    /**
39
     * Name with what you can retrieve this scene while working with multiple scenes
40
     *
41
     * @var string $name
42
     */
43
    private $keyword;
44
45
    /**
46
     * Is scene prepared for rendering
47
     *
48
     * @var bool
49
     */
50
    private $prepared;
51
52
    /**
53
     * Assets
54
     *
55
     * @var \AframeVR\Core\Assets
56
     */
57
    protected $assets;
58
59
    /**
60
     * Aframe Document Object Model
61
     *
62
     * @var \AframeVR\Core\DOM\AframeDOMDocument
63
     */
64
    protected $aframeDomObj;
65
66
    /**
67
     * Scene components
68
     *
69
     * @var array $components
70
     */
71
    protected $components = array();
72
73
    /**
74
     * Children Factory
75
     *
76
     * @var \AframeVR\Core\Helpers\EntityChildrenFactory
77
     */
78
    protected $childrenFactory;
79
80
    /**
81
     * Extra scrits to add into head
82
     *
83
     * Like components and shaders
84
     *
85
     * @var array $scripts
86
     */
87
    protected $scripts = array();
88
89
    /**
90
     * Scene constructor
91
     *
92
     * @param string $keyword
93
     * @param Config $config
94
     */
95 101
    public function __construct(string $keyword, Config $config)
96
    {
97 101
        $this->keyword         = $keyword;
98 101
        $this->aframeDomObj    = new AframeDOMDocument($config);
99 101
        $this->childrenFactory = new EntityChildrenFactory();
100
        /* Initialize assests manager */
101 101
        $this->asset($config);
102 101
    }
103
104
    /**
105
     * Aframe Document Object Model
106
     *
107
     * @api
108
     *
109
     * @return \AframeVR\Core\DOM\AframeDOMDocument
110
     */
111 2
    public function dom()
112
    {
113 2
        return $this->aframeDomObj;
114
    }
115
116
    /**
117
     * Assets
118
     *
119
     * @api
120
     *
121
     * @param null|Config $config
122
     * @return \AframeVR\Core\Assets
123
     */
124 101
    public function asset(Config $config = null): Assets
125
    {
126 101
        return $this->assets ?? $this->assets = new Assets($config);
0 ignored issues
show
Bug introduced by
It seems like $config defined by parameter $config on line 124 can be null; however, AframeVR\Core\Assets::__construct() does not accept null, maybe add an additional type check?

It seems like you allow that null is being passed for a parameter, however the function which is called does not seem to accept null.

We recommend to add an additional type check (or disallow null for the parameter):

function notNullable(stdClass $x) { }

// Unsafe
function withoutCheck(stdClass $x = null) {
    notNullable($x);
}

// Safe - Alternative 1: Adding Additional Type-Check
function withCheck(stdClass $x = null) {
    if ($x instanceof stdClass) {
        notNullable($x);
    }
}

// Safe - Alternative 2: Changing Parameter
function withNonNullableParam(stdClass $x) {
    notNullable($x);
}
Loading history...
127
    }
128
129
    /**
130
     * Child entity / primitive
131
     *
132
     * @return \AframeVR\Core\Helpers\EntityChildrenFactory
133
     */
134 78
    public function child(): EntityChildrenFactory
135
    {
136 78
        return $this->childrenFactory;
137
    }
138
139
    /**
140
     * Render the A-Frame scene and return the HTML
141
     *
142
     * @api
143
     *
144
     * @param bool $only_scene
145
     * @return string
146
     */
147 22
    public function save($only_scene = false, string $file = null): string
148
    {
149 22
        $this->prepare();
150 22
        $html = ! $only_scene ? $this->aframeDomObj->render() : $this->aframeDomObj->renderSceneOnly();
151 22
        if (! empty($file) && is_writable(dirname($file))) {
152 1
            file_put_contents($file, $html);
153
        }
154
155 22
        return $html;
156
    }
157
158
    /**
159
     * Render the A-Frame scene and passthru HTML
160
     *
161
     * @api
162
     *
163
     * @param bool $only_scene
164
     * @return void
165
     */
166 1
    public function render($only_scene = false)
167
    {
168 1
        print $this->save($only_scene);
169 1
    }
170
171
    /**
172
     * Alias of AframeDOMDocument::setTitle(string)
173
     *
174
     * Set <title> tag
175
     * $this->dom()->setTitle(string);
176
     *
177
     * @api
178
     *
179
     * @param string $title
180
     */
181 1
    public function title(string $title)
182
    {
183 1
        $this->dom()->setTitle($title);
184 1
    }
185
186
    /**
187
     * Alias of AframeDOMDocument::setDescription(string)
188
     *
189
     * Set <meta name="description"> tag
190
     * $this->dom()->setDescription(string);
191
     *
192
     * @api
193
     *
194
     * @param string $description
195
     */
196 1
    public function description(string $description)
197
    {
198 1
        $this->dom()->setDescription($description);
199 1
    }
200
201
    /**
202
     * Get scenes keyword
203
     *
204
     * @return string
205
     */
206 1
    public function getKeyword()
207
    {
208 1
        return $this->keyword;
209
    }
210
211
    /**
212
     * Load component for this scene or set it's attr
213
     *
214
     * @param string $component_name
215
     * @param null|string $attr_data
216
     * @throws \AframeVR\Core\Exceptions\BadComponentCallException
217
     * @return object|null
218
     */
219 2
    public function attr(string $component_name, string $attr_data = null)
220
    {
221 2
        if(!is_null($attr_data)) {
222 1
            $this->attrs[$component_name] = $attr_data;
0 ignored issues
show
Bug introduced by
The property attrs 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...
223 1
            return $this;
224
        }
225 2
        if (! array_key_exists($component_name, $this->components)) {
226 2
            $component = sprintf('\AframeVR\Core\Components\ascene\%s\%sComponent', ucfirst($component_name),
227
                ucfirst($component_name));
228 2
            if (class_exists($component)) {
229 1
                $this->components[$component_name] = new $component();
230
            } else {
231 1
                throw new BadComponentCallException($component_name);
232
            }
233
        }
234
235 1
        return $this->components[$component_name] ?? null;
236
    }
237
238
    /**
239
     * Add scripts like components and shaders
240
     *
241
     * @param string $path
242
     * @return void
243
     */
244 1
    public function addScript(string $path)
245
    {
246 1
        $this->scripts[$path] = true;
247 1
    }
248
249
    /**
250
     * Map calls to scene entities and components
251
     *
252
     * Since we might need to customize these to have
253
     * custom components loaded as $this->methosd aswell therefore
254
     * we have these placeholder magic methods here
255
     *
256
     * @param string $method
257
     * @param array $args
258
     * @throws BadShaderCallException
259
     * @return Entity|\AframeVR\Interfaces\ComponentInterface
0 ignored issues
show
Documentation introduced by
Should the return type not be object|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
260
     */
261 80
    public function __call(string $method, array $args)
262
    {
263 80
        $id        = $args[0] ?? 0;
264 80
        $primitive = sprintf('\AframeVR\Extras\Primitives\%s', ucfirst($method));
265
266 80
        if ($method === 'entity' || class_exists($primitive)) {
267 78
            return $this->child()->getEntity($method, $id);
268
        } else {
269 2
            return $this->attr($method);
270
        }
271
    }
272
273
    /**
274
     * Add everyting to DOM
275
     *
276
     * @return void
277
     */
278 22
    protected function prepare()
279
    {
280 22
        if ($this->prepared)
281 1
            return;
282
283
        /* Append all assets */
284 22
        $this->prepareAssets();
285
286
        /* Append all primitives */
287 22
        $this->preparePrimitives();
288
289
        /* Append all entities */
290 22
        $this->aframeDomObj->appendEntities($this->childrenFactory->getChildren());
291 22
        $this->aframeDomObj->appendSceneComponents($this->components);
292
293
        /* Append extra scripts */
294 22
        $this->prepareScripts();
295
296 22
        $this->prepared = true;
297 22
    }
298
299
    /**
300
     * Append all assets
301
     *
302
     * @return void
303
     */
304 22
    protected function prepareAssets()
305
    {
306 22
        $assets = $this->assets->getAssets();
307 22
        (!$assets) ?: $this->aframeDomObj->appendAssets($assets);
308 22
    }
309
310
    /**
311
     * Append extra scripts
312
     *
313
     * like extra components and shaders used in scene
314
     *
315
     * @return void
316
     */
317 22
    protected function prepareScripts()
318
    {
319 22
        (empty($this->scripts)) ?: $this->aframeDomObj->registerScripts($this->scripts);
320 22
    }
321
}
322