CrudTagTrait   A
last analyzed

Complexity

Total Complexity 16

Size/Duplication

Total Lines 166
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Test Coverage

Coverage 94.03%

Importance

Changes 12
Bugs 6 Features 0
Metric Value
wmc 16
c 12
b 6
f 0
lcom 1
cbo 4
dl 0
loc 166
ccs 63
cts 67
cp 0.9403
rs 10

8 Methods

Rating   Name   Duplication   Size   Complexity  
activities() 0 1 ?
queueUpdate() 0 1 ?
queueChangeTags() 0 1 ?
tags() 0 1 ?
save() 0 1 ?
B changeStatus() 0 28 2
C syncTags() 0 67 10
B changeKanbanTag() 0 36 4
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\Support\Collection;
16
use Tinyissue\Model;
17
use Tinyissue\Model\Activity;
18
use Tinyissue\Model\Project;
19
use Tinyissue\Model\Tag;
20
use Tinyissue\Model\User;
21
22
/**
23
 * CrudTagTrait is trait class containing the methods for adding/editing/deleting the tags of Project\Issue model.
24
 *
25
 * @author Mohamed Alsharaf <[email protected]>
26
 *
27
 * @property static $this
28
 */
29
trait CrudTagTrait
30
{
31
    /**
32
     * Change the status of an issue.
33
     *
34
     * @param int  $status
35
     * @param User $user
36
     *
37
     * @return Eloquent\Model
38
     */
39 7
    public function changeStatus($status, User $user)
40
    {
41 7
        if ($status == 0) {
42 7
            $this->closed_by = $user->id;
0 ignored issues
show
Bug introduced by
The property closed_by does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
43 7
            $this->closed_at = (new \DateTime())->format('Y-m-d H:i:s');
0 ignored issues
show
Bug introduced by
The property closed_at does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
44 7
            $activityType    = Activity::TYPE_CLOSE_ISSUE;
45
        } else {
46 2
            $this->closed_by = 0;
47 2
            $this->closed_at = null;
48 2
            $activityType    = Activity::TYPE_REOPEN_ISSUE;
49
        }
50
51
        /* Add to activity log */
52 7
        $this->activities()->save(new User\Activity([
53 7
            'type_id'   => $activityType,
54 7
            'parent_id' => $this->project->id,
0 ignored issues
show
Bug introduced by
The property project does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
55 7
            'user_id'   => $user->id,
56
        ]));
57
58 7
        $this->status = $status;
0 ignored issues
show
Bug introduced by
The property status does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
59
60
        // Add event on successful save
61
        static::saved(function (Project\Issue $issue) use ($user) {
62 7
            $this->queueUpdate($issue, $user);
63 7
        });
64
65 7
        return $this->save();
66
    }
67
68
    /**
69
     * Sync the issue tags.
70
     *
71
     * @param array      $input
72
     * @param Collection $currentTags
73
     *
74
     * @return bool
75
     */
76 37
    public function syncTags(array $input, Collection $currentTags = null)
77
    {
78 37
        $tagIds = array_only($input, [
79 37
            'tag_type', 'tag_status', 'tag_resolution',
80
        ]);
81
82
        // User can edit their own role and can only change issue type
83 37
        if ($this->updatedBy instanceof User && $this->updatedBy->isUser()) {
0 ignored issues
show
Bug introduced by
The property updatedBy does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
84
            $currentTagIds = $currentTags->pluck('id', 'parent.name')->toArray();
0 ignored issues
show
Bug introduced by
It seems like $currentTags is not always an object, but can also be of type null. Maybe add an additional type check?

If a variable is not always an object, we recommend to add an additional type check to ensure your method call is safe:

function someFunction(A $objectMaybe = null)
{
    if ($objectMaybe instanceof A) {
        $objectMaybe->doSomething();
    }
}
Loading history...
85
            $tagIds['tag_status'] = array_key_exists('status', $currentTagIds)? $currentTagIds['status'] : 0;
86
            $tagIds['tag_resolution'] = array_key_exists('resolution', $currentTagIds)? $currentTagIds['resolution'] : 0;
87
        }
88
89 37
        $tags = (new Tag())->whereIn('id', $tagIds)->get();
0 ignored issues
show
Documentation Bug introduced by
The method whereIn does not exist on object<Tinyissue\Model\Tag>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
90
91 37
        $removedTags = [];
92 37
        if (null === $currentTags) {
93
            // Add the following tags except for open status
94
            $addedTags = $tags
95
                ->map(function (Tag $tag) {
96 2
                    return $tag->toShortArray();
97 37
                })
98 37
                ->toArray();
99
        } else {
100
            // Tags remove from the issue
101
            $removedTags = $currentTags
102 6
                ->diff($tags)
103
                ->map(function (Tag $tag) {
104 2
                    return $tag->toShortArray();
105 6
                })
106 6
                ->toArray();
107
108
            // Check if we are adding new tags
109
            $addedTags = $tags
110
                ->filter(function (Tag $tag) use ($currentTags) {
111 5
                    return $currentTags->where('id', $tag->id)->count() === 0;
112 6
                })
113 6
                ->map(function (Tag $tag) {
114 5
                    return $tag->toShortArray();
115 6
                })
116 6
                ->toArray();
117
118
            // No new tags to add or remove
119 6
            if (empty($removedTags) && empty($addedTags)) {
120 1
                return true;
121
            }
122
        }
123
124
        // Save relation
125 37
        $this->tags()->sync($tags->lists('id')->all());
126
127
        // Activity is added when new issue create with tags or updated with tags excluding the open status tag
128 37
        if (!empty($removedTags) || !empty($addedTags)) {
129
            // Add this change to messages queue
130 7
            $this->queueChangeTags($this, $addedTags, $removedTags, $this->user);
0 ignored issues
show
Bug introduced by
The property user does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
131
132
            // Add to activity log for tags if changed
133 7
            $this->activities()->save(new User\Activity([
134 7
                'type_id'   => Activity::TYPE_ISSUE_TAG,
135 7
                'parent_id' => $this->project->id,
136 7
                'user_id'   => $this->user->id,
137 7
                'data'      => ['added_tags' => $addedTags, 'removed_tags' => $removedTags],
138
            ]));
139
        }
140
141 37
        return true;
142
    }
143
144
    /**
145
     * Add tag to the issue & close issue if added tag is Closed.
146
     *
147
     * @param Tag $newTag
148
     * @param Tag $oldTag
149
     *
150
     * @return $this
151
     */
152 1
    public function changeKanbanTag(Tag $newTag, Tag $oldTag)
153
    {
154
        //  skip if there is no change in status tags
155 1
        if ($oldTag->name === $newTag->name) {
156
            return $this;
157
        }
158
159
        // Open issue
160 1
        $data = ['added_tags' => [], 'removed_tags' => []];
161
162
        // Remove previous status tag
163 1
        $this->tags()->detach($oldTag);
164 1
        $data['removed_tags'][] = $oldTag->toShortArray();
165
166
        // Add new tag
167 1
        if (!$this->tags->contains($newTag)) {
0 ignored issues
show
Bug introduced by
The property tags does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
168 1
            $this->tags()->attach($newTag);
169
170 1
            $data['added_tags'][] = $newTag->toShortArray();
171
        }
172
173 1
        if (!empty($data)) {
174
            // Add this change to messages queue
175 1
            $this->queueChangeTags($this, $data['added_tags'], $data['removed_tags'], $this->user);
176
177
            // Add to activity log for tags if changed
178 1
            $this->activities()->save(new User\Activity([
179 1
                'type_id'   => Activity::TYPE_ISSUE_TAG,
180 1
                'parent_id' => $this->project->id,
181 1
                'user_id'   => $this->user->id,
182 1
                'data'      => $data,
183
            ]));
184
        }
185
186 1
        return $this;
187
    }
188
189
    abstract public function activities();
190
    abstract public function queueUpdate(Project\Issue $issue, User $changeBy);
191
    abstract public function queueChangeTags(Project\Issue $issue, array $addedTags, array $removedTags, User $changeBy);
192
    abstract public function save(array $options = []);
193
    abstract public function tags();
194
}
195