236 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			236 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?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;
 | |
|     }
 | |
| }
 |