Completed
Push — master ( 8f9c53...27058f )
by Stephen
02:24 queued 01:11
created

Geometry::buildGeometryClassName()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 14
c 0
b 0
f 0
ccs 7
cts 7
cp 1
rs 9.7998
cc 3
nc 3
nop 1
crap 3
1
<?php
2
3
namespace Spinen\Geometry;
4
5
use Exception;
6
use geoPHP;
7
use Illuminate\Contracts\Foundation\Application;
8
use InvalidArgumentException;
9
use RuntimeException;
10
use Spinen\Geometry\Support\TypeMapper;
11
12
/**
13
 * Class Geometry
14
 *
15
 * @package Spinen\Geometry
16
 *
17
 * @method mixed parseEwkb(mixed $data) Parses data into EWKB format.
18
 * @method mixed parseEwkt(mixed $data) Parses data into EWKT format.
19
 * @method mixed parseGeoHash(mixed $data) Parses data into GeoHash format.
20
 * @method mixed parseGeoJson(mixed $data) Parses data into GeoJSON format.
21
 * @method mixed parseGeoRss(mixed $data) Parses data into GeoRSS format.
22
 * @method mixed parseGoogleGeocode(mixed $data) Parses data into GoogleGeocode format.
23
 * @method mixed parseGpx(mixed $data) Parses data into GPX format.
24
 * @method mixed parseJson(mixed $data) Parses data into GeoJSON format.
25
 * @method mixed parseKml(mixed $data) Parses data into KML format.
26
 * @method mixed parseWkb(mixed $data) Parses data into WKB format.
27
 * @method mixed parseWkt(mixed $data) Parses data into WKT format.
28
 */
29
class Geometry
30
{
31
    /**
32
     * The Laravel application.
33
     *
34
     * @var Application|null
35
     */
36
    protected $app;
37
38
    /**
39
     * Instance of geoPHP.
40
     *
41
     * @var geoPHP
42
     */
43
    protected $geoPhp;
44
45
    /**
46
     * Instance of TypeMapper.
47
     *
48
     * @var TypeMapper
49
     */
50
    protected $mapper;
51
52
    /**
53
     * Geometry constructor.
54
     *
55
     * @param geoPHP           $geoPhp
56
     * @param TypeMapper       $mapper
57
     * @param Application|null $app
58
     */
59 14
    public function __construct(geoPHP $geoPhp, TypeMapper $mapper, $app = null)
60
    {
61 14
        $this->geoPhp = $geoPhp;
62 14
        $this->mapper = $mapper;
63 14
        $this->app = $app;
64 14
    }
65
66
    /**
67
     * Magic method to allow methods that are not specifically defined.
68
     *
69
     * Allow parseStudlyCaseOfType i.e. parseWkt or parseGeoJson to be called & mapped to the load method.
70
     *
71
     * @param string $name Name of the undefined method
72
     * @param array  $arguments
73
     *
74
     * @return bool|\GeometryCollection|mixed
75
     * @throws RuntimeException
76
     */
77 10
    public function __call($name, $arguments)
78
    {
79
        // Sugar to make parse<Format>() work
80 10 View Code Duplication
        if (preg_match("/^parse([A-Z][A-z]*)/u", $name, $parts) && 1 === count($arguments)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
81 9
            return $this->parse($arguments[0], $parts[1]);
82
        }
83
84 1
        throw new RuntimeException(sprintf("Call to undefined method %s::%s().", __CLASS__, $name));
85
    }
86
87
    /**
88
     * Build the name to the proxy geometry class.
89
     *
90
     * @param $geometry
91
     *
92
     * @return string
93
     * @throws InvalidArgumentException|RuntimeException
94
     */
95 11
    public function buildGeometryClassName($geometry)
96
    {
97 11
        if (is_null($geometry)) {
98 1
            throw new InvalidArgumentException("The geometry object cannot be null when building the name to the proxy class.");
99
        }
100
101 10
        $class = __NAMESPACE__ . '\Geometries\\' . get_class($geometry);
102
103 10
        if (class_exists($class)) {
104 9
            return $class;
105
        }
106
107 1
        throw new RuntimeException(sprintf("There proxy class [%s] is not defined.", $class));
108
    }
109
110
    /**
111
     * Call geoPHP to load the data.
112
     *
113
     * @param string|object $data
114
     * @param string|null   $type
115
     *
116
     * @return bool|\GeometryCollection|mixed
117
     * @throws Exception
118
     */
119 10
    protected function loadGeometry($data, $type)
120
    {
121 10
        if (is_null($type)) {
122 1
            return $this->geoPhp->load($data);
123
        }
124
125 9
        return $this->geoPhp->load($data, $this->mapper->map($type));
126
    }
127
128
    /**
129
     * Pass the data to geoPHP to convert to the correct geometry type.
130
     *
131
     * @param string $data
132
     * @param string $type
133
     *
134
     * @return bool|\GeometryCollection|mixed
135
     * @throws Exception|InvalidArgumentException
136
     */
137 10
    public function parse($data, $type = null)
138
    {
139 10
        $geometry = $this->loadGeometry($data, $type);
140
141 10
        if (is_null($geometry)) {
142 1
            throw new InvalidArgumentException("Could not parse the supplied data.");
143
        }
144
145 9
        $geometry_class = $this->buildGeometryClassName($geometry);
146
147
        // If running in Laravel, then use the IoC
148 9
        if (!is_null($this->app)) {
149 1
            return $this->app->make($geometry_class, [$geometry, $this->mapper]);
150
        }
151
152 8
        return new $geometry_class($geometry, $this->mapper);
153
    }
154
}
155