Completed
Pull Request — master (#81)
by
unknown
14:25
created

Widget::init()   C

Complexity

Conditions 14
Paths 55

Size

Total Lines 34
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 34
rs 5.0864
c 0
b 0
f 0
cc 14
eloc 20
nc 55
nop 0

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
namespace the0rist\imperavi;
4
5
use Yii;
6
use yii\base\InvalidConfigException;
7
use yii\base\Model;
8
use yii\base\Widget as BaseWidget;
9
use yii\helpers\ArrayHelper;
10
use yii\helpers\Html;
11
use yii\helpers\Json;
12
use yii\web\JsExpression;
13
14
/**
15
 * Imperavi Redactor widget.
16
 *
17
 * @property array $settings JS Redactor settings
18
 * @property string|null $selector Textarea selector
19
 * @property array $plugins JS Redactor plugins
20
 *
21
 * @author Vasile Crudu <[email protected]>
22
 *
23
 * @link https://github.com/the0rist/yii2-imperavi-widget
24
 * @link http://imperavi.com/redactor
25
 * @license https://github.com/the0rist/yii2-imperavi-widget/blob/master/LICENSE.md
26
 */
27
class Widget extends BaseWidget
28
{
29
    /** Name of inline JavaScript package that is registered by the widget */
30
    const INLINE_JS_KEY = 'the0rist/imperavi/';
31
32
    /**
33
     * @var Model the data model that this widget is associated with.
34
     */
35
    public $model;
36
37
    /**
38
     * @var string the model attribute that this widget is associated with.
39
     */
40
    public $attribute;
41
42
    /**
43
     * @var string the input name. This must be set if [[model]] and [[attribute]] are not set.
44
     */
45
    public $name;
46
47
    /**
48
     * @var string the input value.
49
     */
50
    public $value;
51
52
    /**
53
     * @var string|null Selector pointing to textarea to initialize redactor for.
54
     * Defaults to null meaning that textarea does not exist yet and will be
55
     * rendered by this widget.
56
     */
57
    public $selector;
58
59
    /**
60
     * @var array the HTML attributes for the input tag.
61
     * @see \yii\helpers\Html::renderTagAttributes() for details on how attributes are being rendered.
62
     */
63
    public $options = [];
64
65
    /**
66
     * @var array {@link http://imperavi.com/redactor/docs/ redactor options}.
67
     */
68
    public $settings = [];
69
70
    /**
71
     * @var array Default settings that will be merged with {@link $settings}. Useful with DI container.
72
     */
73
    public $defaultSettings = [];
74
75
    /**
76
     * This property must be used only for registering widget custom plugins.
77
     * The key is the name of the plugin, and the value must be the class name of the plugin bundle.
78
     * @var array Widget custom plugins key => value array
79
     */
80
    public $plugins = [];
81
82
    /**
83
     * @var boolean Depends on this attribute textarea will be rendered or not
84
     */
85
    private $_renderTextarea = true;
86
87
    /**
88
     * @inheritdoc
89
     */
90
    public function init()
91
    {
92
        if ($this->name === null && !$this->hasModel() && $this->selector === null) {
93
            throw new InvalidConfigException("Either 'name', or 'model' and 'attribute' properties must be specified.");
94
        }
95
        if (!isset($this->options['id'])) {
96
            $this->options['id'] = $this->hasModel() ? Html::getInputId($this->model, $this->attribute) : $this->getId();
97
        }
98
        if (!empty($this->defaultSettings)) {
99
            $this->settings = ArrayHelper::merge($this->defaultSettings, $this->settings);
100
        }
101
        if (isset($this->settings['plugins']) && !is_array($this->settings['plugins']) || !is_array($this->plugins)) {
102
            throw new InvalidConfigException('The "plugins" property must be an array.');
103
        }
104
        if (!isset($this->settings['lang']) && Yii::$app->language !== 'en-US') {
105
            $this->settings['lang'] = substr(Yii::$app->language, 0, 2);
106
        }
107
        if ($this->selector === null) {
108
            $this->selector = '#' . $this->options['id'];
109
        } else {
110
            $this->_renderTextarea = false;
111
        }
112
113
        // @codeCoverageIgnoreStart
114
        $request = Yii::$app->getRequest();
115
116
        if ($request->enableCsrfValidation) {
117
            $this->settings['uploadImageFields'][$request->csrfParam] = $request->getCsrfToken();
118
            $this->settings['uploadFileFields'][$request->csrfParam] = $request->getCsrfToken();
119
        }
120
        // @codeCoverageIgnoreEnd
121
122
        parent::init();
123
    }
124
125
    /**
126
     * @inheritdoc
127
     */
128
    public function run()
129
    {
130
        $this->register();
131
132
        if ($this->_renderTextarea === true) {
133
            if ($this->hasModel()) {
134
                return Html::activeTextarea($this->model, $this->attribute, $this->options);
135
            } else {
136
                return Html::textarea($this->name, $this->value, $this->options);
137
            }
138
        }
139
    }
140
141
    /**
142
     * Register widget translations.
143
     */
144
    public static function registerTranslations()
145
    {
146
        if (!isset(Yii::$app->i18n->translations['the0rist/imperavi']) && !isset(Yii::$app->i18n->translations['the0rist/imperavi/*'])) {
147
            Yii::$app->i18n->translations['the0rist/imperavi'] = [
148
                'class' => 'yii\i18n\PhpMessageSource',
149
                'basePath' => '@the0rist/imperavi/messages',
150
                'forceTranslation' => true,
151
                'fileMap' => [
152
                    'the0rist/imperavi' => 'imperavi.php'
153
                ]
154
            ];
155
        }
156
    }
157
158
    /**
159
     * Register all widget logic.
160
     */
161
    protected function register()
162
    {
163
        self::registerTranslations();
164
        $this->registerDefaultCallbacks();
165
        $this->registerClientScripts();
166
    }
167
168
    /**
169
     * Register widget asset.
170
     */
171
    protected function registerClientScripts()
172
    {
173
        $view = $this->getView();
174
        $selector = Json::encode($this->selector);
175
        $asset = Yii::$container->get(Asset::className());
176
        $asset = $asset::register($view);
177
178
        if (isset($this->settings['lang'])) {
179
            $asset->language = $this->settings['lang'];
180
        }
181
        if (isset($this->settings['plugins'])) {
182
            $asset->plugins = $this->settings['plugins'];
183
        }
184
        if (!empty($this->plugins)) {
185
            /** @var \yii\web\AssetBundle $bundle Asset bundle */
186
            foreach ($this->plugins as $plugin => $bundle) {
187
                $this->settings['plugins'][] = $plugin;
188
                $bundle::register($view);
189
            }
190
        }
191
192
        $settings = !empty($this->settings) ? Json::encode($this->settings) : '';
193
194
        $view->registerJs("jQuery($selector).redactor($settings);", $view::POS_READY, self::INLINE_JS_KEY . $this->options['id']);
195
    }
196
197
    /**
198
     * Register default callbacks.
199
     */
200
    protected function registerDefaultCallbacks()
201
    {
202
        if (isset($this->settings['imageUpload']) && !isset($this->settings['imageUploadErrorCallback'])) {
203
            $this->settings['imageUploadErrorCallback'] = new JsExpression('function (response) { alert(response.error); }');
204
        }
205
        if (isset($this->settings['fileUpload']) && !isset($this->settings['fileUploadErrorCallback'])) {
206
            $this->settings['fileUploadErrorCallback'] = new JsExpression('function (response) { alert(response.error); }');
207
        }
208
    }
209
210
    /**
211
     * @return boolean whether this widget is associated with a data model.
212
     */
213
    protected function hasModel()
214
    {
215
        return $this->model instanceof Model && $this->attribute !== null;
216
    }
217
}
218