Passed
Push — master ( 7373ff...8b4303 )
by Hrvoje
02:19
created

GeoJsonRule::message()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 3

Importance

Changes 0
Metric Value
eloc 6
dl 0
loc 9
ccs 7
cts 7
cp 1
rs 10
c 0
b 0
f 0
cc 3
nc 3
nop 0
crap 3
1
<?php
2
3
declare(strict_types=1);
4
5
namespace YucaDoo\LaravelGeoJsonRule;
6
7
use GeoJson\GeoJson;
8
use GeoJson\Geometry\Polygon;
9
use Illuminate\Contracts\Validation\Rule;
10
use InvalidArgumentException;
11
use Throwable;
12
13
/**
14
 * RFC 7946 GeoJSON Format specification.
15
 */
16
class GeoJsonRule implements Rule
17
{
18
    /** @var string */
19
    private $geometryClass;
20
    /** @var Throwable */
21
    private $exception;
22
23
    /**
24
     * Constructor.
25
     * @param string|null $geometryClass Expected geometry.
26
     */
27 468
    public function __construct(?string $geometryClass = null)
28
    {
29 468
        $this->geometryClass = $geometryClass;
30 468
    }
31
32
    /**
33
     * Determine if the validation rule passes.
34
     *
35
     * @param string $attribute
36
     * @param mixed $value
37
     * @return bool
38
     */
39 468
    public function passes($attribute, $value)
40
    {
41
        try {
42 468
            if (is_string($value)) {
43
                // Handle undecoded JSON
44 465
                $value = json_decode($value);
45 465
                if (is_null($value)) {
46 3
                    throw new InvalidArgumentException('JSON is invalid');
47
                }
48
            }
49
            // An exception will be thrown if parsing fails
50 465
            $geometry = GeoJson::jsonUnserialize($value);
51 171
        } catch (Throwable $t) {
52 171
            $this->exception = $t;
53 171
            return false;
54
        }
55
        // Check geometry type if specified
56 297
        if (!empty($this->geometryClass)) {
57 252
            return get_class($geometry) === $this->geometryClass;
58
        }
59 45
        return true;
60
    }
61
62
    /**
63
     * Get the validation error message.
64
     *
65
     * @return string|array
66
     */
67 381
    public function message()
68
    {
69 381
        $message = 'The :attribute does not satisfy the RFC 7946 GeoJSON Format specification';
70 381
        if (!empty($this->exception)) {
71 171
            $message .= ' because ' . $this->exception->getMessage();
72 210
        } elseif (!empty($this->geometryClass)) {
73 210
            $message .= ' for ' . basename(str_replace('\\', '/', $this->geometryClass));
74
        }
75 381
        return $message;
76
    }
77
}
78