Reader   A
last analyzed

Complexity

Total Complexity 7

Size/Duplication

Total Lines 115
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 5

Importance

Changes 0
Metric Value
wmc 7
lcom 1
cbo 5
dl 0
loc 115
rs 10
c 0
b 0
f 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 15 1
A getMapper() 0 4 1
B getMetadataFromFile() 0 28 3
A getCliOutput() 0 21 2
1
<?php
2
/**
3
 * Reader which uses exiftool to read EXIF data
4
 *
5
 * @category    PHPExif
6
 * @copyright   Copyright (c) 2016 Tom Van Herreweghe <[email protected]>
7
 * @license     http://github.com/PHPExif/php-exif-exiftool/blob/master/LICENSE MIT License
8
 * @link        http://github.com/PHPExif/php-exif-exiftool for the canonical source repository
9
 * @package     Exiftool
10
 */
11
12
namespace PHPExif\Adapter\Native;
13
14
use PHPExif\Common\Adapter\MapperInterface;
15
use PHPExif\Common\Adapter\ReaderInterface;
16
use PHPExif\Common\Data\Exif;
17
use PHPExif\Common\Data\Iptc;
18
use PHPExif\Common\Data\Metadata;
19
use PHPExif\Common\Exception\Reader\NoExifDataException;
20
use \RuntimeException;
21
22
/**
23
 * Reader
24
 *
25
 * Reads EXIF data
26
 *
27
 * @category    PHPExif
28
 * @package     Exiftool
29
 */
30
final class Reader implements ReaderInterface
31
{
32
    const PATH = 'path';
33
    const BIN = 'binary';
34
35
    /**
36
     * @var MapperInterface
37
     */
38
    private $mapper;
39
40
    /**
41
     * @var string
42
     */
43
    private $binary;
44
45
    /**
46
     * @var bool
47
     */
48
    private $numeric = true;
49
50
    /**
51
     * @var string
52
     */
53
    private $path;
54
55
    /**
56
     * @param MapperInterface $mapper
57
     */
58
    public function __construct(
59
        MapperInterface $mapper,
60
        array $config = []
61
    ) {
62
        $defaults = [
63
            self::BIN => 'exiftool',
64
            self::PATH => '/usr/bin/env',
65
        ];
66
        $config = array_replace($defaults, $config);
67
68
        $this->binary = $config[self::BIN];
69
        $this->path = $config[self::PATH];
70
71
        $this->mapper = $mapper;
72
    }
73
74
    /**
75
     * {@inheritDoc}
76
     */
77
    public function getMapper()
78
    {
79
        return $this->mapper;
80
    }
81
82
    /**
83
     * {@inheritDoc}
84
     */
85
    public function getMetadataFromFile($filePath)
86
    {
87
        $result = $this->getCliOutput(
88
            sprintf(
89
                '%1$s%3$s -j -a -G1 -c %4$s %2$s',
90
                $this->path,
91
                escapeshellarg($filePath),
92
                $this->numeric ? ' -n' : '',
93
                escapeshellarg('%d deg %d\' %.4f"')
94
            )
95
        );
96
97
        $data = json_decode($result, true);
98
99
        if (false === $data) {
100
            throw NoExifDataException::fromFile($filePath);
101
        }
102
103
        // map the data:
104
        $mapper = $this->getMapper();
105
        $metadata = new Metadata(
106
            new Exif,
107
            new Iptc
108
        );
109
        $mapper->map($data, $metadata);
110
111
        return $metadata;
112
    }
113
114
    /**
115
     * Returns the output from given cli command
116
     *
117
     * @param string $command
118
     *
119
     * @throws RuntimeException If the command can't be executed
120
     *
121
     * @return string
122
     */
123
    protected function getCliOutput($command)
124
    {
125
        $descriptorspec = array(
126
            0 => array('pipe', 'r'),
127
            1 => array('pipe', 'w'),
128
            2 => array('pipe', 'a')
129
        );
130
        $process = proc_open($command, $descriptorspec, $pipes);
131
        if (!is_resource($process)) {
132
            throw new RuntimeException(
133
                'Could not open a resource to the exiftool binary'
134
            );
135
        }
136
        $result = stream_get_contents($pipes[1]);
137
        fclose($pipes[0]);
138
        fclose($pipes[1]);
139
        fclose($pipes[2]);
140
        proc_close($process);
141
142
        return $result;
143
    }
144
}
145