Completed
Push — develop ( a45f48...f809cc )
by Mohamed
08:29
created

QueryTrait::listIssues()   B

Complexity

Conditions 3
Paths 3

Size

Total Lines 30
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 17
CRAP Score 3.0105

Importance

Changes 3
Bugs 0 Features 0
Metric Value
c 3
b 0
f 0
dl 0
loc 30
ccs 17
cts 19
cp 0.8947
rs 8.8571
cc 3
eloc 19
nc 3
nop 2
crap 3.0105
1
<?php
2
3
/*
4
 * This file is part of the Tinyissue package.
5
 *
6
 * (c) Mohamed Alsharaf <[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
namespace Tinyissue\Model\Traits\Project;
13
14
use Illuminate\Database\Eloquent;
15
use Illuminate\Database\Eloquent\Relations;
16
use Illuminate\Database\Eloquent\Relations\Relation;
17
use Illuminate\Database\Query;
18
use Tinyissue\Model\Project;
19
use Tinyissue\Model\Role;
20
use Tinyissue\Model\User;
21
22
/**
23
 * QueryTrait is trait class containing the database queries methods for the Project model.
24
 *
25
 * @author Mohamed Alsharaf <[email protected]>
26
 *
27
 * @property int $id
28
 *
29
 * @method   Eloquent\Model      where($column, $operator = null, $value = null, $boolean = 'and')
30
 * @method   Query\Builder       join($table, $one, $operator = null, $two = null, $type = 'inner', $where = false)
31
 * @method   Relations\HasMany   users()
32
 * @method   Relations\HasMany   issues()
33
 * @method   void                filterAssignTo(Relations\HasMany $query, $userId)
34
 * @method   void                filterTitleOrBody(Relations\HasMany $query, $keyword)
35
 * @method   void                filterTags(Relations\HasMany $query, array $tags)
36
 * @method   void                sortByUpdated(Relations\HasMany $query, $order = 'asc')
37
 * @method   Eloquent\Collection sortByTag(Relations\HasMany $query, $tagGroup, $order = 'asc')
38
 */
39
trait QueryTrait
40
{
41
    /**
42
     * Returns collection of active projects.
43
     *
44
     * @return Eloquent\Collection
45
     */
46
    public static function activeProjects()
47
    {
48
        return static::where('status', '=', Project::STATUS_OPEN)
49
            ->orderBy('name', 'ASC')
50
            ->get();
51
    }
52
53
    /**
54
     * Returns collection of public projects.
55
     *
56
     * @return Eloquent\Collection
57
     */
58
    public function publicProjects()
59
    {
60
        return $this->where('private', '=', Project::PRIVATE_NO)
61
            ->orderBy('name', 'ASC')
62
            ->get();
63
    }
64
65
    /**
66
     * Returns all users that are not assigned in the current project.
67
     *
68
     * @return array
69
     */
70 1
    public function usersNotIn()
71
    {
72 1
        if ($this->id > 0) {
73
            $userIds = $this->users()->lists('user_id')->all();
74
            $users   = User::where('deleted', '=', User::NOT_DELETED_USERS)->whereNotIn('id', $userIds)->get();
75
        } else {
76 1
            $users = User::where('deleted', '=', User::NOT_DELETED_USERS)->get();
77
        }
78
79 1
        return $users->lists('fullname', 'id')->all();
80
    }
81
82
    /**
83
     * Fetch and filter issues in the project.
84
     *
85
     * @param int   $status
86
     * @param array $filter
87
     *
88
     * @return \Illuminate\Database\Eloquent\Collection
89
     */
90 2
    public function listIssues($status = Project\Issue::STATUS_OPEN, array $filter = [])
91
    {
92 2
        $sortOrder = array_get($filter, 'sort.sortorder', 'desc');
93 2
        $sortBy    = array_get($filter, 'sort.sortby', null);
94
95 2
        $query = $this->issues()
96 2
            ->with('countComments', 'user', 'updatedBy', 'tags', 'tags.parent')
97 2
            ->with([
98
                'tags' => function (Relation $query) use ($sortOrder) {
99 2
                    $query->orderBy('name', $sortOrder);
100 2
                },
101
            ])
102 2
            ->where('status', '=', $status);
103
104
        // Filter issues
105 2
        $this->filterAssignTo($query, array_get($filter, 'assignto'));
106 2
        $this->filterTitleOrBody($query, array_get($filter, 'keyword'));
107 2
        $this->filterTags($query, array_get($filter, 'tag_status'));
108 2
        $this->filterTags($query, array_get($filter, 'tag_type'));
109 2
        $this->filterCreatedBy($query, array_get($filter, 'created_by'), $this->isPrivateInternal());
0 ignored issues
show
Bug introduced by
It seems like isPrivateInternal() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
Bug introduced by
It seems like filterCreatedBy() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
110
111
        // Sort
112 2
        if ($sortBy == 'updated') {
113
            $this->sortByUpdated($query, $sortOrder);
114 2
        } elseif (($tagGroup = substr($sortBy, strlen('tag:'))) > 0) {
115
            return $this->sortByTag($query, $tagGroup, $sortOrder);
116
        }
117
118 2
        return $query->get();
119
    }
120
121
    /**
122
     * Fetch issues assigned to a user.
123
     *
124
     * @param User $user
125
     *
126
     * @return \Illuminate\Database\Eloquent\Collection
127
     */
128 1
    public function listAssignedOrCreatedIssues(User $user)
129
    {
130 1
        $assignedOrCreate = $user->isUser() ? 'created_by' : 'assigned_to';
131
132 1
        return $this->issues()
133 1
            ->with('countComments', 'user', 'updatedBy')
134 1
            ->where('status', '=', Project\Issue::STATUS_OPEN)
135 1
            ->where($assignedOrCreate, '=', $user->id)
136 1
            ->orderBy('updated_at', 'DESC')
137 1
            ->get();
138
    }
139
140
    /**
141
     * Returns projects with issues details eager loaded.
142
     *
143
     * @param int $status
144
     * @param int $private
145
     *
146
     * @return Relations\HasMany
147
     */
148 4
    public function projectsWidthIssues($status = Project::STATUS_OPEN, $private = Project::PRIVATE_NO)
149
    {
150
        $query = $this
151 4
            ->where('status', '=', $status)
152 4
            ->orderBy('name');
153
154 4
        if ($private !== Project::PRIVATE_ALL) {
155 4
            $query->where('private', '=', $private);
156
        }
157
158 4
        $query->with([
159 View Code Duplication
            'issues' => function (Relations\Relation $query) use ($status) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
160 3
                $query->with('updatedBy');
161 3
                if ($status === Project::STATUS_OPEN) {
162 3
                    $query->where('status', '=', Project\Issue::STATUS_OPEN);
163
                }
164 4
            },
165
            'issues.user' => function () {
166 4
            },
167
            'issues.countComments' => function () {
168 4
            },
169
        ]);
170
171 4
        return $query;
172
    }
173
174
    /**
175
     * Returns collection of tags for Kanban view.
176
     *
177
     * @param User $user
178
     *
179
     * @return mixed
180
     */
181
    public function getKanbanTagsForUser(User $user)
182
    {
183
        $tags = $this->kanbanTags()
0 ignored issues
show
Bug introduced by
The method kanbanTags() does not exist on Tinyissue\Model\Traits\Project\QueryTrait. Did you maybe mean getKanbanTagsForUser()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
184
            ->where(function (Eloquent\Builder $query) use ($user) {
185
                $query->where('role_limit', '<=', $user->role_id);
186
                $query->orWhere('role_limit', '=', null);
187
            })
188
            ->get();
189
190
        return $tags;
191
    }
192
193
    /**
194
     * Returns collection of issues grouped by tags.
195
     *
196
     * @param $tagIds
197
     *
198
     * @return mixed
199
     */
200
    public function issuesGroupByTags($tagIds)
201
    {
202
        $issues = $this->issues()
203
        ->with('user', 'tags')
204
            ->where('status', '=', Project\Issue::STATUS_OPEN)
205
            ->whereIn('projects_issues_tags.tag_id', $tagIds)
206
            ->join('projects_issues_tags', 'issue_id', '=', 'id')
207
            ->orderBy('id')
208
            ->get()
209
            ->groupBy(function (Project\Issue $issue) {
210
                return $issue->getStatusTag()->name;
211
            });
212
213
        return $issues;
214
    }
215
216
    /**
217
     * Returns users assigned to the project that can fix issues (with edit permission).
218
     *
219
     * @return Relations\BelongsToMany
220
     */
221 8
    public function usersCanFixIssue()
222
    {
223 8
        return $this->users()->where('users.role_id', '>', 1);
224
    }
225
}
226