Blame view

common/modules/comment/widgets/CommentWidget.php 12.5 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',
14009e7f   Yarik   Structure data fix
114
              'itemprop' => 'review',
5fb14ec0   Yarik   Comment structure...
115
              'itemscope' => 'itemscope',
14009e7f   Yarik   Structure data fix
116
              'itemtype' => 'http://schema.org/Review',
e608c5f7   Yarik   Comment added
117
          ];
c05bf005   Yarik   Comment added
118
          
e608c5f7   Yarik   Comment added
119
          /**
c05bf005   Yarik   Comment added
120
121
122
           * Entity ID attribute, default to primaryKey() if ActiveRecord and throws exception if not
           * set
           * @var string entity id attribute
e608c5f7   Yarik   Comment added
123
           */
c05bf005   Yarik   Comment added
124
125
126
127
128
129
130
131
          public $entityIdAttribute;
          
          /**
           * Info to be passed to Comment Model
           * @var string $info Additional info
           */
          public $info = NULL;
          
e608c5f7   Yarik   Comment added
132
          /**
c05bf005   Yarik   Comment added
133
134
           * Client options to be passed to JS
           * @var array comment widget client options
e608c5f7   Yarik   Comment added
135
           */
c05bf005   Yarik   Comment added
136
137
          public $clientOptions = [ ];
          
e608c5f7   Yarik   Comment added
138
          /**
c05bf005   Yarik   Comment added
139
140
           * @todo Check if needed
           * @var string pjax container id
e608c5f7   Yarik   Comment added
141
           */
c05bf005   Yarik   Comment added
142
143
          public $pjaxContainerId;
          
17ca60dd   Yarik   Added comments to...
144
          public $layout = "<div class='comments-border'></div>{form} {reply_form} {list}";
c05bf005   Yarik   Comment added
145
          
e608c5f7   Yarik   Comment added
146
          /**
c05bf005   Yarik   Comment added
147
148
           * Model fully namespaced classname
           * @var string Model namespace
e608c5f7   Yarik   Comment added
149
           */
c05bf005   Yarik   Comment added
150
151
          protected $entity;
          
e608c5f7   Yarik   Comment added
152
          /**
c05bf005   Yarik   Comment added
153
154
           * Entity ID for attached model
           * @var integer Entity ID
e608c5f7   Yarik   Comment added
155
           */
c05bf005   Yarik   Comment added
156
157
          protected $entityId;
          
e608c5f7   Yarik   Comment added
158
          /**
c05bf005   Yarik   Comment added
159
160
161
162
163
           * Encrypted data to be passed to Controller. Consist of:
           * * Model::className()
           * * entityId
           * * info (optional)
           * @var string encrypted entity key
e608c5f7   Yarik   Comment added
164
           */
c05bf005   Yarik   Comment added
165
166
          protected $encryptedEntityKey;
          
e608c5f7   Yarik   Comment added
167
          /**
c05bf005   Yarik   Comment added
168
169
           * Parts for widget
           * @var array $parts
e608c5f7   Yarik   Comment added
170
           */
c05bf005   Yarik   Comment added
171
172
          protected $parts;
          
e608c5f7   Yarik   Comment added
173
          /**
c05bf005   Yarik   Comment added
174
           * Initializes the widget params.
e608c5f7   Yarik   Comment added
175
176
177
           */
          public function init()
          {
c05bf005   Yarik   Comment added
178
179
180
181
182
183
184
185
186
187
              // 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
188
              }
c05bf005   Yarik   Comment added
189
190
191
192
193
194
195
196
197
198
199
              
              $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
200
              }
c05bf005   Yarik   Comment added
201
202
203
204
205
              
              // Generate encryptedEntityKey
              $this->encryptedEntityKey = $this->generateEntityKey();
              
              $this->registerAssets();
e608c5f7   Yarik   Comment added
206
          }
c05bf005   Yarik   Comment added
207
          
e608c5f7   Yarik   Comment added
208
          /**
c05bf005   Yarik   Comment added
209
210
           * Executes the widget.
           * @return string the result of widget execution to be outputted.
e608c5f7   Yarik   Comment added
211
212
213
           */
          public function run()
          {
c05bf005   Yarik   Comment added
214
215
216
217
218
219
220
              /* @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...
221
                  'scenario' => \Yii::$app->user->getIsGuest()?$commentModelClass::SCENARIO_GUEST:$commentModelClass::SCENARIO_USER,
c05bf005   Yarik   Comment added
222
223
224
225
226
227
228
229
230
231
232
233
              ]);
              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
234
235
              return $this->renderWidget();
          }
c05bf005   Yarik   Comment added
236
237
238
239
240
          
          /**
           * Register assets.
           */
          protected function registerAssets()
e608c5f7   Yarik   Comment added
241
          {
c05bf005   Yarik   Comment added
242
243
244
245
246
              $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...
247
              $view->registerJs("jQuery('#{$this->formId}').artbox_comment({$options});");
e608c5f7   Yarik   Comment added
248
          }
c05bf005   Yarik   Comment added
249
250
251
252
253
254
          
          /**
           * Get encrypted entity key
           * @return string
           */
          protected function generateEntityKey()
e608c5f7   Yarik   Comment added
255
          {
c05bf005   Yarik   Comment added
256
257
258
259
260
261
              return Yii::$app->getSecurity()
                              ->encryptByKey(Json::encode([
                                  'entity'    => $this->entity,
                                  'entity_id' => $this->entityId,
                                  'info'      => $this->info,
                              ]), Module::$encryptionKey);
e608c5f7   Yarik   Comment added
262
          }
c05bf005   Yarik   Comment added
263
264
265
266
267
268
269
270
271
272
273
          
          /**
           * 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
274
          {
c05bf005   Yarik   Comment added
275
276
277
278
              $options = array_merge($config, [ 'class' => $className ]);
              $object = Yii::createObject($options);
              if($object instanceof CommentInterface) {
                  return $object;
e608c5f7   Yarik   Comment added
279
              }
c05bf005   Yarik   Comment added
280
              throw new InvalidConfigException(/*Yii::t(\'artbox-comment\', \'Comment model must be instance of CommentInterface.\')*/);
e608c5f7   Yarik   Comment added
281
          }
c05bf005   Yarik   Comment added
282
283
284
285
286
287
288
289
290
291
292
      
          /**
           * 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
293
          {
c05bf005   Yarik   Comment added
294
295
296
297
              $options = array_merge($config, [ 'class' => $className ]);
              $object = Yii::createObject($options);
              if($object instanceof RatingModel) {
                  return $object;
e608c5f7   Yarik   Comment added
298
              }
c05bf005   Yarik   Comment added
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
324
325
326
              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
327
              }
c05bf005   Yarik   Comment added
328
329
330
331
332
333
334
335
336
337
              
              $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
338
          }
c05bf005   Yarik   Comment added
339
340
341
342
343
          
          /**
           * @return string
           */
          protected function renderWidget(): string
e608c5f7   Yarik   Comment added
344
          {
c05bf005   Yarik   Comment added
345
              $layout = $this->layout;
e608c5f7   Yarik   Comment added
346
347
              $parts = $this->parts;
              $options = $this->options;
c05bf005   Yarik   Comment added
348
349
350
              $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
351
              $tag = ArrayHelper::remove($options, 'tag', 'div');
c05bf005   Yarik   Comment added
352
              return Html::tag($tag, $layout, $options);
e608c5f7   Yarik   Comment added
353
          }
c05bf005   Yarik   Comment added
354
355
          
          public function setModel(\yii\base\Model $model)
e608c5f7   Yarik   Comment added
356
          {
c05bf005   Yarik   Comment added
357
358
359
360
361
362
363
              $this->model = $model;
          }
          
          public function getModel(): \yii\base\Model
          {
              if(!empty( $this->model )) {
                  return $this->model;
e608c5f7   Yarik   Comment added
364
              }
c05bf005   Yarik   Comment added
365
              throw new InvalidConfigException(/*Yii::t(\'artbox-comment\', \'The "model" property must be set.\')*/);
e608c5f7   Yarik   Comment added
366
          }
3f2bc3d0   Administrator   first commit
367
      }