Test Setup Failed
Push — master ( 3f2310...2b4a21 )
by Jordan
03:55
created

Component::start()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 15
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 9
nc 3
nop 2
dl 0
loc 15
rs 9.9666
c 0
b 0
f 0
1
<?php
2
3
namespace Jhoff\BladeVue\Components;
4
5
use Exception;
6
use Illuminate\Support\Arr;
7
use Illuminate\Support\Str;
8
use Jhoff\BladeVue\Element;
9
10
abstract class Component
11
{
12
    /**
13
     * Dom element builder instance
14
     *
15
     * @var \Jhoff\BladeVue\Element
16
     */
17
    protected $element;
18
19
    /**
20
     * Default attributes to apply to the component
21
     *
22
     * @var array
23
     */
24
    protected static $defaultAttributes = [];
25
26
    /**
27
     * Builds a component element and returns the ending element tag
28
     *
29
     * @return string
30
     */
31
    public static function end() : string
32
    {
33
        return (new static)
34
            ->getEndTag();
35
    }
36
37
    /**
38
     * Builds a component element and returns the starting element tag
39
     *
40
     * @param string $name
41
     * @param array $attributes
42
     * @return string
43
     */
44
    public static function start(string $name, array $attributes = []) : string
45
    {
46
        if (count(func_get_args()) > 2) {
47
            throw new Exception('Too many arguments passed to vue directive');
48
        }
49
50
        if (!empty($attributes) && !Arr::isAssoc($attributes)) {
51
            throw new Exception('Second argument for vue directive must be an associtive array');
52
        }
53
54
        return (new static)
55
            ->setAttributes(static::$defaultAttributes)
56
            ->setAttribute('is', $name)
57
            ->setAttributes($attributes)
58
            ->getStartTag();
59
    }
60
61
    /**
62
     * Instantiates a new component element to build off of
63
     */
64
    protected function __construct()
65
    {
66
        $this->element = new Element('component');
67
    }
68
69
    /**
70
     * Gets the end tag from the element
71
     *
72
     * @return string
73
     */
74
    protected function getEndTag() : string
75
    {
76
        return $this->element->getEndTag();
77
    }
78
79
    /**
80
     * Gets the start tag from the element
81
     *
82
     * @return string
83
     */
84
    protected function getStartTag() : string
85
    {
86
        return $this->element->getStartTag();
87
    }
88
89
    /**
90
     * Resolves the given attribute to vue component form
91
     *
92
     * @param string $name
93
     * @param mixed $value
94
     * @return array
95
     */
96
    protected function resolveAttributeValue(string $name, $value) : array
97
    {
98
        if (is_bool($value)) {
99
            return [":$name", $value ? 'true' : 'false'];
100
        }
101
102
        if (is_numeric($value)) {
103
            return [":$name", $value];
104
        }
105
106
        if (!is_scalar($value) && !is_null($value)) {
107
            return [":$name", e(json_encode($value))];
108
        }
109
110
        return [$name, $value];
111
    }
112
113
    /**
114
     * Resolve and set an attribute on the element
115
     *
116
     * @param string $name
117
     * @param mixed $value
118
     * @return $this
119
     */
120
    protected function setAttribute(string $name, $value = null)
121
    {
122
        list($name, $value) = $this->resolveAttributeValue($name, $value);
123
124
        $this->element->setAttribute(Str::kebab($name), $value);
125
126
        return $this;
127
    }
128
129
    /**
130
     * Sets an array of attributes on the element
131
     *
132
     * @param array $attributes
133
     * @return $this
134
     */
135
    protected function setAttributes(array $attributes)
136
    {
137
        foreach ($attributes as $name => $value) {
138
            $this->setAttribute($name, $value);
139
        }
140
141
        return $this;
142
    }
143
}
144