Passed
Push — master ( f6b34e...90b0c1 )
by Dan Michael O.
03:15
created

CheckoutRequest::importUser()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 21
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 2
eloc 14
c 1
b 0
f 1
nc 2
nop 1
dl 0
loc 21
rs 9.7998

1 Method

Rating   Name   Duplication   Size   Complexity  
A CheckoutRequest::almaSearch() 0 9 2
1
<?php
2
3
namespace App\Http\Requests;
4
5
use App\Alma\AlmaUsers;
6
use App\Alma\User as AlmaUser;
7
use App\Alma\AlmaUsers as AlmaConnector;
8
use App\Item;
9
use App\Rules\ConfirmationNeeded;
10
use App\Rules\NotOnLoan;
11
use App\Rules\NotTrashed;
12
use App\Rules\RequiresBarcode;
13
use App\Rules\ThingExists;
14
use App\Rules\UniqueAlmaUser;
15
use App\Rules\UserBarcodeExists;
16
use App\Rules\UserExists;
17
use App\Thing;
18
use App\User;
19
use Illuminate\Foundation\Http\FormRequest;
0 ignored issues
show
Bug introduced by
The type Illuminate\Foundation\Http\FormRequest was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
20
use Illuminate\Support\Arr;
0 ignored issues
show
Bug introduced by
The type Illuminate\Support\Arr was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
21
use Scriptotek\Alma\Bibs\Item as AlmaItem;
0 ignored issues
show
Bug introduced by
The type Scriptotek\Alma\Bibs\Item was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
22
use Scriptotek\Alma\Client as AlmaClient;
0 ignored issues
show
Bug introduced by
The type Scriptotek\Alma\Client was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
23
24
class CheckoutRequest extends FormRequest
25
{
26
    public $item;
27
    public $user;
28
    public $localUser;
29
30
    /**
31
     * Determine if the user is authorized to make this request.
32
     *
33
     * @return bool
34
     */
35
    public function authorize()
36
    {
37
        return true;
38
    }
39
40
    /**
41
     * Get the validation rules that apply to the request.
42
     *
43
     * @return array
44
     */
45
    public function rules()
46
    {
47
        $library = \Auth::user();
0 ignored issues
show
Bug introduced by
The type Auth was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
48
49
        $input = $this->all();
50
51
        /** @var AlmaClient $alma */
52
        $alma = app(AlmaClient::class);
0 ignored issues
show
Bug introduced by
The function app was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

52
        $alma = /** @scrutinizer ignore-call */ app(AlmaClient::class);
Loading history...
53
54
        /** @var AlmaUsers $almaUsers */
55
        $almaUsers = app(AlmaUsers::class);
56
57
        // ======================== Lookup item and thing ========================
58
59
        $thing = null;
60
        $item = null;
61
62
        if (empty(Arr::get($input, 'thing.name'))) {
63
            // No thing was entered
64
        } elseif (!Arr::get($input, 'thing.type')) {
65
            // A thing was entered manually, not selected from the typeahead menu.
66
            // First check if the value matches a barcode.
67
            $item = Item::withTrashed()->where('barcode', '=', Arr::get($input, 'thing.name'))->first();
68
69
            if (is_null($item)) {
70
                // Next, check if it matches a thing name.
71
                $thing = Thing::where('properties->name->nob', '=', Arr::get($input, 'thing.name'))->first();
72
            }
73
74
            if (is_null($item) && !empty($library->library_code)) {
75
                // Next, check if it can be found in Alma.
76
                // If the library doesn't have a library code set, it means we should not check Alma.
77
                $item = $alma->items->fromBarcode(Arr::get($input, 'thing.name'));
78
            }
79
        } elseif (Arr::get($input, 'thing.type') == 'item') {
80
            $item = Item::withTrashed()->where('id', '=', Arr::get($input, 'thing.id'))->first();
81
        } elseif (Arr::get($input, 'thing.type') == 'thing') {
82
            $thing = Thing::where('id', '=', Arr::get($input, 'thing.id'))->first();
83
        }
84
85
        if (is_null($item) && !is_null($thing)) {
86
            // Then find a generic item, if one exists
87
            if (!$thing->library_settings->loans_without_barcode) {
88
                return [
89
                    'thing' => [new RequiresBarcode()],
90
                ];
91
            }
92
93
            $item = Item::where('thing_id', '=', $thing->id)->whereNull('barcode')->first();
94
            if (!$item) {
95
                \Log::info('Creating generic item for thing ' . $thing->id);
96
                $item = new Item();
97
                $item->thing_id = $thing->id;
98
                $item->save();
99
            }
100
        }
101
102
        if (!is_null($item) && $item->thing_id == 1 && !empty($library->library_code)) {
103
            // Local copy of an Alma item
104
            $item = $alma->items->fromBarcode($item->barcode);
105
        }
106
107
        // ======================== Lookup or import user ========================
108
109
        $user = null;
110
111
        if (empty(Arr::get($input, 'user.name'))) {
112
            // No user was entered
113
        } elseif (Arr::get($input, 'user.type') == 'local') {
114
            // Lookup local user by id
115
            $user = User::find(Arr::get($input, 'user.id'));
116
        } elseif (Arr::get($input, 'user.id')) {
117
            // Import user from Alma by primary ID
118
            $almaUser = $almaUsers->findById(Arr::get($input, 'user.id'));
119
            if (!is_null($almaUser)) {
120
                $user = $almaUsers->updateOrCreateLocalUserFromAlmaUser($almaUser);
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::where('barcode', '=', $userValue)
137
                    ->orWhere('university_id', '=', $userValue)
138
                    ->orWhere('alma_primary_id', '=', $userValue)
139
                    ->first();
140
            }
141
142
            if (is_null($user)) {
143
                // If user was not found locally, try Alma.
144
                // Check if the input value matches primary_id first,
145
                // since there is less risk of matching multiple users.
146
                $almaUser = $almaUsers->findById($userValue);
147
                if (!is_null($almaUser)) {
148
                    $user = $almaUsers->updateOrCreateLocalUserFromAlmaUser($almaUser);
149
                } else {
150
                    $query = 'ALL~' . $userValue;
151
                    $results = $this->almaSearch($alma, $query);
152
                    if (count($results) == 1) {
153
                        $user = $almaUsers->updateOrCreateLocalUserFromAlmaUser($results[0]);
154
                    } elseif (count($results) > 1) {
155
                        return ['user' => [new UniqueAlmaUser($query)]];
156
                    }
157
                }
158
            }
159
160
            if (is_null($user)) {
161
                // User was not found locally or in Alma.
162
163
                // If the input looks like a barcode, we will make suggestions based on that.
164
                if (AlmaUser::isUserBarcode($userValue)) {
165
                    return ['user' => [new UserExists(null, [
166
                        'barcode' => $userValue,
167
                    ])]];
168
                }
169
170
                // If the input looks like a name, we will make suggestions based on that.
171
                if (!is_null($fullname)) {
172
                    return ['user' => [new UserExists(null, [
173
                        'firstname' => $fullname[1],
174
                        'lastname' => $fullname[0],
175
                    ])]];
176
                }
177
            }
178
        }
179
180
        $this->user = $user;
181
        $this->item = $item;
182
183
        return [
184
            'confirmed' => [new ConfirmationNeeded($user)],
185
            'user' => [new UserExists($user)],
186
            'thing' => [new ThingExists($item), new NotTrashed($item), new NotOnLoan($alma, $item)],
187
        ];
188
    }
189
190
    protected function almaSearch($alma, $query)
191
    {
192
        if (is_null($alma->key)) {
193
            \Log::warning('Cannot search Alma users since no Alma API key is configured.');
194
            return collect([]);
0 ignored issues
show
Bug introduced by
The function collect was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

194
            return /** @scrutinizer ignore-call */ collect([]);
Loading history...
195
        }
196
197
        return collect($alma->users->search($query, ['limit' => 2]))->map(function ($user) {
198
            return new AlmaUser($user);
199
        });
200
    }
201
}
202