Completed
Pull Request — master (#66)
by Marko
06:34
created

AframeDOMDocument::appendSceneAttributes()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 8
ccs 0
cts 0
cp 0
rs 9.2
cc 4
eloc 5
nc 4
nop 1
crap 20
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 98
     * @var array $scripts
131
     */
132
    protected $scripts = array();
133 98
134
    /**
135
     * A-Frame DOM
136 98
     *
137
     * @param Config $config
138
     */
139 98
    public function __construct(Config $config)
140
    {
141
        /* Config */
142 98
        $this->configOptions($config);
143 98
144
        /* Create HTML5 Document type */
145
        $this->createDocType('html');
146
147
        /* Create A-Frame DOM Document */
148
        $this->createAframeDocument();
149
150 8
        /* Create boostrap elements */
151
        $this->documentBootstrap();
152 8
    }
153
154 8
    /**
155 8
     * Render scene this DOM Object is attached to
156
     *
157 8
     * @return string
158
     */
159 8
    public function render(): string
160
    {
161 8
        $html = $this->docObj->getElementsByTagName('html')->item(0);
162
        /* Make sure we do not add duplicates when render is called multiple times */
163 8
        if (! $html->hasChildNodes()) {
164
            $this->renderHead();
165
166
            $html->appendChild($this->head);
167
168
            $this->renderBody();
169
170
            $html->appendChild($this->body);
171 1
        }
172
        return $this->format_output ? $this->correctOutputFormat($this->docObj->saveHTML()) : $this->docObj->saveHTML();
173 1
    }
174 1
175
    /**
176
     * Set Scene meta title
177
     *
178
     * @param string $title
179
     */
180
    public function setTitle(string $title)
181 1
    {
182
        $this->scene_title = $title;
183 1
    }
184 1
185
    /**
186
     * Set Scene meta description
187
     *
188
     * @param string $description
189
     */
190
    public function setDescription(string $description)
191
    {
192 19
        $this->scene_description = $description;
193
    }
194 19
195 11
    /**
196 11
     * Append entities
197
     *
198
     * @param array $entities
199 19
     * @return void
200
     */
201
    public function appendEntities(array $entities)
202
    {
203
        if (! empty($entities)) {
204
            foreach ($entities as $entity) {
205
                $this->appendEntity($entity);
206
            }
207 2
        }
208
    }
209 2
210 2
    /**
211 2
     * Append assets
212 2
     *
213
     * @param array $assets
214 2
     * @return void
215 2
     */
216
    public function appendAssets(array $assets)
217 2
    {
218
        if (! empty($assets)) {
219 2
            if ($this->format_output) {
220
                $com = $this->docObj->createComment('');
221
                $this->scene->appendChild($com);
222
            }
223
            foreach ($assets as $asset) {
224
                $this->appendAsset($asset);
225
            }
226
            $this->scene->appendChild($this->assets);
227
        }
228 2
    }
229
230 2
    /**
231 2
     * Register scripts to be added to DOM
232 2
     *
233
     * @param array $scripts
234
     * @return void
235
     */
236
    public function registerScripts(array $scripts)
237
    {
238
        $this->scripts = array_merge($this->scripts, $scripts);
239
    }
240
    /**
241
     * Append scripts
242 13
     *
243
     * @param array $scripts
244 13
     * @return void
245 13
     */
246 13
    public function appendScripts(array $scripts)
247
    {
248
        foreach($scripts as $url => $use) {
249
            (!$use)?:$this->appendScript($url);
250
        }
251
    }
252
253 12
    /**
254
     * Append script
255 12
     *
256 12
     * @param string $script_uri
257
     * @return void
258 12
     */
259 12
    public function appendScript(string $script_uri)
260 12
    {
261
        $extra_script_url = sprintf('%s%s',$this->assets_uri, $script_uri);
262
        $extra_script     = $this->docObj->createElement('script');
263
        $extra_script->setAttribute('src', $extra_script_url);
264
        $this->head->appendChild($extra_script);
265
    }
266
    /**
267
     * Append asset
268
     *
269 19
     * Create asset DOMElement
270
     *
271 19
     * @param AssetsInterface $asset
272
     */
273
    public function appendAsset(AssetsInterface $asset)
274
    {
275
        $this->appendFormatComment('assets', "\n\t");
276 1
        $this->assets->appendChild($asset->domElement($this->docObj));
277 1
    }
278
279 19
    /**
280
     * Create entity DOMElement
281
     *
282
     * Created entity and append it to scene
283
     *
284
     * @param Entity $entity
285
     * @return void
286
     */
287 98
    public function appendEntity(Entity $entity)
288
    {
289 98
        $this->appendFormatComment('scene', "\n");
290 98
        $this->scene->appendChild($entity->domElement($this->docObj));
291 98
    }
292 98
293 98
    /**
294
     * Get HTML of Scene only
295
     *
296
     * @return string
297
     */
298
    public function renderSceneOnly()
299
    {
300
        $html               = new DOMDocument();
301
        $html->formatOutput = $this->format_output;
302
303 98
        $html_scene = $html->importNode($this->scene, true);
304
        $html->appendChild($html_scene);
305 98
        return $this->format_output ? $this->correctOutputFormat($html->saveHTML()) : $html->saveHTML();
306 98
    }
307
308
    /**
309
     * Add scene components
310
     *
311
     * @param array $components
312
     * @return void
313
     */
314
    public function appendSceneComponents(array $components)
315
    {
316
        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
            if ($component->hasDOMAttributes())
322
                $this->scene->setAttributeNode($component->getDOMAttr());
323
        }
324
    }
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
    public function appendSceneAttributes(array $attrs)
332
    {
333
        foreach ($attrs as $attr => $val) {
334
            if(is_bool($val))
335
                $val = $val ? '' : 'false';
336
                $this->appendSceneAttribute($attr, $val);
337
        }
338
    }
339
340
    private function appendSceneAttribute($attr, $val)
341
    {
342
        if ($attr === 'id' && is_numeric($val))
343
            return;
344
345
            $this->scene->setAttribute($attr, $val);
346
    }
347
348
349
    /**
350
     * Set configuration option related to DOM
351
     *
352
     * @param Config $config
353
     * @return void
354
     */
355
    protected function configOptions(Config $config)
356
    {
357
        $this->setConfigurationOption($config, 'format_output', false);
358
        $this->setConfigurationOption($config, 'cdn_url', null);
359
        $this->setConfigurationOption($config, 'use_cdn', false);
360
        $this->setConfigurationOption($config, 'assets_uri', '/aframe');
361
    }
362
363
    /**
364
     * Set individual option
365
     *
366
     * @param Config $config
367
     * @param string $opt
368
     * @param mixed $default
369
     * @return void
370
     */
371
    protected function setConfigurationOption(Config $config, string $opt, $default)
372
    {
373
        $this->{$opt} = $config->get($opt) ?? $default;
374
    }
375
}
376