Completed
Push — develop-3.0 ( 5ab583...f20237 )
by Mohamed
06:33
created

Fetcher::getRecentActivities()   A

Complexity

Conditions 4
Paths 2

Size

Total Lines 15
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 15
rs 9.2
c 0
b 0
f 0
cc 4
eloc 9
nc 2
nop 2
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
     * Get project by its key.
35
     *
36
     * @param string $key
37
     *
38
     * @return Project
39
     */
40
    public function getByKey($key)
41
    {
42
        return $this->model->where('key', '=', $key)->limit(1)->first();
43
    }
44
45
    /**
46
     * Returns collection of active projects.
47
     *
48
     * @return Collection
49
     */
50
    public function getActiveProjects()
51
    {
52
        return $this->model->active()->orderBy('name', 'ASC')->get();
53
    }
54
55
    /**
56
     * Get collection of notes in project.
57
     *
58
     * @return Collection
59
     */
60
    public function getNotes()
61
    {
62
        return $this->model->notes()->with('createdBy')->get();
63
    }
64
65
    /**
66
     * Returns collection of public projects.
67
     *
68
     * @return Collection
69
     */
70
    public function getPublicProjects()
71
    {
72
        return $this->model->public()->orderBy('name', 'ASC')->get();
73
    }
74
75
    /**
76
     * Returns all users that are not assigned in the current project.
77
     *
78
     * @return array
79
     */
80
    public function getNotMembers()
81
    {
82
        return (new User())->active()->notMemberOfProject($this->model)->get();
83
    }
84
85
    /**
86
     * Fetch and filter issues in the project.
87
     *
88
     * @param int   $status
89
     * @param array $filter
90
     *
91
     * @return Collection
92
     */
93
    public function getIssues($status = Project\Issue::STATUS_OPEN, array $filter = [])
94
    {
95
        $sortOrder = array_get($filter, 'sort.sortorder', 'desc');
96
        $sortBy    = array_get($filter, 'sort.sortby', null);
97
98
        $query = $this->model->issues()
99
            ->with('countComments', 'user', 'updatedBy', 'tags', 'tags.parent')
100
            ->with([
101
                'tags' => function (Relation $query) use ($sortOrder) {
102
                    $query->orderBy('name', $sortOrder);
103
                },
104
            ])
105
            ->status($status)
106
            ->assignedTo(array_get($filter, 'assignto'))
107
            ->searchContent(array_get($filter, 'keyword'))
108
            ->createdBy(array_get($filter, 'created_by'))
109
            ->whereTags(array_get($filter, 'tag_status'), array_get($filter, 'tag_type'));
110
111
        // Sort
112
        if ($sortBy === 'updated') {
113
            $this->sortByUpdated($query, $sortOrder);
114
        } elseif (($tagGroup = substr($sortBy, strlen('tag:'))) > 0) {
115
            return $this->sortByTag($query, $tagGroup, $sortOrder);
116
        }
117
118
        return $query->get();
119
    }
120
121
    /**
122
     * Fetch and filter issues in the project.
123
     *
124
     * @param int   $status
125
     * @param array $filter
126
     *
127
     * @return Collection
128
     */
129
    public function getIssuesForLoggedUser($status = Project\Issue::STATUS_OPEN, array $filter = [])
130
    {
131
        if ($this->model->isPrivateInternal() && $this->getLoggedUser()->isUser()) {
132
            $filter['created_by'] = $this->getLoggedUser()->id;
133
        }
134
135
        return $this->getIssues($status, $filter);
136
    }
137
138
    /**
139
     * Fetch issues assigned to a user.
140
     *
141
     * @param User $user
142
     *
143
     * @return Collection
144
     */
145
    public function getAssignedOrCreatedIssues(User $user)
146
    {
147
        if ($user->isUser()) {
148
            return $this->getCreatedIssues($user);
149
        }
150
151
        return $this->getAssignedIssues($user);
152
    }
153
154
    /**
155
     * Get collection of issue created by user.
156
     *
157
     * @param User $user
158
     *
159
     * @return Collection
160
     */
161
    public function getCreatedIssues(User $user)
162
    {
163
        return $this->model->openIssues()
164
            ->with('countComments', 'user', 'updatedBy')
165
            ->createdBy($user)
166
            ->orderBy('updated_at', 'DESC')
167
            ->get();
168
    }
169
170
    /**
171
     * Get collection of issue assigned to user.
172
     *
173
     * @param User $user
174
     *
175
     * @return Collection
176
     */
177
    public function getAssignedIssues(User $user)
178
    {
179
        return $this->model->openIssues()
180
            ->with('countComments', 'user', 'updatedBy')
181
            ->assignedTo($user)
182
            ->orderBy('updated_at', 'DESC')
183
            ->get();
184
    }
185
186
    /**
187
     * Get collection of recent activities in the project.
188
     *
189
     * @param User|null $user
190
     * @param int       $limit
191
     *
192
     * @return Collection
193
     */
194
    public function getRecentActivities(User $user = null, $limit = 10)
195
    {
196
        $activities = $this->model->activities()
197
            ->with('activity', 'issue', 'user', 'assignTo', 'comment', 'note')
198
            ->orderBy('users_activity.created_at', 'DESC')
199
            ->take($limit);
200
201
        // Internal project and logged user can see created only
202
        if ($this->model->isPrivateInternal() && $user instanceof User && $user->isUser()) {
203
            $activities->join('projects_issues', 'projects_issues.id', '=', 'item_id');
204
            $activities->where('created_by', '=', $user->id);
205
        }
206
207
        return $activities->get();
208
    }
209
210
    /**
211
     * Returns projects with issues details eager loaded.
212
     *
213
     * @return Collection
214
     */
215
    public function getPublicProjectsWithRecentIssues()
216
    {
217
        return $this->model
218
            ->active()
219
            ->public()
220
            ->with('openIssuesWithUpdater', 'issues.user', 'issues.countComments')
221
            ->orderBy('name')
222
            ->get();
223
    }
224
225
    /**
226
     * Returns collection of tags for Kanban view.
227
     *
228
     * @param User $user
229
     *
230
     * @return Collection
231
     */
232
    public function getKanbanTagsForUser(User $user)
233
    {
234
        return $this->model->kanbanTags()->accessibleToUser($user)->get();
235
    }
236
237
    /**
238
     * Get collection of tags for kanban view.
239
     *
240
     * @return Collection
241
     */
242
    public function getKanbanTags()
243
    {
244
        return $this->model->kanbanTags()->get();
245
    }
246
247
    /**
248
     * Returns users assigned to the project that can fix issues (with edit permission).
249
     *
250
     * @return Collection
251
     */
252
    public function getUsersCanFixIssue()
253
    {
254
        return $this->model->users()->developerOrHigher()->active()->get();
255
    }
256
257
    /**
258
     * Get collection of users in project.
259
     *
260
     * @return Collection
261
     */
262
    public function getUsers()
263
    {
264
        return $this->model->users()->active()->get();
265
    }
266
267
    /**
268
     * Sort by updated_at column.
269
     *
270
     * @param Builder $query
271
     * @param string  $order
272
     *
273
     * @return void
274
     */
275
    protected function sortByUpdated(Builder $query, $order = 'asc')
276
    {
277
        $query->orderBy('updated_at', $order);
0 ignored issues
show
Bug introduced by
The method orderBy() does not exist on Illuminate\Database\Eloquent\Builder. Did you maybe mean enforceOrderBy()?

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...
278
    }
279
280
    /**
281
     * Sort by issues tag group
282
     * Note: this sort will return the collection.
283
     *
284
     * @param Builder $query
285
     * @param string  $tagGroup
286
     * @param string  $order
287
     *
288
     * @return Collection
289
     */
290
    protected function sortByTag(Builder $query, $tagGroup, $order = 'asc')
291
    {
292
        // If tag group is string prefixed with tag:
293
        if (!is_numeric($tagGroup)) {
294
            $tagGroup = substr($tagGroup, strlen('tag:'));
295
        }
296
297
        $results = $query->get()
298
            ->sort(function (Project\Issue $issue1, Project\Issue $issue2) use ($tagGroup, $order) {
299
                $tag1 = $issue1->tags->where('parent.id', $tagGroup)->first();
300
                $tag2 = $issue2->tags->where('parent.id', $tagGroup)->first();
301
                $tag1 = $tag1 ? $tag1->name : '';
302
                $tag2 = $tag2 ? $tag2->name : '';
303
304
                if ($order === 'asc') {
305
                    return strcmp($tag1, $tag2);
306
                }
307
308
                return strcmp($tag2, $tag1);
309
            });
310
311
        return $results;
312
    }
313
314
    /**
315
     * Returns projects with open issue count.
316
     *
317
     * @param int $status
318
     * @param int $private
319
     *
320
     * @return Collection
321
     */
322
    public function getProjectsWithOpenIssuesCount($status = Project::STATUS_OPEN, $private = Project::PRIVATE_YES)
323
    {
324
        $query = $this->model->with('openIssuesCount')->status($status);
325
326
        if ($private !== Project::PRIVATE_ALL) {
327
            $query->where('private', '=', $private);
328
        }
329
330
        return $query->get();
331
    }
332
333
    /**
334
     * Return projects with count of open & closed issues.
335
     *
336
     * @param array $projectIds
337
     *
338
     * @return Collection
339
     */
340
    public function getProjectsWithCountIssues(array $projectIds)
341
    {
342
        return $this->model
343
            ->with('openIssuesCount', 'closedIssuesCount')
344
            ->whereIn('id', $projectIds)
345
            ->get();
346
    }
347
348
    /**
349
     * Get collection of issues group by a list of tags.
350
     *
351
     * @param Collection $tagIds
352
     * @return Collection
353
     */
354
    public function getIssuesGroupByTags(Collection $tagIds)
355
    {
356
        $tagIds = $tagIds->pluck('id')->all();
357
358
        $issues = $this->model->issues()
359
            ->with('user', 'tags')
360
            ->open()
361
            ->forProject($this->model->id)
362
            ->join('projects_issues_tags', 'issue_id', '=', 'id')
363
            ->whereIn('projects_issues_tags.tag_id', $tagIds)
364
            ->orderBy('id')
365
            ->get()
366
            ->groupBy(function (Project\Issue $issue) {
367
                return $issue->getStatusTag()->name;
368
            });
369
370
        return $issues;
371
    }
372
}
373