Ukhmt::processAkasAndFkas()   B
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 29
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 17
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 29
ccs 17
cts 17
cp 1
rs 8.8571
cc 2
eloc 16
nc 2
nop 0
crap 2
1
<?php
2
3
namespace ADiaz\AML\OpenList\parsers;
4
5
use ADiaz\AML\OpenList\models\Address;
6
use ADiaz\AML\OpenList\models\Aka;
7
use ADiaz\AML\OpenList\models\Citizenship;
8
use ADiaz\AML\OpenList\models\DateOfBirth;
9
use ADiaz\AML\OpenList\models\Entity;
10
use ADiaz\AML\OpenList\models\Id;
11
use ADiaz\AML\OpenList\models\Nationality;
12
use ADiaz\AML\OpenList\models\PlaceOfBirth;
13
use ADiaz\AML\OpenList\models\Program;
14
15
/**
16
 * This file is part of the OpenList Parser utility.
17
 *
18
 * @category PHP
19
 *
20
 * @author    Alberto Diaz <[email protected]>
21
 * @copyright 2016 Alberto Diaz <[email protected]>
22
 * @license   This source file is subject to the MIT license that is bundled
23
 *
24
 * @version Release: @package_version@
25
 *
26
 * @link http://tytem.com
27
 */
28
class Ukhmt implements ListInterface
29
{
30
    protected $prime_alias;
31
    protected $aka_fka_rows;
32
    protected $list_file_content;
33
    protected $path_source;
34
    protected $entities = [];
35
    protected $date;
36
37
    const ERROR_DIVIDING_ROWS = 'Error dividing the rows.';
38
    const ERROR_FILE = 'Error. The sanction list was not found. Have you executed the downloader?.';
39
    const ERROR_VERIFYING_ENTITIES = 'Error. The sanction list was not found. Please verify if it was downloaded and the list configuration file.';
40
41
    /**
42
     * Add the entity if it doesn't exsist already in teh array of entities
43
     * if it exists it does nothing.
44
     *
45
     * @param Entity $entity
46
     *
47
     * @return null|bool if the entity is added to the array
48
     */
49 2
    protected function addEntity(Entity $entity)
50
    {
51 2
        foreach ($this->entities as $ent) {
52 2
            if ($ent->external_id === $entity->external_id) {
53 2
                return;
54
            }
55
        }
56
57 2
        $this->entities [] = $entity;
58
59 2
        return true;
60
    }
61
62
    /**
63
     * Get the value from one or multiple cols.
64
     *
65
     * @param string $value
66
     * @param array  $cols
67
     *
68
     * @return string|null
69
     */
70 2
    protected function getCols($value, $cols)
71
    {
72 2
        $mValue = $this->getMap()[$value];
73
74 2
        if (is_array($mValue)) {
75 2
            $str = '';
76 2
            foreach ($mValue as $subIdMapper) {
77 2
                $str .= $cols[$subIdMapper].' ';
78
            }
79
        } else {
80 2
            $str = $cols[$mValue];
81
        }
82
83 2
        $strNoExtraSpaces = trim(preg_replace('/\s+/', ' ', $str));
84
85 2
        return ($strNoExtraSpaces !== '') ? $strNoExtraSpaces : null;
86
    }
87
88
    public function getDate()
89
    {
90
        return $this->date;
91
    }
92
93 2
    public function getEntities()
94
    {
95 2
        return $this->entities;
96
    }
97
98
    /**
99
     * Get the ids of the entities.
100
     *
101
     * @return array
102
     */
103 2
    protected function getEntitiesIds()
104
    {
105 2
        $entitiesIds = [];
106
107 2
        foreach ($this->entities as $entity) {
108 2
            $entitiesIds[] = $entity->external_id;
109
        }
110
111 2
        return $entitiesIds;
112
    }
113
114
    /**
115
     * Get a new entity if it doesn't exist, or get the entity created
116
     * if already exists.
117
     *
118
     * @param int $id
119
     *
120
     * @return Entity
121
     */
122 2
    protected function getEntity($id)
123
    {
124 2
        foreach ($this->entities as $entity) {
125 2
            if ($entity->external_id === $id) {
126 2
                return $entity;
127
            }
128
        }
129
130 2
        return new Entity($id);
131
    }
132
133
    /**
134
     * Get the ids of the list.
135
     *
136
     * @return array
137
     */
138 2
    protected function getGroupsIdsFromSource()
139
    {
140 2
        $group_ids = [];
141 2
        $i = 0;
142
143
        // iterate over each line
144 2
        foreach (preg_split("/((\r?\n)|(\r\n?))/", $this->list_file_content) as $line) {
145 2
            $cols = str_getcsv($line);
146
147 2
            if ($i > 1) {
148 2
                $group_id = $cols[$this->getMap()['group_id']];
149
150 2
                $group_ids [$group_id] = $group_id;
151
            }
152 2
            ++$i;
153
        }
154
155 2
        return $group_ids;
156
    }
157
158
    /**
159
     * Return the mappers the fields with the columns of the excel document.
160
     *
161
     * @return array with the mapping
162
     */
163 2
    protected function getMap()
164
    {
165
        $fields = [
166 2
            'last_name'         => 0,
167
            'first_name'        => [1, 2, 3, 4, 5],
168
            'title'             => 6,
169
            'dob'               => 7,
170
            'tob'               => 8,
171
            'cob'               => 9,
172
            'nationality'       => 10,
173
            'passport'          => 11,
174
            'ni_number'         => 12,
175
            'position'          => 13,
176
            'address'           => [14, 15, 16, 17, 18],
177
            'city'              => 19,
178
            'postcode'          => 20,
179
            'country'           => 21,
180
            'other_information' => 22,
181
            'group_type'        => 23,
182
            'row_type'          => 24,
183
            'regime'            => 25,
184
            'listen_on'         => 26,
185
            'last_updated'      => 27,
186
            'group_id'          => 28,
187
        ];
188
189 2
        return $fields;
190
    }
191
192
    /**
193
     * Check if if a row (after str_getcsv) is prime alias.
194
     *
195
     * @param array $cols
196
     *
197
     * @return bool true if yes
198
     */
199 2
    protected function isPrimeAlias(array $cols)
200
    {
201 2
        return $cols[$this->getMap()['row_type']] === Entity::ALIAS_TYPE_PRIME_ALIAS;
202
    }
203
204
    /**
205
     * Check if if a row (after str_getcsv) is an AKA.
206
     *
207
     * @param array $cols
208
     *
209
     * @return bool true if yes
210
     */
211 2
    protected function isAka(array $cols)
212
    {
213 2
        return $cols[$this->getMap()['row_type']] === Entity::ALIAS_TYPE_AKA;
214
    }
215
216
    /**
217
     * Check if if a row (after str_getcsv) is an FKA.
218
     *
219
     * @param array $cols
220
     *
221
     * @return bool true if yes
222
     */
223 2
    protected function isFka(array $cols)
224
    {
225 2
        return $cols[$this->getMap()['row_type']] === Entity::ALIAS_TYPE_FKA;
226
    }
227
228
    /**
229
     * A separate record is provided for each permutation of data involving “Name”, “Date of Birth”,
230
     *   “Address” and “Regime”.
231
     */
232 2
    protected function processAkasAndFkas()
233
    {
234 2
        foreach ($this->aka_fka_rows as $row) {
235 2
            $cols = str_getcsv($row);
236
237
            // get the entity to fill it with info
238 2
            $entity = $this->getEntity($this->getCols('group_id', $cols));
239
240
            //add aka
241 2
            $aka = new Aka();
242 2
            $aka->last_name = $this->getCols('last_name', $cols);
243 2
            $aka->first_name = $this->getCols('first_name', $cols);
244 2
            $entity->addAka($aka);
245
246
            // add dob
247 2
            $entity->addDateOfBirth(new DateOfBirth($this->getCols('dob', $cols)));
0 ignored issues
show
Unused Code introduced by
The call to DateOfBirth::__construct() has too many arguments starting with $this->getCols('dob', $cols).

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
248
249
            // add address
250 2
            $address = new Address();
251 2
            $address->address1 = $this->getCols('address', $cols);
252 2
            $address->city = $this->getCols('city', $cols);
253 2
            $address->country = $this->getCols('country', $cols);
254 2
            $address->postal_code = $this->getCols('postcode', $cols);
255 2
            $entity->addAddress($address);
256
257
            // add program
258 2
            $entity->addProgram(new Program($this->getCols('regime', $cols)));
0 ignored issues
show
Unused Code introduced by
The call to Program::__construct() has too many arguments starting with $this->getCols('regime', $cols).

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
259
        }
260 2
    }
261
262 2
    public function processEntities()
263
    {
264 2
        $this->processPrimeAlias();
265 2
        $this->processAkasAndFkas();
266 2
    }
267
268 2
    public function run()
269
    {
270 2
        $this->readEntities();
271 2
        $this->processEntities();
272 2
        $this->setDate();
273
274 2
        return $this->verifyEntities();
275
        //log die(self::ERROR_VERIFYING_ENTITIES);
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
276
    }
277
278
    /**
279
     * Process entity prime alias.
280
     */
281 2
    protected function processPrimeAlias()
282
    {
283 2
        foreach ($this->prime_alias as $row) {
284 2
            $cols = str_getcsv($row);
285
286 2
            $entity = $this->getEntity($this->getCols('group_id', $cols));
287
288 2
            $entity->setter('last_name', $this->getCols('last_name', $cols));
289 2
            $entity->setter('first_name', $this->getCols('first_name', $cols));
290 2
            $entity->setter('title', $this->getCols('title', $cols));
291 2
            $entity->setType($this->getCols('group_type', $cols));
292 2
            $entity->setter('position', $this->getCols('position', $cols));
293 2
            $entity->setter('remarks', $this->getCols('other_information', $cols));
294
295
            // add address
296 2
            $address = new Address();
297 2
            $address->address1 = $this->getCols('address', $cols);
298 2
            $address->city = $this->getCols('city', $cols);
299 2
            $address->country = $this->getCols('country', $cols);
300 2
            $address->postal_code = $this->getCols('postcode', $cols);
301 2
            $entity->addAddress($address);
302
303
            // add dob
304 2
            $dateOfBirth = new DateOfBirth();
305 2
            $dateOfBirth->date_of_birth = $this->getCols('dob', $cols);
306 2
            $entity->addDateOfBirth($dateOfBirth);
307
308
            // add POB town of birth
309 2
            $placeOfBirth = new PlaceOfBirth();
310 2
            $placeOfBirth->place_of_birth = $this->getCols('tob', $cols);
311 2
            $entity->addPlaceOfBirth($placeOfBirth);
312
313
            // add COB country of birth to the place of birth
314 2
            $countryOfBirth = new PlaceOfBirth();
315 2
            $countryOfBirth->place_of_birth = $this->getCols('cob', $cols);
316 2
            $entity->addPlaceOfBirth($countryOfBirth);
317
318
            // add program
319 2
            $program = new Program();
320 2
            $program->program = $this->getCols('regime', $cols);
321 2
            $entity->addProgram($program);
322
323
            // add citizenship
324 2
            $citizenship = new Citizenship();
325 2
            $citizenship->country = $this->getCols('nationality', $cols);
326 2
            $entity->addCitizenship($citizenship);
327
328
            // add nationality
329 2
            $nationality = new Nationality();
330 2
            $nationality->country = $this->getCols('nationality', $cols);
331 2
            $entity->addNationality($nationality);
332
333
            // add Passport number(s) - where issued, issued/expiry dates
334 2
            $passport = new Id();
335 2
            $passport->type = Id::TYPE_PASSPORT;
336 2
            $passport->mixed = $this->getCols('passport', $cols);
337 2
            $entity->addId($passport);
338
339
            // add ids (ssn, national ids, passports)
340 2
            $nid = new Id();
341 2
            $nid->type = Id::TYPE_NATIONAL_ID_OR_SSN;
342 2
            $nid->mixed = $this->getCols('nationality', $cols);
343 2
            $entity->addId($nid);
344
345 2
            $this->addEntity($entity);
346
        }
347 2
    }
348
349 2
    public function readEntities()
350
    {
351
        // change encoding, review it in the future since https://www.gov.uk/government/publications/open-standards-for-government/cross-platform-character-encoding-profile
352 2
        $this->list_file_content = utf8_encode(file_get_contents($this->path_source));
353
354
        // check the file
355 2
        if (!$this->list_file_content) {
356
            throw new \UnexpectedValueException(self::ERROR_FILE);
357
        }
358
359 2
        $this->setPrimaryEntitiesAkasFkas();
360 2
    }
361
362 2
    public function setDate()
363
    {
364 2
        $lines = preg_split("/((\r?\n)|(\r\n?))/", $this->list_file_content);
365
366 2
        $dateLine = str_getcsv($lines[0]);
367
368 2
        $this->date = $dateLine[1];
369 2
    }
370
371
    /**
372
     * Divide the entities in primary, akas and fkas.
373
     */
374 2
    protected function setPrimaryEntitiesAkasFkas()
375
    {
376 2
        $firstLine = true;
377
378
        // iterate over each line
379 2
        foreach (preg_split("/((\r?\n)|(\r\n?))/", $this->list_file_content) as $line) {
380 2
            $cols = str_getcsv($line);
381
382 2
            if ($firstLine) {
383 2
                $firstLine = false;
384 2
                continue;
385
            }
386
387 2
            if ($this->isPrimeAlias($cols)) {
388 2
                $this->prime_alias[] = $line;
389 2
            } elseif ($this->isAka($cols) || $this->isFka($cols)) {
390 2
                $this->aka_fka_rows[] = $line;
391
            }
392
        }
393 2
    }
394
395 2
    public function setSourcePath($pathSource)
396
    {
397 2
        $this->path_source = $pathSource;
398 2
    }
399
400
    /**
401
     * Check the number of entities math with the total of entities of the document.
402
     */
403 2
    public function verifyEntities()
404
    {
405 2
        return $this->verifyIds();
406
    }
407
408
    /**
409
     * Check if the ids of the entities are the same that the ids from the list file.
410
     *
411
     * @return bool
412
     */
413 2
    protected function verifyIds()
414
    {
415 2
        return count(array_diff($this->getGroupsIdsFromSource(), $this->getEntitiesIds())) == 0
416 2
        && count($this->getEntitiesIds()) > 0;
417
    }
418
}
419