/** * @param array|string $categories * @return DbSubscriptionQuery $this */ public function matchingCategory($categories) { if ($categories === null) { return $this; } $modelClass = $this->modelClass; $t = $modelClass::tableName(); $r = DbSubscriptionCategory::tableName(); if (!is_array($categories)) { $categories = [$categories]; } if (empty($categories)) { return $this; } $this->innerJoinWith('categories'); $i = 0; $conditions = ['AND']; $params = []; foreach ($categories as $category) { $conditions[] = ['OR', "({$r}.is_exception = false AND :category{$i} LIKE {$r}.category)", "({$r}.is_exception = true AND :category{$i} NOT LIKE {$r}.category)"]; $params[':category' . $i++] = $category; } $this->andWhere($conditions, $params); return $this; }
/** * @inheritdoc * @param boolean $permanent if false, the subscription will only be marked as removed * and the messages will remain in the storage; * if true, everything is removed permanently */ public function unsubscribe($subscriber_id, $categories = null, $permanent = true) { $trx = models\DbSubscription::getDb()->transaction !== null ? null : models\DbSubscription::getDb()->beginTransaction(); $subscription = models\DbSubscription::find()->withQueue($this->id)->withSubscriber($subscriber_id)->matchingCategory($categories)->one(); if ($subscription !== null) { $canDelete = true; if ($categories !== null) { // it may be a case when some (but not all) categories are about to be unsubscribed // if that happens and this subscription ends up with some other categories, only given categories // should be deleted, not the whole subscription $primaryKey = models\DbSubscriptionCategory::primaryKey(); models\DbSubscriptionCategory::deleteAll([reset($primaryKey) => array_map(function ($c) { return $c->id; }, $subscription->categories)]); $canDelete = models\DbSubscriptionCategory::find()->where(['subscription_id' => $subscription->id])->count() <= 0; } if ($canDelete) { if ($permanent) { $subscription->delete(); } else { $subscription->is_deleted = 1; $subscription->update(true, ['is_deleted']); } } } if ($trx !== null) { $trx->commit(); } }
public function getCategories() { return $this->hasMany(DbSubscriptionCategory::className(), ['subscription_id' => 'id']); }