Passed
Push — master ( cab2ec...9dc70f )
by Innocent
05:52
created

CRUDServices::getServiceVariable()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 8
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 6
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 8
rs 10
1
<?php
2
3
namespace InnoFlash\LaraStart\Services;
4
5
use Illuminate\Database\Eloquent\Model;
6
use Illuminate\Support\Str;
7
use InnoFlash\LaraStart\Traits\APIResponses;
8
use InvalidArgumentException;
9
10
abstract class CRUDServices
11
{
12
    use APIResponses;
13
14
    /**
15
     * This sets the attributes to be removed from the given set for updating or creating.
16
     * @return array
17
     */
18
    abstract public function getUnsetFields(): array;
19
20
    /**
21
     * This gets the relationship of the given model to the parent.
22
     *
23
     * @return mixed
24
     */
25
    public function getParentRelationship()
26
    {
27
        throw new InvalidArgumentException('A relationship for these models is not set!');
28
    }
29
30
    /**
31
     * Deletes the model from the database.
32
     *
33
     * @param  string  $message
34
     *
35
     * @return
36
     */
37
    public function destroy(string $message = 'Deleted successful!')
38
    {
39
        try {
40
            $this->getServiceVariable()->delete();
41
42
            if (config('larastart.return_object')) {
43
                return '';
44
            }
45
46
            return $this->successResponse($message, [], 204);
47
        } catch (\Exception $e) {
48
            abort(500, $e->getMessage());
49
        }
50
    }
51
52
    /**
53
     *  Updates the model with the given filtered attributes.
54
     *
55
     * @param  array  $attributes
56
     * @param  string  $message
57
     * @param  bool  $returnObject
58
     *
59
     * @return \Illuminate\Http\JsonResponse|mixed
60
     */
61
    public function update(array $attributes, string $message = 'Update successful!', bool $returnObject = false)
62
    {
63
        try {
64
            $this->getServiceVariable()->update($this->optimizeAttributes($attributes));
65
66
            if ($returnObject || config('larastart.return_object')) {
67
                return $this->getServiceVariable()->refresh();
68
            }
69
70
            return $this->successResponse($message);
71
        } catch (\Exception $e) {
72
            abort(500, $e->getMessage());
73
        }
74
    }
75
76
    /**
77
     * Creates a new model with the given filtered attributes.
78
     *
79
     * @param  array  $attributes
80
     * @param  string  $message
81
     * @param  bool  $returnObject
82
     *
83
     * @return \Illuminate\Http\JsonResponse
84
     */
85
    public function create(array $attributes, string $message = 'Created successfully!', bool $returnObject = false)
86
    {
87
88
        try {
89
            $model = $this->getModelClassName()::create($this->optimizeAttributes($attributes));
90
91
            if ($returnObject || config('larastart.return_object')) {
92
                return $model;
93
            }
94
95
            return $this->successResponse($message, [], 201);
96
        } catch (\Exception $e) {
97
            abort(500, $e->getMessage());
98
        }
99
    }
100
101
    /**
102
     * Creates a new model from the given parent relationship.
103
     *
104
     * @param  array  $attributes
105
     * @param  string  $message
106
     * @param  bool  $returnObject
107
     *
108
     * @return \Illuminate\Http\JsonResponse
109
     */
110
    public function createFromParent(
111
        array $attributes,
112
        string $message = 'Created successfully!',
113
        bool $returnObject = false
114
    ) {
115
        $class = $this->getModelClassName();
116
        $model = new $class($this->optimizeAttributes($attributes));
117
118
        try {
119
            $this->getParent()->save($model);
120
            if ($returnObject || config('larastart.return_object')) {
121
                return $model;
122
            }
123
124
            return $this->successResponse($message, [], 201);
125
        } catch (\Exception $e) {
126
            abort(500, $e->getMessage());
127
        }
128
    }
129
130
    /**
131
     * This removes unwanted fields from the incoming create/update requests.
132
     *
133
     * @param  array  $attributes
134
     *
135
     * @return array
136
     */
137
    protected function optimizeAttributes(array $attributes)
138
    {
139
        return collect($attributes)
140
            ->except($this->getUnsetFields())
141
            ->toArray();
142
    }
143
144
    /**
145
     * Retrieves the parent to child relationship between this model and its parent.
146
     */
147
    private function getParent()
148
    {
149
        if (\is_object($this->getParentRelationship())) {
150
            return $this->getParentRelationship();
151
        }
152
153
        if (\is_array($this->getParentRelationship())) {
154
            [$class, $relationship, $parentIdRouteKey] = $this->getParentRelationship();
155
156
            $_class = new $class();
157
            $parent = $class::findOrFail(request($_class->getForeignKey()));
158
159
            if ($parentIdRouteKey) {
160
                $parent = $class::findOrFail(request($parentIdRouteKey));
161
            }
162
163
            return $parent->$relationship();
164
        }
165
166
        throw new InvalidArgumentException('You have set an invalid parent for this model');
167
    }
168
169
    /**
170
     * Return the class name of the service main model.
171
     *
172
     * @return string
173
     */
174
    protected function getModelClassName(): string
175
    {
176
        return get_class($this->getServiceVariable());
177
    }
178
179
    /**
180
     * Get the service variable.
181
     *
182
     * @return mixed
183
     */
184
    private function getServiceVariable()
185
    {
186
        return collect(get_object_vars($this))
187
            ->reject(fn ($var) => ! ($var instanceof Model))
188
            ->filter(function ($var, $key) {
189
                return Str::contains('get'.Str::ucfirst($key), get_class_methods($this))
190
                    && Str::startsWith(Str::lower(class_basename($this)), $key);
191
            })->first();
192
    }
193
}
194