Issues (33)

src/Reactable/ReactableEloquentBuilderTrait.php (1 issue)

Labels
Severity
1
<?php
2
3
/*
4
 * This file is part of Laravel Love.
5
 *
6
 * (c) Anton Komarev <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
declare(strict_types=1);
13
14
namespace Cog\Laravel\Love\Reactable;
15
16
use Cog\Contracts\Love\Reacterable\Models\Reacterable as ReacterableInterface;
17
use Cog\Laravel\Love\Reactant\ReactionCounter\Models\ReactionCounter;
18
use Cog\Laravel\Love\Reactant\ReactionTotal\Models\ReactionTotal;
19
use Cog\Laravel\Love\ReactionType\Models\ReactionType;
20
use Illuminate\Database\Eloquent\Builder;
21
use Illuminate\Database\Query\JoinClause;
22
use Illuminate\Support\Str;
23
24
/**
25
 * @mixin Builder
26
 */
27
trait ReactableEloquentBuilderTrait
28
{
29
    public function whereReactedBy(
30
        ReacterableInterface $reacterable,
31
        string | null $reactionTypeName = null,
32
    ): Builder {
33
        return $this->whereHas(
34
            'loveReactant.reactions',
35
            function (Builder $reactionsQuery) use (
36
                $reacterable,
37
                $reactionTypeName,
38
            ): void {
0 ignored issues
show
A parse error occurred: Syntax error, unexpected ')', expecting T_VARIABLE on line 38 at column 12
Loading history...
39
                $reactionsQuery->where(
40
                    'reacter_id',
41
                    $reacterable->getLoveReacter()->getId(),
42
                );
43
44
                if ($reactionTypeName !== null) {
45
                    $reactionsQuery->where(
46
                        'reaction_type_id',
47
                        ReactionType::fromName($reactionTypeName)->getId(),
48
                    );
49
                }
50
            }
51
        );
52
    }
53
54
    public function whereNotReactedBy(
55
        ReacterableInterface $reacterable,
56
        string | null $reactionTypeName = null,
57
    ): Builder {
58
        return $this->whereDoesntHave(
59
            'loveReactant.reactions',
60
            function (Builder $reactionsQuery) use (
61
                $reacterable,
62
                $reactionTypeName,
63
            ): void {
64
                $reactionsQuery->where(
65
                    'reacter_id',
66
                    $reacterable->getLoveReacter()->getId(),
67
                );
68
69
                if ($reactionTypeName !== null) {
70
                    $reactionsQuery->where(
71
                        'reaction_type_id',
72
                        ReactionType::fromName($reactionTypeName)->getId(),
73
                    );
74
                }
75
            }
76
        );
77
    }
78
79
    public function joinReactionCounterOfType(
80
        string $reactionTypeName,
81
        string | null $alias = null,
82
    ): Builder {
83
        $reactionType = ReactionType::fromName($reactionTypeName);
84
        $alias = $alias === null
85
            ? 'reaction_' . Str::snake($reactionType->getName())
86
            : $alias;
87
88
        $select = $this->getQuery()->columns ?? ["{$this->getModel()->getTable()}.*"];
89
        $select[] = $this->raw("COALESCE({$alias}.count, 0) as {$alias}_count");
90
        $select[] = $this->raw("COALESCE({$alias}.weight, 0) as {$alias}_weight");
91
92
        return $this
93
            ->leftJoin(
94
                (new ReactionCounter())->getTable() . ' as ' . $alias,
95
                function (JoinClause $join) use (
96
                    $reactionType,
97
                    $alias,
98
                ): void {
99
                    $join->on(
100
                        "{$alias}.reactant_id",
101
                        '=',
102
                        "{$this->getModel()->getTable()}.love_reactant_id",
103
                    );
104
                    $join->where(
105
                        "{$alias}.reaction_type_id",
106
                        $reactionType->getId(),
107
                    );
108
                }
109
            )
110
            ->select($select);
111
    }
112
113
    public function joinReactionTotal(
114
        string | null $alias = null,
115
    ): Builder {
116
        $alias = $alias === null
117
            ? 'reaction_total'
118
            : $alias;
119
120
        $select = $this->getQuery()->columns ?? ["{$this->getModel()->getTable()}.*"];
121
        $select[] = $this->raw("COALESCE({$alias}.count, 0) as {$alias}_count");
122
        $select[] = $this->raw("COALESCE({$alias}.weight, 0) as {$alias}_weight");
123
124
        return $this
125
            ->leftJoin(
126
                (new ReactionTotal())->getTable() . ' as ' . $alias,
127
                "{$alias}.reactant_id",
128
                '=',
129
                "{$this->getModel()->getTable()}.love_reactant_id",
130
            )
131
            ->select($select);
132
    }
133
}
134