oDb = &$oDb; $this->oProject = &$oProject; } public function getPicsInfo() { if(empty($this->asPics)) { if($this->oProject->getProjectId()) { $asPics = $this->oDb->selectRows(array( 'select' => array(Db::getId(self::PIC_TABLE), 'filename', 'taken_on', 'timestamp AS added_on', 'rotate'), 'from' => self::PIC_TABLE, 'constraint'=> array(Db::getId(Project::PROJ_TABLE) => $this->oProject->getProjectId()) )); foreach($asPics as &$asPic) { $asPic['pic_path'] = self::getPicPath($asPic['filename']); $asPic['thumb_path'] = self::getPicThumbnail($asPic['filename']); } $this->asPics = $asPics; } } return $this->asPics; } public function isProjectModeValid() { return ($this->oProject->getMode() == Project::MODE_BLOG); } public function addPic($sPicName, $sMethod='upload') { $sError = ''; if(!$this->isProjectModeValid() && $sMethod!='sync') $sError = 'Le projet (id='.$this->oProject->getProjectId().') n\'est pas en mode "blog"'; elseif($this->oDb->pingValue(self::PIC_TABLE, array('filename'=>$sPicName))) $sError = 'l\'image existe déjà'; else { //Add picture to DB $asPicInfo = self::getPicInfo($sPicName); $iPicId = $this->oDb->insertRow(self::PIC_TABLE, array( Db::getId(Project::PROJ_TABLE) => $this->oProject->getProjectId(), 'filename' => $sPicName, 'taken_on' => date(Db::TIMESTAMP_FORMAT, $asPicInfo['taken_ts']), 'timestamp' => date(Db::TIMESTAMP_FORMAT, $asPicInfo['file_ts']), 'rotate' => $asPicInfo['rotate'] )); if(!$iPicId) $sError = 'l\'image n\'a pas pu être entrée en base'; else { //Create thumbnail self::getPicThumbnail($sPicName); } } if($sError!='') { $sError = 'Erreur lors de l\'ajout de "'.$sPicName.'" : '.$sError; $this->addError($sError); } return $sError; } /** * One-shot function to initialize DB with existing images */ public function syncFileFolder() { $asPicPaths = glob(self::getPicPath('*.{jpg,JPG,jpeg,JPEG,png,PNG}'), GLOB_BRACE); foreach($asPicPaths as $sPicPath) { $sPicName = pathinfo($sPicPath, PATHINFO_BASENAME); $this->addPic($sPicName, 'sync'); } $this->setExtractMode(PhpObject::MODE_HTML); return $this->getCleanMessageStack(); } private static function getPicInfo($sPicName) { $sPicPath = self::getPicPath($sPicName); $iPicTimeStamp = $iPicTakenTimeStamp = $iPicFileTimeStamp = 0; $asExif = @exif_read_data($sPicPath, 0, true); if(!$asExif) $asExif['FILE']['FileDateTime'] = filemtime($sPicPath); //Timestamps if(array_key_exists('EXIF', $asExif) && array_key_exists('DateTimeOriginal', $asExif['EXIF'])) $iPicTakenTimeStamp = strtotime($asExif['EXIF']['DateTimeOriginal']); if(array_key_exists('FILE', $asExif) && array_key_exists('FileDateTime', $asExif['FILE'])) $iPicFileTimeStamp = $asExif['FILE']['FileDateTime']; //Merge timestamps $iPicTimeStamp = ($iPicTakenTimeStamp > 0)?$iPicTakenTimeStamp:$iPicFileTimeStamp; //Orientation if(array_key_exists('IFD0', $asExif) && array_key_exists('Orientation', $asExif['IFD0'])) { switch($asExif['IFD0']['Orientation']) { case 1: $sRotate = '0'; break; //None case 3: $sRotate = '180'; break; //Flip over case 6: $sRotate = '90'; break; //Clockwise case 8: $sRotate = '-90'; break; //Trigo default: $sRotate = '0'; } } else $sRotate = '0'; return array( 'timestamp' => $iPicTimeStamp, 'taken_ts' => $iPicTakenTimeStamp, 'file_ts' => $iPicFileTimeStamp, 'rotate' => $sRotate ); } private static function getPicThumbnail($sPicName) { $sPicPath = self::getPicPath($sPicName); $sThumbPath = self::getPicPath($sPicName, 'thumbnail'); if(!file_exists($sThumbPath)) $asThumbInfo = ToolBox::createThumbnail($sPicPath, 400, 0, $sThumbPath/*, false, array('jpg', 'jpeg', 'gif', 'png'), true*/); else $asThumbInfo = array('error'=>'', 'out'=>$sThumbPath); return ($asThumbInfo['error']=='')?$asThumbInfo['out']:$sPicPath; } private static function getPicPath($sPicName, $sFileType='picture') { return ($sFileType=='thumbnail'?self::THUMB_FOLDER:self::PIC_FOLDER).$sPicName; } }