CheckoutRequest::rules()   F
last analyzed

Complexity

Conditions 29
Paths 1880

Size

Total Lines 142
Code Lines 75

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 1
Metric Value
cc 29
eloc 75
c 2
b 0
f 1
nc 1880
nop 0
dl 0
loc 142
rs 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace App\Http\Requests;
4
5
use App\Alma\AlmaUsers;
6
use App\Alma\User as AlmaUser;
7
use App\Item;
8
use App\Rules\ConfirmationNeeded;
9
use App\Rules\NotOnLoan;
10
use App\Rules\NotTrashed;
11
use App\Rules\RequiresBarcode;
12
use App\Rules\ThingExists;
13
use App\Rules\UniqueAlmaUser;
14
use App\Rules\UserExists;
15
use App\Thing;
16
use App\User;
17
use Illuminate\Foundation\Http\FormRequest;
18
use Illuminate\Support\Arr;
19
use Scriptotek\Alma\Client as AlmaClient;
20
21
class CheckoutRequest extends FormRequest
22
{
23
    public $item;
24
    public $user;
25
    public $localUser;
26
27
    /**
28
     * Determine if the user is authorized to make this request.
29
     *
30
     * @return bool
31
     */
32
    public function authorize()
33
    {
34
        return true;
35
    }
36
37
    /**
38
     * Get the validation rules that apply to the request.
39
     *
40
     * @return array
41
     */
42
    public function rules()
43
    {
44
        $library = \Auth::user();
45
46
        $input = $this->all();
47
48
        /** @var AlmaClient $alma */
49
        $alma = app(AlmaClient::class);
50
51
        /** @var AlmaUsers $almaUsers */
52
        $almaUsers = app(AlmaUsers::class);
53
54
        // ======================== Lookup item and thing ========================
55
56
        $thing = null;
57
        $item = null;
58
59
        if (empty(Arr::get($input, 'thing.name'))) {
60
            // No thing was entered
61
        } elseif (!Arr::get($input, 'thing.type')) {
62
            // A thing was entered manually, not selected from the typeahead menu.
63
            // First check if the value matches a barcode.
64
            $item = Item::withTrashed()->where('barcode', '=', Arr::get($input, 'thing.name'))->first();
65
66
            if (is_null($item)) {
67
                // Next, check if it matches a thing name.
68
                $thing = Thing::where('properties->name->nob', '=', Arr::get($input, 'thing.name'))->first();
69
            }
70
71
            if (is_null($item) && !empty($library->library_code)) {
0 ignored issues
show
Bug introduced by
The property library_code does not exist on App\User. Did you mean library_id?
Loading history...
72
                // Next, check if it can be found in Alma.
73
                // If the library doesn't have a library code set, it means we should not check Alma.
74
                $item = $alma->items->fromBarcode(Arr::get($input, 'thing.name'));
75
            }
76
        } elseif (Arr::get($input, 'thing.type') == 'item') {
77
            $item = Item::withTrashed()->where('id', '=', Arr::get($input, 'thing.id'))->first();
78
        } elseif (Arr::get($input, 'thing.type') == 'thing') {
79
            $thing = Thing::where('id', '=', Arr::get($input, 'thing.id'))->first();
80
        }
81
82
        if (is_null($item) && !is_null($thing)) {
83
            // Then find a generic item, if one exists
84
            if (!$thing->library_settings->loans_without_barcode) {
85
                return [
86
                    'thing' => [new RequiresBarcode()],
87
                ];
88
            }
89
90
            $item = Item::where('thing_id', '=', $thing->id)->whereNull('barcode')->first();
91
            if (!$item) {
92
                \Log::info('Creating generic item for thing ' . $thing->id);
93
                $item = new Item();
94
                $item->thing_id = $thing->id;
95
                $item->save();
96
            }
97
        }
98
99
        if (!is_null($item) && $item->thing_id == 1 && !empty($library->library_code)) {
100
            // Local copy of an Alma item
101
            $item = $alma->items->fromBarcode($item->barcode);
102
        }
103
104
        // ======================== Lookup or import user ========================
105
106
        $user = null;
107
108
        if (empty(Arr::get($input, 'user.name'))) {
109
            // No user was entered
110
        } elseif (Arr::get($input, 'user.type') == 'local') {
111
            // Lookup local user by id
112
            $user = User::find(Arr::get($input, 'user.id'));
113
        } elseif (Arr::get($input, 'user.id')) {
114
            // Import user from Alma by primary ID
115
            $user = User::where('alma_primary_id', '=', Arr::get($input, 'user.id'))->first();
116
            if (is_null($user)) {
117
                $almaUser = $almaUsers->findById(Arr::get($input, 'user.id'));
118
                if (!is_null($almaUser)) {
119
                    $user = $almaUsers->updateOrCreateLocalUserFromAlmaUser($almaUser);
120
                }
121
            }
122
        } else {
123
            $userValue = Arr::get($input, 'user.name');
124
125
            if (strpos($userValue, ',') !== false) {
126
                // Try looking up local user by name
127
                $fullname = explode(',', $userValue);
128
                $fullname = array_map('trim', $fullname);
129
                $user = User::where('lastname', '=', $fullname[0])
130
                    ->where('firstname', '=', $fullname[1])
131
                    ->first();
132
            } else {
133
                $fullname = null;
134
135
                // Try looking up local user by barcode
136
                $user = User::fromIdentifier($userValue);
137
            }
138
139
            if (is_null($user) && !is_null($alma->key)) {
140
                // If user was not found locally, try Alma.
141
                // Check if the input value matches primary_id first,
142
                // since there is less risk of matching multiple users.
143
                $almaUser = $almaUsers->findById($userValue);
144
                if (!is_null($almaUser)) {
145
                    $user = $almaUsers->updateOrCreateLocalUserFromAlmaUser($almaUser);
146
                } else {
147
                    $query = 'ALL~' . $userValue;
148
                    $results = $this->almaSearch($alma, $query);
149
                    if (count($results) == 1) {
150
                        $user = $almaUsers->updateOrCreateLocalUserFromAlmaUser($results[0]);
151
                    } elseif (count($results) > 1) {
152
                        return ['user' => [new UniqueAlmaUser($query)]];
153
                    }
154
                }
155
            }
156
157
            if (is_null($user)) {
158
                // User was not found locally or in Alma.
159
160
                // If the input looks like a barcode, we will make suggestions based on that.
161
                if (AlmaUser::isUserBarcode($userValue)) {
162
                    return ['user' => [new UserExists(null, [
163
                        'barcode' => $userValue,
164
                    ])]];
165
                }
166
167
                // If the input looks like a name, we will make suggestions based on that.
168
                if (!is_null($fullname)) {
169
                    return ['user' => [new UserExists(null, [
170
                        'firstname' => $fullname[1],
171
                        'lastname' => $fullname[0],
172
                    ])]];
173
                }
174
            }
175
        }
176
177
        $this->user = $user;
178
        $this->item = $item;
179
180
        return [
181
            'confirmed' => [new ConfirmationNeeded($user)],
182
            'user' => [new UserExists($user)],
183
            'thing' => [new ThingExists($item), new NotTrashed($item), new NotOnLoan($alma, $item)],
184
        ];
185
    }
186
187
    protected function almaSearch($alma, $query)
188
    {
189
        if (is_null($alma->key)) {
190
            \Log::warning('Cannot search Alma users since no Alma API key is configured.');
191
            return collect([]);
192
        }
193
194
        return collect($alma->users->search($query, ['limit' => 2]))->map(function ($user) {
195
            return new AlmaUser($user);
196
        });
197
    }
198
}
199