DocBlock::getOutput()   C
last analyzed

Complexity

Conditions 8
Paths 16

Size

Total Lines 43
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 24
CRAP Score 8

Importance

Changes 0
Metric Value
cc 8
eloc 25
nc 16
nop 0
dl 0
loc 43
ccs 24
cts 24
cp 1
crap 8
rs 5.3846
c 0
b 0
f 0
1
<?php
2
3
namespace Jhoff\PhpEditor;
4
5
use Illuminate\Support\Str;
6
use Illuminate\Support\Collection;
7
8
class DocBlock
9
{
10
    /**
11
     * DocBlock message
12
     *
13
     * @var string|null
14
     */
15
    protected $message = null;
16
17
    /**
18
     * DocBlock description
19
     *
20
     * @var string|null
21
     */
22
    protected $description = null;
23
24
    /**
25
     * DocBlock tags
26
     *
27
     * @var array
28
     */
29
    protected $tags = [];
30
31
    /**
32
     * Create a new instance from a set of options
33
     *
34
     * @param array $options
35
     *
36
     * @return static
37
     */
38 4
    public static function create(array $options)
39
    {
40 4
        if (isset($options['message'])) {
41 1
            $message = $options['message'];
42 1
            unset($options['message']);
43
        }
44
45 4
        if (isset($options['description'])) {
46 1
            $description = $options['description'];
47 1
            unset($options['description']);
48
        }
49
50 4
        return new static($message ?? null, $description ?? null, $options);
51
    }
52
53
    /**
54
     * Instantiate a new docblock builder
55
     *
56
     * @param mixed $message
57
     * @param mixed $description
58
     * @param array $tags
59
     */
60 15
    public function __construct($message = null, $description = null, array $tags = [])
61
    {
62 15
        if (is_array($message)) {
63 3
            $this->tags = $message;
64 3
            return;
65
        }
66
67 12
        if (is_array($description)) {
68 1
            $this->message = $message;
69 1
            $this->tags = $description;
70 1
            return;
71
        }
72
73 11
        $this->message = $message;
74 11
        $this->description = $description;
75 11
        $this->tags = $tags;
76 11
    }
77
78
    /**
79
     * Dynamic getter for tag values
80
     *
81
     * @param string $property
82
     *
83
     * @return string
84
     */
85 4
    public function __get(string $property)
86
    {
87 4
        if ($property === 'message') {
88 2
            return $this->message;
89
        }
90
91 3
        if ($property === 'description') {
92 2
            return $this->description;
93
        }
94
95 2
        return $this->tags[$property];
96
    }
97
98
    /**
99
     * Dynamic setter
100
     *
101
     * @param string $property
102
     * @param mixed $value
103
     *
104
     * @return void
105
     */
106 2
    public function __set(string $property, $value)
107
    {
108 2
        if ($property === 'message') {
109 2
            return $this->message = $value;
110
        }
111
112 2
        if ($property === 'description') {
113 2
            return $this->description = $value;
114
        }
115
116 2
        $this->tags[$property] = $value;
117 2
    }
118
119
    /**
120
     * Return the string representation of the docblock
121
     *
122
     * @return string
123
     */
124 1
    public function __toString()
125
    {
126 1
        return $this->getOutput();
127
    }
128
129
    /**
130
     * Gets the output
131
     *
132
     * @return string
133
     */
134 11
    public function getOutput()
135
    {
136 11
        $groups = new Collection;
137
138 11
        if ($this->message) {
139 5
            $groups->push($this->message);
140
        }
141
142 11
        if ($this->description) {
143 4
            $groups->push($this->description);
144
        }
145
146 11
        if (!empty($tags = static::filterTags($this->tags))) {
147 7
            foreach ($tags as $tag => $values) {
148 7
                $group = new Collection;
149
150 7
                foreach ((array) $values as $value) {
151 7
                    $group->push(
152 7
                        $value === true
153 1
                            ? "@$tag"
154 7
                            : "@$tag $value"
155
                    );
156
                }
157
158 7
                $groups->push($group);
159
            }
160
        }
161
162 11
        if ($groups->isEmpty()) {
163 4
            return "/**\n *\n */";
164
        }
165
166
        return "/**\n" .
167
            $groups
168
                ->transform(function ($group) {
169 7
                    return Collection::wrap($group)
170
                        ->transform(function ($line) {
171 7
                            return " * $line";
172 7
                        })
173 7
                        ->implode("\n");
174 7
                })
175 7
                ->implode("\n *\n") .
176 7
            "\n */";
177
    }
178
179
    /**
180
     * Removes any tags or nested tags that are set to false
181
     *
182
     * @param array $tags
183
     * @return array
184
     */
185 11
    protected static function filterTags(array $tags)
186
    {
187 11
        foreach (array_keys($tags) as $key) {
188 7
            if (is_array($tags[$key])) {
189 1
                $tags[$key] = static::filterTags($tags[$key]);
190
            }
191
192 7
            if ($tags[$key] === false) {
193 7
                unset($tags[$key]);
194
            }
195
        }
196
197 11
        return $tags;
198
    }
199
}
200