Completed
Push — master ( 3bdb8b...8aadce )
by Freek
05:25 queued 01:17
created

Renderer::normalizeArguments()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 16
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 16
rs 9.2
c 0
b 0
f 0
cc 4
eloc 8
nc 4
nop 1
1
<?php
2
3
namespace Spatie\BladeJavaScript;
4
5
use Illuminate\Config\Repository;
6
use Illuminate\Contracts\Support\Arrayable;
7
use Illuminate\Support\Collection;
8
use Spatie\BladeJavaScript\Exceptions\Untransformable;
9
use Spatie\BladeJavaScript\Transformers\ArrayTransformer;
10
use Spatie\BladeJavaScript\Transformers\BooleanTransformer;
11
use Spatie\BladeJavaScript\Transformers\NullTransformer;
12
use Spatie\BladeJavaScript\Transformers\NumericTransformer;
13
use Spatie\BladeJavaScript\Transformers\ObjectTransformer;
14
use Spatie\BladeJavaScript\Transformers\StringTransformer;
15
use Spatie\BladeJavaScript\Transformers\Transformer;
16
17
class Renderer
18
{
19
    protected $namespace = 'window';
20
21
    protected $transformers = [
22
        ArrayTransformer::class,
23
        BooleanTransformer::class,
24
        NullTransformer::class,
25
        NumericTransformer::class,
26
        ObjectTransformer::class,
27
        StringTransformer::class,
28
    ];
29
30
    public function __construct(Repository $config)
31
    {
32
        $this->namespace = $config->get('laravel-blade-javascript.namespace', 'window');
33
    }
34
35
    /**
36
     * @param array ...$arguments
37
     *
38
     * @return string
39
     */
40
    public function render(...$arguments): string
41
    {
42
        $variables = $this->normalizeArguments($arguments);
43
44
        return '<script>'.$this->buildJavaScriptSyntax($variables).'</script>';
45
    }
46
47
    /**
48
     * @param $arguments
49
     *
50
     * @return mixed
51
     */
52
    protected function normalizeArguments(array $arguments)
53
    {
54
        if (count($arguments) === 2) {
55
            return [$arguments[0] => $arguments[1]];
56
        }
57
58
        if ($arguments[0] instanceof Arrayable) {
59
            return $arguments[0]->toArray();
60
        }
61
62
        if (!is_array($arguments[0])) {
63
            $arguments[0] = [$arguments[0]];
64
        }
65
66
        return $arguments[0];
67
    }
68
69
    public function buildJavaScriptSyntax(array $variables): string
70
    {
71
        return collect($variables)
72
            ->map(function ($value, $key) {
73
                return $this->buildVariableInitialization($key, $value);
74
            })
75
            ->reduce(function ($javaScriptSyntax, $variableInitialization) {
76
                return $javaScriptSyntax.$variableInitialization;
77
            }, $this->buildNamespaceDeclaration());
78
    }
79
80
    protected function buildNamespaceDeclaration(): string
81
    {
82
        if (empty($this->namespace)) {
83
            return '';
84
        }
85
86
        return "window['{$this->namespace}'] = window['{$this->namespace}'] || {};";
87
    }
88
89
    /**
90
     * @param string $key
91
     * @param mixed  $value
92
     *
93
     * @return string
94
     */
95
    protected function buildVariableInitialization(string $key, $value)
96
    {
97
        $variableName = $this->namespace ? "window['{$this->namespace}']['{$key}']" : "window['{$key}']";
98
99
        return "{$variableName} = {$this->optimizeValueForJavaScript($value)};";
100
    }
101
102
    /**
103
     * @param mixed $value
104
     *
105
     * @return string
106
     *
107
     * @throws \Spatie\BladeJavaScript\Exceptions\Untransformable
108
     */
109
    protected function optimizeValueForJavaScript($value): string
110
    {
111
        return $this->getTransformer($value)->transform($value);
112
    }
113
114
    public function getAllTransformers(): Collection
115
    {
116
        return collect($this->transformers)->map(function (string $className): Transformer {
117
            return new $className();
118
        });
119
    }
120
121
    /**
122
     * @param mixed $value
123
     *
124
     * @return \Spatie\BladeJavaScript\Transformers\Transformer
125
     *
126
     * @throws \Spatie\BladeJavaScript\Exceptions\Untransformable
127
     */
128
    public function getTransformer($value): Transformer
129
    {
130
        foreach($this->getAllTransformers() as $transformer)
131
        {
132
             if ($transformer->canTransform($value)) {
133
                 return $transformer;
134
             };
135
        }
136
137
        throw Untransformable::noTransformerFound($value);
138
    }
139
}
140