Passed
Push — master ( 624a9a...4c85b9 )
by Arthur
36:47
created

ScriptService::updateUserExclusivity()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2.0185

Importance

Changes 0
Metric Value
cc 2
eloc 5
nc 2
nop 2
dl 0
loc 11
ccs 5
cts 6
cp 0.8333
crap 2.0185
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Modules\Script\Services;
4
5
use Modules\Script\Dtos\UserExclusivityGrantDto;
6
use Modules\Script\Dtos\UserExclusivityUpdateDto;
7
use Modules\Script\Entities\Script;
8
use Modules\Script\Entities\ScriptConfigProfile;
9
use Modules\Script\Entities\ScriptExclusivity;
10
use Modules\Script\Entities\ScriptRelease;
11
use Modules\Script\Entities\ScriptReview;
12
use Modules\Script\Entities\ScriptReviewReply;
13
use Modules\Script\Events\ScriptWasCreatedEvent;
14
use Modules\Script\Events\ScriptWasUpdatedEvent;
15
use Modules\Script\Events\ScriptWasDeletedEvent;
16
use Modules\Script\Contracts\ScriptServiceContract;
17
use Illuminate\Database\Eloquent\Collection;
18
use Modules\Script\Exceptions\ScriptAlreadyReviewedException;
19
use Modules\Script\Exceptions\ScriptReviewReplyAlreadyExistsException;
20
use Modules\Script\Exceptions\UserAlreadyHasExclusivityException;
21
use Modules\Script\Exceptions\UserDoesNotHaveExclusivityException;
22
use Modules\Script\Guards\ScriptAlreadyReviewedGuard;
23
use Modules\Script\Support\Version;
24
25
class ScriptService implements ScriptServiceContract
26
{
27
    /**
28
     * @param $id
29
     * @return Script|null
30
     */
31 10
    public function resolve($id): ?Script
32
    {
33 10
        if ($id instanceof Script) {
34 8
            return $id;
35
        }
36
37 3
        return Script::find($id);
38
    }
39
40
    /**
41
     * @param $userId
42
     * @return Script[]
43
     */
44 1
    public function getByUserId($userId): Collection
45
    {
46 1
        return Script::where('user_id', $userId)->get();
0 ignored issues
show
Bug Best Practice introduced by
The expression return Modules\Script\En...er_id', $userId)->get() returns the type Illuminate\Database\Eloquent\Collection which is incompatible with the documented return type Modules\Script\Entities\Script[].
Loading history...
47
    }
48
49
    /**
50
     * @param $id
51
     * @return Script|null
52
     */
53 1
    public function update($id, array $data): Script
54
    {
55 1
        $script = $this->resolve($id);
56 1
        $script->update($data);
57 1
        event(new ScriptWasUpdatedEvent($script));
58
59 1
        return $script;
60
    }
61
62
    /**
63
     * @param $id
64
     * @return Script
65
     */
66 7
    public function create(array $data): Script
67
    {
68 7
        $data[Script::AUTHOR_ID] = get_authenticated_user_id();
69 7
        $script = Script::create($data);
70 7
        event(new ScriptWasCreatedEvent($script));
71 7
        return $script;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $script returns the type Illuminate\Database\Eloq...go\Abstracts\MongoModel which includes types incompatible with the type-hinted return Modules\Script\Entities\Script.
Loading history...
72
    }
73
74
    /**
75
     * @param $id
76
     * @return bool
77
     */
78 1
    public function delete($id): bool
79
    {
80 1
        $script = $this->resolve($id);
81 1
        $deleted = $script->delete();
82 1
        if ($deleted)
83 1
            event(new ScriptWasDeletedEvent($script));
84 1
        return $deleted;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $deleted could return the type null which is incompatible with the type-hinted return boolean. Consider adding an additional type-check to rule them out.
Loading history...
85
    }
86
87 7
    public function releaseVersion($id, array $data): Script
88
    {
89 7
        $script = $this->resolve($id);
90 7
        $releases = $script->releases()->get();
91 7
        if ($releases->isEmpty())
92 7
            $lastVersion = "0.0.0";
93
        else
94 1
            $lastVersion = $releases->last()->version;
95
96 7
        $version = new Version($lastVersion);
97
98 7
        switch ($data['type']) {
99 7
            case 'MAJOR':
100 1
                $version->incrementMajor();
101 1
                break;
102 7
            case 'MINOR':
103 7
                $version->incrementMinor();
104 7
                break;
105
            case 'PATCH':
106
                $version->incrementPatch();
107
                break;
108
            default:
109
                throw new \Exception("Invalid release type specified");
110
        }
111
112
        //TODO ADD CONFIG TEMPLATE
113 7
        $script->releases()->create([
114 7
            ScriptRelease::VERSION => $version->__toString(),
115 7
            ScriptRelease::TYPE => $data['type'],
116 7
            ScriptRelease::CHANGELOG => $data['changelog']
117
        ]);
118
119 7
        return $script;
120
    }
121
122 2
    public function publishReview($id, array $data): ScriptReview
123
    {
124 2
        $script = $this->resolve($id);
125
126 2
        guard(new ScriptAlreadyReviewedGuard($script));
127
128
        //TODO CHECK IF THE USER IS ACTUALLY SUBSCRIBED TO THE SCRIPT
129
        //TODO PREVENT THE AUTHOR FROM REVIEWING HIS OWN SCRIPT
130
131 2
        $review = $script->reviews()->create([
132 2
            ScriptReview::REVIEWER_ID => get_authenticated_user_id(),
133 2
            ScriptReview::VERSION => $script->releases->last()->version,
0 ignored issues
show
Bug introduced by
The property releases does not seem to exist on Modules\Script\Entities\Script. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
134 2
            ScriptReview::MESSAGE => $data['message']
135
        ]);
136
137 2
        return $review;
138
    }
139
140 1
    public function publishReviewReply($id, array $data): ScriptReviewReply
141
    {
142 1
        $script = $this->resolve($id);
143
144 1
        $review = $script->reviews()->withTrashed()->find($data['review_id']);
145
146 1
        if (!isset($review)) {
147
            throw new ScriptAlreadyReviewedException();
148
        }
149
150 1
        if ($review->reply !== null) {
151 1
            throw new ScriptReviewReplyAlreadyExistsException();
152
        }
153
154 1
        $reply = $review->reply()->create([
155 1
            ScriptReviewReply::REPLIER_ID => get_authenticated_user_id(),
156 1
            ScriptReviewReply::MESSAGE => $data['message']
157
        ]);
158
159 1
        return $reply;
160
    }
161
162 3
    public function grantUserExclusivity($id, UserExclusivityGrantDto $data): ScriptExclusivity
163
    {
164 3
        $script = $this->resolve($id);
165 3
        if ($script->exclusivity()->where(ScriptExclusivity::USER_ID, $data->user_id ?? null)->first() !== null) {
166
            throw new UserAlreadyHasExclusivityException();
167
        }
168
169 3
        return $script->exclusivity()->create($data->toArray());
170
    }
171
172 1
    public function removeUserExclusivity($id, $userId): bool
173
    {
174 1
        $script = $this->resolve($id);
175
176 1
        if (($exclusivity = $script->exclusivity()->where(ScriptExclusivity::USER_ID, $userId)->first()) === null) {
177
            throw new UserDoesNotHaveExclusivityException();
178
        }
179
180 1
        return $exclusivity->delete();
181
    }
182
183 1
    public function updateUserExclusivity($id, UserExclusivityUpdateDto $data): ScriptExclusivity
184
    {
185 1
        $script = $this->resolve($id);
186
187 1
        if (($exclusivity = $script->exclusivity()->where(ScriptExclusivity::USER_ID, $data->user_id ?? null)->first()) === null) {
188
            throw new UserDoesNotHaveExclusivityException();
189
        }
190
191 1
        $exclusivity->update($data->toArray());
192
193 1
        return $exclusivity;
194
    }
195
196
    public function subscribe($id, array $data): ScriptExclusivity
197
    {
198
        // TODO: Implement subscribe() method.
199
    }
0 ignored issues
show
Bug Best Practice introduced by
In this branch, the function will implicitly return null which is incompatible with the type-hinted return Modules\Script\Entities\ScriptExclusivity. Consider adding a return statement or allowing null as return value.

For hinted functions/methods where all return statements with the correct type are only reachable via conditions, ?null? gets implicitly returned which may be incompatible with the hinted type. Let?s take a look at an example:

interface ReturnsInt {
    public function returnsIntHinted(): int;
}

class MyClass implements ReturnsInt {
    public function returnsIntHinted(): int
    {
        if (foo()) {
            return 123;
        }
        // here: null is implicitly returned
    }
}
Loading history...
200
201
    public function unsubscribe($id, array $data): ScriptExclusivity
202
    {
203
        // TODO: Implement unsubscribe() method.
204
    }
0 ignored issues
show
Bug Best Practice introduced by
In this branch, the function will implicitly return null which is incompatible with the type-hinted return Modules\Script\Entities\ScriptExclusivity. Consider adding a return statement or allowing null as return value.

For hinted functions/methods where all return statements with the correct type are only reachable via conditions, ?null? gets implicitly returned which may be incompatible with the hinted type. Let?s take a look at an example:

interface ReturnsInt {
    public function returnsIntHinted(): int;
}

class MyClass implements ReturnsInt {
    public function returnsIntHinted(): int
    {
        if (foo()) {
            return 123;
        }
        // here: null is implicitly returned
    }
}
Loading history...
205
206
    public function createConfigProfile($id, array $data): ScriptConfigProfile
207
    {
208
        // TODO: Implement createConfigProfile() method.
209
    }
0 ignored issues
show
Bug Best Practice introduced by
In this branch, the function will implicitly return null which is incompatible with the type-hinted return Modules\Script\Entities\ScriptConfigProfile. Consider adding a return statement or allowing null as return value.

For hinted functions/methods where all return statements with the correct type are only reachable via conditions, ?null? gets implicitly returned which may be incompatible with the hinted type. Let?s take a look at an example:

interface ReturnsInt {
    public function returnsIntHinted(): int;
}

class MyClass implements ReturnsInt {
    public function returnsIntHinted(): int
    {
        if (foo()) {
            return 123;
        }
        // here: null is implicitly returned
    }
}
Loading history...
210
211
    public function updateConfigProfile($id, array $data): ScriptConfigProfile
212
    {
213
        // TODO: Implement updateConfigProfile() method.
214
    }
0 ignored issues
show
Bug Best Practice introduced by
In this branch, the function will implicitly return null which is incompatible with the type-hinted return Modules\Script\Entities\ScriptConfigProfile. Consider adding a return statement or allowing null as return value.

For hinted functions/methods where all return statements with the correct type are only reachable via conditions, ?null? gets implicitly returned which may be incompatible with the hinted type. Let?s take a look at an example:

interface ReturnsInt {
    public function returnsIntHinted(): int;
}

class MyClass implements ReturnsInt {
    public function returnsIntHinted(): int
    {
        if (foo()) {
            return 123;
        }
        // here: null is implicitly returned
    }
}
Loading history...
215
216
    public function deleteConfigProfile($id): bool
217
    {
218
        // TODO: Implement deleteConfigProfile() method.
219
    }
0 ignored issues
show
Bug Best Practice introduced by
In this branch, the function will implicitly return null which is incompatible with the type-hinted return boolean. Consider adding a return statement or allowing null as return value.

For hinted functions/methods where all return statements with the correct type are only reachable via conditions, ?null? gets implicitly returned which may be incompatible with the hinted type. Let?s take a look at an example:

interface ReturnsInt {
    public function returnsIntHinted(): int;
}

class MyClass implements ReturnsInt {
    public function returnsIntHinted(): int
    {
        if (foo()) {
            return 123;
        }
        // here: null is implicitly returned
    }
}
Loading history...
220
221
222
}
223