ExifParser   A
last analyzed

Complexity

Total Complexity 39

Size/Duplication

Total Lines 239
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 1
Metric Value
eloc 72
c 2
b 0
f 1
dl 0
loc 239
rs 9.28
wmc 39

22 Methods

Rating   Name   Duplication   Size   Complexity  
F getGPS() 0 33 15
A toArray() 0 28 1
A gps2Num() 0 11 3
A getLensSerialNumber() 0 3 1
A getShutterSpeed() 0 3 1
A getLensSpecification() 0 3 1
A __construct() 0 6 2
A getResolutionX() 0 3 1
A getSoftware() 0 3 1
A getApertureValue() 0 3 1
A getMake() 0 3 1
A getModel() 0 3 1
A getLensModel() 0 3 1
A getCameraSerialNumber() 0 3 1
A getFlash() 0 3 1
A getExposure() 0 3 1
A getFocalLength() 0 3 1
A getExposureCompensation() 0 3 1
A getISO() 0 3 1
A getResolutionY() 0 3 1
A getCameraOwnerName() 0 3 1
A getMeteringMode() 0 3 1
1
<?php
2
3
namespace Jackal\ImageMerge\Metadata\Parser;
4
5
use Jackal\ImageMerge\Exception\ModuleNotFoundException;
6
use Jackal\ImageMerge\Model\File\FileObjectInterface;
7
8
/**
9
 * Class ExifParser
10
 * @package Jackal\ImageMerge\Metadata\Parser
11
 */
12
class ExifParser extends AbstractParser
13
{
14
    /**
15
     * ExifParser constructor.
16
     * @param FileObjectInterface $file
17
     * @throws ModuleNotFoundException
18
     */
19
    public function __construct(FileObjectInterface $file)
20
    {
21
        if (!function_exists('exif_read_data')) {
22
            throw new ModuleNotFoundException('function exif_read_data not installed');
23
        }
24
        $this->data = @exif_read_data($file->getPathname());
25
    }
26
27
    /**
28
     * @return null|string
29
     */
30
    public function getMake()
31
    {
32
        return $this->getSingleValue('Make');
33
    }
34
35
    /**
36
     * @return null|string
37
     */
38
    public function getModel()
39
    {
40
        return $this->getSingleValue('Model');
41
    }
42
43
    /**
44
     * @return null|string
45
     */
46
    public function getExposure()
47
    {
48
        return $this->getSingleValue('ExposureTime');
49
    }
50
51
    /**
52
     * @return bool|null
53
     */
54
    public function getFlash()
55
    {
56
        return $this->getBooleanValue('Flash');
57
    }
58
59
    /**
60
     * @return null|string
61
     */
62
    public function getISO()
63
    {
64
        return $this->getSingleValue('ISOSpeedRatings');
65
    }
66
67
    /**
68
     * @return int|string
69
     */
70
    public function getResolutionX()
71
    {
72
        return $this->getDivisionValue('XResolution');
73
    }
74
75
    /**
76
     * @return int|string
77
     */
78
    public function getResolutionY()
79
    {
80
        return $this->getDivisionValue('YResolution');
81
    }
82
83
    /**
84
     * @return int|string
85
     */
86
    public function getFocalLength()
87
    {
88
        return $this->getDivisionValue('FocalLength');
89
    }
90
91
    /**
92
     * @return null|string
93
     */
94
    public function getSoftware()
95
    {
96
        return $this->getSingleValue('Software');
97
    }
98
99
    /**
100
     * @return null|string
101
     */
102
    public function getLensModel()
103
    {
104
        return $this->getSingleValue('UndefinedTag:0xA434');
105
    }
106
107
    /**
108
     * @return null|string
109
     */
110
    public function getCameraSerialNumber()
111
    {
112
        return $this->getSingleValue('UndefinedTag:0xA431');
113
    }
114
115
    /**
116
     * @return null|string
117
     */
118
    public function getLensSerialNumber()
119
    {
120
        return $this->getSingleValue('UndefinedTag:0xA435');
121
    }
122
123
    /**
124
     * @return null|string
125
     */
126
    public function getCameraOwnerName()
127
    {
128
        return $this->getSingleValue('UndefinedTag:0xA430');
129
    }
130
131
    /**
132
     * @return null|string
133
     */
134
    public function getLensSpecification()
135
    {
136
        return $this->getValue('UndefinedTag:0xA432');
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getValue('UndefinedTag:0xA432') also could return the type array which is incompatible with the documented return type null|string.
Loading history...
137
    }
138
139
    /**
140
     * @return null|string
141
     */
142
    public function getExposureCompensation()
143
    {
144
        return $this->getSingleValue('ExposureBiasValue');
145
    }
146
147
    /**
148
     * @return int|string
149
     */
150
    public function getApertureValue()
151
    {
152
        return $this->getDivisionValue('FNumber');
153
    }
154
155
    /**
156
     * @return null|string
157
     */
158
    public function getMeteringMode()
159
    {
160
        return $this->getSingleValue('MeteringMode');
161
    }
162
163
    /**
164
     * @return null|string
165
     */
166
    public function getShutterSpeed()
167
    {
168
        return $this->getSingleValue('ExposureTime');
169
    }
170
171
    public function getGPS()
172
    {
173
174
        /**
175
         * Taken from https://www.codexworld.com/get-geolocation-latitude-longitude-from-image-php/
176
         */
177
        $GPSLatitudeRef = $this->getValue('GPSLatitudeRef');
178
        $GPSLatitude = $this->getValue('GPSLatitude') ? $this->getValue('GPSLatitude') : [];
179
        $GPSLongitudeRef = $this->getValue('GPSLongitudeRef');
180
        $GPSLongitude = $this->getValue('GPSLongitude') ? $this->getValue('GPSLongitude') : [];
181
182
        $lat_degrees = count($GPSLatitude) > 0 ? $this->gps2Num($GPSLatitude[0]) : 0;
0 ignored issues
show
Bug introduced by
It seems like $GPSLatitude can also be of type string; however, parameter $var of count() does only seem to accept Countable|array, 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

182
        $lat_degrees = count(/** @scrutinizer ignore-type */ $GPSLatitude) > 0 ? $this->gps2Num($GPSLatitude[0]) : 0;
Loading history...
183
        $lat_minutes = count($GPSLatitude) > 1 ? $this->gps2Num($GPSLatitude[1]) : 0;
184
        $lat_seconds = count($GPSLatitude) > 2 ? $this->gps2Num($GPSLatitude[2]) : 0;
185
186
        $lon_degrees = count($GPSLongitude) > 0 ? $this->gps2Num($GPSLongitude[0]) : 0;
187
        $lon_minutes = count($GPSLongitude) > 1 ? $this->gps2Num($GPSLongitude[1]) : 0;
188
        $lon_seconds = count($GPSLongitude) > 2 ? $this->gps2Num($GPSLongitude[2]) : 0;
189
190
        $lat_direction = ($GPSLatitudeRef == 'W' or $GPSLatitudeRef == 'S') ? -1 : 1;
191
        $lon_direction = ($GPSLongitudeRef == 'W' or $GPSLongitudeRef == 'S') ? -1 : 1;
192
193
        $latitude = $lat_direction * ($lat_degrees + ($lat_minutes / 60) + ($lat_seconds / (60 * 60)));
194
        $longitude = $lon_direction * ($lon_degrees + ($lon_minutes / 60) + ($lon_seconds / (60 * 60)));
195
196
        $latitude_deg = sprintf('%s°%s\'%s" %s', $lat_degrees, $lat_minutes, $lat_seconds, $lat_direction == 1 ? 'N':'S');
197
        $longitude_deg = sprintf('%s°%s\'%s" %s', $lon_degrees, $lon_minutes, $lon_seconds, $lon_direction == 1 ? 'E':'W');
198
199
        return [
200
            'lat' => $latitude,
201
            'lon' => $longitude,
202
            'lat_deg' => $latitude_deg,
203
            'lon_deg' => $longitude_deg,
204
        ];
205
    }
206
207
    private function gps2Num($coordPart)
208
    {
209
        $parts = explode('/', $coordPart);
210
        if (count($parts) <= 0) {
211
            return 0;
212
        }
213
        if (count($parts) == 1) {
214
            return $parts[0];
215
        }
216
217
        return floatval($parts[0]) / floatval($parts[1]);
218
    }
219
220
    /**
221
     * @return array
222
     */
223
    public function toArray()
224
    {
225
        return [
226
            'gps' => $this->getGPS(),
227
            'camera' => [
228
                'make' => $this->getMake(),
229
                'model' => $this->getModel(),
230
                'serial_number' => $this->getCameraSerialNumber(),
231
                'owner' => $this->getCameraOwnerName(),
232
            ],
233
            'exposure' => $this->getExposure(),
234
            'exposure_compensation' => $this->getExposureCompensation(),
235
            'flash' => $this->getFlash(),
236
            'iso' => $this->getISO(),
237
            'resolution' => [
238
                'x' => $this->getResolutionX(),
239
                'y' => $this->getResolutionY(),
240
            ],
241
            'focal_length' => $this->getFocalLength(),
242
            'software' => $this->getSoftware(),
243
            'lens' => [
244
                'model' => $this->getLensModel(),
245
                'serial_number' => $this->getLensSerialNumber(),
246
                'specification' => $this->getLensSpecification(),
247
            ],
248
            'aperture' => $this->getApertureValue(),
249
            'metering' => $this->getMeteringMode(),
250
            'shutter' => $this->getShutterSpeed(),
251
        ];
252
    }
253
}
254