Completed
Push — master ( fa2f20...0aef32 )
by Marko
02:47
created

AframeDOMDocument::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 15
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 15
ccs 8
cts 8
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 7
nc 1
nop 1
crap 1
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
32
final class AframeDOMDocument extends DOMImplementation
33
{
34
35
    /**
36
     * A-Frame DOM Document type
37
     *
38
     * @var \DOMDocumentType
39
     */
40
    protected $doctypeObj;
41
42
    /**
43
     * A-Frame DOM Document
44
     *
45
     * @var \DOMDocument
46
     */
47
    protected $docObj;
48
49
    /**
50
     * Scene meta tile
51
     *
52
     * @var string $scene_title
53
     */
54
    protected $scene_title = 'Untitled';
55
56
    /**
57
     * Scene meta description
58
     *
59
     * @var string $scene_description
60
     */
61
    protected $scene_description = '';
62
63
    /**
64
     * CDN Of aframe.js
65
     *
66
     * @var string
67
     */
68
    protected $aframe_cdn;
69
70
    /**
71
     * Whether to use CDN
72
     *
73
     * @var bool $use_cdn
74
     */
75
    protected $use_cdn = false;
76
77
    /**
78
     * <head>
79
     *
80
     * @var \DOMElement $head
81
     */
82
    protected $head;
83
84
    /**
85
     * <body>
86
     *
87
     * @var \DOMElement $body
88
     */
89
    protected $body;
90
91
    /**
92
     * <a-scene>
93
     *
94
     * @var \DOMElement $scene
95
     */
96
    protected $scene;
97
98
    /**
99
     * Nicely formats output with indentation and extra space.
100
     *
101
     * @var bool
102
     */
103
    public $formatOutput = true;
104
105
    /**
106
     * A-Frame DOM
107
     *
108
     * @param Config $config            
109
     */
110 60
    public function __construct(Config $config)
111
    {
112
        /* Create HTML5 Document type */
113 60
        $this->createDocType('html');
114
        /* Create A-Frame DOM Document */
115 60
        $this->createAframeDocument();
116
        /* Create <head> element */
117 60
        $this->createHead();
118
        /* Create <body> element */
119 60
        $this->createBody();
120
        /* Create <a-scene> element */
121 60
        $this->createScene();
122
        /* Set CDN of aframe.js */
123 60
        $this->setCDN($config->get('CDN'));
124 60
    }
125
126
    /**
127
     * Load aframe.in.js from CDN
128
     *
129
     * @return void
130
     */
131 2
    public function useCDN()
132
    {
133 2
        $this->use_cdn = true;
134 2
    }
135
136
    /**
137
     * Set CDN for aframe.js or min.js
138
     *
139
     * @param string $cdn            
140
     * @return void
141
     */
142 60
    public function setCDN(string $cdn)
143
    {
144 60
        $this->aframe_cdn = $cdn;
145 60
    }
146
147
    /**
148
     * Render scene this DOM Object is attached to
149
     *
150
     * @return string
151
     */
152 3
    public function render(): string
153
    {
154 3
        $this->docObj->formatOutput = $this->formatOutput;
155 3
        $html = $this->docObj->getElementsByTagName('html')[0];
156
        
157 3
        $this->renderHead();
158 3
        $html->appendChild($this->head);
159
        
160 3
        $this->renderBody();
161 3
        $html->appendChild($this->body);
162 3
        return $this->docObj->saveHTML();
163
    }
164
165
    /**
166
     * Set Scene meta title
167
     *
168
     * @param string $title            
169
     */
170 2
    public function setTitle(string $title)
171
    {
172 2
        $this->scene_title = $title;
173 2
    }
174
175
    /**
176
     * Set Scene meta description
177
     *
178
     * @param string $description            
179
     */
180 2
    public function setDescription(string $description)
181
    {
182 2
        $this->scene_description = $description;
183 2
    }
184
185
    /**
186
     * Append entities
187
     *
188
     * @param array $entities            
189
     * @return void
190
     */
191 3
    public function appendEntities(array $entities)
192
    {
193 3
        if (! empty($entities)) {
194 1
            foreach ($entities as $entity) {
195 1
                $this->appendEntity($entity);
196
            }
197
        }
198 3
    }
199
200
    /**
201
     * Add entity
202
     *
203
     * @param Entity $entity            
204
     * @return void
205
     */
206 1
    public function appendEntity(Entity $entity)
207
    {
208 1
        $this->scene->appendChild($entity->DOMElement($this->docObj));
209 1
    }
210
211
    /**
212
     * Get HTML of Scene only
213
     *
214
     * @return string
215
     */
216 1
    public function renderSceneOnly()
217
    {
218 1
        $html = new DOMDocument();
219 1
        $html_scene = $html->importNode($this->scene, true);
220 1
        $html->appendChild($html_scene);
221 1
        return $html->saveHTML();
222
    }
223
224
    /**
225
     * Prepeare head
226
     *
227
     * @return void
228
     */
229 3
    protected function renderHead()
230
    {
231 3
        $this->appendTitle();
232 3
        $this->appendDefaultMetaTags();
233 3
        $this->appendCDN();
234 3
    }
235
236
    /**
237
     * Append deffault metatags
238
     *
239
     * @return void
240
     */
241 3
    protected function appendDefaultMetaTags()
242
    {
243 3
        foreach ($this->getDefaultMetaTags() as $tag)
244 3
            $this->appendMetaTag($tag);
245 3
    }
246
247
    /**
248
     * Get default meta tags
249
     *
250
     * @return array
251
     */
252 3
    protected function getDefaultMetaTags(): array
253
    {
254
        return array(
255
            array(
256 3
                'name' => 'description',
257 3
                'content' => $this->scene_description
258 3
            ),
259
            array(
260
                'charset' => 'utf-8'
261
            ),
262
            array(
263
                'name' => 'viewport',
264
                'content' => 'width=device-width,initial-scale=1,maximum-scale=1,shrink-to-fit=no,user-scalable=no,minimal-ui'
265
            ),
266
            array(
267
                'name' => 'mobile-web-app-capable',
268
                'content' => 'yes'
269
            ),
270
            array(
271
                'name' => 'theme-color',
272
                'content' => 'black'
273
            )
274
        );
275
    }
276
277
    /**
278
     * If requested by user use aframe CDN
279
     *
280
     * @return void
281
     */
282 3
    protected function appendCDN()
283
    {
284 3
        if ($this->use_cdn) {
285 2
            $cdn_script = $this->docObj->createElement('script');
286 2
            $cdn_script->setAttribute('src', $this->aframe_cdn);
287 2
            $this->head->appendChild($cdn_script);
288
        }
289 3
    }
290
291
    /**
292
     * Prepare body
293
     *
294
     * @return void
295
     */
296 3
    protected function renderBody()
297
    {
298 3
        $this->body->appendChild($this->scene);
299 3
    }
300
301
    /**
302
     * Create meta tags
303
     *
304
     * @param array $attr            
305
     */
306 3
    protected function appendMetaTag(array $attr)
307
    {
308 3
        $metatag = $this->docObj->createElement('meta');
309 3
        foreach ($attr as $key => $val)
310 3
            $metatag->setAttribute($key, $val);
311 3
        $this->head->appendChild($metatag);
312 3
    }
313
314
    /**
315
     * Create title tag
316
     *
317
     * @return void
318
     */
319 3
    protected function appendTitle()
320
    {
321 3
        $title = $this->docObj->createElement('title', $this->scene_title);
322 3
        $this->head->appendChild($title);
323 3
    }
324
325
    /**
326
     * Creates an empty DOMDocumentType object
327
     *
328
     * @param string $doctype            
329
     * @return void
330
     */
331 60
    protected function createDocType(string $doctype)
332
    {
333 60
        $this->doctypeObj = $this->createDocumentType($doctype);
334 60
    }
335
336
    /**
337
     * Creates a DOMDocument object of the specified type with its document element
338
     *
339
     * @return void
340
     */
341 60
    protected function createAframeDocument()
342
    {
343 60
        $this->docObj = $this->createDocument(null, 'html', $this->doctypeObj);
344 60
    }
345
346
    /**
347
     * Create <head> element node
348
     *
349
     * @return void
350
     */
351 60
    protected function createHead()
352
    {
353 60
        $this->head = $this->docObj->createElement('head');
354 60
    }
355
356
    /**
357
     * Create <body> element node
358
     *
359
     * @return void
360
     */
361 60
    protected function createBody()
362
    {
363 60
        $this->body = $this->docObj->createElement('body');
364 60
    }
365
366
    /**
367
     * Create <a-scene> element node
368
     *
369
     * @return void
370
     */
371 60
    protected function createScene()
372
    {
373 60
        $this->scene = $this->docObj->createElement('a-scene');
374 60
    }
375
}
376