src/Taggable.php
public function scopeWithAllTags(Builder $query, $tags): Builder
    {
        /** @var TagService $service */
        $service = app(TagService::class);
        $normalized = $service->buildTagArrayNormalized($tags);

        // If there are no tags specified, then there
        // can't be any results so short-circuit
        if (count($normalized) === 0) {
            if (config('taggable.throwEmptyExceptions')) {
                throw new NoTagsSpecifiedException('Empty tag data passed to withAllTags scope.');
            }

            return $query->where(\DB::raw(1), 0);
        }

        $tagKeys = $service->getTagModelKeys($normalized);

        // If some of the tags specified don't exist, then there can't
        // be any models with all the tags, so so short-circuit
        if (count($tagKeys) !== count($normalized)) {
            return $query->where(\DB::raw(1), 0);
        }

        $alias = $this->taggableCreateNewAlias(__FUNCTION__);
        $morphTagKeyName = $this->getQualifiedRelatedPivotKeyNameWithAlias($alias);

        return $this->prepareTableJoin($query, 'inner', $alias)
            ->whereIn($morphTagKeyName, $tagKeys)
            ->havingRaw("COUNT(DISTINCT {$morphTagKeyName}) = ?", [count($tagKeys)]);
    }
public function scopeWithAllTags(Builder $query, $tags): Builder
    {
        /** @var TagService $service */
        $service = app(TagService::class);
        $normalized = $service->buildTagArrayNormalized($tags);

        // If there are no tags specified, then there
        // can't be any results so short-circuit
        if (count($normalized) === 0) {
            if (config('taggable.throwEmptyExceptions')) {
                throw new NoTagsSpecifiedException('Empty tag data passed to withAllTags scope.');
            }

            return $query->where(\DB::raw(1), 0);
        }

        $tagKeys = $service->getTagModelKeys($normalized);

        // If some of the tags specified don't exist, then there can't
        // be any models with all the tags, so so short-circuit
        if (count($tagKeys) !== count($normalized)) {
            return $query->where(\DB::raw(1), 0);
        }

        $alias = $this->taggableCreateNewAlias(__FUNCTION__);
        $morphTagKeyName = $this->getQualifiedRelatedPivotKeyNameWithAlias($alias);

        return $this->prepareTableJoin($query, 'inner', $alias)
            ->whereIn($morphTagKeyName, $tagKeys)
            ->havingRaw("COUNT(DISTINCT {$morphTagKeyName}) = ?", [count($tagKeys)]);
    }
Query scope for models that have all of the given tags.

@param Builder $query
@param array|string $tags

@return Builder
@throws \Cviebrock\EloquentTaggable\Exceptions\NoTagsSpecifiedException
@throws \ErrorException