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