Passed
Push — master ( ab5002...bcfa32 )
by Alexander
02:25
created

VoteToggle   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 123
Duplicated Lines 39.84 %

Coupling/Cohesion

Components 1
Dependencies 6

Importance

Changes 5
Bugs 0 Features 1
Metric Value
wmc 10
c 5
b 0
f 1
lcom 1
cbo 6
dl 49
loc 123
rs 10

6 Methods

Rating   Name   Duplication   Size   Complexity  
A getDefaultOptions() 0 6 1
A getDefaultButtonOptions() 0 8 1
A init() 0 8 1
A run() 0 13 2
B initJsEvents() 29 29 4
A registerJs() 20 20 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
3
namespace hauntd\vote\widgets;
4
5
use yii\bootstrap\Html;
6
use yii\web\View;
7
use yii\web\JsExpression;
8
use Yii;
9
10
/**
11
 * @author Alexander Kononenko <[email protected]>
12
 * @package hauntd\vote\widgets
13
 */
14
class VoteToggle extends BaseWidget
15
{
16
    /**
17
     * @var string
18
     */
19
    public $jsCodeKey = 'vote-toggle';
20
21
    /**
22
     * @var string
23
     */
24
    public $viewFile = 'toggle';
25
26
    /**
27
     * @var array
28
     */
29
    public $buttonOptions = [];
30
31
    /**
32
     * @return array
33
     */
34
    public function getDefaultOptions()
35
    {
36
        return [
37
            'class' => 'vote-toggle',
38
        ];
39
    }
40
41
    /**
42
     * @return array
43
     */
44
    public function getDefaultButtonOptions()
45
    {
46
        return [
47
            'class' => 'vote-btn btn btn-default',
48
            'icon' => Html::icon('glyphicon glyphicon-arrow-up'),
49
            'label' => Yii::t('vote', 'Vote up'),
50
        ];
51
    }
52
53
    public function init()
54
    {
55
        parent::init();
56
        $this->options = array_merge($this->getDefaultOptions(), $this->options);
57
        $this->buttonOptions = array_merge($this->getDefaultButtonOptions(), $this->buttonOptions);
58
        $this->initJsEvents();
59
        $this->registerJs();
60
    }
61
62
    /**
63
     * @return string
64
     * @throws \yii\base\InvalidConfigException
65
     */
66
    public function run()
67
    {
68
        return $this->render($this->viewFile, [
69
            'jsCodeKey' => $this->jsCodeKey,
70
            'entity' => $this->entity,
71
            'model' => $this->model,
72
            'targetId' => $this->targetId,
73
            'userValue' => $this->userValue,
74
            'count' => isset($this->aggregateModel->positive) ? $this->aggregateModel->positive : 0,
75
            'options' => $this->options,
76
            'buttonOptions' => $this->buttonOptions,
77
        ]);
78
    }
79
80
    /**
81
     * Initialize with default events.
82
     */
83 View Code Duplication
    public function initJsEvents()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
84
    {
85
        parent::initJsEvents();
86
        $selector = $this->getSelector($this->options['class']);
87
        if (!isset($this->jsChangeCounters)) {
88
            $this->jsChangeCounters = "
89
                if (typeof(data.success) !== 'undefined') {
90
                    $('$selector .vote-count').text(data.aggregate.positive);
91
                    if (data.toggleValue) {
92
                        button.addClass('vote-active');
93
                    } else {
94
                        button.removeClass('vote-active');
95
                    }
96
                }
97
            ";
98
        }
99
        if (!isset($this->jsBeforeVote)) {
100
            $this->jsBeforeVote = "
101
                $('$selector .vote-btn').prop('disabled', 'disabled').addClass('vote-loading');
102
                $('$selector .vote-btn').append('<div class=\"vote-loader\"><span></span><span></span><span></span></div>');
103
            ";
104
        }
105
        if (!isset($this->jsAfterVote)) {
106
            $this->jsAfterVote = "
107
                $('$selector .vote-btn').prop('disabled', false).removeClass('vote-loading');
108
                $('$selector .vote-btn .vote-loader').remove();
109
            ";
110
        }
111
    }
112
113
    /**
114
     * Registers jQuery handler.
115
     */
116 View Code Duplication
    protected function registerJs()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
117
    {
118
        $js = new JsExpression("
119
            $('body').on('click', '[data-rel=\"{$this->jsCodeKey}\"] button', function(event) {
120
                var vote = $(this).closest('[data-rel=\"{$this->jsCodeKey}\"]'),
121
                    button = $(this),
122
                    entity = vote.attr('data-entity'),
123
                    target = vote.attr('data-target-id');
124
                jQuery.ajax({
125
                    url: '$this->voteUrl', type: 'POST', dataType: 'json', cache: false,
126
                    data: { 'VoteForm[entity]': entity, 'VoteForm[targetId]': target, 'VoteForm[action]': 'toggle' },
127
                    beforeSend: function(jqXHR, settings) { $this->jsBeforeVote },
128
                    success: function(data, textStatus, jqXHR) { $this->jsChangeCounters $this->jsShowMessage },
129
                    complete: function(jqXHR, textStatus) { $this->jsAfterVote },
130
                    error: function(jqXHR, textStatus, errorThrown) { $this->jsErrorVote }
131
                });
132
            });
133
        ");
134
        $this->view->registerJs($js, View::POS_END, $this->jsCodeKey);
135
    }
136
}
137