Completed
Push — master ( 195b94...858be2 )
by Mohamed
07:34
created

CrudTagTrait::changeKanbanTag()   B

Complexity

Conditions 4
Paths 5

Size

Total Lines 33
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 4
Bugs 1 Features 0
Metric Value
c 4
b 1
f 0
dl 0
loc 33
ccs 0
cts 16
cp 0
rs 8.5806
cc 4
eloc 16
nc 5
nop 2
crap 20
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 int $id
28
 * @property int $created_by
29
 * @property int $project_id
30
 * @property string $title
31
 * @property string $body
32
 * @property int $assigned_to
33
 * @property int $time_quote
34
 * @property int $closed_by
35
 * @property int $closed_at
36
 * @property int status
37
 * @property int $updated_at
38
 * @property int $updated_by
39
 * @property Model\Project $project
40
 * @property Model\User $user
41
 * @property Model\User $updatedBy
42
 */
43
trait CrudTagTrait
44
{
45
    /**
46
     * Change the status of an issue.
47
     *
48
     * @param int $status
49
     * @param int $userId
50
     *
51
     * @return Eloquent\Model
52
     */
53 5
    public function changeStatus($status, $userId)
54
    {
55 5
        if ($status == 0) {
56 5
            $this->closed_by = $userId;
57 5
            $this->closed_at = (new \DateTime())->format('Y-m-d H:i:s');
58 5
            $activityType    = Activity::TYPE_CLOSE_ISSUE;
59
        } else {
60 1
            $this->closed_by = 0;
61 1
            $this->closed_at = null;
62 1
            $activityType    = Activity::TYPE_REOPEN_ISSUE;
63
        }
64
65
        /* Add to activity log */
66 5
        $this->activities()->save(new User\Activity([
0 ignored issues
show
Bug introduced by
It seems like activities() 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...
67 5
            'type_id'   => $activityType,
68 5
            'parent_id' => $this->project->id,
69 5
            'user_id'   => $userId,
70
        ]));
71
72 5
        $this->status = $status;
73
74 5
        return $this->save();
0 ignored issues
show
Bug introduced by
It seems like save() 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...
75
    }
76
77
    /**
78
     * Sync the issue tags.
79
     *
80
     * @param array      $input
81
     * @param Collection $currentTags
82
     *
83
     * @return bool
84
     */
85 28
    public function syncTags(array $input, Collection $currentTags = null)
86
    {
87 28
        $tagIds = array_only($input, [
88 28
            'tag_type', 'tag_status', 'tag_resolution',
89
        ]);
90 28
        $tags = (new Tag())->whereIn('id', $tagIds)->get();
91
92 28
        $removedTags = [];
93 28
        if (null === $currentTags) {
94
            // Add the following tags except for open status
95
            $addedTags = $tags
0 ignored issues
show
Bug introduced by
The method map cannot be called on $tags (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
96
                ->map(function (Tag $tag) {
97 2
                    return $tag->toShortArray();
98 28
                })
99 28
                ->toArray();
100
        } else {
101
            // Tags remove from the issue
102
            $removedTags = $currentTags
103 1
                ->diff($tags)
104
                ->map(function (Tag $tag) {
105
                    return $tag->toShortArray();
106 1
                })
107 1
                ->toArray();
108
109
            // Check if we are adding new tags
110
            $addedTags = $tags
0 ignored issues
show
Bug introduced by
The method filter cannot be called on $tags (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
111
                ->filter(function (Tag $tag) use ($currentTags) {
112
                    return $currentTags->where('id', $tag->id)->count() === 0;
113 1
                })
114 1
                ->map(function (Tag $tag) {
115
                    return $tag->toShortArray();
116 1
                })
117 1
                ->toArray();
118
119
            // No new tags to add or remove
120 1
            if (empty($removedTags) && empty($addedTags)) {
121 1
                return true;
122
            }
123
        }
124
125
        // Save relation
126 28
        $this->tags()->sync($tags->lists('id')->all());
0 ignored issues
show
Bug introduced by
It seems like tags() 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...
Bug introduced by
The method lists cannot be called on $tags (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
127
128
        // Activity is added when new issue create with tags or updated with tags excluding the open status tag
129 28
        if (!empty($removedTags) || !empty($addedTags)) {
130
            // Add to activity log for tags if changed
131 2
            $this->activities()->save(new User\Activity([
0 ignored issues
show
Bug introduced by
It seems like activities() 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...
132 2
                'type_id'   => Activity::TYPE_ISSUE_TAG,
133 2
                'parent_id' => $this->project->id,
134 2
                'user_id'   => $this->user->id,
135 2
                'data'      => ['added_tags' => $addedTags, 'removed_tags' => $removedTags],
136
            ]));
137
        }
138
139 28
        return true;
140
    }
141
142
    /**
143
     * Add tag to the issue & close issue if added tag is Closed.
144
     *
145
     * @param Tag $newTag
146
     * @param Tag $oldTag
147
     *
148
     * @return $this
149
     */
150
    public function changeKanbanTag(Tag $newTag, Tag $oldTag)
151
    {
152
        //  skip if there is no change in status tags
153
        if ($oldTag->name === $newTag->name) {
154
            return $this;
155
        }
156
157
        // Open issue
158
        $data = ['added_tags' => [], 'removed_tags' => []];
159
160
        // Remove previous status tag
161
        $this->tags()->detach($oldTag);
0 ignored issues
show
Bug introduced by
It seems like tags() 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...
162
        $data['removed_tags'][] = $oldTag->toShortArray();
163
164
        // Add new tag
165
        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...
166
            $this->tags()->attach($newTag);
0 ignored issues
show
Bug introduced by
It seems like tags() 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
            $data['added_tags'][] = $newTag->toShortArray();
169
        }
170
171
        // Add to activity log for tags if changed
172
        if (!empty($data)) {
173
            $this->activities()->save(new User\Activity([
0 ignored issues
show
Bug introduced by
It seems like activities() 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...
174
                'type_id'   => Activity::TYPE_ISSUE_TAG,
175
                'parent_id' => $this->project->id,
176
                'user_id'   => $this->user->id,
177
                'data'      => $data,
178
            ]));
179
        }
180
181
        return $this;
182
    }
183
}
184