Completed
Push — master ( 6e239d...3f337a )
by Dmitrijs
03:56 queued 01:59
created

Card::run()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 21
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 12
dl 0
loc 21
rs 9.8666
c 0
b 0
f 0
cc 3
nc 2
nop 0
1
<?php
2
/**
3
 * @link https://github.com/DMGPage/yii2-materialize
4
 * @copyright Copyright (c) 2018 Dmitrijs Reinmanis
5
 * @license https://github.com/DMGPage/yii2-materialize/blob/master/LICENSE
6
 */
7
8
namespace dmgpage\yii2materialize\widgets;
9
10
use dmgpage\yii2materialize\helpers\Html;
11
use yii\helpers\ArrayHelper;
12
use yii\base\InvalidConfigException;
13
use dmgpage\yii2materialize\assets\MaterializeExtraAsset;
14
15
/**
16
 * Cards are a convenient means of displaying content composed of different types of objects.
17
 * They’re also well-suited for presenting similar objects whose size or supported actions can vary considerably,
18
 * like photos with captions of variable length.
19
 *
20
 * You can use Cards like this:
21
 *
22
 * ```php
23
 * Card::begin([
24
 *     'colOptions' => ['class' => 's12 m6'],
25
 *     'cardOptions' => ['class' => 'blue-grey darken-1'],
26
 *     'contentOptions' => ['class' => 'white-text'],
27
 *     'title' => 'Card Title',
28
 *     'actions' => [
29
 *         [
30
 *             'label' => 'This is a link #1',
31
 *             'icon' => 'add',
32
 *             'encode' => false,
33
 *         ],
34
 *         ['label' => 'This is a link #2']
35
 *     ]
36
 * ]);
37
 *     echo 'I am a very simple card. I am good at containing small bits of information. I am convenient because I require little markup to use effectively.';
38
 * Card::end();
39
 * ```
40
 */
41
class Card extends Widget
42
{
43
    /**
44
     * @var array the HTML attributes for the row container tag of the card view.
45
     * @see \yii\helpers\Html::renderTagAttributes() for details on how attributes are being rendered.
46
     */
47
    public $options = [];
48
49
    /**
50
     * @var array the HTML attributes for the column container tag of the card view.
51
     * @see \yii\helpers\Html::renderTagAttributes() for details on how attributes are being rendered.
52
     */
53
    public $colOptions = ['class' => 's12 m6'];
54
55
    /**
56
     * @var array the HTML attributes for the card container tag of the card view.
57
     * @see \yii\helpers\Html::renderTagAttributes() for details on how attributes are being rendered.
58
     */
59
    public $cardOptions = [];
60
61
    /**
62
     * @var array the HTML attributes for the card content wrapper tag of the card view.
63
     * @see \yii\helpers\Html::renderTagAttributes() for details on how attributes are being rendered.
64
     */
65
    public $contentOptions = [];
66
67
    /**
68
     * @var string title of the card
69
     */
70
    public $title;
71
72
    /**
73
     * @var array the HTML attributes for the card title tag of the card view. Uses only if "cardTitle" attribute is specified.
74
     * - encode: boolean, optional, whether this item`s label should be HTML-encoded.
75
     * @see \yii\helpers\Html::renderTagAttributes() for details on how attributes are being rendered.
76
     */
77
    public $titleOptions = [];
78
79
    /**
80
     * @var array list of card action items. Each action item should be an array of the following structure:
81
     * - label: string, specifies the action item label. When [[encodeLabels]] is true, the label
82
     *   will be HTML-encoded.
83
     * - encode: boolean, optional, whether this item`s label should be HTML-encoded. This param will override
84
     *   global [[encodeLabels]] param.
85
     * - url: string or array, optional, specifies the URL of the action item. It will be processed by [[Url::to]].
86
     * - options: array, optional, the HTML attributes for the action container tag.
87
     */
88
    public $actions = [];
89
90
    /**
91
     * @var array the HTML attributes for the card action tag of the card view. Uses only if "actions" attribute is specified.
92
     * @see \yii\helpers\Html::renderTagAttributes() for details on how attributes are being rendered.
93
     */
94
    public $actionOptions = [];
95
96
    /**
97
     * @var bool whether to HTML-encode the link labels.
98
     */
99
    public $encodeLabels = true;
100
101
    /**
102
     * Initializes the widget.
103
     */
104
    public function init()
105
    {
106
        parent::init();
107
108
        Html::addCssClass($this->cardOptions, ['class' => 'card']);
109
        Html::addCssClass($this->contentOptions, ['class' => 'card-content']);
110
111
        $html = Html::beginGridRow($this->options);
112
        $html .= Html::beginGridCol($this->colOptions);
113
        $html .= Html::beginTag('div', $this->cardOptions);
114
        $html .= Html::beginTag('div', $this->contentOptions);
115
116
        if (!empty($this->title)) {
117
            $encode = isset($this->titleOptions['encode']) ? $this->titleOptions['encode'] : $this->encodeLabels;
118
            unset($this->titleOptions['encode']);
119
            Html::addCssClass($this->titleOptions, ['class' => 'card-title']);
120
            $title = $encode ? Html::encode($this->title) : $this->title;
121
            $html .= Html::tag('span', $title, $this->titleOptions);
122
        }
123
124
        echo $html;
125
    }
126
127
    /**
128
     * Renders the widget.
129
     */
130
    public function run()
131
    {
132
        $this->registerPlugin('card');
133
        $html = Html::endTag('div'); // ends container tag
134
135
        if (!empty($this->actions)) {
136
            Html::addCssClass($this->actionOptions, ['class' => 'card-action']);
137
            $html .= Html::beginTag('div', $this->actionOptions);
138
139
            foreach ($this->actions as $action) {
140
                $html .= $this->renderActionItem($action);
141
            }
142
143
            $html .= Html::endTag('div');
144
        }
145
146
        $html .= Html::endTag('div');
147
        $html .= Html::endGridCol();
148
        $html .= Html::endGridRow();
149
150
        echo $html;
151
    }
152
153
    /**
154
     * Renders a single card action item.
155
     *
156
     * @param array $link the link to be rendered. It must contain the "label" element. The "url" and "icon" element is optional.
157
     * @return string the rendering result
158
     * @throws InvalidConfigException if `$link` does not have "label" element.
159
     */
160
    protected function renderActionItem($link)
161
    {
162
        $encodeLabel = ArrayHelper::remove($link, 'encode', $this->encodeLabels);
163
164
        if (array_key_exists('label', $link)) {
165
            $label = $encodeLabel ? Html::encode($link['label']) : $link['label'];
166
        } else {
167
            throw new InvalidConfigException('The "label" element is required for each link.');
168
        }
169
170
        // Add icon to label text
171
        if (isset($link['icon'])) {
172
            $view = $this->getView();
173
            MaterializeExtraAsset::register($view);
174
175
            // Has issues on positioning: https://github.com/google/material-design-icons/issues/206
176
            $label = $this->renderIcon($link['icon']) . $label;
177
        }
178
179
        $options = $link['options'];
180
181
        if (isset($link['url'])) {
182
            return Html::a($label, $link['url'], $options);
183
        } else {
184
            return Html::a($label, '#', $options);
185
        }
186
    }
187
}
188