Completed
Push — master ( f2162d...33b4d1 )
by François
01:53
created

Parser::readExif()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 4
ccs 3
cts 3
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 0
crap 1
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 3
    public function __construct($resource)
90
    {
91 3
        $this->resource = $resource;
92 3
    }
93
94 1
    public function readExif()
95
    {
96 1
        $this->metadata['exif'] = exif_read_data($this->resource);
97 1
    }
98
99 1
    public function readIptc()
100
    {
101 1
        getimagesize($this->resource, $info);
102
103 1
        if (isset($info['APP13'])) {
104 1
            $data = iptcparse($info['APP13']);
105 1
            $map = $this->iptclabels;
106
107 1
            foreach ($data as $key => $value) {
108 1
                $newData[$map[$key]] = $value;
0 ignored issues
show
Coding Style Comprehensibility introduced by
$newData was never initialized. Although not strictly required by PHP, it is generally a good practice to add $newData = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
109 1
            }
110
111 1
            $this->metadata['iptc'] = $newData;
0 ignored issues
show
Bug introduced by
The variable $newData does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
112 1
        }
113 1
    }
114
115 1
    public function readXmp()
116
    {
117 1
        $loadxml = (new \DOMDocument())->loadXML($this->readXmpData());
118 1
        $this->metadata['xmp'] = $loadxml;
119 1
    }
120
121 1
    private function readXmpData($chunk_size = 10000)
122
    {
123 1
        $buffer = null;
124 1
        $file_pointer = fopen($this->resource, 'r');
125
126 1
        $chunk = fread($file_pointer, $chunk_size);
127 1
        $posStart = strpos($chunk, '<x:xmpmeta');
128 1
        if ($posStart !== false) {
129 1
            $buffer = substr($chunk, $posStart);
130 1
            $posEnd = strpos($buffer, '</x:xmpmeta>');
131 1
            $buffer = substr($buffer, 0, $posEnd + 12);
132 1
        }
133
134 1
        fclose($file_pointer);
135
136
        // recursion here
137 1
        if (!strpos($buffer, '</x:xmpmeta>')) {
138 1
            $buffer = $this->readXmpData($chunk_size * 2);
139 1
        }
140
141 1
        return $buffer;
142
    }
143
144 3
    public function getMetaData()
145
    {
146 3
        return $this->metadata;
147
    }
148
}
149