ActiveField::callComponentOrClass()   A
last analyzed

Complexity

Conditions 4
Paths 3

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
eloc 4
c 1
b 0
f 0
nc 3
nop 0
dl 0
loc 9
rs 10
1
<?php
2
3
namespace thoulah\fontawesome\bootstrap4;
4
5
use thoulah\fontawesome\config\Options;
6
use thoulah\fontawesome\Icon;
7
use thoulah\fontawesome\IconComponent;
8
use Yii;
9
use yii\helpers\ArrayHelper;
10
11
/**
12
 * Provides an easy way to use icons in forms are described on the Boostrap
13
 * [Input group](https://getbootstrap.com/docs/4.3/components/input-group/) page.
14
 *
15
 * ## Automatic
16
 *
17
 * ```php
18
 * use thoulah\fontawesome\bootstrap4\ActiveForm;
19
 *
20
 * $form = ActiveForm::begin();
21
 *
22
 * echo $form->field($model, 'field1', [
23
 *     'icon' => 'user',
24
 * ]);
25
 *
26
 * echo $form->field($model, 'field2', [
27
 *     'icon' => [
28
 *         'name' => 'github',
29
 *         'style' => 'brands',
30
 *     ],
31
 * ]);
32
 *
33
 * echo $form->field($model, 'field3', [
34
 *     'icon' => [
35
 *         'name' => 'github',
36
 *         'style' => 'brands',
37
 *         'append' => true,
38
 *     ],
39
 * ]);
40
 *
41
 * ActiveForm::end();
42
 * ```
43
 *
44
 * ## Manual
45
 *
46
 * For `$icon` you can use [[Icon]] or [[IconComponent]].
47
 *
48
 * ```php
49
 * $form = ActiveForm::begin();
50
 *
51
 * echo $form->field($model, 'field', [
52
 *     'inputTemplate' => $icon->activeFieldAddon('user'),
53
 * ]);
54
 *
55
 * ActiveForm::end();
56
 * ```
57
 *
58
 * ```php
59
 * $form = ActiveForm::begin();
60
 *
61
 * echo $form->field($model, 'field', [
62
 *     'inputTemplate' => '<div id="yourClass" class="float-right">YourText</div>' .
63
 *         $icon->activeFieldAddon('font-awesome', ['style' => 'brands']),
64
 * ]);
65
 *
66
 * ActiveForm::end();
67
 * ```
68
 *
69
 * ```php
70
 * $form = ActiveForm::begin();
71
 *
72
 * echo $form->field($model, 'field', [
73
 *     'inputTemplate' => '<div class="input-group">YourText' .
74
 *         $icon->activeFieldIcon('font-awesome', ['style' => 'brands']).'{input}</div>',
75
 * ]);
76
 *
77
 * ActiveForm::end();
78
 * ```
79
 */
80
class ActiveField extends \yii\bootstrap4\ActiveField
81
{
82
    /** @var array per-icon settings */
83
    public $icon;
84
85
    /**
86
     * Constructor.
87
     *
88
     * @param array $config name-value pairs that will be used to initialize the object properties
89
     */
90
    public function __construct($config = [])
91
    {
92
        $icon = ArrayHelper::getValue($config, 'icon');
93
        if (is_string($icon)) {
94
            ArrayHelper::setValue($config, 'icon', ['name' => $icon]);
95
        }
96
97
        parent::__construct($config);
98
    }
99
100
    /**
101
     * Renders the whole field.
102
     *
103
     * @param string|callable $content the content within the field container
104
     *
105
     * @return string the rendering result
106
     */
107
    public function render($content = null): string
108
    {
109
        if (!empty($this->icon)) {
110
            $groupSize = ArrayHelper::remove($this->icon, 'groupSize');
111
            $append = ArrayHelper::getValue($this->icon, 'append');
112
113
            $fieldAddon = Html::activeFieldAddon($groupSize, $append);
114
            $fieldIcon = Html::activeFieldIcon($append);
115
            $inputTemplate = str_replace('{icon}', $fieldIcon, $fieldAddon);
116
            $this->inputTemplate = str_replace('{icon}', $this->callComponentOrClass(), $inputTemplate);
117
        }
118
119
        return parent::render($content);
120
    }
121
122
    /**
123
     * Tries to find component id. If that cannot be found we fall be to running as class.
124
     *
125
     * @return string The icon
126
     */
127
    private function callComponentOrClass(): string
128
    {
129
        foreach (Yii::$app->components as $key => $value) {
130
            if (is_object($value['class']) && in_array(IconComponent::class, [$value['class'], get_parent_class($value['class'])])) {
131
                return $this->runAsComponent(Yii::$app->$key);
132
            }
133
        }
134
135
        return $this->runAsClass();
136
    }
137
138
    /**
139
     * We run as class.
140
     *
141
     * @return string The icon
142
     */
143
    private function runAsClass(): string
144
    {
145
        $icon = new Icon();
146
        $iconName = ArrayHelper::remove($this->icon, 'name');
147
148
        if (!isset($this->icon['fixedWidth'])) {
149
            $this->icon['fixedWidth'] = $icon->defaults->activeFormFixedWidth;
150
        }
151
152
        return $icon->show($iconName ?? '', $this->icon);
153
    }
154
155
    /**
156
     * We run as component.
157
     *
158
     * @param IconComponent $icon
159
     *
160
     * @return string The icon
161
     */
162
    private function runAsComponent(IconComponent $icon): string
163
    {
164
        $iconName = ArrayHelper::remove($this->icon, 'name');
165
        $iconStyle = ArrayHelper::remove($this->icon, 'style');
166
        $icon->name($iconName ?? '', $iconStyle);
167
168
        $fixedWidth = ArrayHelper::remove($this->icon, 'fixedWidth', $icon->defaults->activeFormFixedWidth);
169
        $icon->fixedWidth($fixedWidth);
170
171
        $properties = get_object_vars(new Options());
172
        foreach (array_keys($properties) as $property) {
173
            $value = ArrayHelper::remove($this->icon, $property);
174
            if (null !== $value) {
175
                $icon->$property($value);
176
            }
177
        }
178
179
        return $icon;
180
    }
181
}
182