Completed
Push — develop-3.0 ( 360277...bd5ff0 )
by Mohamed
06:52
created

Fetcher::getUsers()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
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\Repository\Project;
13
14
use Illuminate\Database\Eloquent\Builder;
15
use Illuminate\Database\Eloquent\Collection;
16
use Illuminate\Database\Eloquent\Relations\Relation;
17
use Tinyissue\Model\Project;
18
use Tinyissue\Model\User;
19
use Tinyissue\Repository\Repository;
20
21
class Fetcher extends Repository
22
{
23
    /**
24
     * @var Project
25
     */
26
    protected $model;
27
28
    public function __construct(Project $model)
29
    {
30
        $this->model = $model;
31
    }
32
33
    /**
34
     * Returns collection of active projects.
35
     *
36
     * @return Collection
37
     */
38
    public function getActiveProjects()
39
    {
40
        return $this->model->active()->orderBy('name', 'ASC')->get();
41
    }
42
43
    /**
44
     * Get collection of notes in project.
45
     *
46
     * @return Collection
47
     */
48
    public function getNotes()
49
    {
50
        return $this->model->notes()->with('createdBy')->get();
51
    }
52
53
    /**
54
     * Returns collection of public projects.
55
     *
56
     * @return Collection
57
     */
58
    public function getPublicProjects()
59
    {
60
        return $this->model->public()->orderBy('name', 'ASC')->get();
61
    }
62
63
    /**
64
     * Returns all users that are not assigned in the current project.
65
     *
66
     * @return array
67
     */
68
    public function getNotMembers()
69
    {
70
        return (new User())->active()->notMemberOfProject($this->model)->get();
71
    }
72
73
    /**
74
     * Fetch and filter issues in the project.
75
     *
76
     * @param int   $status
77
     * @param array $filter
78
     *
79
     * @return Collection
80
     */
81
    public function getIssues($status = Project\Issue::STATUS_OPEN, array $filter = [])
82
    {
83
        $sortOrder = array_get($filter, 'sort.sortorder', 'desc');
84
        $sortBy    = array_get($filter, 'sort.sortby', null);
85
86
        $query = $this->model->issues()
87
            ->with('countComments', 'user', 'updatedBy', 'tags', 'tags.parent')
88
            ->with([
89
                'tags' => function (Relation $query) use ($sortOrder) {
90
                    $query->orderBy('name', $sortOrder);
91
                },
92
            ])
93
            ->status($status)
94
            ->assignedTo(array_get($filter, 'assignto'))
95
            ->searchContent(array_get($filter, 'keyword'))
96
            ->createdBy(array_get($filter, 'created_by'))
97
            ->whereTags(array_get($filter, 'tag_status'), array_get($filter, 'tag_type'));
98
99
        // Sort
100
        if ($sortBy === 'updated') {
101
            $this->sortByUpdated($query, $sortOrder);
102
        } elseif (($tagGroup = substr($sortBy, strlen('tag:'))) > 0) {
103
            return $this->sortByTag($query, $tagGroup, $sortOrder);
104
        }
105
106
        return $query->get();
107
    }
108
109
    /**
110
     * Fetch and filter issues in the project.
111
     *
112
     * @param int   $status
113
     * @param array $filter
114
     *
115
     * @return Collection
116
     */
117
    public function getIssuesForLoggedUser($status = Project\Issue::STATUS_OPEN, array $filter = [])
118
    {
119
        if ($this->model->isPrivateInternal() && $this->getLoggedUser()->isUser()) {
120
            $filter['created_by'] = $this->getLoggedUser()->id;
121
        }
122
123
        return $this->getIssues($status, $filter);
124
    }
125
126
    /**
127
     * Fetch issues assigned to a user.
128
     *
129
     * @param User $user
130
     *
131
     * @return Collection
132
     */
133
    public function getAssignedOrCreatedIssues(User $user)
134
    {
135
        if ($user->isUser()) {
136
            return $this->getCreatedIssues($user);
137
        }
138
139
        return $this->getAssignedIssues($user);
140
    }
141
142
    /**
143
     * Get collection of issue created by user.
144
     *
145
     * @param User $user
146
     *
147
     * @return Collection
148
     */
149
    public function getCreatedIssues(User $user)
150
    {
151
        return $this->model->openIssues()
152
            ->with('countComments', 'user', 'updatedBy')
153
            ->createdBy($user)
154
            ->orderBy('updated_at', 'DESC')
155
            ->get();
156
    }
157
158
    /**
159
     * Get collection of issue assigned to user.
160
     *
161
     * @param User $user
162
     *
163
     * @return Collection
164
     */
165
    public function getAssignedIssues(User $user)
166
    {
167
        return $this->model->openIssues()
168
            ->with('countComments', 'user', 'updatedBy')
169
            ->assignedTo($user)
170
            ->orderBy('updated_at', 'DESC')
171
            ->get();
172
    }
173
174
    /**
175
     * Get collection of recent activities in the project.
176
     *
177
     * @param User|null $user
178
     * @param int       $limit
179
     *
180
     * @return Collection
181
     */
182
    public function getRecentActivities(User $user = null, $limit = 10)
183
    {
184
        $activities = $this->model->activities()
185
            ->with('activity', 'issue', 'user', 'assignTo', 'comment', 'note')
186
            ->orderBy('users_activity.created_at', 'DESC')
187
            ->take($limit);
188
189
        // Internal project and logged user can see created only
190
        if ($this->model->isPrivateInternal() && $user instanceof User && $user->isUser()) {
191
            $activities->join('projects_issues', 'projects_issues.id', '=', 'item_id');
192
            $activities->where('created_by', '=', $user->id);
193
        }
194
195
        return $activities->get();
196
    }
197
198
    /**
199
     * Returns projects with issues details eager loaded.
200
     *
201
     * @return Collection
202
     */
203
    public function getPublicProjectsWithRecentIssues()
204
    {
205
        return $this->model
206
            ->active()
207
            ->public()
208
            ->with('openIssuesWithUpdater', 'issues.user', 'issues.countComments')
209
            ->orderBy('name')
210
            ->get();
211
    }
212
213
    /**
214
     * Returns collection of tags for Kanban view.
215
     *
216
     * @param User $user
217
     *
218
     * @return Collection
219
     */
220
    public function getKanbanTagsForUser(User $user)
221
    {
222
        return $this->model->kanbanTags()->accessibleToUser($user)->get();
223
    }
224
225
    /**
226
     * Get collection of tags for kanban view.
227
     *
228
     * @return Collection
229
     */
230
    public function getKanbanTags()
231
    {
232
        return $this->model->kanbanTags()->get();
233
    }
234
235
    /**
236
     * Returns users assigned to the project that can fix issues (with edit permission).
237
     *
238
     * @return Collection
239
     */
240
    public function getUsersCanFixIssue()
241
    {
242
        return $this->model->users()->developerOrHigher()->active()->get();
243
    }
244
245
    /**
246
     * Get collection of users in project.
247
     *
248
     * @return Collection
249
     */
250
    public function getUsers()
251
    {
252
        return $this->model->users()->active()->get();
253
    }
254
255
    /**
256
     * Sort by updated_at column.
257
     *
258
     * @param Builder $query
259
     * @param string  $order
260
     *
261
     * @return void
262
     */
263
    protected function sortByUpdated(Builder $query, $order = 'asc')
264
    {
265
        $query->orderBy('updated_at', $order);
266
    }
267
268
    /**
269
     * Sort by issues tag group
270
     * Note: this sort will return the collection.
271
     *
272
     * @param Builder $query
273
     * @param string  $tagGroup
274
     * @param string  $order
275
     *
276
     * @return Collection
277
     */
278
    protected function sortByTag(Builder $query, $tagGroup, $order = 'asc')
279
    {
280
        // If tag group is string prefixed with tag:
281
        if (!is_numeric($tagGroup)) {
282
            $tagGroup = substr($tagGroup, strlen('tag:'));
283
        }
284
285
        $results = $query->get()
286
            ->sort(function (Project\Issue $issue1, Project\Issue $issue2) use ($tagGroup, $order) {
287
                $tag1 = $issue1->tags->where('parent.id', $tagGroup)->first();
288
                $tag2 = $issue2->tags->where('parent.id', $tagGroup)->first();
289
                $tag1 = $tag1 ? $tag1->name : '';
290
                $tag2 = $tag2 ? $tag2->name : '';
291
292
                if ($order === 'asc') {
293
                    return strcmp($tag1, $tag2);
294
                }
295
296
                return strcmp($tag2, $tag1);
297
            });
298
299
        return $results;
300
    }
301
302
    /**
303
     * Returns projects with open issue count.
304
     *
305
     * @param int $status
306
     * @param int $private
307
     *
308
     * @return Collection
309
     */
310
    public function getProjectsWithOpenIssuesCount($status = Project::STATUS_OPEN, $private = Project::PRIVATE_YES)
311
    {
312
        $query = $this->model->with('openIssuesCount')->status($status);
313
314
        if ($private !== Project::PRIVATE_ALL) {
315
            $query->where('private', '=', $private);
316
        }
317
318
        return $query->get();
319
    }
320
321
    /**
322
     * Return projects with count of open & closed issues.
323
     *
324
     * @param array $projectIds
325
     *
326
     * @return Collection
327
     */
328
    public function getProjectsWithCountIssues(array $projectIds)
329
    {
330
        return $this->model
331
            ->with('openIssuesCount', 'closedIssuesCount')
332
            ->whereIn('id', $projectIds)
333
            ->get();
334
    }
335
}
336