Passed
Push — master ( 990947...a164fb )
by Maurício
02:00
created

ShapeRecord::savePointZRecord()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * phpMyAdmin ShapeFile library
4
 * <https://github.com/phpmyadmin/shapefile/>.
5
 *
6
 * Copyright 2006-2007 Ovidio <ovidio AT users.sourceforge.net>
7
 * Copyright 2016 - 2017 Michal Čihař <[email protected]>
8
 *
9
 * This program is free software; you can redistribute it and/or
10
 * modify it under the terms of the GNU General Public License
11
 * as published by the Free Software Foundation.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU General Public License
19
 * along with this program; if not, you can download one from
20
 * https://www.gnu.org/copyleft/gpl.html.
21
 */
22
declare(strict_types=1);
23
24
namespace PhpMyAdmin\ShapeFile;
25
26
/**
27
 * ShapeFile record class.
28
 */
29
class ShapeRecord
30
{
31
    private $SHPFile = null;
32
    private $DBFFile = null;
33
    private $ShapeFile = null;
34
35
    private $size = 0;
36
    private $read = 0;
37
38
    public $recordNumber = null;
39
    public $shapeType = null;
40
41
    public $lastError = '';
42
43
    public $SHPData = [];
44
    public $DBFData = [];
45
46
    /**
47
     * @param int $shapeType
48 20
     */
49
    public function __construct($shapeType)
50 20
    {
51 20
        $this->shapeType = $shapeType;
52
    }
53
54
    /**
55
     * Loads record from files.
56
     *
57
     * @param ShapeFile $ShapeFile
58
     * @param file      &$SHPFile  Opened SHP file
0 ignored issues
show
Bug introduced by
The type PhpMyAdmin\ShapeFile\file 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...
59
     * @param file      &$DBFFile  Opened DBF file
60 19
     */
61
    public function loadFromFile(&$ShapeFile, &$SHPFile, &$DBFFile)
62 19
    {
63 19
        $this->ShapeFile = $ShapeFile;
64 19
        $this->SHPFile = $SHPFile;
65 19
        $this->DBFFile = $DBFFile;
66
        $this->loadHeaders();
67
68 19
        /* No header read */
69 19
        if ($this->read == 0) {
70
            return;
71
        }
72 19
73 19
        switch ($this->shapeType) {
74
            case 0:
75
                $this->loadNullRecord();
76 19
                break;
77 4
            case 1:
78 4
                $this->loadPointRecord();
79 15
                break;
80 1
            case 21:
81 1
                $this->loadPointMRecord();
82 14
                break;
83 1
            case 11:
84 1
                $this->loadPointZRecord();
85 13
                break;
86 1
            case 3:
87 1
                $this->loadPolyLineRecord();
88 12
                break;
89 1
            case 23:
90 1
                $this->loadPolyLineMRecord();
91 11
                break;
92 1
            case 13:
93 1
                $this->loadPolyLineZRecord();
94 10
                break;
95 3
            case 5:
96 3
                $this->loadPolygonRecord();
97 7
                break;
98 1
            case 25:
99 1
                $this->loadPolygonMRecord();
100 6
                break;
101 2
            case 15:
102 2
                $this->loadPolygonZRecord();
103 4
                break;
104 1
            case 8:
105 1
                $this->loadMultiPointRecord();
106 3
                break;
107 1
            case 28:
108 1
                $this->loadMultiPointMRecord();
109 2
                break;
110 2
            case 18:
111 2
                $this->loadMultiPointZRecord();
112
                break;
113
            default:
114
                $this->setError(sprintf('The Shape Type "%s" is not supported.', $this->shapeType));
0 ignored issues
show
Bug introduced by
It seems like $this->shapeType can also be of type false; however, parameter $args of sprintf() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

114
                $this->setError(sprintf('The Shape Type "%s" is not supported.', /** @scrutinizer ignore-type */ $this->shapeType));
Loading history...
115 19
                break;
116
        }
117
118 19
        /* We need to skip rest of the record */
119 6
        while ($this->read < $this->size) {
120 6
            $this->loadData('V', 4);
121
        }
122
123 19
        /* Check if we didn't read too much */
124
        if ($this->read != $this->size) {
125
            $this->setError(sprintf('Failed to parse record, read=%d, size=%d', $this->read, $this->size));
126
        }
127 19
128
        if (ShapeFile::supportsDbase() && isset($this->DBFFile)) {
129
            $this->loadDBFData();
130 19
        }
131
    }
132
133
    /**
134
     * Saves record to files.
135
     *
136
     * @param file &$SHPFile     Opened SHP file
137
     * @param file &$DBFFile     Opened DBF file
138
     * @param int  $recordNumber Record number
139 12
     */
140
    public function saveToFile(&$SHPFile, &$DBFFile, $recordNumber)
141 12
    {
142 12
        $this->SHPFile = $SHPFile;
143 12
        $this->DBFFile = $DBFFile;
144 12
        $this->recordNumber = $recordNumber;
145
        $this->saveHeaders();
146 12
147 12
        switch ($this->shapeType) {
148
            case 0:
149
                // Nothing to save
150 12
                break;
151 1
            case 1:
152 1
                $this->savePointRecord();
153 11
                break;
154 1
            case 21:
155 1
                $this->savePointMRecord();
156 10
                break;
157 1
            case 11:
158 1
                $this->savePointZRecord();
159 9
                break;
160 1
            case 3:
161 1
                $this->savePolyLineRecord();
162 8
                break;
163 1
            case 23:
164 1
                $this->savePolyLineMRecord();
165 7
                break;
166 1
            case 13:
167 1
                $this->savePolyLineZRecord();
168 6
                break;
169 1
            case 5:
170 1
                $this->savePolygonRecord();
171 5
                break;
172 1
            case 25:
173 1
                $this->savePolygonMRecord();
174 4
                break;
175 1
            case 15:
176 1
                $this->savePolygonZRecord();
177 3
                break;
178 1
            case 8:
179 1
                $this->saveMultiPointRecord();
180 2
                break;
181 1
            case 28:
182 1
                $this->saveMultiPointMRecord();
183 1
                break;
184 1
            case 18:
185 1
                $this->saveMultiPointZRecord();
186
                break;
187
            default:
188
                $this->setError(sprintf('The Shape Type "%s" is not supported.', $this->shapeType));
189 12
                break;
190 12
        }
191
        if (ShapeFile::supportsDbase() && ! is_null($this->DBFFile)) {
192
            $this->saveDBFData();
193 12
        }
194
    }
195
196
    /**
197
     * Updates DBF data to match header.
198
     *
199
     * @param array $header DBF structure header
200 12
     */
201
    public function updateDBFInfo($header)
202 12
    {
203 12
        $tmp = $this->DBFData;
204 12
        unset($this->DBFData);
205 12
        $this->DBFData = [];
206 12
        foreach ($header as $value) {
207 12
            $this->DBFData[$value[0]] = (isset($tmp[$value[0]])) ? $tmp[$value[0]] : '';
208 12
        }
209
    }
210
211
    /**
212
     * Reads data.
213
     *
214
     * @param string $type  type for unpack()
215
     * @param int    $count number of bytes
216
     *
217
     * @return mixed
218 19
     */
219
    private function loadData($type, $count)
220 19
    {
221 19
        $data = $this->ShapeFile->readSHP($count);
222
        if ($data === false) {
223
            return false;
224 19
        }
225
        $this->read += strlen($data);
226 19
227
        return Util::loadData($type, $data);
228
    }
229
230
    /**
231
     * Loads metadata header from a file.
232 19
     */
233
    private function loadHeaders()
234 19
    {
235 19
        $this->shapeType = false;
236 19
        $this->recordNumber = $this->loadData('N', 4);
237 19
        if ($this->recordNumber === false) {
238
            return;
239
        }
240 19
        // We read the length of the record
241 19
        $this->size = $this->loadData('N', 4);
242
        if ($this->size === false) {
243
            return;
244 19
        }
245 19
        $this->size = $this->size * 2 + 8;
246 19
        $this->shapeType = $this->loadData('V', 4);
247
    }
248
249
    /**
250
     * Saves metadata header to a file.
251 12
     */
252
    private function saveHeaders()
253 12
    {
254 12
        fwrite($this->SHPFile, pack('N', $this->recordNumber));
255 12
        fwrite($this->SHPFile, pack('N', $this->getContentLength()));
256 12
        fwrite($this->SHPFile, pack('V', $this->shapeType));
257
    }
258 19
259
    private function loadPoint()
260 19
    {
261
        $data = [];
262 19
263 19
        $data['x'] = $this->loadData('d', 8);
264
        $data['y'] = $this->loadData('d', 8);
265 19
266
        return $data;
267
    }
268 1
269
    private function loadPointM()
270 1
    {
271
        $data = $this->loadPoint();
272 1
273
        $data['m'] = $this->loadData('d', 8);
274 1
275
        return $data;
276
    }
277 1
278
    private function loadPointZ()
279 1
    {
280
        $data = $this->loadPoint();
281 1
282 1
        $data['z'] = $this->loadData('d', 8);
283
        $data['m'] = $this->loadData('d', 8);
284 1
285
        return $data;
286
    }
287 10
288
    private function savePoint($data)
289 10
    {
290 10
        fwrite($this->SHPFile, Util::packDouble($data['x']));
291 10
        fwrite($this->SHPFile, Util::packDouble($data['y']));
292
    }
293 1
294
    private function savePointM($data)
295 1
    {
296 1
        fwrite($this->SHPFile, Util::packDouble($data['x']));
297 1
        fwrite($this->SHPFile, Util::packDouble($data['y']));
298 1
        fwrite($this->SHPFile, Util::packDouble($data['m']));
299
    }
300 1
301
    private function savePointZ($data)
302 1
    {
303 1
        fwrite($this->SHPFile, Util::packDouble($data['x']));
304 1
        fwrite($this->SHPFile, Util::packDouble($data['y']));
305 1
        fwrite($this->SHPFile, Util::packDouble($data['z']));
306 1
        fwrite($this->SHPFile, Util::packDouble($data['m']));
307
    }
308
309
    private function loadNullRecord()
310
    {
311
        $this->SHPData = [];
312
    }
313 4
314
    private function loadPointRecord()
315 4
    {
316 4
        $this->SHPData = $this->loadPoint();
317
    }
318 1
319
    private function loadPointMRecord()
320 1
    {
321 1
        $this->SHPData = $this->loadPointM();
322
    }
323 1
324
    private function loadPointZRecord()
325 1
    {
326 1
        $this->SHPData = $this->loadPointZ();
327
    }
328 1
329
    private function savePointRecord()
330 1
    {
331 1
        $this->savePoint($this->SHPData);
332
    }
333 1
334
    private function savePointMRecord()
335 1
    {
336 1
        $this->savePointM($this->SHPData);
337
    }
338 1
339
    private function savePointZRecord()
340 1
    {
341 1
        $this->savePointZ($this->SHPData);
342
    }
343 13
344
    private function loadBBox()
345 13
    {
346 13
        $this->SHPData['xmin'] = $this->loadData('d', 8);
347 13
        $this->SHPData['ymin'] = $this->loadData('d', 8);
348 13
        $this->SHPData['xmax'] = $this->loadData('d', 8);
349 13
        $this->SHPData['ymax'] = $this->loadData('d', 8);
350
    }
351 4
352
    private function loadMultiPointRecord()
353 4
    {
354 4
        $this->SHPData = [];
355
        $this->loadBBox();
356 4
357
        $this->SHPData['numpoints'] = $this->loadData('V', 4);
358 4
359 4
        for ($i = 0; $i < $this->SHPData['numpoints']; ++$i) {
360 4
            $this->SHPData['points'][] = $this->loadPoint();
361 4
        }
362
    }
363
364
    /**
365
     * @param string $type
366 3
     */
367
    private function loadMultiPointMZRecord($type)
368
    {
369 3
        /* The m dimension is optional, depends on bounding box data */
370 3
        if ($type == 'm' && ! $this->ShapeFile->hasMeasure()) {
371
            return;
372
        }
373 2
374 2
        $this->SHPData[$type . 'min'] = $this->loadData('d', 8);
375
        $this->SHPData[$type . 'max'] = $this->loadData('d', 8);
376 2
377 2
        for ($i = 0; $i < $this->SHPData['numpoints']; ++$i) {
378 2
            $this->SHPData['points'][$i][$type] = $this->loadData('d', 8);
379 2
        }
380
    }
381 1
382
    private function loadMultiPointMRecord()
383 1
    {
384
        $this->loadMultiPointRecord();
385 1
386 1
        $this->loadMultiPointMZRecord('m');
387
    }
388 2
389
    private function loadMultiPointZRecord()
390 2
    {
391
        $this->loadMultiPointRecord();
392 2
393 2
        $this->loadMultiPointMZRecord('z');
394 2
        $this->loadMultiPointMZRecord('m');
395
    }
396 3
397
    private function saveMultiPointRecord()
398 3
    {
399
        fwrite($this->SHPFile, pack('dddd', $this->SHPData['xmin'], $this->SHPData['ymin'], $this->SHPData['xmax'], $this->SHPData['ymax']));
400 3
401
        fwrite($this->SHPFile, pack('V', $this->SHPData['numpoints']));
402 3
403 3
        for ($i = 0; $i < $this->SHPData['numpoints']; ++$i) {
404 3
            $this->savePoint($this->SHPData['points'][$i]);
405 3
        }
406
    }
407
408
    /**
409
     * @param string $type
410 2
     */
411
    private function saveMultiPointMZRecord($type)
412 2
    {
413
        fwrite($this->SHPFile, pack('dd', $this->SHPData[$type . 'min'], $this->SHPData[$type . 'max']));
414 2
415 2
        for ($i = 0; $i < $this->SHPData['numpoints']; ++$i) {
416 2
            fwrite($this->SHPFile, Util::packDouble($this->SHPData['points'][$i][$type]));
417 2
        }
418
    }
419 1
420
    private function saveMultiPointMRecord()
421 1
    {
422
        $this->saveMultiPointRecord();
423 1
424 1
        $this->saveMultiPointMZRecord('m');
425
    }
426 1
427
    private function saveMultiPointZRecord()
428 1
    {
429
        $this->saveMultiPointRecord();
430 1
431 1
        $this->saveMultiPointMZRecord('z');
432 1
        $this->saveMultiPointMZRecord('m');
433
    }
434 9
435
    private function loadPolyLineRecord()
436 9
    {
437 9
        $this->SHPData = [];
438
        $this->loadBBox();
439 9
440 9
        $this->SHPData['numparts'] = $this->loadData('V', 4);
441
        $this->SHPData['numpoints'] = $this->loadData('V', 4);
442 9
443 9
        $numparts = $this->SHPData['numparts'];
444
        $numpoints = $this->SHPData['numpoints'];
445 9
446 9
        for ($i = 0; $i < $numparts; ++$i) {
447 9
            $this->SHPData['parts'][$i] = $this->loadData('V', 4);
448
        }
449 9
450 9
        $part = 0;
451 9
        for ($i = 0; $i < $numpoints; ++$i) {
452 8
            if ($part + 1 < $numparts && $i == $this->SHPData['parts'][$part + 1]) {
453 8
                ++$part;
454 9
            }
455 9
            if (! isset($this->SHPData['parts'][$part]['points']) || ! is_array($this->SHPData['parts'][$part]['points'])) {
456 9
                $this->SHPData['parts'][$part] = ['points' => []];
457 9
            }
458 9
            $this->SHPData['parts'][$part]['points'][] = $this->loadPoint();
459 9
        }
460
    }
461
462
    /**
463
     * @param string $type
464 5
     */
465
    private function loadPolyLineMZRecord($type)
466
    {
467 5
        /* The m dimension is optional, depends on bounding box data */
468 5
        if ($type == 'm' && ! $this->ShapeFile->hasMeasure()) {
469
            return;
470
        }
471 3
472 3
        $this->SHPData[$type . 'min'] = $this->loadData('d', 8);
473
        $this->SHPData[$type . 'max'] = $this->loadData('d', 8);
474 3
475 3
        $numparts = $this->SHPData['numparts'];
476
        $numpoints = $this->SHPData['numpoints'];
477 3
478 3
        $part = 0;
479 3
        for ($i = 0; $i < $numpoints; ++$i) {
480
            if ($part + 1 < $numparts && $i == $this->SHPData['parts'][$part + 1]) {
481
                ++$part;
482 3
            }
483 3
            $this->SHPData['parts'][$part]['points'][$i][$type] = $this->loadData('d', 8);
484 3
        }
485
    }
486 2
487
    private function loadPolyLineMRecord()
488 2
    {
489
        $this->loadPolyLineRecord();
490 2
491 2
        $this->loadPolyLineMZRecord('m');
492
    }
493 3
494
    private function loadPolyLineZRecord()
495 3
    {
496
        $this->loadPolyLineRecord();
497 3
498 3
        $this->loadPolyLineMZRecord('z');
499 3
        $this->loadPolyLineMZRecord('m');
500
    }
501 6
502
    private function savePolyLineRecord()
503 6
    {
504
        fwrite($this->SHPFile, pack('dddd', $this->SHPData['xmin'], $this->SHPData['ymin'], $this->SHPData['xmax'], $this->SHPData['ymax']));
505 6
506
        fwrite($this->SHPFile, pack('VV', $this->SHPData['numparts'], $this->SHPData['numpoints']));
507 6
508 6
        $part_index = 0;
509 6
        for ($i = 0; $i < $this->SHPData['numparts']; ++$i) {
510 6
            fwrite($this->SHPFile, pack('V', $part_index));
511 6
            $part_index += count($this->SHPData['parts'][$i]['points']);
512
        }
513 6
514 6
        foreach ($this->SHPData['parts'] as $partData) {
515 6
            foreach ($partData['points'] as $pointData) {
516 6
                $this->savePoint($pointData);
517 6
            }
518 6
        }
519
    }
520
521
    /**
522
     * @param string $type
523 4
     */
524
    private function savePolyLineMZRecord($type)
525 4
    {
526
        fwrite($this->SHPFile, pack('dd', $this->SHPData[$type . 'min'], $this->SHPData[$type . 'max']));
527 4
528 4
        foreach ($this->SHPData['parts'] as $partData) {
529 4
            foreach ($partData['points'] as $pointData) {
530 4
                fwrite($this->SHPFile, Util::packDouble($pointData[$type]));
531 4
            }
532 4
        }
533
    }
534 2
535
    private function savePolyLineMRecord()
536 2
    {
537
        $this->savePolyLineRecord();
538 2
539 2
        $this->savePolyLineMZRecord('m');
540
    }
541 2
542
    private function savePolyLineZRecord()
543 2
    {
544
        $this->savePolyLineRecord();
545 2
546 2
        $this->savePolyLineMZRecord('z');
547 2
        $this->savePolyLineMZRecord('m');
548
    }
549 3
550
    private function loadPolygonRecord()
551 3
    {
552 3
        $this->loadPolyLineRecord();
553
    }
554 1
555
    private function loadPolygonMRecord()
556 1
    {
557 1
        $this->loadPolyLineMRecord();
558
    }
559 2
560
    private function loadPolygonZRecord()
561 2
    {
562 2
        $this->loadPolyLineZRecord();
563
    }
564 1
565
    private function savePolygonRecord()
566 1
    {
567 1
        $this->savePolyLineRecord();
568
    }
569 1
570
    private function savePolygonMRecord()
571 1
    {
572 1
        $this->savePolyLineMRecord();
573
    }
574 1
575
    private function savePolygonZRecord()
576 1
    {
577 1
        $this->savePolyLineZRecord();
578
    }
579 12
580
    private function adjustBBox($point)
581
    {
582 12
        // Adjusts bounding box based on point
583 12
        $directions = [
584 12
            'x',
585 8
            'y',
586
            'z',
587 12
            'm',
588 12
        ];
589 12
        foreach ($directions as $direction) {
590 12
            if (! isset($point[$direction])) {
591 12
                continue;
592 12
            }
593 12
            $min = $direction . 'min';
594 12
            $max = $direction . 'max';
595 12
            if (! isset($this->SHPData[$min]) || ($this->SHPData[$min] > $point[$direction])) {
596 12
                $this->SHPData[$min] = $point[$direction];
597
            }
598
            if (! isset($this->SHPData[$max]) || ($this->SHPData[$max] < $point[$direction])) {
599
                $this->SHPData[$max] = $point[$direction];
600
            }
601
        }
602
    }
603
604
    /**
605
     * Sets dimension to 0 if not set.
606 8
     *
607
     * @param array  $point     Point to check
608 8
     * @param string $dimension Dimension to check
609 8
     *
610 8
     * @return array
611
     */
612 8
    private function fixPoint($point, $dimension)
613
    {
614
        if (! isset($point[$dimension])) {
615
            $point[$dimension] = 0.0; // no_value
616
        }
617
618
        return $point;
619
    }
620
621
    /**
622 12
     * Adjust point and bounding box when adding point.
623
     *
624 12
     * @param array $point Point data
625 12
     *
626 4
     * @return array Fixed point data
627 12
     */
628 4
    private function adjustPoint($point)
629 4
    {
630 4
        $type = $this->shapeType / 10;
631
        if ($type >= 2) {
632 12
            $point = $this->fixPoint($point, 'm');
633
        } elseif ($type >= 1) {
634
            $point = $this->fixPoint($point, 'z');
635
            $point = $this->fixPoint($point, 'm');
636
        }
637
638
        return $point;
639
    }
640
641 12
    /**
642
     * Adds point to a record.
643 12
     *
644 12
     * @param array $point     Point data
645 12
     * @param int   $partIndex Part index
646
     */
647
    public function addPoint($point, $partIndex = 0)
648 12
    {
649 12
        $point = $this->adjustPoint($point);
650 12
        switch ($this->shapeType) {
651
            case 0:
652 3
                //Don't add anything
653 3
                return;
654 9
            case 1:
655 9
            case 11:
656 9
            case 21:
657 9
                //Substitutes the value of the current point
658 9
                $this->SHPData = $point;
659 9
                break;
660
            case 3:
661 6
            case 5:
662 6
            case 13:
663 6
            case 15:
664 6
            case 23:
665 3
            case 25:
666 3
                //Adds a new point to the selected part
667 3
                $this->SHPData['parts'][$partIndex]['points'][] = $point;
668
                $this->SHPData['numparts'] = count($this->SHPData['parts']);
669 3
                $this->SHPData['numpoints'] = 1 + (isset($this->SHPData['numpoints']) ? $this->SHPData['numpoints'] : 0);
670 3
                break;
671 3
            case 8:
672
            case 18:
673
            case 28:
674
                //Adds a new point
675
                $this->SHPData['points'][] = $point;
676 12
                $this->SHPData['numpoints'] = 1 + (isset($this->SHPData['numpoints']) ? $this->SHPData['numpoints'] : 0);
677 12
                break;
678 12
            default:
679
                $this->setError(sprintf('The Shape Type "%s" is not supported.', $this->shapeType));
680
681
                return;
682
        }
683
        $this->adjustBBox($point);
684
    }
685
686 12
    /**
687
     * Deletes point from a record.
688 12
     *
689 12
     * @param int $pointIndex Point index
690
     * @param int $partIndex  Part index
691
     */
692 12
    public function deletePoint($pointIndex = 0, $partIndex = 0)
693 12
    {
694 12
        switch ($this->shapeType) {
695
            case 0:
696 3
                //Don't delete anything
697 3
                break;
698 3
            case 1:
699 2
            case 11:
700 2
            case 21:
701 3
                //Sets the value of the point to zero
702 1
                $this->SHPData['x'] = 0.0;
703 1
                $this->SHPData['y'] = 0.0;
704 3
                if (in_array($this->shapeType, [11, 21])) {
705 9
                    $this->SHPData['m'] = 0.0;
706 9
                }
707 9
                if (in_array($this->shapeType, [11])) {
708 9
                    $this->SHPData['z'] = 0.0;
709 9
                }
710 9
                break;
711
            case 3:
712 6
            case 5:
713 6
            case 13:
714 6
            case 15:
715 6
            case 23:
716 6
            case 25:
717 6
                //Deletes the point from the selected part, if exists
718
                if (isset($this->SHPData['parts'][$partIndex]) && isset($this->SHPData['parts'][$partIndex]['points'][$pointIndex])) {
719 6
                    $count = count($this->SHPData['parts'][$partIndex]['points']) - 1;
720 6
                    for ($i = $pointIndex; $i < $count; ++$i) {
721 6
                        $this->SHPData['parts'][$partIndex]['points'][$i] = $this->SHPData['parts'][$partIndex]['points'][$i + 1];
722 6
                    }
723 3
                    unset($this->SHPData['parts'][$partIndex]['points'][count($this->SHPData['parts'][$partIndex]['points']) - 1]);
724 3
725 3
                    $this->SHPData['numparts'] = count($this->SHPData['parts']);
726
                    --$this->SHPData['numpoints'];
727 3
                }
728 3
                break;
729 3
            case 8:
730 3
            case 18:
731 3
            case 28:
732 3
                //Deletes the point, if exists
733
                if (isset($this->SHPData['points'][$pointIndex])) {
734 3
                    $count = count($this->SHPData['points']) - 1;
735 3
                    for ($i = $pointIndex; $i < $count; ++$i) {
736 3
                        $this->SHPData['points'][$i] = $this->SHPData['points'][$i + 1];
737
                    }
738
                    unset($this->SHPData['points'][count($this->SHPData['points']) - 1]);
739
740 12
                    --$this->SHPData['numpoints'];
741 12
                }
742
                break;
743
            default:
744
                $this->setError(sprintf('The Shape Type "%s" is not supported.', $this->shapeType));
745
                break;
746
        }
747
    }
748 12
749
    /**
750
     * Returns length of content.
751
     *
752 12
     * @return int
753 12
     */
754
    public function getContentLength()
755
    {
756 12
        // The content length for a record is the length of the record contents section measured in 16-bit words.
757 1
        // one coordinate makes 4 16-bit words (64 bit double)
758 1
        switch ($this->shapeType) {
759 11
            case 0:
760 1
                $result = 0;
761 1
                break;
762 10
            case 1:
763 1
                $result = 10;
764 1
                break;
765 9
            case 21:
766 9
                $result = 10 + 4;
767 2
                break;
768 2
            case 11:
769 2
                $result = 10 + 8;
770 2
                break;
771 2
            case 3:
772 2
            case 5:
773 7
                $count = count($this->SHPData['parts']);
774 7
                $result = 22 + 2 * $count;
775 2
                for ($i = 0; $i < $count; ++$i) {
776 2
                    $result += 8 * count($this->SHPData['parts'][$i]['points']);
777 2
                }
778 2
                break;
779 2
            case 23:
780 2
            case 25:
781 5
                $count = count($this->SHPData['parts']);
782 5
                $result = 22 + (2 * 4) + 2 * $count;
783 2
                for ($i = 0; $i < $count; ++$i) {
784 2
                    $result += (8 + 4) * count($this->SHPData['parts'][$i]['points']);
785 2
                }
786 2
                break;
787 2
            case 13:
788 2
            case 15:
789 3
                $count = count($this->SHPData['parts']);
790 1
                $result = 22 + (4 * 4) + 2 * $count;
791 1
                for ($i = 0; $i < $count; ++$i) {
792 2
                    $result += (8 + 8) * count($this->SHPData['parts'][$i]['points']);
793 1
                }
794 1
                break;
795 1
            case 8:
796 1
                $result = 20 + 8 * count($this->SHPData['points']);
797 1
                break;
798
            case 28:
799
                $result = 20 + (2 * 4) + (8 + 4) * count($this->SHPData['points']);
800
                break;
801
            case 18:
802 12
                $result = 20 + (4 * 4) + (8 + 8) * count($this->SHPData['points']);
803
                break;
804 12
            default:
805
                $result = false;
806
                $this->setError(sprintf('The Shape Type "%s" is not supported.', $this->shapeType));
807
                break;
808
        }
809
810
        return $result;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $result could also return false which is incompatible with the documented return type integer. Did you maybe forget to handle an error condition?

If the returned type also contains false, it is an indicator that maybe an error condition leading to the specific return statement remains unhandled.

Loading history...
811
    }
812
813
    private function loadDBFData()
814
    {
815
        $this->DBFData = @dbase_get_record_with_names($this->DBFFile, $this->recordNumber);
0 ignored issues
show
Bug introduced by
The function dbase_get_record_with_names 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

815
        $this->DBFData = @/** @scrutinizer ignore-call */ dbase_get_record_with_names($this->DBFFile, $this->recordNumber);
Loading history...
816
        unset($this->DBFData['deleted']);
817
    }
818
819
    private function saveDBFData()
820
    {
821
        if (count($this->DBFData) == 0) {
822
            return;
823
        }
824
        unset($this->DBFData['deleted']);
825
        if ($this->recordNumber <= dbase_numrecords($this->DBFFile)) {
0 ignored issues
show
Bug introduced by
The function dbase_numrecords 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

825
        if ($this->recordNumber <= /** @scrutinizer ignore-call */ dbase_numrecords($this->DBFFile)) {
Loading history...
826
            if (! dbase_replace_record($this->DBFFile, array_values($this->DBFData), $this->recordNumber)) {
0 ignored issues
show
Bug introduced by
The function dbase_replace_record 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

826
            if (! /** @scrutinizer ignore-call */ dbase_replace_record($this->DBFFile, array_values($this->DBFData), $this->recordNumber)) {
Loading history...
827
                $this->setError('I wasn\'t possible to update the information in the DBF file.');
828
            }
829
        } else {
830
            if (! dbase_add_record($this->DBFFile, array_values($this->DBFData))) {
0 ignored issues
show
Bug introduced by
The function dbase_add_record 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

830
            if (! /** @scrutinizer ignore-call */ dbase_add_record($this->DBFFile, array_values($this->DBFData))) {
Loading history...
831
                $this->setError('I wasn\'t possible to add the information to the DBF file.');
832
            }
833
        }
834
    }
835
836
    /**
837
     * Sets error message.
838
     *
839
     * @param string $error
840
     */
841
    public function setError($error)
842
    {
843
        $this->lastError = $error;
844
    }
845 1
846
    /**
847 1
     * Returns shape name.
848
     *
849
     * @return string
850
     */
851
    public function getShapeName()
852
    {
853
        return Util::nameShape($this->shapeType);
854
    }
855
}
856