first commit

This commit is contained in:
root
2020-02-19 16:42:35 +01:00
commit d668d90f82
2224 changed files with 334338 additions and 0 deletions

View File

@ -0,0 +1,132 @@
<?php
/**
* PHP Exif Reader Adapter Abstract: Common functionality for adapters
*
* @link http://github.com/miljar/PHPExif for the canonical source repository
* @copyright Copyright (c) 2013 Tom Van Herreweghe <tom@theanalogguy.be>
* @license http://github.com/miljar/PHPExif/blob/master/LICENSE MIT License
* @category PHPExif
* @package Reader
*/
namespace PHPExif\Adapter;
use PHPExif\Mapper\MapperInterface;
use PHPExif\Hydrator\HydratorInterface;
/**
* PHP Exif Reader Adapter Abstract
*
* Implements common functionality for the reader adapters
*
* @category PHPExif
* @package Reader
*/
abstract class AdapterAbstract implements AdapterInterface
{
/**
* @var string
*/
protected $hydratorClass = '\\PHPExif\\Hydrator\\Mutator';
/**
* @var \PHPExif\Mapper\MapperInterface
*/
protected $mapper;
/**
* @var \PHPExif\Hydrator\HydratorInterface
*/
protected $hydrator;
/**
* @var string
*/
protected $mapperClass = '';
/**
* Class constructor
*
* @param array $options Optional array of data to initialize the object with
*/
public function __construct(array $options = array())
{
if (!empty($options)) {
$this->setOptions($options);
}
}
/**
* Mutator for the data mapper
*
* @param \PHPExif\Mapper\MapperInterface $mapper
* @return \PHPExif\Adapter\AdapterInterface
*/
public function setMapper(MapperInterface $mapper)
{
$this->mapper = $mapper;
return $this;
}
/**
* Accessor for the data mapper
*
* @return \PHPExif\Mapper\MapperInterface
*/
public function getMapper()
{
if (null === $this->mapper) {
// lazy load one
$mapper = new $this->mapperClass;
$this->setMapper($mapper);
}
return $this->mapper;
}
/**
* Mutator for the hydrator
*
* @param \PHPExif\Hydrator\HydratorInterface $hydrator
* @return \PHPExif\Adapter\AdapterInterface
*/
public function setHydrator(HydratorInterface $hydrator)
{
$this->hydrator = $hydrator;
return $this;
}
/**
* Accessor for the data hydrator
*
* @return \PHPExif\Hydrator\HydratorInterface
*/
public function getHydrator()
{
if (null === $this->hydrator) {
// lazy load one
$hydrator = new $this->hydratorClass;
$this->setHydrator($hydrator);
}
return $this->hydrator;
}
/**
* Set array of options in the current object
*
* @param array $options
* @return \PHPExif\Reader\AdapterAbstract
*/
public function setOptions(array $options)
{
$hydrator = $this->getHydrator();
$hydrator->hydrate($this, $options);
return $this;
}
}

View File

@ -0,0 +1,33 @@
<?php
/**
* PHP Exif Reader Adapter Interface: Defines the interface for reader adapters
*
* @link http://github.com/miljar/PHPExif for the canonical source repository
* @copyright Copyright (c) 2013 Tom Van Herreweghe <tom@theanalogguy.be>
* @license http://github.com/miljar/PHPExif/blob/master/LICENSE MIT License
* @category PHPExif
* @package Reader
* @codeCoverageIgnore
*/
namespace PHPExif\Adapter;
/**
* PHP Exif Reader Adapter
*
* Defines the interface for reader adapters
*
* @category PHPExif
* @package Reader
*/
interface AdapterInterface
{
/**
* Reads & parses the EXIF data from given file
*
* @param string $file
* @return \PHPExif\Exif Instance of Exif object with data
* @throws \RuntimeException If the EXIF data could not be read
*/
public function getExifFromFile($file);
}

View File

@ -0,0 +1,202 @@
<?php
/**
* PHP Exif Exiftool Reader Adapter
*
* @link http://github.com/miljar/PHPExif for the canonical source repository
* @copyright Copyright (c) 2013 Tom Van Herreweghe <tom@theanalogguy.be>
* @license http://github.com/miljar/PHPExif/blob/master/LICENSE MIT License
* @category PHPExif
* @package Reader
*/
namespace PHPExif\Adapter;
use PHPExif\Exif;
use InvalidArgumentException;
use RuntimeException;
/**
* PHP Exif Exiftool Reader Adapter
*
* Uses native PHP functionality to read data from a file
*
* @category PHPExif
* @package Reader
*/
class Exiftool extends AdapterAbstract
{
const TOOL_NAME = 'exiftool';
/**
* Path to the exiftool binary
*
* @var string
*/
protected $toolPath;
/**
* @var boolean
*/
protected $numeric = true;
/**
* @var array
*/
protected $encoding = array();
/**
* @var string
*/
protected $mapperClass = '\\PHPExif\\Mapper\\Exiftool';
/**
* Setter for the exiftool binary path
*
* @param string $path The path to the exiftool binary
* @return \PHPExif\Adapter\Exiftool Current instance
* @throws \InvalidArgumentException When path is invalid
*/
public function setToolPath($path)
{
if (!file_exists($path)) {
throw new InvalidArgumentException(
sprintf(
'Given path (%1$s) to the exiftool binary is invalid',
$path
)
);
}
$this->toolPath = $path;
return $this;
}
/**
* @param boolean $numeric
*/
public function setNumeric($numeric)
{
$this->numeric = $numeric;
}
/**
* @see http://www.sno.phy.queensu.ca/~phil/exiftool/faq.html#Q10
* @param array $encoding encoding parameters in an array eg. ["exif" => "UTF-8"]
*/
public function setEncoding($encoding)
{
$possible_keys = array("exif", "iptc", "id3", "photoshop", "quicktime",);
$possible_values = array("UTF8", "cp65001", "UTF-8", "Thai", "cp874", "Latin", "cp1252",
"Latin1", "MacRoman", "cp10000", "Mac", "Roman", "Latin2", "cp1250", "MacLatin2",
"cp10029", "Cyrillic", "cp1251", "Russian", "MacCyrillic", "cp10007", "Greek",
"cp1253", "MacGreek", "cp10006", "Turkish", "cp1254", "MacTurkish", "cp10081",
"Hebrew", "cp1255", "MacRomanian", "cp10010", "Arabic", "cp1256", "MacIceland",
"cp10079", "Baltic", "cp1257", "MacCroatian", "cp10082", "Vietnam", "cp1258",);
foreach ($encoding as $type => $encoding) {
if (in_array($type, $possible_keys) && in_array($encoding, $possible_values)) {
$this->encoding[$type] = $encoding;
}
}
}
/**
* Getter for the exiftool binary path
* Lazy loads the "default" path
*
* @return string
*/
public function getToolPath()
{
if (empty($this->toolPath)) {
$path = exec('which ' . self::TOOL_NAME);
$this->setToolPath($path);
}
return $this->toolPath;
}
/**
* Reads & parses the EXIF data from given file
*
* @param string $file
* @return \PHPExif\Exif Instance of Exif object with data
* @throws \RuntimeException If the EXIF data could not be read
*/
public function getExifFromFile($file)
{
$encoding = '';
if (!empty($this->encoding)) {
$encoding = '-charset ';
foreach ($this->encoding as $key => $value) {
$encoding .= escapeshellarg($key).'='.escapeshellarg($value);
}
}
$result = $this->getCliOutput(
sprintf(
'%1$s%3$s -j -a -G1 %5$s -c %4$s %2$s',
$this->getToolPath(),
escapeshellarg($file),
$this->numeric ? ' -n' : '',
escapeshellarg('%d deg %d\' %.4f"'),
$encoding
)
);
if (!mb_check_encoding($result, "utf-8")) {
$result = utf8_encode($result);
}
$data = json_decode($result, true);
if (!is_array($data)) {
throw new RuntimeException(
'Could not decode exiftool output'
);
}
// map the data:
$mapper = $this->getMapper();
$mapper->setNumeric($this->numeric);
$mappedData = $mapper->mapRawData(reset($data));
// hydrate a new Exif object
$exif = new Exif();
$hydrator = $this->getHydrator();
$hydrator->hydrate($exif, $mappedData);
$exif->setRawData(reset($data));
return $exif;
}
/**
* Returns the output from given cli command
*
* @param string $command
* @return mixed
* @throws RuntimeException If the command can't be executed
*/
protected function getCliOutput($command)
{
$descriptorspec = array(
0 => array('pipe', 'r'),
1 => array('pipe', 'w'),
2 => array('pipe', 'a')
);
$process = proc_open($command, $descriptorspec, $pipes);
if (!is_resource($process)) {
throw new RuntimeException(
'Could not open a resource to the exiftool binary'
);
}
$result = stream_get_contents($pipes[1]);
fclose($pipes[0]);
fclose($pipes[1]);
fclose($pipes[2]);
proc_close($process);
return $result;
}
}

View File

@ -0,0 +1,235 @@
<?php
/**
* PHP Exif Native Reader Adapter
*
* @link http://github.com/miljar/PHPExif for the canonical source repository
* @copyright Copyright (c) 2013 Tom Van Herreweghe <tom@theanalogguy.be>
* @license http://github.com/miljar/PHPExif/blob/master/LICENSE MIT License
* @category PHPExif
* @package Reader
*/
namespace PHPExif\Adapter;
use PHPExif\Exif;
/**
* PHP Exif Native Reader Adapter
*
* Uses native PHP functionality to read data from a file
*
* @category PHPExif
* @package Reader
*/
class Native extends AdapterAbstract
{
const INCLUDE_THUMBNAIL = true;
const NO_THUMBNAIL = false;
const SECTIONS_AS_ARRAYS = true;
const SECTIONS_FLAT = false;
const SECTION_FILE = 'FILE';
const SECTION_COMPUTED = 'COMPUTED';
const SECTION_IFD0 = 'IFD0';
const SECTION_THUMBNAIL = 'THUMBNAIL';
const SECTION_COMMENT = 'COMMENT';
const SECTION_EXIF = 'EXIF';
const SECTION_ALL = 'ANY_TAG';
const SECTION_IPTC = 'IPTC';
/**
* List of EXIF sections
*
* @var array
*/
protected $requiredSections = array();
/**
* Include the thumbnail in the EXIF data?
*
* @var boolean
*/
protected $includeThumbnail = self::NO_THUMBNAIL;
/**
* Parse the sections as arrays?
*
* @var boolean
*/
protected $sectionsAsArrays = self::SECTIONS_FLAT;
/**
* @var string
*/
protected $mapperClass = '\\PHPExif\\Mapper\\Native';
/**
* Contains the mapping of names to IPTC field numbers
*
* @var array
*/
protected $iptcMapping = array(
'title' => '2#005',
'keywords' => '2#025',
'copyright' => '2#116',
'caption' => '2#120',
'headline' => '2#105',
'credit' => '2#110',
'source' => '2#115',
'jobtitle' => '2#085'
);
/**
* Getter for the EXIF sections
*
* @return array
*/
public function getRequiredSections()
{
return $this->requiredSections;
}
/**
* Setter for the EXIF sections
*
* @param array $sections List of EXIF sections
* @return \PHPExif\Adapter\Native Current instance for chaining
*/
public function setRequiredSections(array $sections)
{
$this->requiredSections = $sections;
return $this;
}
/**
* Adds an EXIF section to the list
*
* @param string $section
* @return \PHPExif\Adapter\Native Current instance for chaining
*/
public function addRequiredSection($section)
{
if (!in_array($section, $this->requiredSections)) {
array_push($this->requiredSections, $section);
}
return $this;
}
/**
* Define if the thumbnail should be included into the EXIF data or not
*
* @param boolean $value
* @return \PHPExif\Adapter\Native Current instance for chaining
*/
public function setIncludeThumbnail($value)
{
$this->includeThumbnail = $value;
return $this;
}
/**
* Returns if the thumbnail should be included into the EXIF data or not
*
* @return boolean
*/
public function getIncludeThumbnail()
{
return $this->includeThumbnail;
}
/**
* Define if the sections should be parsed as arrays
*
* @param boolean $value
* @return \PHPExif\Adapter\Native Current instance for chaining
*/
public function setSectionsAsArrays($value)
{
$this->sectionsAsArrays = (bool) $value;
return $this;
}
/**
* Returns if the sections should be parsed as arrays
*
* @return boolean
*/
public function getSectionsAsArrays()
{
return $this->sectionsAsArrays;
}
/**
* Reads & parses the EXIF data from given file
*
* @param string $file
* @return \PHPExif\Exif|boolean Instance of Exif object with data
*/
public function getExifFromFile($file)
{
$sections = $this->getRequiredSections();
$sections = implode(',', $sections);
$sections = (empty($sections)) ? null : $sections;
$data = @exif_read_data(
$file,
$sections,
$this->getSectionsAsArrays(),
$this->getIncludeThumbnail()
);
if (false === $data) {
return false;
}
$xmpData = $this->getIptcData($file);
$data = array_merge($data, array(self::SECTION_IPTC => $xmpData));
// map the data:
$mapper = $this->getMapper();
$mappedData = $mapper->mapRawData($data);
// hydrate a new Exif object
$exif = new Exif();
$hydrator = $this->getHydrator();
$hydrator->hydrate($exif, $mappedData);
$exif->setRawData($data);
return $exif;
}
/**
* Returns an array of IPTC data
*
* @param string $file The file to read the IPTC data from
* @return array
*/
public function getIptcData($file)
{
getimagesize($file, $info);
$arrData = array();
if (isset($info['APP13'])) {
$iptc = iptcparse($info['APP13']);
foreach ($this->iptcMapping as $name => $field) {
if (!isset($iptc[$field])) {
continue;
}
if (count($iptc[$field]) === 1) {
$arrData[$name] = reset($iptc[$field]);
} else {
$arrData[$name] = $iptc[$field];
}
}
}
return $arrData;
}
}

View File

@ -0,0 +1,28 @@
<?php
/**
* PHP Exif Reader Adapter Interface: Defines the interface for reader adapters
*
* @link http://github.com/miljar/PHPExif for the canonical source repository
* @copyright Copyright (c) 2013 Tom Van Herreweghe <tom@theanalogguy.be>
* @license http://github.com/miljar/PHPExif/blob/master/LICENSE MIT License
* @category PHPExif
* @package Reader
* @codeCoverageIgnore
*/
namespace PHPExif\Adapter;
use Exception;
/**
* PHP Exif Reader Adapter
*
* Defines the interface for reader adapters
*
* @category PHPExif
* @package Reader
*/
class NoAdapterException extends Exception
{
//empty
}