Completed
Push — master ( e54ea7...7cecbb )
by Oleg
05:53
created

Builder::create()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 23
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 17
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 23
ccs 17
cts 17
cp 1
rs 9.0856
cc 2
eloc 14
nc 2
nop 6
crap 2
1
<?php
2
namespace Malezha\Menu\Entity;
3
4
use Illuminate\Contracts\Container\Container;
5
use Malezha\Menu\Contracts\Attributes as AttributesContract;
6
use Malezha\Menu\Contracts\Builder as BuilderContract;
7
use Malezha\Menu\Contracts\SubMenu as GroupContract;
8
use Malezha\Menu\Contracts\Item as ItemContract;
9
use Malezha\Menu\Contracts\Link as LinkContract;
10
use Malezha\Menu\Contracts\MenuRender;
11
use Malezha\Menu\Traits\HasAttributes;
12
13
/**
14
 * Class Builder
15
 * @package Malezha\Menu\Entity
16
 */
17
class Builder implements BuilderContract
18
{
19
    use HasAttributes;
20
21
    /**
22
     * @var Container
23
     */
24
    protected $container;
25
26
    /**
27
     * @var array
28
     */
29
    protected $items;
30
31
    /**
32
     * @var string
33
     */
34
    protected $name;
35
36
    /**
37
     * @var string
38
     */
39
    protected $type;
40
41
    /**
42
     * @var AttributesContract
43
     */
44
    protected $activeAttributes;
45
46
    /**
47
     * @var MenuRender
48
     */
49
    protected $viewFactory;
50
51
    /**
52
     * @var array
53
     */
54
    protected $config;
55
56
    /**
57
     * @var string
58
     */
59
    protected $view = null;
60
    
61
    /**
62
     * @inheritDoc
63
     */
64 21
    public function __construct(Container $container, $name, AttributesContract $attributes,
65
                                AttributesContract $activeAttributes, $type = self::UL, $view = null)
66
    {
67 21
        $this->container = $container;
68 21
        $this->name = $name;
69 21
        $this->type = $type;
70 21
        $this->attributes = $attributes;
71 21
        $this->items = [];
72 21
        $this->activeAttributes = $activeAttributes;
73 21
        $this->viewFactory = $this->container->make(MenuRender::class);
74 21
        $this->config = $this->container->make('config')->get('menu');
75
        try {
76 21
            $this->setView($view);
77 21
        } catch (\Exception $e) {}
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
78 21
    }
79
80
    /**
81
     * @inheritDoc
82
     */
83 5
    public function submenu($name, \Closure $itemCallable, \Closure $menuCallable)
84
    {
85 5
        $item = $this->container->make(ItemContract::class, [
86 5
            'builder' => $this,
87 5
            'attributes' => $this->container->make(AttributesContract::class, ['attributes' => []]),
88 5
            'link' => $this->container->make(LinkContract::class, [
89 5
                'title' => $name,
90 5
                'attributes' => $this->container->make(AttributesContract::class, ['attributes' => []]),
91 5
            ]),
92 5
            'request' => $this->container->make('request'),
93 5
        ]);
94 5
        call_user_func($itemCallable, $item);
95
96 5
        $menu = $this->container->make(BuilderContract::class, [
97 5
            'container' => $this->container, 
98 5
            'name' => $name,
99 5
            'activeAttributes' => $this->activeAttributes(),
100 5
            'attributes' => $this->container->make(AttributesContract::class, ['attributes' => []]),
101 5
            'view' => $this->getView(),
102 5
        ]);
103 5
        call_user_func($menuCallable, $menu);
104
105 5
        $group = $this->container->make(GroupContract::class, [
106 5
            'menu' => $menu,
107 5
            'item' => $item,
108 5
        ]);
109 5
        $this->items[$name] = $group;
110
111 5
        return $group;
112
    }
113
114
    /**
115
     * @inheritDoc
116
     */
117 13
    public function create($name, $title, $url, $attributes = [], $linkAttributes = [], $callback = null)
118
    {
119 13
        $link = $this->container->make(LinkContract::class, [
120 13
            'title' => $title,
121 13
            'url' => $url,
122 13
            'attributes' => $this->container->make(AttributesContract::class, ['attributes' => $linkAttributes]),
123 13
        ]);
124
        
125 13
        $item = $this->container->make(ItemContract::class, [
126 13
            'builder' => $this,
127 13
            'attributes' => $this->container->make(AttributesContract::class, ['attributes' => $attributes]),
128 13
            'link' => $link,
129 13
            'request' => $this->container->make('request'),
130 13
        ]);
131
132 13
        if (is_callable($callback)) {
133 4
            call_user_func($callback, $item);
134 4
        }
135
136 13
        $this->items[$name] = $item;
137
138 13
        return $item;
139
    }
140
141
    /**
142
     * @inheritDoc
143
     */
144 5
    public function has($name)
145
    {
146 5
        return array_key_exists($name, $this->items);
147
    }
148
149
    /**
150
     * @inheritDoc
151
     */
152 3
    public function get($name, $default = null)
153
    {
154 3
        if ($this->has($name)) {
155 3
            return $this->items[$name];
156
        }
157 1
        return $default;
158
    }
159
160
    /**
161
     * @inheritDoc
162
     */
163 7
    public function all()
164
    {
165 7
        return $this->items;
166
    }
167
168
    /**
169
     * @inheritDoc
170
     */
171 1
    public function forget($name)
172
    {
173 1
        if ($this->has($name)) {
174 1
            unset($this->items[$name]);
175 1
        }
176 1
    }
177
178
    /**
179
     * @inheritDoc
180
     */
181 7
    public function getType()
182
    {
183 7
        return $this->type;
184
    }
185
186
    /**
187
     * @inheritDoc
188
     */
189 1
    public function setType($type)
190
    {
191 1
        $this->type = (string) $type;
192 1
    }
193
194
    /**
195
     * @inheritDoc
196
     */
197 6
    public function render($renderView = null)
198
    {
199 6
        $view = $this->getRenderView($renderView);
200
201 6
        $minify = $this->config['minify'];
202
203 6
        $rendered = $this->viewFactory->make($view)->with([
204 6
            'menu' => $this,
205 6
            'renderView' => $renderView,
206 6
        ])->render();
207
        
208 6
        if ($minify) {
209 6
            $rendered = $this->minifyHtmlOutput($rendered);
210 6
        }
211
        
212 6
        return $rendered;
213
    }
214
215
    /**
216
     * @inheritDoc
217
     */
218 9
    public function activeAttributes($callback = null)
219
    {
220 9
        if (is_callable($callback)) {
221 1
            return call_user_func($callback, $this->activeAttributes);
222
        }
223
224 9
        return $this->activeAttributes;
225
    }
226
227
    /**
228
     * @inheritDoc
229
     */
230 5
    public function getView()
231
    {
232 5
        return $this->view;
233
    }
234
235
    /**
236
     * @inheritDoc
237
     */
238 21
    public function setView($view)
239
    {
240 21
        if (!$this->viewFactory->exists($view)) {
241 21
            throw new \Exception('View not found');
242
        }
243
        
244 1
        $this->view = $view;
245 1
    }
246
247
    /**
248
     * Minify html
249
     *
250
     * @param string $html
251
     * @return string
252
     */
253 6
    protected function minifyHtmlOutput($html)
254
    {
255
        $search = array(
256 6
            '/\>[^\S]+/s', // strip whitespaces after tags, except space
257 6
            '/[^\S]+\</s', // strip whitespaces before tags, except space
258
            '/(\s)+/s'       // shorten multiple whitespace sequences
259 6
        );
260
261
        $replace = array(
262 6
            '>',
263 6
            '<',
264
            '\\1'
265 6
        );
266
267 6
        return preg_replace($search, $replace, $html);
268
    }
269
270
    /**
271
     * Get view for render
272
     * 
273
     * @param string $view
274
     * @return string
275
     */
276 6
    protected function getRenderView($view = null)
277
    {
278 6
        $renderView = $this->config['view'];
279
        
280 6
        if (!empty($this->view)) {
281 1
            $renderView = $this->view;
282 1
        }
283
        
284 6
        if (!empty($view) && $this->viewFactory->exists($view)) {
285 1
            $renderView = $view;
286 1
        }
287
        
288 6
        return $renderView;
289
    }
290
}