Completed
Push — develop-3.0 ( bd5ff0...545efb )
by Mohamed
02:33
created

Fetcher::sortByUpdated()   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 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);
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