Completed
Push — master ( 91f8d9...64265e )
by Mohamed
09:45 queued 06:57
created

CrudTrait::createIssue()   B

Complexity

Conditions 4
Paths 4

Size

Total Lines 38
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 20
CRAP Score 4.0016

Importance

Changes 6
Bugs 2 Features 1
Metric Value
c 6
b 2
f 1
dl 0
loc 38
ccs 20
cts 21
cp 0.9524
rs 8.5806
cc 4
eloc 22
nc 4
nop 1
crap 4.0016
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\Issue;
13
14
use Illuminate\Database\Eloquent;
15
use Illuminate\Database\Eloquent\Relations;
16
use Tinyissue\Model;
17
use Tinyissue\Model\Activity;
18
use Tinyissue\Model\Project;
19
use Tinyissue\Model\Project\Issue\Attachment;
20
use Tinyissue\Model\User;
21
use Tinyissue\Services\SettingsManager;
22
23
/**
24
 * CrudTrait is trait class containing the methods for adding/editing/deleting the Project\Issue model.
25
 *
26
 * @author Mohamed Alsharaf <[email protected]>
27
 *
28
 * @property int                        $id
29
 * @property int                        $created_by
30
 * @property int                        $project_id
31
 * @property string                     $title
32
 * @property string                     $body
33
 * @property int                        $assigned_to
34
 * @property int                        $time_quote
35
 * @property int                        $closed_by
36
 * @property int                        $closed_at
37
 * @property int                        status
38
 * @property int                        $updated_at
39
 * @property int                        $updated_by
40
 * @property Project                    $project
41
 * @property User                       $user
42
 * @property User                       $updatedBy
43
 *
44
 * @method   Eloquent\Model             save()
45
 * @method   Eloquent\Model             fill(array $attributes)
46
 * @method   Relations\BelongsToMany    tags()
47
 * @method   Relations\HasMany          activities()
48
 * @method   Relations\HasMany          comments()
49
 */
50
trait CrudTrait
51
{
52
    /**
53
     * Set the issue is updated by a user.
54
     *
55
     * @param int $userId
56
     *
57
     * @return Eloquent\Model
58
     */
59 8
    public function changeUpdatedBy($userId)
60
    {
61 8
        $time             = new \DateTime();
62 8
        $this->updated_at = $time->format('Y-m-d H:i:s');
63 8
        $this->updated_by = $userId;
64
65 8
        return $this->save();
66
    }
67
68
    /**
69
     * Reassign the issue to a new user.
70
     *
71
     * @param int|User $assignTo
72
     * @param int|User $user
73
     *
74
     * @return Eloquent\Model
75
     */
76 2
    public function reassign($assignTo, $user)
77
    {
78 2
        $assignToId        = !$assignTo instanceof User ? $assignTo : $assignTo->id;
79 2
        $userId            = !$user instanceof User ? $user : $user->id;
80 2
        $this->assigned_to = $assignToId;
81 2
        $this->save();
82
83 2
        return $this->activities()->save(new User\Activity([
84 2
            'type_id'   => Activity::TYPE_REASSIGN_ISSUE,
85 2
            'parent_id' => $this->project->id,
86 2
            'user_id'   => $userId,
87 2
            'action_id' => $this->assigned_to,
88
        ]));
89
    }
90
91
    /**
92
     * Update the given issue.
93
     *
94
     * @param array $input
95
     *
96
     * @return Eloquent\Model
97
     */
98 1
    public function updateIssue(array $input)
99
    {
100
        $fill = [
101 1
            'title'       => $input['title'],
102 1
            'body'        => $input['body'],
103 1
            'assigned_to' => $input['assigned_to'],
104 1
            'time_quote'  => $input['time_quote'],
105 1
            'updated_by'  => $this->updatedBy->id,
106
        ];
107
108
        /* Add to activity log for assignment if changed */
109 1
        if ($input['assigned_to'] != $this->assigned_to) {
110 1
            $this->activities()->save(new User\Activity([
111 1
                'type_id'   => Activity::TYPE_REASSIGN_ISSUE,
112 1
                'parent_id' => $this->project->id,
113 1
                'user_id'   => $this->updatedBy->id,
114 1
                'action_id' => $this->assigned_to,
115
            ]));
116
        }
117
118 1
        $this->fill($fill);
119
120 1
        $this->syncTags($input, $this->tags()->with('parent')->get());
0 ignored issues
show
Bug introduced by
It seems like syncTags() 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...
121
122 1
        return $this->save();
123
    }
124
125
    /**
126
     * Create a new issue.
127
     *
128
     * @param array $input
129
     *
130
     * @return CrudTrait
0 ignored issues
show
Comprehensibility Bug introduced by
The return type CrudTrait is a trait, and thus cannot be used for type-hinting in PHP. Maybe consider adding an interface and use that for type-hinting?

In PHP traits cannot be used for type-hinting as they do not define a well-defined structure. This is because any class that uses a trait can rename that trait’s methods.

If you would like to return an object that has a guaranteed set of methods, you could create a companion interface that lists these methods explicitly.

Loading history...
131
     */
132 28
    public function createIssue(array $input)
133
    {
134
        $fill = [
135 28
            'created_by' => $this->user->id,
136 28
            'project_id' => $this->project->id,
137 28
            'title'      => $input['title'],
138 28
            'body'       => $input['body'],
139
        ];
140
141 28
        if ($this->user->permission('issue-modify')) {
142 27
            $fill['assigned_to'] = $input['assigned_to'];
143 27
            $fill['time_quote']  = $input['time_quote'];
144
        }
145
146 28
        $this->fill($fill)->save();
147
148
        /* Add to user's activity log */
149 28
        $this->activities()->save(new User\Activity([
150 28
            'type_id'   => Activity::TYPE_CREATE_ISSUE,
151 28
            'parent_id' => $this->project->id,
152 28
            'user_id'   => $this->user->id,
153
        ]));
154
155
        /* Add attachments to issue */
156 28
        Attachment::where('upload_token', '=', $input['upload_token'])
0 ignored issues
show
Unused Code introduced by
The call to Attachment::where() has too many arguments starting with 'upload_token'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
157 28
            ->where('uploaded_by', '=', $this->user->id)
158 28
            ->update(['issue_id' => $this->id]);
159
160
        // Add default tag to newly created issue
161 28
        $defaultTag = app('tinyissue.settings')->getFirstStatusTagId();
162 28
        if ($defaultTag > 0 && empty($input['tag_status'])) {
163
            $input['tag_status'] = $defaultTag;
164
        }
165
166 28
        $this->syncTags($input);
0 ignored issues
show
Bug introduced by
It seems like syncTags() 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...
167
168 28
        return $this;
169
    }
170
171
    /**
172
     * Move the issue (comments & activities) to another project.
173
     *
174
     * @param int $projectId
175
     *
176
     * @return $this
177
     */
178 1
    public function changeProject($projectId)
179
    {
180 1
        $this->project_id = $projectId;
181 1
        $this->save();
182 1
        $comments = $this->comments()->get();
183 1
        foreach ($comments as $comment) {
184 1
            $comment->project_id = $projectId;
185 1
            $comment->save();
186
        }
187
188 1
        $activities = $this->activities()->get();
189 1
        foreach ($activities as $activity) {
190 1
            $activity->parent_id = $projectId;
191 1
            $activity->save();
192
        }
193
194 1
        return $this;
195
    }
196
}
197