Fix: Refactored ActiveQueryContent::contentTag method, added method parameter

This commit is contained in:
Lucas Bartholemy 2018-08-31 15:57:15 +02:00
parent 0e79fd31c3
commit f920ab3b91
2 changed files with 47 additions and 44 deletions

View File

@ -32,6 +32,7 @@ HumHub Change Log
- Fix: Activity exception on integrity check
- Fix: Ensure profile field "internal name" contains at least one character
- Fix: Do not allow user self deletion via admin section
- Fix: Refactored ActiveQueryContent::contentTag method, added method parameter
1.3.1 (August 7, 2018)

View File

@ -9,13 +9,15 @@
namespace humhub\modules\content\components;
use humhub\modules\content\models\ContentTag;
use Yii;
use humhub\modules\user\models\User;
use humhub\modules\content\models\ContentTagRelation;
use humhub\modules\space\models\Space;
use humhub\modules\user\models\User;
use Yii;
use yii\db\Expression;
/**
* ActiveQueryContent is an enhanced ActiveQuery with additional selectors for especially content.
*
*
* @inheritdoc
*
* @author luke
@ -24,7 +26,7 @@ class ActiveQueryContent extends \yii\db\ActiveQuery
{
/**
* Own content scope for userRelated
* Own content scope for userRelated
* @see ActiveQueryContent::userRelated
*/
const USER_RELATED_SCOPE_OWN = 1;
@ -35,7 +37,7 @@ class ActiveQueryContent extends \yii\db\ActiveQuery
/**
* Only returns user readable records
*
*
* @param \humhub\modules\user\models\User $user
* @return \humhub\modules\content\components\ActiveQueryContent
*/
@ -83,14 +85,13 @@ class ActiveQueryContent extends \yii\db\ActiveQuery
$this->andWhere("{$conditionSpace} OR {$conditionUser}");
return $this;
}
/**
* Limits the returned records to the given ContentContainer.
*
* @param ContentContainerActiveRecord $container|null or null for global content
*
* @param ContentContainerActiveRecord $container |null or null for global content
* @return \humhub\modules\content\components\ActiveQueryContent
* @throws \yii\base\Exception
*/
@ -108,44 +109,45 @@ class ActiveQueryContent extends \yii\db\ActiveQuery
}
/**
* Filters contents by given contentTags.
* Returns only content which has one or all of given ContentTags
*
* @param array|string|ContentTag $contentTags array of or single content tag classes or instances
* @return $this
* @since 1.3
* @param $contentTags ContentTag[]|ContentTag
* @param $mode string
* @return ActiveQueryContent
*/
public function contentTag($contentTags = [])
public function contentTag($contentTags, $mode = 'AND')
{
if(empty($contentTag)) {
return $this;
}
if(!is_array($contentTags)) {
if (!is_array($contentTags)) {
$contentTags = [$contentTags];
}
$this->innerJoinWith('tags');
foreach ($contentTags as $contentTag) {
$contentTagClass = null;
if($contentTag instanceof ContentTag) {
$contentTagClass = get_class($contentTag);
} elseif(is_string($contentTag)) {
$contentTagClass = $contentTag;
if ($mode == 'AND') {
foreach ($contentTags as $contentTag) {
$contentTagQuery = ContentTagRelation::find()->select('content_id');
$contentTagQuery->andWhere(['content_tag_relation.tag_id' => $contentTag->id]);
$contentTagQuery->andWhere('content_tag_relation.content_id=content.id');
$this->andWhere(['content.id' =>$contentTagQuery]);
}
} else if ($mode == 'OR') {
$names = array_map(function ($v) {
return $v->name;
}, $contentTags);
if($contentTagClass) {
call_user_func($contentTagClass .'::addQueryCondition', $this);
}
$this->joinWith('content.tags');
$this->andWhere(['IS NOT', 'content_tag.id', new Expression('NULL')]);
$this->andWhere(['IN', 'content_tag.name', $names]);
$this->distinct();
}
return $this;
}
/**
* Adds an additional WHERE condition to the existing one.
*
*
* @inheritdoc
*
*
* @param array|string $condition
* @param array $params
* @return $this
@ -158,8 +160,8 @@ class ActiveQueryContent extends \yii\db\ActiveQuery
/**
* Finds user related content.
* All available scopes: ActiveQueryContent::USER_RELATED_SCOPE_*
*
* @param array $scopes
*
* @param array $scopes
* @param User $user
* @return \humhub\modules\content\components\ActiveQueryContent
*/
@ -182,10 +184,10 @@ class ActiveQueryContent extends \yii\db\ActiveQuery
if (in_array(self::USER_RELATED_SCOPE_SPACES, $scopes)) {
$spaceMemberships = (new \yii\db\Query())
->select("sm.id")
->from('space_membership')
->leftJoin('space sm', 'sm.id=space_membership.space_id')
->where('space_membership.user_id=:userId AND space_membership.status=' . \humhub\modules\space\models\Membership::STATUS_MEMBER);
->select("sm.id")
->from('space_membership')
->leftJoin('space sm', 'sm.id=space_membership.space_id')
->where('space_membership.user_id=:userId AND space_membership.status=' . \humhub\modules\space\models\Membership::STATUS_MEMBER);
$conditions[] = 'contentcontainer.pk IN (' . Yii::$app->db->getQueryBuilder()->build($spaceMemberships)[0] . ') AND contentcontainer.class = :spaceClass';
$params[':userId'] = $user->id;
$params[':spaceClass'] = Space::class;
@ -198,10 +200,10 @@ class ActiveQueryContent extends \yii\db\ActiveQuery
if (in_array(self::USER_RELATED_SCOPE_FOLLOWED_SPACES, $scopes)) {
$spaceFollow = (new \yii\db\Query())
->select("sf.id")
->from('user_follow')
->leftJoin('space sf', 'sf.id=user_follow.object_id AND user_follow.object_model=:spaceClass')
->where('user_follow.user_id=:userId AND sf.id IS NOT NULL');
->select("sf.id")
->from('user_follow')
->leftJoin('space sf', 'sf.id=user_follow.object_id AND user_follow.object_model=:spaceClass')
->where('user_follow.user_id=:userId AND sf.id IS NOT NULL');
$conditions[] = 'contentcontainer.pk IN (' . Yii::$app->db->getQueryBuilder()->build($spaceFollow)[0] . ') AND contentcontainer.class = :spaceClass';
$params[':spaceClass'] = Space::class;
$params[':userId'] = $user->id;
@ -209,10 +211,10 @@ class ActiveQueryContent extends \yii\db\ActiveQuery
if (in_array(self::USER_RELATED_SCOPE_FOLLOWED_USERS, $scopes)) {
$userFollow = (new \yii\db\Query())
->select(["uf.id"])
->from('user_follow')
->leftJoin('user uf', 'uf.id=user_follow.object_id AND user_follow.object_model=:userClass')
->where('user_follow.user_id=:userId AND uf.id IS NOT NULL');
->select(["uf.id"])
->from('user_follow')
->leftJoin('user uf', 'uf.id=user_follow.object_id AND user_follow.object_model=:userClass')
->where('user_follow.user_id=:userId AND uf.id IS NOT NULL');
$conditions[] = 'contentcontainer.pk IN (' . Yii::$app->db->getQueryBuilder()->build($userFollow)[0] . ' AND contentcontainer.class=:userClass)';
$params[':userClass'] = User::class;
$params[':userId'] = $user->id;