Completed
Push — master ( 431b60...331673 )
by Marko
10s
created

AframeDOMDocument::appendSceneComponents()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 11
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 11
ccs 5
cts 5
cp 1
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 4
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
     * A-Frame DOM
127
     *
128
     * @param Config $config            
129
     */
130 98
    public function __construct(Config $config)
131
    {
132
        /* Config */
133 98
        $this->configOptions($config);
134
        
135
        /* Create HTML5 Document type */
136 98
        $this->createDocType('html');
137
        
138
        /* Create A-Frame DOM Document */
139 98
        $this->createAframeDocument();
140
        
141
        /* Create boostrap elements */
142 98
        $this->documentBootstrap();
143 98
    }
144
145
    /**
146
     * Render scene this DOM Object is attached to
147
     *
148
     * @return string
149
     */
150 7
    public function render(): string
151
    {
152 7
        $html = $this->docObj->getElementsByTagName('html')->item(0);
153
        /* Make sure we do not add duplicates when render is called multiple times */
154 7
        if (! $html->hasChildNodes()) {
155 7
            $this->renderHead();
156
            
157 7
            $html->appendChild($this->head);
158
            
159 7
            $this->renderBody();
160
            
161 7
            $html->appendChild($this->body);
162
        }
163 7
        return $this->format_output ? $this->correctOutputFormat($this->docObj->saveHTML()) : $this->docObj->saveHTML();
164
    }
165
166
    /**
167
     * Set Scene meta title
168
     *
169
     * @param string $title            
170
     */
171 7
    public function setTitle(string $title)
172
    {
173 7
        $this->scene_title = $title;
174 7
    }
175
176
    /**
177
     * Set Scene meta description
178
     *
179
     * @param string $description            
180
     */
181 7
    public function setDescription(string $description)
182
    {
183 7
        $this->scene_description = $description;
184 7
    }
185
186
    /**
187
     * Append entities
188
     *
189
     * @param array $entities            
190
     * @return void
191
     */
192 9
    public function appendEntities(array $entities)
193
    {
194 9
        if (! empty($entities)) {
195 5
            foreach ($entities as $entity) {
196 5
                $this->appendEntity($entity);
197
            }
198
        }
199 9
    }
200
201
    /**
202
     * Append assets
203
     *
204
     * @param array $assets            
205
     * @return void
206
     */
207 2
    public function appendAssets(array $assets)
208
    {
209 2
        if (! empty($assets)) {
210 2
            if ($this->format_output) {
211 2
                $com = $this->docObj->createComment('');
212 2
                $this->scene->appendChild($com);
213
            }
214 2
            foreach ($assets as $asset) {
215 2
                $this->appendAsset($asset);
216
            }
217 2
            $this->scene->appendChild($this->assets);
218
        }
219 2
    }
220
221
    /**
222
     * Append asset
223
     *
224
     * Create asset DOMElement
225
     *
226
     * @param AssetsInterface $asset            
227
     */
228 2
    public function appendAsset(AssetsInterface $asset)
229
    {
230 2
        $this->appendFormatComment('assets', "\n\t");
231 2
        $this->assets->appendChild($asset->domElement($this->docObj));
232 2
    }
233
234
    /**
235
     * Create entity DOMElement
236
     *
237
     * Created entity and append it to scene
238
     *
239
     * @param Entity $entity            
240
     * @return void
241
     */
242 5
    public function appendEntity(Entity $entity)
243
    {
244 5
        $this->appendFormatComment('scene', "\n");
245 5
        $this->scene->appendChild($entity->domElement($this->docObj));
246 5
    }
247
248
    /**
249
     * Get HTML of Scene only
250
     *
251
     * @return string
252
     */
253 3
    public function renderSceneOnly()
254
    {
255 3
        $html               = new DOMDocument();
256 3
        $html->formatOutput = $this->format_output;
257
        
258 3
        $html_scene = $html->importNode($this->scene, true);
259 3
        $html->appendChild($html_scene);
260 3
        return $this->format_output ? $this->correctOutputFormat($html->saveHTML()) : $html->saveHTML();
261
    }
262
    
263
    /**
264
     * Add scene components
265
     * 
266
     * @param array $components
267
     * @return void
268
     */
269 9
    public function appendSceneComponents(array $components)
270
    {
271 9
        foreach ($components as $component) {
272
            /*
273
             * Check does component has any attributes to add to scene DOM element.
274
             * default attributes most of cases are ommited so we might not have any attributes to add
275
             */
276 1
            if ($component->hasDOMAttributes())
277 1
                $this->scene->setAttributeNode($component->getDOMAttr());
278
        }
279 9
    }
280
    
281
    /**
282
     * Set configuration option related to DOM
283
     * 
284
     * @param Config $config
285
     * @return void
286
     */
287 98
    protected function configOptions(Config $config)
288
    {
289 98
        $this->setConfigurationOption($config, 'format_output', false);
290 98
        $this->setConfigurationOption($config, 'cdn_url', null);
291 98
        $this->setConfigurationOption($config, 'use_cdn', false);
292 98
        $this->setConfigurationOption($config, 'assets_uri', '/aframe');
293 98
    }
294
    
295
    /**
296
     * Set individual option
297
     * 
298
     * @param Config $config
299
     * @param string $opt
300
     * @param mixed $default
301
     * @return void
302
     */
303 98
    protected function setConfigurationOption(Config $config, string $opt, $default)
304
    {
305 98
        $this->{$opt} = $config->get($opt) ?? $default;
306 98
    }
307
}
308