Blame view

common/modules/comment/widgets/CommentWidget.php 12.4 KB
e608c5f7   Yarik   Comment added
1
  <?php
c05bf005   Yarik   Comment added
2
      
e608c5f7   Yarik   Comment added
3
      namespace common\modules\comment\widgets;
c05bf005   Yarik   Comment added
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
      
      use common\modules\comment\assets\CommentAsset;
      use common\modules\comment\models\interfaces\CommentInterface;
      use common\modules\comment\models\RatingModel;
      use common\modules\comment\Module;
      use Yii;
      use yii\base\InvalidConfigException;
      use yii\base\Widget;
      use yii\data\ActiveDataProvider;
      use yii\helpers\ArrayHelper;
      use yii\helpers\Html;
      use yii\helpers\Json;
      
      /**
       * Class CommentWidget
       * @property \yii\base\Model $model Model, to which comment attached
       * @package common\modules\comment\widgets
       */
      class CommentWidget extends Widget
e608c5f7   Yarik   Comment added
23
      {
c05bf005   Yarik   Comment added
24
          
e608c5f7   Yarik   Comment added
25
          /**
c05bf005   Yarik   Comment added
26
27
           * Model, to which comment attached
           * @var \yii\base\Model Model
e608c5f7   Yarik   Comment added
28
           */
c05bf005   Yarik   Comment added
29
30
31
32
33
34
          //public $model;
          
          /**
           * Options
           * @var array
           */
17ca60dd   Yarik   Added comments to...
35
          public $options = [ 'class' => 'artbox_comment_container comments-start', 'id' => 'artbox-comment' ];
c05bf005   Yarik   Comment added
36
37
38
39
40
41
42
43
44
45
46
47
          
          /**
           * @var string the view file that will render comment form.
           */
          public $formView = '@artbox-comment/views/artbox_comment_form';
          
          /**
           * Form options
           * @var array
           */
          public $formOptions = [
              'class' => 'artbox_form_container',
e608c5f7   Yarik   Comment added
48
          ];
c05bf005   Yarik   Comment added
49
          
e608c5f7   Yarik   Comment added
50
          /**
c05bf005   Yarik   Comment added
51
52
           * Params to be passed to form
           * @var array
e608c5f7   Yarik   Comment added
53
           */
c05bf005   Yarik   Comment added
54
55
          public $formParams = [ ];
          
e608c5f7   Yarik   Comment added
56
          /**
c05bf005   Yarik   Comment added
57
           * @var string the view file that will render comments list.
e608c5f7   Yarik   Comment added
58
           */
c05bf005   Yarik   Comment added
59
60
          public $listView = '@artbox-comment/views/artbox_comment_list';
          
e608c5f7   Yarik   Comment added
61
          /**
c05bf005   Yarik   Comment added
62
63
           * List options
           * @var array
e608c5f7   Yarik   Comment added
64
           */
c05bf005   Yarik   Comment added
65
66
67
68
          public $listOptions = [
              'class' => 'artbox_list_container',
          ];
          
e608c5f7   Yarik   Comment added
69
          /**
c05bf005   Yarik   Comment added
70
           * List params
e608c5f7   Yarik   Comment added
71
72
           * @var array
           */
c05bf005   Yarik   Comment added
73
74
          public $listParams = [ ];
          
e608c5f7   Yarik   Comment added
75
          /**
c05bf005   Yarik   Comment added
76
77
           * Reply options
           * @var array
e608c5f7   Yarik   Comment added
78
           */
c05bf005   Yarik   Comment added
79
80
81
82
83
          public $replyOptions = [
              'style' => 'display: none;',
              'class' => 'artbox_comment_reply_container',
          ];
          
e608c5f7   Yarik   Comment added
84
          /**
c05bf005   Yarik   Comment added
85
86
           * Reply view
           * @var string
e608c5f7   Yarik   Comment added
87
           */
c05bf005   Yarik   Comment added
88
89
          public $replyView = '@artbox-comment/views/artbox_comment_reply';
          
e608c5f7   Yarik   Comment added
90
          /**
c05bf005   Yarik   Comment added
91
92
           * Comment form ID. If you have multiple forms on the same page, please use unique IDs.
           * @var string Form ID
e608c5f7   Yarik   Comment added
93
           */
c05bf005   Yarik   Comment added
94
95
          public $formId = 'artbox-comment-form';
          
e608c5f7   Yarik   Comment added
96
          /**
c05bf005   Yarik   Comment added
97
98
           * Comment list ID. If you have multiple forms on the same page, please use unique IDs.
           * @var string List ID
e608c5f7   Yarik   Comment added
99
           */
c05bf005   Yarik   Comment added
100
101
          public $listId = 'artbox-comment-list';
          
e608c5f7   Yarik   Comment added
102
          /**
c05bf005   Yarik   Comment added
103
104
           * Item view
           * @var string
e608c5f7   Yarik   Comment added
105
           */
c05bf005   Yarik   Comment added
106
107
          public $itemView = '@artbox-comment/views/artbox_comment_item';
          
e608c5f7   Yarik   Comment added
108
          /**
c05bf005   Yarik   Comment added
109
110
           * Item options
           * @var array
e608c5f7   Yarik   Comment added
111
           */
c05bf005   Yarik   Comment added
112
113
          public $itemOptions = [
              'class' => 'artbox_item_container',
e608c5f7   Yarik   Comment added
114
          ];
c05bf005   Yarik   Comment added
115
          
e608c5f7   Yarik   Comment added
116
          /**
c05bf005   Yarik   Comment added
117
118
119
           * Entity ID attribute, default to primaryKey() if ActiveRecord and throws exception if not
           * set
           * @var string entity id attribute
e608c5f7   Yarik   Comment added
120
           */
c05bf005   Yarik   Comment added
121
122
123
124
125
126
127
128
          public $entityIdAttribute;
          
          /**
           * Info to be passed to Comment Model
           * @var string $info Additional info
           */
          public $info = NULL;
          
e608c5f7   Yarik   Comment added
129
          /**
c05bf005   Yarik   Comment added
130
131
           * Client options to be passed to JS
           * @var array comment widget client options
e608c5f7   Yarik   Comment added
132
           */
c05bf005   Yarik   Comment added
133
134
          public $clientOptions = [ ];
          
e608c5f7   Yarik   Comment added
135
          /**
c05bf005   Yarik   Comment added
136
137
           * @todo Check if needed
           * @var string pjax container id
e608c5f7   Yarik   Comment added
138
           */
c05bf005   Yarik   Comment added
139
140
          public $pjaxContainerId;
          
17ca60dd   Yarik   Added comments to...
141
          public $layout = "<div class='comments-border'></div>{form} {reply_form} {list}";
c05bf005   Yarik   Comment added
142
          
e608c5f7   Yarik   Comment added
143
          /**
c05bf005   Yarik   Comment added
144
145
           * Model fully namespaced classname
           * @var string Model namespace
e608c5f7   Yarik   Comment added
146
           */
c05bf005   Yarik   Comment added
147
148
          protected $entity;
          
e608c5f7   Yarik   Comment added
149
          /**
c05bf005   Yarik   Comment added
150
151
           * Entity ID for attached model
           * @var integer Entity ID
e608c5f7   Yarik   Comment added
152
           */
c05bf005   Yarik   Comment added
153
154
          protected $entityId;
          
e608c5f7   Yarik   Comment added
155
          /**
c05bf005   Yarik   Comment added
156
157
158
159
160
           * Encrypted data to be passed to Controller. Consist of:
           * * Model::className()
           * * entityId
           * * info (optional)
           * @var string encrypted entity key
e608c5f7   Yarik   Comment added
161
           */
c05bf005   Yarik   Comment added
162
163
          protected $encryptedEntityKey;
          
e608c5f7   Yarik   Comment added
164
          /**
c05bf005   Yarik   Comment added
165
166
           * Parts for widget
           * @var array $parts
e608c5f7   Yarik   Comment added
167
           */
c05bf005   Yarik   Comment added
168
169
          protected $parts;
          
e608c5f7   Yarik   Comment added
170
          /**
c05bf005   Yarik   Comment added
171
           * Initializes the widget params.
e608c5f7   Yarik   Comment added
172
173
174
           */
          public function init()
          {
c05bf005   Yarik   Comment added
175
176
177
178
179
180
181
182
183
184
              // Module init
              Yii::$app->getModule(Module::$name);
              // Model init
              $model = $this->getModel();
              
              /**
               * @todo Check if needed
               */
              if(empty( $this->pjaxContainerId )) {
                  $this->pjaxContainerId = 'comment-pjax-container-' . $this->getId();
e608c5f7   Yarik   Comment added
185
              }
c05bf005   Yarik   Comment added
186
187
188
189
190
191
192
193
194
195
196
              
              $this->entity = $model::className();
              // Entity ID init
              if(!empty( $this->entityIdAttribute ) && $this->model->hasProperty($this->entityIdAttribute)) {
                  $this->entityId = $this->model->{$this->entityIdAttribute};
              } else {
                  if($this->model instanceof \yii\db\ActiveRecord && !empty( $this->model->getPrimaryKey() )) {
                      $this->entityId = (int) $this->model->getPrimaryKey();
                  } else {
                      throw new InvalidConfigException(/*Yii::t('artbox-comment', 'The "entityIdAttribute" value for widget model cannot be empty.')*/);
                  }
e608c5f7   Yarik   Comment added
197
              }
c05bf005   Yarik   Comment added
198
199
200
201
202
              
              // Generate encryptedEntityKey
              $this->encryptedEntityKey = $this->generateEntityKey();
              
              $this->registerAssets();
e608c5f7   Yarik   Comment added
203
          }
c05bf005   Yarik   Comment added
204
          
e608c5f7   Yarik   Comment added
205
          /**
c05bf005   Yarik   Comment added
206
207
           * Executes the widget.
           * @return string the result of widget execution to be outputted.
e608c5f7   Yarik   Comment added
208
209
210
           */
          public function run()
          {
c05bf005   Yarik   Comment added
211
212
213
214
215
216
217
              /* @var Module $module */
              $module = Yii::$app->getModule(Module::$name);
              $commentModelClass = $module->commentModelClass;
              $commentModel = $this->createModel($commentModelClass, [
                  'entity'          => $this->entity,
                  'entityId'        => $this->entityId,
                  'encryptedEntity' => $this->encryptedEntityKey,
17ca60dd   Yarik   Added comments to...
218
                  'scenario' => \Yii::$app->user->getIsGuest()?$commentModelClass::SCENARIO_GUEST:$commentModelClass::SCENARIO_USER,
c05bf005   Yarik   Comment added
219
220
221
222
223
224
225
226
227
228
229
230
              ]);
              if($module::$enableRating) {
                  $ratingModelClass = $module->ratingModelClass;
                  $ratingModel = $this->createRating($ratingModelClass);
              } else {
                  $ratingModel = NULL;
              }
              
              $comments = $commentModelClass::getTree($this->entity, $this->entityId);
              
              $this->buildParts($commentModel, $comments, $ratingModel);
              
e608c5f7   Yarik   Comment added
231
232
              return $this->renderWidget();
          }
c05bf005   Yarik   Comment added
233
234
235
236
237
          
          /**
           * Register assets.
           */
          protected function registerAssets()
e608c5f7   Yarik   Comment added
238
          {
c05bf005   Yarik   Comment added
239
240
241
242
243
              $this->clientOptions[ 'formSelector' ] = '#' . $this->formId;
              $this->clientOptions[ 'listSelector' ] = '#' . $this->listId;
              $options = Json::encode($this->clientOptions);
              $view = $this->getView();
              CommentAsset::register($view);
17ca60dd   Yarik   Added comments to...
244
              $view->registerJs("jQuery('#{$this->formId}').artbox_comment({$options});");
e608c5f7   Yarik   Comment added
245
          }
c05bf005   Yarik   Comment added
246
247
248
249
250
251
          
          /**
           * Get encrypted entity key
           * @return string
           */
          protected function generateEntityKey()
e608c5f7   Yarik   Comment added
252
          {
c05bf005   Yarik   Comment added
253
254
255
256
257
258
              return Yii::$app->getSecurity()
                              ->encryptByKey(Json::encode([
                                  'entity'    => $this->entity,
                                  'entity_id' => $this->entityId,
                                  'info'      => $this->info,
                              ]), Module::$encryptionKey);
e608c5f7   Yarik   Comment added
259
          }
c05bf005   Yarik   Comment added
260
261
262
263
264
265
266
267
268
269
270
          
          /**
           * Create comment model
           *
           * @param string $className Full namespaced model
           * @param array  $config    Init config
           *
           * @return CommentInterface Comment model
           * @throws InvalidConfigException If object not instance of \yii\base\Model
           */
          protected function createModel(string $className, array $config = [ ]): CommentInterface
e608c5f7   Yarik   Comment added
271
          {
c05bf005   Yarik   Comment added
272
273
274
275
              $options = array_merge($config, [ 'class' => $className ]);
              $object = Yii::createObject($options);
              if($object instanceof CommentInterface) {
                  return $object;
e608c5f7   Yarik   Comment added
276
              }
c05bf005   Yarik   Comment added
277
              throw new InvalidConfigException(/*Yii::t(\'artbox-comment\', \'Comment model must be instance of CommentInterface.\')*/);
e608c5f7   Yarik   Comment added
278
          }
c05bf005   Yarik   Comment added
279
280
281
282
283
284
285
286
287
288
289
      
          /**
           * Create rating model
           *
           * @param string $className Full namespaced model
           * @param array  $config    Init config
           *
           * @return CommentInterface Comment model
           * @throws InvalidConfigException If object not instance of \yii\base\Model
           */
          protected function createRating(string $className, array $config = [ ]): RatingModel
e608c5f7   Yarik   Comment added
290
          {
c05bf005   Yarik   Comment added
291
292
293
294
              $options = array_merge($config, [ 'class' => $className ]);
              $object = Yii::createObject($options);
              if($object instanceof RatingModel) {
                  return $object;
e608c5f7   Yarik   Comment added
295
              }
c05bf005   Yarik   Comment added
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
              throw new InvalidConfigException(/*Yii::t(\'artbox-comment\', \'Comment model must be instance of RatingModel.\')*/);
          }
          
          /**
           * Build parts for rendering widget
           *
           * @param CommentInterface   $commentModel
           * @param ActiveDataProvider $comments
           */
          protected function buildParts(CommentInterface $commentModel, ActiveDataProvider $comments, $ratingModel = NULL)
          {
              $form_options = $this->formOptions;
              $this->parts[ 'form' ] = Html::tag(ArrayHelper::remove($form_options, 'tag', 'div'), $this->render($this->formView, [
                  'comment_model' => $commentModel,
                  'form_params'   => $this->formParams,
                  'model'         => $this->getModel(),
                  'formId'        => $this->formId,
                  'rating_model'   => $ratingModel,
              ]), $form_options);
              
              if(!\Yii::$app->user->isGuest) {
                  $reply_options = $this->replyOptions;
                  $this->parts[ 'reply_form' ] = Html::tag(ArrayHelper::remove($reply_options, 'tag', 'div'), $this->render($this->replyView, [
                      'comment_model' => $commentModel,
                      'form_params'   => $this->formParams,
                      'model'         => $this->getModel(),
                      'formId'        => $this->formId,
                  ]), $reply_options);
e608c5f7   Yarik   Comment added
324
              }
c05bf005   Yarik   Comment added
325
326
327
328
329
330
331
332
333
334
              
              $list_options = array_merge($this->listOptions, [ 'id' => $this->listId ]);
              $this->parts[ 'list' ] = Html::tag(ArrayHelper::remove($list_options, 'tag', 'div'), $this->render($this->listView, [
                  'comment_model' => $commentModel,
                  'list_params'   => $this->listParams,
                  'model'         => $this->getModel(),
                  'comments'      => $comments,
                  'item_options'  => $this->itemOptions,
                  'item_view'     => $this->itemView,
              ]), $list_options);
e608c5f7   Yarik   Comment added
335
          }
c05bf005   Yarik   Comment added
336
337
338
339
340
          
          /**
           * @return string
           */
          protected function renderWidget(): string
e608c5f7   Yarik   Comment added
341
          {
c05bf005   Yarik   Comment added
342
              $layout = $this->layout;
e608c5f7   Yarik   Comment added
343
344
              $parts = $this->parts;
              $options = $this->options;
c05bf005   Yarik   Comment added
345
346
347
              $layout = preg_replace('/{list}/', ArrayHelper::getValue($parts, 'list', ''), $layout);
              $layout = preg_replace('/{form}/', ArrayHelper::getValue($parts, 'form', ''), $layout);
              $layout = preg_replace('/{reply_form}/', ArrayHelper::getValue($parts, 'reply_form', ''), $layout);
e608c5f7   Yarik   Comment added
348
              $tag = ArrayHelper::remove($options, 'tag', 'div');
c05bf005   Yarik   Comment added
349
              return Html::tag($tag, $layout, $options);
e608c5f7   Yarik   Comment added
350
          }
c05bf005   Yarik   Comment added
351
352
          
          public function setModel(\yii\base\Model $model)
e608c5f7   Yarik   Comment added
353
          {
c05bf005   Yarik   Comment added
354
355
356
357
358
359
360
              $this->model = $model;
          }
          
          public function getModel(): \yii\base\Model
          {
              if(!empty( $this->model )) {
                  return $this->model;
e608c5f7   Yarik   Comment added
361
              }
c05bf005   Yarik   Comment added
362
              throw new InvalidConfigException(/*Yii::t(\'artbox-comment\', \'The "model" property must be set.\')*/);
e608c5f7   Yarik   Comment added
363
          }
3f2bc3d0   Administrator   first commit
364
      }