Passed
Push — master ( 25d9a0...98be68 )
by Alexander
02:31
created

BaseWidget::initDefaults()   D

Complexity

Conditions 11
Paths 144

Size

Total Lines 29
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 1 Features 0
Metric Value
c 3
b 1
f 0
dl 0
loc 29
rs 4.9629
cc 11
eloc 18
nc 144
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 hauntd\vote\widgets;
4
5
use hauntd\vote\assets\VoteAsset;
6
use hauntd\vote\behaviors\VoteBehavior;
7
use hauntd\vote\models\Vote;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, hauntd\vote\widgets\Vote.

Let’s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let’s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
8
use hauntd\vote\models\VoteAggregate;
9
use hauntd\vote\traits\ModuleTrait;
10
use yii\base\InvalidParamException;
11
use yii\base\Widget;
12
use yii\db\ActiveRecord;
13
use yii\web\View;
14
use yii\web\JsExpression;
15
use Yii;
16
17
/**
18
 * @author Alexander Kononenko <[email protected]>
19
 * @package hauntd\vote\widgets
20
 */
21
abstract class BaseWidget extends Widget
22
{
23
    use ModuleTrait;
24
25
    /**
26
     * @var string
27
     */
28
    public $entity;
29
30
    /**
31
     * @var null|\yii\db\ActiveRecord
32
     */
33
    public $model;
34
35
    /**
36
     * @var null|integer;
37
     */
38
    public $targetId;
39
40
    /**
41
     * @var string
42
     */
43
    public $voteUrl;
44
45
    /**
46
     * @var null|\hauntd\vote\models\VoteAggregate
47
     */
48
    public $aggregateModel;
49
50
    /**
51
     * @var null|integer
52
     */
53
    public $userValue;
54
55
    /**
56
     * @var string
57
     */
58
    public $jsBeforeVote;
59
60
    /**
61
     * @var string
62
     */
63
    public $jsAfterVote;
64
65
    /**
66
     * @var string
67
     */
68
    public $jsCodeKey = 'vote';
69
70
    /**
71
     * @var string
72
     */
73
    public $jsErrorVote;
74
75
    /**
76
     * @var string
77
     */
78
    public $jsShowMessage;
79
80
    /**
81
     * @var string
82
     */
83
    public $jsChangeCounters;
84
85
    /**
86
     * @var array
87
     */
88
    public $options = [];
89
90
    /**
91
     * @var string
92
     */
93
    public $viewFile = 'vote';
94
95
    /**
96
     * @var array
97
     */
98
    public $viewParams = [];
99
100
    /**
101
     * @return string
102
     */
103
    public function getSelector()
104
    {
105
        $classes = str_replace(' ', '.', $this->options['class']);
106
        return ".{$classes}[data-entity=\"' + entity + '\"][data-target-id=\"' + target  + '\"]";
107
    }
108
109
    /**
110
     * @inheritdoc
111
     * @throws \yii\base\InvalidConfigException
112
     */
113
    public function init()
114
    {
115
        parent::init();
116
117
        if (!isset($this->entity) || !isset($this->model) || !($this->model instanceof ActiveRecord)) {
118
            throw new InvalidParamException(Yii::t('vote', 'Entity and model must be set.'));
119
        }
120
121
        $this->initDefaults();
122
123
        if ($this->getModule()->registerAsset) {
124
            $this->view->registerAssetBundle(VoteAsset::class);
125
        }
126
    }
127
128
    /**
129
     * Initialize widget with default options.
130
     *
131
     * @throws \yii\base\InvalidConfigException
132
     */
133
    public function initDefaults()
134
    {
135
        $this->voteUrl = isset($this->voteUrl) ?: Yii::$app->getUrlManager()->createUrl(['vote/default/vote']);
136
        $this->targetId = isset($this->targetId) ?: $this->model->getPrimaryKey();
137
138
        $behaviorIncluded = false;
139
        if (!isset($this->aggregateModel) || !isset($this->userValue)) {
140
            $behaviors = $this->model->getBehaviors();
141
            foreach ($behaviors as $behavior) {
142
                if ($behavior instanceof VoteBehavior) {
143
                    $behaviorIncluded = true;
144
                    break;
145
                }
146
            }
147
        }
148
149
        if (!isset($this->aggregateModel)) {
150
            $this->aggregateModel = $behaviorIncluded ?
151
                $this->model->getVoteAggregate($this->entity) :
152
                VoteAggregate::findOne([
153
                    'entity' => $this->getModule()->encodeEntity($this->entity),
154
                    'target_id' => $this->targetId,
155
                ]);
156
        }
157
158
        if (!isset($this->userValue)) {
159
            $this->userValue = $behaviorIncluded ? $this->model->getUserValue($this->entity) : null;
160
        }
161
    }
162
163
    /**
164
     * Registers jQuery handler.
165
     */
166
    protected function registerJs()
167
    {
168
        $jsCode = new JsExpression("
169
            $('body').on('click', '[data-rel=\"{$this->jsCodeKey}\"] button', function(event) {
170
                var vote = $(this).closest('[data-rel=\"{$this->jsCodeKey}\"]'),
171
                    button = $(this),
172
                    action = button.attr('data-action'),
173
                    entity = vote.attr('data-entity'),
174
                    target = vote.attr('data-target-id');
175
                jQuery.ajax({
176
                    url: '$this->voteUrl', type: 'POST', dataType: 'json', cache: false,
177
                    data: { 'VoteForm[entity]': entity, 'VoteForm[targetId]': target, 'VoteForm[action]': action },
178
                    beforeSend: function(jqXHR, settings) { $this->jsBeforeVote },
179
                    success: function(data, textStatus, jqXHR) { $this->jsChangeCounters $this->jsShowMessage },
180
                    complete: function(jqXHR, textStatus) { $this->jsAfterVote },
181
                    error: function(jqXHR, textStatus, errorThrown) { $this->jsErrorVote }
182
                });
183
            });
184
        ");
185
        $this->view->registerJs($jsCode, View::POS_END, $this->jsCodeKey);
186
    }
187
188
    /**
189
     * @param array $params
190
     * @return array
191
     */
192
    protected function getViewParams(array $params)
193
    {
194
        return array_merge($this->viewParams, $params);
195
    }
196
}
197