Completed
Branch master (a1edd4)
by
unknown
54:09
created

InputAddonTrait::getAddonContent()   D

Complexity

Conditions 10
Paths 22

Size

Total Lines 42
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 42
rs 4.8196
c 0
b 0
f 0
cc 10
eloc 27
nc 22
nop 2

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * This file is part of the fangface/yii2-concord package
4
 *
5
 * For the full copyright and license information, please view
6
 * the file LICENSE.md that was distributed with this source code.
7
 *
8
 * @package fangface/yii2-concord
9
 * @author Fangface <[email protected]>
10
 * @copyright Copyright (c) 2014 Fangface <[email protected]>
11
 * @license https://github.com/fangface/yii2-concord/blob/master/LICENSE.md MIT License
12
 *
13
 */
14
15
namespace fangface\base\traits;
16
17
use fangface\forms\InputField;
18
use fangface\helpers\Html;
19
use yii\helpers\ArrayHelper;
20
21
22
trait InputAddonTrait
23
{
24
25
    /**
26
     * @var string the input type
27
     */
28
    public $type = null;
29
30
    /**
31
     * @var array addon options. The following settings can be configured:
32
     * - prepend: array the prepend addon configuration
33
     * - append: array the append addon configuration
34
     * - content: string the prepend addon content
35
     * - asButton: boolean whether the addon is a button or button group. Defaults to false.
36
     * - options: array the HTML attributes to be added to the container.
37
     * - groupOptions: array HTML options for the input group
38
     * - contentBefore: string content placed before addon
39
     * - contentAfter: string content placed after addon
40
     * - icon: array HTML options for the input group
41
     * - iconPosition: string icon position 'left' or 'right'
42
     */
43
    public $addon = [];
44
45
46
    /**
47
     * Set the input field type
48
     *
49
     * @param string $type input field type
50
     */
51
    public function setType($type)
52
    {
53
        $this->type = $type;
54
    }
55
56
    /**
57
     * Add an addon to prepend or append to the output
58
     *
59
     * @param string|array $config addon config or string content
60
     * @param string $type [optional] default 'append' can be 'append' or 'prepend'
61
     * @param boolean $first [optional] force to front of array, default false
62
     * @return void
63
     */
64
    public function addAddon($config, $type = 'append', $first = false)
65
    {
66
        if (is_string($config)) {
67
            $config = ['content' => $config];
68
        }
69
        if (!isset($this->addon[$type])) {
70
            $this->addon[$type] = [];
71
        }
72
        if ($first) {
73
            array_unshift($this->addon[$type], $config);
74
        } else {
75
            $this->addon[$type][] = $config;
76
        }
77
    }
78
79
    /**
80
     * Add an icon addon
81
     *
82
     * @param string $options HTML options for the icon element
83
     * @param string $position [optional] default null (left) or right
84
     * @return void
85
     */
86
    public function addIconAddon($options, $position = null)
87
    {
88
        $this->addon['icon'] = $options;
89
        $this->addon['iconPosition'] = $position;
90
    }
91
92
    /**
93
     * Merge in extra addon settings
94
     *
95
     * @param array $addon
96
     * @return void
97
     */
98
    public function mergeAddon($addon)
99
    {
100
        $prepend = ArrayHelper::remove($addon, 'prepend', []);
101
        $append = ArrayHelper::remove($addon, 'append', []);
102
        $this->addon = array_merge($this->addon, $addon);
103
        if ($prepend) {
104
            if (is_string($prepend)) {
105
                $this->addAddon($prepend, 'prepend');
106
            } else {
107
                foreach ($prepend as $k => $v) {
0 ignored issues
show
Bug introduced by
The expression $prepend of type object|integer|double|null|array|boolean is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
108
                    $this->addAddon($v, 'prepend');
109
                }
110
            }
111
        }
112
        if ($append) {
113
            if (is_string($append)) {
114
                $this->addAddon($append, 'append');
115
            } else {
116
                foreach ($append as $k => $v) {
0 ignored issues
show
Bug introduced by
The expression $append of type object|integer|double|null|array|boolean is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
117
                    $this->addAddon($v, 'append');
118
                }
119
            }
120
        }
121
    }
122
123
    /**
124
     * Setup or extend the groupOptions
125
     *
126
     * @param string $name
127
     * @param mixed $value
128
     * @param boolean $extend [optional] default false
129
     * @return void
130
     */
131
    public function setGroupOption($name, $value, $extend = false)
132
    {
133
        if ($extend) {
134
            if (isset($this->addon['groupOptions'][$name])) {
135
                if (strpos($this->addon['groupOptions'][$name], $value) !== false) {
136
                    // value already exists
137
                } else {
138
                    $this->addon['groupOptions'][$name] .= ' ' . $value;
139
                }
140
            } else {
141
                $this->addon['groupOptions'][$name] = $value;
142
            }
143
        } else {
144
            $this->addon['groupOptions'][$name] = $value;
145
        }
146
    }
147
148
    /**
149
     * Set the default group size for the input-group
150
     *
151
     * @param string $size
152
     * @return void
153
     */
154
    public function setGroupSize($size = '')
155
    {
156
        if ($size) {
157
            $this->addon['groupSize'] = $size;
158
        }
159
    }
160
161
    /**
162
     * Generates the addon markup
163
     *
164
     * @return string
165
     */
166
    protected function generateAddon()
167
    {
168
        $content = '{input}';
169
        if (empty($this->addon)) {
170
            return $content;
171
        }
172
173
        $addon = $this->addon;
174
        $icon = ArrayHelper::getValue($addon, 'icon', []);
175
        if ($icon) {
176
            $iconPosition = ArrayHelper::getValue($addon, 'iconPosition', InputField::ICON_POSITION_LEFT);
177
            if ($this->isUnsupportedIconInput()) {
178
                $this->addAddon(['content' => Html::tag('i', '', $icon)], 'prepend', true);
179
            } else {
180
                $content = Html::tag('i', '', $icon) . "\n" . $content;
181
                $content = Html::tag('div', $content, [
182
                    'class' => trim('input-icon' . ($iconPosition && $iconPosition != InputField::ICON_POSITION_LEFT ? ' ' . $iconPosition : '')),
183
                ]);
184
            }
185
        }
186
187
        $addon = $this->addon;
188
        $prepend = $this->getAddonContent(ArrayHelper::getValue($addon, 'prepend', ''), 'prepend');
189
        $append = $this->getAddonContent(ArrayHelper::getValue($addon, 'append', ''), 'append');
190
        if ($prepend || $append) {
191
            $content = $prepend . ($prepend ? "\n" : '') . $content . ($append ? "\n" : '') . $append;
192
            $group = ArrayHelper::getValue($addon, 'groupOptions', []);
193
            $groupSize = ArrayHelper::getValue($addon, 'groupSize', '');
194
            $tag = ArrayHelper::remove($group, 'tag', 'div');
195
            Html::addCssClass($group, 'input-group');
196
            if ($groupSize) {
197
                Html::addCssClass($group, 'input-' . $groupSize);
198
            }
199
            $contentBefore = ArrayHelper::getValue($addon, 'contentBefore', '');
200
            $contentAfter = ArrayHelper::getValue($addon, 'contentAfter', '');
201
            $content = Html::tag($tag, $contentBefore . $content . $contentAfter, $group);
202
        }
203
        return $content;
204
    }
205
206
207
    /**
208
     * Parses and returns addon content
209
     *
210
     * @param string|array $addon the addon parameter
211
     * @param string $type type of addon prepend or append
212
     * @return string
213
     */
214
    protected function getAddonContent($addon, $type = 'append')
215
    {
216
        if (!is_array($addon)) {
217
            return $addon;
218
        }
219
220
        if (is_string($addon)) {
221
            return $addon;
222
        } elseif (isset($addon['content'])) {
223
            // a single addon
224
            $addons = [$addon];
225
        } else {
226
            // multiple addons
227
            $addons = $addon;
228
        }
229
230
        $allContent = '';
231
        foreach ($addons as $k => $addon) {
232
            $content = ArrayHelper::getValue($addon, 'content', '');
0 ignored issues
show
Bug introduced by
It seems like $addon defined by $addon on line 231 can also be of type null; however, yii\helpers\BaseArrayHelper::getValue() does only seem to accept array|object, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
233
            if ($content == '') {
234
                if (isset($addon['class'])) {
235
                    // assume an icon needs to be output
236
                    $content = Html::tag('i', '', $addon);
237
                }
238
            }
239
            if (ArrayHelper::getValue($addon, 'raw', false) == true) {
0 ignored issues
show
Bug introduced by
It seems like $addon defined by $addon on line 231 can also be of type null; however, yii\helpers\BaseArrayHelper::getValue() does only seem to accept array|object, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
240
                // content already prepared
241
                $allContent .= "\n" . $content;
242
            } else {
243
                $options = ArrayHelper::getValue($addon, 'options', []);
0 ignored issues
show
Bug introduced by
It seems like $addon defined by $addon on line 231 can also be of type null; however, yii\helpers\BaseArrayHelper::getValue() does only seem to accept array|object, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
244
                $tag = ArrayHelper::remove($options, 'tag', 'span');
245
                if (ArrayHelper::getValue($addon, 'asButton', false) == true) {
0 ignored issues
show
Bug introduced by
It seems like $addon defined by $addon on line 231 can also be of type null; however, yii\helpers\BaseArrayHelper::getValue() does only seem to accept array|object, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
246
                    Html::addCssClass($options, 'input-group-btn');
247
                    $allContent .= "\n" . Html::tag($tag, $content, $options);
248
                } else {
249
                    Html::addCssClass($options, 'input-group-addon' . ($type == 'append' ? ' addon-after' : ''));
250
                    $allContent .= "\n" . Html::tag($tag, $content, $options);
251
                }
252
            }
253
        }
254
        return $allContent;
255
    }
256
257
    protected function isUnsupportedIconInput()
258
    {
259
        switch ($this->type) {
260
            case InputField::INPUT_SELECT2:
261
            case InputField::INPUT_SELECT2_MULTI:
262
            case InputField::INPUT_SELECT2_TAGS:
263
            case InputField::INPUT_SELECT_PICKER:
264
            case InputField::INPUT_SELECT_PICKER_MULTI:
265
            case InputField::INPUT_SELECT_SPLITTER:
266
            case InputField::INPUT_MULTISELECT:
267
            case InputField::INPUT_MINI_COLORS:
268
            case InputField::INPUT_EDITOR_CK:
269
                return true;
270
        }
271
        return false;
272
    }
273
}
274