Commit 226062a5b428979b838756aa2c4b8661b81b5e82

Authored by Yarik
1 parent 36275378

CommentBehavior

behaviors/CommentBehavior.php 0 โ†’ 100644
  1 +<?php
  2 +
  3 + namespace artweb\artbox\comment\behaviors;
  4 +
  5 + use artweb\artbox\comment\models\CommentModel;
  6 + use artweb\artbox\comment\models\interfaces\RatingCacheInterface;
  7 + use yii\base\Behavior;
  8 + use yii\base\InvalidConfigException;
  9 + use yii\db\ActiveQuery;
  10 + use yii\db\ActiveRecord;
  11 +
  12 + /**
  13 + * Class CommentBehavior
  14 + *
  15 + * @property ActiveQuery $averageRating
  16 + * @property CommentModel[] $comments
  17 + * @package artweb\artbox\comment\behaviors
  18 + */
  19 + class CommentBehavior extends Behavior
  20 + {
  21 +
  22 + /**
  23 + * Fully-classified name of class to hold rating cache
  24 + *
  25 + * @var string
  26 + */
  27 + private $cacheModelName = '';
  28 +
  29 + /**
  30 + * Class to hold rating cache
  31 + *
  32 + * @var RatingCacheInterface
  33 + */
  34 + private $cacheModel = null;
  35 +
  36 + /**
  37 + * Whether to cache rating or not
  38 + *
  39 + * @var bool
  40 + */
  41 + private $cacheRating = false;
  42 +
  43 + /**
  44 + * @inheritdoc
  45 + */
  46 + public function attach($owner)
  47 + {
  48 + if ($this->cacheRating) {
  49 + if (empty( $this->cacheModelName ) || !is_string($this->cacheModelName)) {
  50 + throw new InvalidConfigException(
  51 + 'To use rating cache you must set $cacheModelName where to store it'
  52 + );
  53 + }
  54 + $this->setCacheModel(
  55 + \Yii::createObject(
  56 + [
  57 + 'class' => $this->cacheModelName,
  58 + ]
  59 + )
  60 + );
  61 + }
  62 + parent::attach($owner);
  63 + }
  64 +
  65 + /**
  66 + * Get fully-classified name of class to hold rating cache
  67 + *
  68 + * @return string
  69 + */
  70 + public function getCacheModelName():string
  71 + {
  72 + return $this->cacheModelName;
  73 + }
  74 +
  75 + /**
  76 + * Set fully-classified name of class to hold rating cache
  77 + *
  78 + * @param string $value
  79 + */
  80 + public function setCacheModelName(string $value)
  81 + {
  82 + $this->cacheModelName = $value;
  83 + }
  84 +
  85 + /**
  86 + * Get model to hold rating cache
  87 + *
  88 + * @return \artweb\artbox\comment\models\interfaces\RatingCacheInterface
  89 + */
  90 + public function getCacheModel():RatingCacheInterface
  91 + {
  92 + return $this->cacheModel;
  93 + }
  94 +
  95 + /**
  96 + * Set model to hold cache
  97 + *
  98 + * @param \artweb\artbox\comment\models\interfaces\RatingCacheInterface|null $value
  99 + */
  100 + private function setCacheModel(RatingCacheInterface $value = null)
  101 + {
  102 + $this->cacheModel = $value;
  103 + }
  104 +
  105 + /**
  106 + * Whether cache rating or not
  107 + *
  108 + * @return bool
  109 + */
  110 + public function getCacheRating(): bool
  111 + {
  112 + return $this->cacheRating;
  113 + }
  114 +
  115 + /**
  116 + * Set whether to cache rating or not
  117 + *
  118 + * @param bool $value
  119 + */
  120 + public function setCacheRating(bool $value)
  121 + {
  122 + $this->cacheRating = $value;
  123 + }
  124 +
  125 + /**
  126 + * Get query to get all comments for current $owner model
  127 + *
  128 + * @return \yii\db\ActiveQuery
  129 + */
  130 + public function getComments(): ActiveQuery
  131 + {
  132 + /**
  133 + * @var ActiveRecord $owner
  134 + */
  135 + $owner = $this->owner;
  136 + $pk = $owner->primaryKey()[ 0 ];
  137 + $query = $owner->hasMany(CommentModel::className(), [ 'entity_id' => $pk ])
  138 + ->where(
  139 + [
  140 + 'artbox_comment.entity' => $owner::className(),
  141 + 'artbox_comment.status' => CommentModel::STATUS_ACTIVE,
  142 + 'artbox_comment.artbox_comment_pid' => null,
  143 + ]
  144 + );
  145 + return $query;
  146 + }
  147 +
  148 + /**
  149 + * Get query to get average rating for current $owner model if it cached
  150 + *
  151 + * @return \yii\db\ActiveQuery
  152 + */
  153 + public function getAverageRating(): ActiveQuery
  154 + {
  155 + /**
  156 + * @var ActiveRecord $owner
  157 + */
  158 + $owner = $this->owner;
  159 + $pk = $owner->primaryKey()[ 0 ];
  160 + $query = $owner->hasOne($this->cacheModelName, [ $this->cacheModel->getLinkAttribute() => $pk ]);
  161 + return $query;
  162 + }
  163 +
  164 + /**
  165 + * Recalculate cache for current $owner model
  166 + *
  167 + * @return bool
  168 + */
  169 + public function recalculateRating(): bool
  170 + {
  171 + /**
  172 + * @var RatingCacheInterface $averageRating
  173 + */
  174 + $average = $this->getComments()
  175 + ->joinWith('rating')
  176 + ->select([ 'average' => 'avg(artbox_comment_rating.value)::float' ])
  177 + ->scalar();
  178 + if (!$average) {
  179 + $average = 0;
  180 + }
  181 + $averageRating = $this->getAverageRating()
  182 + ->one();
  183 + if (!empty( $averageRating )) {
  184 + $averageRating->setValue($average);
  185 + } else {
  186 + /**
  187 + * @var ActiveRecord $owner
  188 + * @var RatingCacheInterface $averageRating
  189 + */
  190 + $owner = $this->owner;
  191 + $pk = $owner->primaryKey()[ 0 ];
  192 + $averageRating = \Yii::createObject(
  193 + [
  194 + 'class' => $this->cacheModelName,
  195 + $this->cacheModel->getLinkAttribute() => $this->owner->$pk,
  196 + ]
  197 + );
  198 + $averageRating->setValue($average);
  199 + }
  200 + if ($averageRating->save()) {
  201 + return true;
  202 + } else {
  203 + return false;
  204 + }
  205 + }
  206 + }
  207 +
0 208 \ No newline at end of file
... ...
models/interfaces/RatingCacheInterface.php 0 โ†’ 100644
  1 +<?php
  2 +
  3 + namespace artweb\artbox\comment\models\interfaces;
  4 +
  5 + use yii\db\ActiveRecordInterface;
  6 +
  7 + interface RatingCacheInterface extends ActiveRecordInterface
  8 + {
  9 + /**
  10 + * Get foreign key attribute name
  11 + *
  12 + * @return string
  13 + */
  14 + public function getLinkAttribute(): string;
  15 +
  16 + /**
  17 + * Get value
  18 + *
  19 + * @return float
  20 + */
  21 + public function getValue(): float;
  22 +
  23 + /**
  24 + * Set value
  25 + *
  26 + * @param float $value
  27 + *
  28 + * @return void
  29 + */
  30 + public function setValue(float $value);
  31 + }
0 32 \ No newline at end of file
... ...
readme 0 โ†’ 100644
  1 +PHPDoc FOR CommentBehavior
  2 +
  3 +** From CommentBehavior **
  4 +* @property string $cacheModelName
  5 +* @property RatingCacheInterface $cacheModel
  6 +* @property boolean $cacheRating
  7 +* @property CommentModel[] $comments
  8 +* @property RatingCacheInterface $averageRating
  9 +* @method string getCacheModelName()
  10 +* @method void setCacheModelName(string $value)
  11 +* @method RatingCacheInterface getCacheModel()
  12 +* @method void setCacheModel(RatingCacheInterface $value)
  13 +* @method boolean getCacheRating()
  14 +* @method void setCacheRating(bool $value)
  15 +* @method ActiveQuery getComments()
  16 +* @method ActiveQuery getAverageRating()
  17 +* @method bool recalculateRating()
  18 +** End CommentBehavior **
0 19 \ No newline at end of file
... ...