1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Imparse; |
4
|
|
|
|
5
|
|
|
class Parser |
6
|
|
|
{ |
7
|
|
|
private $iptclabels = [ |
8
|
|
|
'1#000' => 'Model Version', |
9
|
|
|
'1#005' => 'Destination', |
10
|
|
|
'1#020' => 'File Format', |
11
|
|
|
'1#022' => 'File Format Version', |
12
|
|
|
'1#030' => 'Service Identifier', |
13
|
|
|
'1#040' => 'Envelope Number', |
14
|
|
|
'1#050' => 'Product I.D.', |
15
|
|
|
'1#060' => 'Envelope Priority', |
16
|
|
|
'1#070' => 'Date Sent', |
17
|
|
|
'1#080' => 'Time Sent', |
18
|
|
|
'1#090' => 'Coded Character Set', |
19
|
|
|
'1#100' => 'UNO', |
20
|
|
|
'1#120' => 'ARM Identifier', |
21
|
|
|
'1#122' => 'ARM Version', |
22
|
|
|
'2#000' => 'Record Version', |
23
|
|
|
'2#003' => 'Object Type Reference', |
24
|
|
|
'2#004' => 'Object Attribute Reference', |
25
|
|
|
'2#005' => 'Object Name', |
26
|
|
|
'2#007' => 'Edit Status', |
27
|
|
|
'2#008' => 'EditorialUpdate', |
28
|
|
|
'2#010' => 'Urgency', |
29
|
|
|
'2#012' => 'Subject Reference', |
30
|
|
|
'2#015' => 'Category', |
31
|
|
|
'2#020' => 'Supplemental Category', |
32
|
|
|
'2#022' => 'Fixture Identifier', |
33
|
|
|
'2#025' => 'Keywords', |
34
|
|
|
'2#026' => 'Content Location Code', |
35
|
|
|
'2#027' => 'Content Location Name', |
36
|
|
|
'2#030' => 'Release Date', |
37
|
|
|
'2#035' => 'Release Time', |
38
|
|
|
'2#037' => 'ExpirationDate', |
39
|
|
|
'2#038' => 'Expiration Time', |
40
|
|
|
'2#040' => 'Special Instructions', |
41
|
|
|
'2#042' => 'Action Advised', |
42
|
|
|
'2#045' => 'Reference Service', |
43
|
|
|
'2#047' => 'Reference Date', |
44
|
|
|
'2#050' => 'Reference Number', |
45
|
|
|
'2#055' => 'Date Created', |
46
|
|
|
'2#060' => 'Time Created', |
47
|
|
|
'2#062' => 'Digital Creation Date', |
48
|
|
|
'2#063' => 'Digital Creation Time', |
49
|
|
|
'2#065' => 'Originating Program', |
50
|
|
|
'2#070' => 'Program Version', |
51
|
|
|
'2#075' => 'Object Cycle', |
52
|
|
|
'2#080' => 'By-line', |
53
|
|
|
'2#085' => 'By-line Title', |
54
|
|
|
'2#090' => 'City', |
55
|
|
|
'2#092' => 'Sublocation', |
56
|
|
|
'2#095' => 'Province/State', |
57
|
|
|
'2#100' => 'Country/Primary Location Code', |
58
|
|
|
'2#101' => 'Country/Primary Location Name', |
59
|
|
|
'2#103' => 'Original Transmission Reference', |
60
|
|
|
'2#105' => 'Headline', |
61
|
|
|
'2#110' => 'Credit', |
62
|
|
|
'2#115' => 'Source', |
63
|
|
|
'2#116' => 'Copyright Notice', |
64
|
|
|
'2#118' => 'Contact', |
65
|
|
|
'2#120' => 'Caption/Abstract', |
66
|
|
|
'2#122' => 'Writer/Editor', |
67
|
|
|
'2#125' => 'Rasterized Caption', |
68
|
|
|
'2#130' => 'Image Type', |
69
|
|
|
'2#131' => 'Image Orientation', |
70
|
|
|
'2#135' => 'Language Identifier', |
71
|
|
|
'2#150' => 'Audio Type', |
72
|
|
|
'2#151' => 'Audio SamplingRate', |
73
|
|
|
'2#152' => 'Audio Sampling Resolution', |
74
|
|
|
'2#153' => 'Audio Duration', |
75
|
|
|
'2#154' => 'Audio Outcue', |
76
|
|
|
'2#200' => 'ObjectData Preview File Format', |
77
|
|
|
'2#201' => 'ObjectData Preview File Format Version', |
78
|
|
|
'2#202' => 'ObjectData Preview Data' |
79
|
|
|
]; |
80
|
|
|
|
81
|
|
|
private $metadata = array( |
82
|
|
|
'exif' => null, |
83
|
|
|
'iptc' => null, |
84
|
|
|
'xmp' => null |
85
|
|
|
); |
86
|
|
|
|
87
|
|
|
private $resource; |
88
|
|
|
|
89
|
|
|
private $file_pointer; |
90
|
|
|
|
91
|
3 |
|
public function __construct($resource) |
92
|
|
|
{ |
93
|
3 |
|
$this->resource = $resource; |
94
|
3 |
|
} |
95
|
|
|
|
96
|
1 |
|
public function readExif() |
97
|
|
|
{ |
98
|
1 |
|
$this->metadata['exif'] = exif_read_data($this->resource); |
99
|
1 |
|
} |
100
|
|
|
|
101
|
1 |
|
public function readIptc() |
102
|
|
|
{ |
103
|
1 |
|
getimagesize($this->resource, $info); |
104
|
|
|
|
105
|
1 |
|
if (isset($info['APP13'])) { |
106
|
1 |
|
$iptc = iptcparse($info['APP13']); |
107
|
1 |
|
$map = $this->iptclabels; |
108
|
|
|
|
109
|
1 |
|
if ($iptc) { |
|
|
|
|
110
|
1 |
|
$data = []; |
111
|
|
|
|
112
|
1 |
|
foreach ($iptc as $key => $value) { |
113
|
1 |
|
$data[$map[$key]] = $value; |
114
|
1 |
|
} |
115
|
|
|
|
116
|
1 |
|
$this->metadata['iptc'] = $data; |
117
|
1 |
|
} |
118
|
1 |
|
} |
119
|
1 |
|
} |
120
|
|
|
|
121
|
1 |
|
public function readXmp() |
122
|
|
|
{ |
123
|
1 |
|
$xml = $this->readXmpData(); |
124
|
1 |
|
if ($xml !== null) { |
125
|
1 |
|
$xml = (new \DOMDocument())->loadXML($xml); |
126
|
|
|
} |
127
|
|
|
$this->metadata['xmp'] = $xml; |
128
|
|
|
} |
129
|
|
|
|
130
|
1 |
|
private function readXmpData($chunk_size = 1024) |
131
|
|
|
{ |
132
|
1 |
|
if ($this->file_pointer === null) { |
133
|
1 |
|
$this->file_pointer = fopen($this->resource, 'r'); |
134
|
1 |
|
} |
135
|
|
|
|
136
|
1 |
|
$buffer = $this->extractXmpChunk($chunk_size); |
137
|
|
|
|
138
|
1 |
|
fclose($this->file_pointer); |
139
|
|
|
|
140
|
1 |
|
return $buffer; |
141
|
|
|
} |
142
|
|
|
|
143
|
1 |
|
private function extractXmpChunk($chunk_size) |
144
|
|
|
{ |
145
|
1 |
|
$buffer = null; |
146
|
|
|
|
147
|
|
|
do { |
148
|
1 |
|
$chunk = fread($this->file_pointer, $chunk_size); |
149
|
|
|
|
150
|
1 |
|
$eof = feof($this->file_pointer); |
151
|
1 |
|
$posStart = strpos($chunk, '<x:xmpmeta'); |
152
|
|
|
|
153
|
1 |
|
if ($buffer !== null) { |
154
|
1 |
|
$buffer += $chunk; |
155
|
1 |
|
} else if ($posStart !== false) { |
156
|
1 |
|
$buffer = substr($chunk, $posStart); |
157
|
1 |
|
} |
158
|
|
|
|
159
|
1 |
|
$posEnd = strpos($buffer, '</x:xmpmeta>'); |
160
|
1 |
|
if ($posEnd) { |
161
|
|
|
$buffer = substr($buffer, 0, $posEnd + 12); |
162
|
|
|
} |
163
|
1 |
|
} while (!$eof); |
164
|
|
|
|
165
|
1 |
|
return $buffer; |
166
|
|
|
} |
167
|
|
|
|
168
|
2 |
|
public function getMetaData() |
169
|
|
|
{ |
170
|
2 |
|
return $this->metadata; |
171
|
|
|
} |
172
|
|
|
} |
173
|
|
|
|
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)
or! empty(...)
instead.