Breadcrumbs   A
last analyzed

Complexity

Total Complexity 20

Size/Duplication

Total Lines 213
Duplicated Lines 0 %

Test Coverage

Coverage 54.55%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 57
c 1
b 0
f 0
dl 0
loc 213
ccs 30
cts 55
cp 0.5455
rs 10
wmc 20

10 Methods

Rating   Name   Duplication   Size   Complexity  
A tag() 0 5 1
B run() 0 34 7
A links() 0 5 1
A options() 0 5 1
A encodeLabels() 0 5 1
A activeItemTemplate() 0 5 1
A homeLink() 0 5 1
A renderItem() 0 23 5
A itemTemplate() 0 5 1
A navOptions() 0 5 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Yii\Bootstrap4;
6
7
use JsonException;
8
use RuntimeException;
9
use Yiisoft\Arrays\ArrayHelper;
10
use Yiisoft\Html\Html;
11
12
use function array_key_exists;
13
use function implode;
14
use function is_array;
15
use function strtr;
16
17
/**
18
 * Button renders a bootstrap button.
19
 *
20
 * For example,
21
 *
22
 * ```php
23
 * echo Breadcrumbs::widget()
24
 *     ->links(['label' => !empty($this->params['breadcrumbs']) ? $this->params['breadcrumbs'] : []]);
25
 * ```
26
 */
27
class Breadcrumbs extends Widget
28
{
29
    private string $tag = 'ol';
30
    private bool $encodeLabels = true;
31
    private array $homeLink = [];
32
    private array $links = [];
33
    private string $itemTemplate = "<li class=\"breadcrumb-item\">{link}</li>\n";
34
    private string $activeItemTemplate = "<li class=\"breadcrumb-item active\" aria-current=\"page\">{link}</li>\n";
35
    private array $navOptions = ['aria-label' => 'breadcrumb'];
36
    private array $options = [];
37
38 1
    protected function run(): string
39
    {
40 1
        if (!isset($this->options['id'])) {
41 1
            $this->options['id'] = "{$this->getId()}-breadcrumb";
42
        }
43
44 1
        Html::addCssClass($this->options, ['widget' => 'breadcrumb']);
45
46 1
        $this->registerPlugin('breadcrumb', $this->options);
47
48 1
        if (empty($this->links)) {
49
            return '';
50
        }
51
52 1
        $links = [];
53
54 1
        if ($this->homeLink === []) {
55
            $links[] = $this->renderItem([
56
                'label' => 'Home',
57
                'url' => '/',
58
            ], $this->itemTemplate);
59
        } else {
60 1
            $links[] = $this->renderItem($this->homeLink, $this->itemTemplate);
61
        }
62
63 1
        foreach ($this->links as $link) {
64 1
            if (!is_array($link)) {
65
                $link = ['label' => $link];
66
            }
67
68 1
            $links[] = $this->renderItem($link, isset($link['url']) ? $this->itemTemplate : $this->activeItemTemplate);
69
        }
70
71 1
        return Html::tag('nav', Html::tag($this->tag, implode('', $links), $this->options), $this->navOptions);
72
    }
73
74
    /**
75
     * Renders a single breadcrumb item.
76
     *
77
     * @param array $link the link to be rendered. It must contain the "label" element. The "url" element is optional.
78
     * @param string $template the template to be used to rendered the link. The token "{link}" will be replaced by the
79
     * link.
80
     *
81
     * @throws JsonException|RuntimeException if `$link` does not have "label" element.
82
     *
83
     * @return string the rendering result
84
     */
85 1
    protected function renderItem(array $link, string $template): string
86
    {
87 1
        $encodeLabel = ArrayHelper::remove($link, 'encode', $this->encodeLabels);
88
89 1
        if (array_key_exists('label', $link)) {
90 1
            $label = $encodeLabel ? Html::encode($link['label']) : $link['label'];
91
        } else {
92
            throw new RuntimeException('The "label" element is required for each link.');
93
        }
94
95 1
        if (isset($link['template'])) {
96
            $template = $link['template'];
97
        }
98
99 1
        if (isset($link['url'])) {
100 1
            $options = $link;
101 1
            unset($options['template'], $options['label'], $options['url']);
102 1
            $linkHtml = Html::a($label, $link['url'], $options);
103
        } else {
104 1
            $linkHtml = $label;
105
        }
106
107 1
        return strtr($template, ['{link}' => $linkHtml]);
108
    }
109
110
    /**
111
     * The template used to render each active item in the breadcrumbs. The token `{link}` will be replaced with the
112
     * actual HTML link for each active item.
113
     *
114
     * @param string $value
115
     *
116
     * @return $this
117
     */
118
    public function activeItemTemplate(string $value): self
119
    {
120
        $this->activeItemTemplate = $value;
121
122
        return $this;
123
    }
124
125
    /**
126
     * Whether to HTML-encode the link labels.
127
     *
128
     * @param bool $value
129
     *
130
     * @return $this
131
     */
132
    public function encodeLabels(bool $value): self
133
    {
134
        $this->encodeLabels = $value;
135
136
        return $this;
137
    }
138
139
    /**
140
     * The first hyperlink in the breadcrumbs (called home link).
141
     *
142
     * Please refer to {@see links} on the format of the link.
143
     *
144
     * If this property is not set, it will default to a link pointing with the label 'Home'. If this property is false,
145
     * the home link will not be rendered.
146
     *
147
     * @param array $value
148
     *
149
     * @return $this
150
     */
151 1
    public function homeLink(array $value): self
152
    {
153 1
        $this->homeLink = $value;
154
155 1
        return $this;
156
    }
157
158
    /**
159
     * The template used to render each inactive item in the breadcrumbs. The token `{link}` will be replaced with the
160
     * actual HTML link for each inactive item.
161
     *
162
     * @param string $value
163
     *
164
     * @return $this
165
     */
166
    public function itemTemplate(string $value): self
167
    {
168
        $this->itemTemplate = $value;
169
170
        return $this;
171
    }
172
173
    /**
174
     * List of links to appear in the breadcrumbs. If this property is empty, the widget will not render anything. Each
175
     * array element represents a single link in the breadcrumbs with the following structure:
176
     *
177
     * ```php
178
     * [
179
     *     'label' => 'label of the link',  // required
180
     *     'url' => 'url of the link',      // optional, will be processed by Url::to()
181
     *     'template' => 'own template of the item', // optional, if not set $this->itemTemplate will be used
182
     * ]
183
     * ```
184
     *
185
     * @param array $value
186
     *
187
     * @return $this
188
     */
189 1
    public function links(array $value): self
190
    {
191 1
        $this->links = $value;
192
193 1
        return $this;
194
    }
195
196
    /**
197
     * The HTML attributes for the widgets nav container tag.
198
     *
199
     * {@see \Yiisoft\Html\Html::renderTagAttributes()} for details on how attributes are being rendered.
200
     *
201
     * @param array $value
202
     *
203
     * @return $this
204
     */
205
    public function navOptions(array $value): self
206
    {
207
        $this->navOptions = $value;
208
209
        return $this;
210
    }
211
212
    /**
213
     * The HTML attributes for the widget container tag. The following special options are recognized.
214
     *
215
     * {@see \Yiisoft\Html\Html::renderTagAttributes()} for details on how attributes are being rendered.
216
     *
217
     * @param array $value
218
     *
219
     * @return $this
220
     */
221
    public function options(array $value): self
222
    {
223
        $this->options = $value;
224
225
        return $this;
226
    }
227
228
    /**
229
     * The name of the breadcrumb container tag.
230
     *
231
     * @param string $value
232
     *
233
     * @return $this
234
     */
235
    public function tag(string $value): self
236
    {
237
        $this->tag = $value;
238
239
        return $this;
240
    }
241
}
242