Completed
Push — master ( 5fc4df...311e23 )
by Freek
02:49
created

Renderer::buildJavaScriptSyntax()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 10
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 5
nc 2
nop 1
1
<?php
2
3
namespace Spatie\BladeJavaScript;
4
5
use Illuminate\Config\Repository;
6
use Illuminate\Contracts\Support\Arrayable;
7
8
class Renderer
9
{
10
    protected $namespace;
11
12
    public function __construct(Repository $config)
13
    {
14
        $this->namespace = $config->get('laravel-blade-javascript.namespace') ?? 'window';
15
    }
16
17
    /**
18
     * @param array ...$arguments
19
     *
20
     * @return string
21
     */
22
    public function render(...$arguments): string
23
    {
24
        $variables = $this->normalizeArguments($arguments);
25
26
        return '<script type="text/javascript">'.$this->buildJavaScriptSyntax($variables).'</script>';
27
    }
28
29
    /**
30
     * @param $arguments
31
     *
32
     * @return array
33
     */
34
    protected function normalizeArguments($arguments)
35
    {
36
        if ($arguments[0] instanceof Arrayable) {
37
            return $arguments[0]->toArray();
38
        }
39
40
        if (count($arguments) == 2) {
41
            return [$arguments[0] => $arguments[1]];
42
        }
43
44
        return $arguments[0];
45
    }
46
47
    /**
48
     * @param array $variables
49
     *
50
     * @return array
51
     */
52
    public function buildJavaScriptSyntax($variables)
53
    {
54
        $js = $this->buildNamespaceDeclaration();
55
56
        foreach ($variables as $key => $value) {
57
            $js .= $this->buildVariableInitialization($key, $value);
58
        }
59
60
        return $js;
61
    }
62
63
    /**
64
     * @return string
65
     */
66
    protected function buildNamespaceDeclaration()
67
    {
68
        if ($this->namespace == 'window') {
69
            return '';
70
        }
71
72
        return "window.{$this->namespace} = window.{$this->namespace} || {};";
73
    }
74
75
    /**
76
     * @param string $key
77
     * @param string $value
78
     *
79
     * @return string
80
     */
81
    protected function buildVariableInitialization($key, $value)
82
    {
83
        return "{$this->namespace}.{$key} = {$this->optimizeValueForJavaScript($value)};";
84
    }
85
86
    /**
87
     * @param string $value
88
     *
89
     * @return string
90
     *
91
     * @throws \Exception
92
     */
93
    protected function optimizeValueForJavaScript($value)
94
    {
95
        $transformers = $this->getAllTransformers();
96
97
        $transformers = $transformers->filter(function (Transformer $transformer) use ($value) {
98
           return $transformer->canTransform($value);
99
        });
100
101
        if ($transformers->isEmpty()) {
102
            throw new \Exception("Cannot transform value {$value}");
103
        }
104
105
        return $transformers->first()->transform($value);
106
    }
107
108
    public function getAllTransformers()
109
    {
110
        return collect(glob(__DIR__.'/Transformers/*.php'))->map(function ($fileName) {
111
            $className = pathinfo($fileName, PATHINFO_FILENAME);
112
113
            $fullClassName = '\\Spatie\\BladeJavaScript\\Transformers\\'.$className;
114
115
            return new $fullClassName();
116
        });
117
    }
118
}
119