AframeDOMDocument::appendScripts()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 3

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 6
ccs 4
cts 4
cp 1
rs 9.4285
cc 3
eloc 3
nc 3
nop 1
crap 3
1
<?php
2
/** @formatter:off
3
 * ******************************************************************
4
 * Created by   Marko Kungla on Jun 27, 2016 - 9:55:09 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         AframeDOMDocument.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\DOM;
25
26
use \AframeVR\Core\Config;
27
use \DOMImplementation;
28
use \DOMDocumentType;
29
use \DOMDocument;
30
use \AframeVR\Core\Entity;
31
use \AframeVR\Interfaces\AssetsInterface;
32
33
final class AframeDOMDocument extends DOMImplementation
34
{
35
    use AframeDOMProcessor;
36
37
    /**
38
     * A-Frame DOM Document type
39
     *
40
     * @var \DOMDocumentType
41
     */
42
    protected $doctypeObj;
43
44
    /**
45
     * A-Frame DOM Document
46
     *
47
     * @var \DOMDocument
48
     */
49
    protected $docObj;
50
51
    /**
52
     * Scene meta tile
53
     *
54
     * @var string $scene_title
55
     */
56
    protected $scene_title = 'Untitled';
57
58
    /**
59
     * Scene meta description
60
     *
61
     * @var string $scene_description
62
     */
63
    protected $scene_description = '';
64
65
    /**
66
     * <head>
67
     *
68
     * @var \DOMElement
69
     */
70
    protected $head;
71
72
    /**
73
     * <body>
74
     *
75
     * @var \DOMElement
76
     */
77
    protected $body;
78
79
    /**
80
     * <a-scene>
81
     *
82
     * @var \DOMElement
83
     */
84
    protected $scene;
85
86
    /**
87
     * <a-assets>
88
     *
89
     * @var \DOMElement
90
     */
91
    protected $assets;
92
93
    /************
94
     * CONFIG
95
     ***********/
96
97
    /**
98
     * Nicely formats output with indentation and extra space.
99
     *
100
     * @var bool
101
     */
102
    protected $format_output = false;
103
104
    /**
105
     * CDN Of aframe.js
106
     *
107
     * @var string
108
     */
109
    protected $cdn_url;
110
111
    /**
112
     * Whether to use CDN
113
     *
114
     * @var bool $use_cdn
115
     */
116
    protected $use_cdn = false;
117
118
    /**
119
     * aframe assets URI relative to App's base URL / domain
120
     *
121
     * @var string assets_uri
122
     */
123
    protected $assets_uri;
124
125
    /**
126
     * Extra scrits to add into head
127
     *
128
     * Like components and shaders
129
     *
130
     * @var array $scripts
131
     */
132
    protected $scripts = array();
133
134
    /**
135
     * A-Frame DOM
136
     *
137
     * @param Config $config
138
     */
139 103
    public function __construct(Config $config)
140
    {
141
        /* Config */
142 103
        $this->configOptions($config);
143
144
        /* Create HTML5 Document type */
145 103
        $this->createDocType('html');
146
147
        /* Create A-Frame DOM Document */
148 103
        $this->createAframeDocument();
149
150
        /* Create boostrap elements */
151 103
        $this->documentBootstrap();
152 103
    }
153
154
    /**
155
     * Render scene this DOM Object is attached to
156
     *
157
     * @return string
158
     */
159 13
    public function render(): string
160
    {
161 13
        $html = $this->docObj->getElementsByTagName('html')->item(0);
162
        /* Make sure we do not add duplicates when render is called multiple times */
163 13
        if (! $html->hasChildNodes()) {
164 13
            $this->renderHead();
165
166 13
            $html->appendChild($this->head);
167
168 13
            $this->renderBody();
169
170 13
            $html->appendChild($this->body);
171
        }
172 13
        return $this->format_output ? $this->correctOutputFormat($this->docObj->saveHTML()) : $this->docObj->saveHTML();
173
    }
174
175
    /**
176
     * Set Scene meta title
177
     *
178
     * @param string $title
179
     */
180 1
    public function setTitle(string $title)
181
    {
182 1
        $this->scene_title = $title;
183 1
    }
184
185
    /**
186
     * Set Scene meta description
187
     *
188
     * @param string $description
189
     */
190 1
    public function setDescription(string $description)
191
    {
192 1
        $this->scene_description = $description;
193 1
    }
194
195
    /**
196
     * Append entities
197
     *
198
     * @param array $entities
199
     * @return void
200
     */
201 24
    public function appendEntities(array $entities)
202
    {
203 24
        if (! empty($entities)) {
204 12
            foreach ($entities as $entity) {
205 12
                $this->appendEntity($entity);
206
            }
207
        }
208 24
    }
209
210
    /**
211
     * Append assets
212
     *
213
     * @param array $assets
214
     * @return void
215
     */
216 3
    public function appendAssets(array $assets)
217
    {
218 3
        if (! empty($assets)) {
219 3
            if ($this->format_output) {
220 3
                $com = $this->docObj->createComment('');
221 3
                $this->scene->appendChild($com);
222
            }
223 3
            foreach ($assets as $asset) {
224 3
                $this->appendAsset($asset);
225
            }
226 3
            $this->scene->appendChild($this->assets);
227
        }
228 3
    }
229
230
    /**
231
     * Register scripts to be added to DOM
232
     *
233
     * @param array $scripts
234
     * @return void
235
     */
236 2
    public function registerScripts(array $scripts)
237
    {
238 2
        $this->scripts = array_merge($this->scripts, $scripts);
239 2
    }
240
    /**
241
     * Append scripts
242
     *
243
     * @param array $scripts
244
     * @return void
245
     */
246 13
    public function appendScripts(array $scripts)
247
    {
248 13
        foreach($scripts as $url => $use) {
249 2
            (!$use)?:$this->appendScript($url);
250
        }
251 13
    }
252
253
    /**
254
     * Append script
255
     *
256
     * @param string $script_uri
257
     * @return void
258
     */
259 2
    public function appendScript(string $script_uri)
260
    {
261 2
        $extra_script_url = sprintf('%s%s',$this->assets_uri, $script_uri);
262 2
        $extra_script     = $this->docObj->createElement('script');
263 2
        $extra_script->setAttribute('src', $extra_script_url);
264 2
        $this->head->appendChild($extra_script);
265 2
    }
266
    /**
267
     * Append asset
268
     *
269
     * Create asset DOMElement
270
     *
271
     * @param AssetsInterface $asset
272
     */
273 3
    public function appendAsset(AssetsInterface $asset)
274
    {
275 3
        $this->appendFormatComment('assets', "\n\t");
276 3
        $this->assets->appendChild($asset->domElement($this->docObj));
277 3
    }
278
279
    /**
280
     * Create entity DOMElement
281
     *
282
     * Created entity and append it to scene
283
     *
284
     * @param Entity $entity
285
     * @return void
286
     */
287 14
    public function appendEntity(Entity $entity)
288
    {
289 14
        $this->appendFormatComment('scene', "\n");
290 14
        $this->scene->appendChild($entity->domElement($this->docObj));
291 14
    }
292
293
    /**
294
     * Get HTML of Scene only
295
     *
296
     * @return string
297
     */
298 12
    public function renderSceneOnly()
299
    {
300 12
        $html               = new DOMDocument();
301 12
        $html->formatOutput = $this->format_output;
302
303 12
        $html_scene = $html->importNode($this->scene, true);
304 12
        $html->appendChild($html_scene);
305 12
        return $this->format_output ? $this->correctOutputFormat($html->saveHTML()) : $html->saveHTML();
306
    }
307
308
    /**
309
     * Add scene components
310
     *
311
     * @param array $components
312
     * @return void
313
     */
314 24
    public function appendSceneComponents(array $components)
315
    {
316 24
        foreach ($components as $component) {
317
            /*
318
             * Check does component has any attributes to add to scene DOM element.
319
             * default attributes most of cases are ommited so we might not have any attributes to add
320
             */
321 1
            if ($component->hasDOMAttributes())
322 1
                $this->scene->setAttributeNode($component->getDOMAttr());
323
        }
324 24
    }
325
326
    /**
327
     * Append DOM attributes no set by components
328
     *
329
     * @param \DOMElement $a_entity
0 ignored issues
show
Bug introduced by
There is no parameter named $a_entity. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
330
     */
331 24
    public function appendSceneAttributes(array $attrs)
332
    {
333 24
        foreach ($attrs as $attr => $val) {
334 2
            if(is_bool($val))
335 1
                $val = $val ? '' : 'false';
336 2
                $this->appendSceneAttribute($attr, $val);
337
        }
338 24
    }
339
340 2
    private function appendSceneAttribute($attr, $val)
341
    {
342 2
        if ($attr === 'id' || is_numeric($val))
343 1
            return;
344
345 2
            $this->scene->setAttribute($attr, $val);
346 2
    }
347
348
349
    /**
350
     * Set configuration option related to DOM
351
     *
352
     * @param Config $config
353
     * @return void
354
     */
355 103
    protected function configOptions(Config $config)
356
    {
357 103
        $this->setConfigurationOption($config, 'format_output', false);
358 103
        $this->setConfigurationOption($config, 'cdn_url', null);
359 103
        $this->setConfigurationOption($config, 'use_cdn', false);
360 103
        $this->setConfigurationOption($config, 'assets_uri', '/aframe');
361 103
    }
362
363
    /**
364
     * Set individual option
365
     *
366
     * @param Config $config
367
     * @param string $opt
368
     * @param mixed $default
369
     * @return void
370
     */
371 103
    protected function setConfigurationOption(Config $config, string $opt, $default)
372
    {
373 103
        $this->{$opt} = $config->get($opt) ?? $default;
374 103
    }
375
}
376