Exemple #1
0
 /**
  * {@inheritdoc}
  *
  * @throws \InvalidArgumentException
  */
 public function transform(File $file, $self = false)
 {
     $config = $this->getConfig();
     $width = $file->width();
     $height = $file->height();
     $src_x = 0;
     $src_y = 0;
     $src_w = $width;
     $src_h = $height;
     switch ($config['direction']) {
         case self::VERTICAL:
             $src_y = $height;
             $src_h = -$height;
             break;
         case self::HORIZONTAL:
             $src_x = $width;
             $src_w = -$width;
             break;
         case self::BOTH:
             $src_x = $width;
             $src_y = $height;
             $src_w = -$width;
             $src_h = -$height;
             break;
         default:
             throw new InvalidArgumentException(sprintf('Invalid flip direction %s', $config['direction']));
             break;
     }
     return $this->_process($file, array('dest_w' => $width, 'dest_h' => $height, 'source_x' => $src_x, 'source_y' => $src_y, 'source_w' => $src_w, 'source_h' => $src_h, 'quality' => $config['quality'], 'overwrite' => $self, 'target' => sprintf('%s-flip-%s', $file->name(), $config['direction'])));
 }
Exemple #2
0
 /**
  * {@inheritdoc}
  *
  * @throws \InvalidArgumentException
  */
 public function transform(File $file, $self = false)
 {
     $config = $this->getConfig();
     $baseWidth = $file->width();
     $baseHeight = $file->height();
     $width = $config['width'];
     $height = $config['height'];
     if (is_numeric($width) && !$height) {
         $height = round($baseHeight / $baseWidth * $width);
     } else {
         if (is_numeric($height) && !$width) {
             $width = round($baseWidth / $baseHeight * $height);
         } else {
             if (!is_numeric($height) && !is_numeric($width)) {
                 throw new InvalidArgumentException('Invalid width and height for crop');
             }
         }
     }
     $location = $config['location'];
     $widthScale = $baseWidth / $width;
     $heightScale = $baseHeight / $height;
     $src_x = 0;
     $src_y = 0;
     $src_w = $baseWidth;
     $src_h = $baseHeight;
     // If an array is passed, use those dimensions
     if (is_array($location)) {
         list($src_x, $src_y, $src_w, $src_h) = $location;
         // Source width is larger, use height scale as the base
     } else {
         if ($widthScale > $heightScale) {
             $src_w = $width * $heightScale;
             // Position horizontally in the middle
             if ($location === self::CENTER) {
                 $src_x = $baseWidth / 2 - $width / 2 * $heightScale;
                 // Position at the far right
             } else {
                 if ($location === self::RIGHT || $location === self::BOTTOM) {
                     $src_x = $baseWidth - $src_w;
                 }
             }
             // Source height is larger, use width scale as the base
         } else {
             $src_h = $height * $widthScale;
             // Position vertically in the middle
             if ($location === self::CENTER) {
                 $src_y = $baseHeight / 2 - $height / 2 * $widthScale;
                 // Position at the bottom
             } else {
                 if ($location === self::RIGHT || $location === self::BOTTOM) {
                     $src_y = $baseHeight - $src_h;
                 }
             }
         }
     }
     return $this->_process($file, array('dest_w' => $width, 'dest_h' => $height, 'source_x' => $src_x, 'source_y' => $src_y, 'source_w' => $src_w, 'source_h' => $src_h, 'quality' => $config['quality'], 'overwrite' => $self));
 }
 /**
  * Calculate the transformation options and process.
  *
  * @param \Transit\File $file
  * @param bool $self
  * @return \Transit\File
  * @throws \InvalidArgumentException
  */
 public function transform(File $file, $self = false)
 {
     $config = $this->_config;
     if (empty($config['percent']) || !is_numeric($config['percent'])) {
         throw new InvalidArgumentException('Invalid percent for scaling');
     }
     $width = round($file->width() * $config['percent']);
     $height = round($file->height() * $config['percent']);
     return $this->_process($file, array('dest_w' => $width, 'dest_h' => $height, 'quality' => $config['quality'], 'overwrite' => $self));
 }
 /**
  * {@inheritdoc}
  *
  * @throws \InvalidArgumentException
  */
 public function transform(File $file, $self = false)
 {
     $config = $this->getConfig();
     $baseWidth = $file->width();
     $baseHeight = $file->height();
     $width = $config['width'];
     $height = $config['height'];
     $newWidth = null;
     $newHeight = null;
     if (is_numeric($width) && !$height) {
         $height = round($baseHeight / $baseWidth * $width);
     } else {
         if (is_numeric($height) && !$width) {
             $width = round($baseWidth / $baseHeight * $height);
         } else {
             if (!is_numeric($height) && !is_numeric($width)) {
                 throw new InvalidArgumentException('Invalid width and height for resize');
             }
         }
     }
     // Maintains the aspect ratio of the image
     if ($config['aspect']) {
         $widthScale = $width / $baseWidth;
         $heightScale = $height / $baseHeight;
         if ($config['mode'] === self::WIDTH && $widthScale < $heightScale || $config['mode'] === self::HEIGHT && $widthScale > $heightScale) {
             $newWidth = $width;
             $newHeight = $baseHeight * $newWidth / $baseWidth;
         } else {
             if ($config['mode'] === self::WIDTH && $widthScale > $heightScale || $config['mode'] === self::HEIGHT && $widthScale < $heightScale) {
                 $newHeight = $height;
                 $newWidth = $newHeight * $baseWidth / $baseHeight;
             } else {
                 $newWidth = $width;
                 $newHeight = $height;
             }
         }
     } else {
         $newWidth = $width;
         $newHeight = $height;
     }
     // Don't expand if we don't want it too
     if (!$config['expand']) {
         if ($newWidth > $baseWidth) {
             $newWidth = $baseWidth;
         }
         if ($newHeight > $baseHeight) {
             $newHeight = $baseHeight;
         }
     }
     return $this->_process($file, array('dest_w' => $newWidth, 'dest_h' => $newHeight, 'quality' => $config['quality'], 'overwrite' => $self));
 }
 /**
  * Delete the temporary file.
  *
  * @param Model $model
  * @return bool
  */
 public function afterValidate(Model $model)
 {
     if ($this->_tempFile) {
         $this->_tempFile->delete();
     }
     return true;
 }
Exemple #6
0
 /**
  * {@inheritdoc}
  *
  * @throws \InvalidArgumentException
  */
 public function transform(File $file, $self = false)
 {
     $config = $this->getConfig();
     $baseWidth = $file->width();
     $baseHeight = $file->height();
     $width = $config['width'];
     $height = $config['height'];
     $newWidth = null;
     $newHeight = null;
     if (!is_numeric($height) && !is_numeric($width)) {
         throw new InvalidArgumentException('Invalid width and height for resize');
     }
     $widthAspect = $baseWidth / $width;
     $heightAspect = $baseHeight / $height;
     $aspect = $heightAspect > $widthAspect ? $heightAspect : $widthAspect;
     $newWidth = $baseWidth / $aspect;
     $newHeight = $baseHeight / $aspect;
     // Do a simple resize if there is no fill defined
     if (!$config['fill'] || $newHeight == $height && $newWidth == $width) {
         return $this->_process($file, array('dest_w' => $newWidth, 'dest_h' => $newHeight, 'quality' => $config['quality'], 'overwrite' => $self));
     }
     // Determine the alignment
     $vertGap = 0;
     $horiGap = 0;
     // Horizontal
     if ($newWidth < $width) {
         if ($config['horizontal'] === self::CENTER) {
             $horiGap = ($width - $newWidth) / 2;
         } else {
             if ($config['horizontal'] === self::RIGHT) {
                 $horiGap = $width - $newWidth;
             }
         }
         // Vertical
     } else {
         if ($newHeight < $height) {
             if ($config['vertical'] === self::CENTER) {
                 $vertGap = ($height - $newHeight) / 2;
             } else {
                 if ($config['vertical'] === self::BOTTOM) {
                     $vertGap = $height - $newHeight;
                 }
             }
         }
     }
     return $this->_process($file, array('width' => $width, 'height' => $height, 'dest_x' => $horiGap, 'dest_y' => $vertGap, 'dest_w' => $newWidth, 'dest_h' => $newHeight, 'quality' => $config['quality'], 'overwrite' => $self, 'preCallback' => array($this, 'fill')));
 }
Exemple #7
0
 /**
  * {@inheritdoc}
  */
 public function transform(File $file, $self = false)
 {
     if ($file->type() !== 'image/jpeg') {
         return $file;
         // Exif only in JPGs
     }
     $width = $file->width();
     $height = $file->height();
     $exif = $file->exif();
     $this->setConfig('degrees', 0);
     // Reset degrees
     $options = array('dest_w' => $width, 'dest_h' => $height, 'source_w' => $width, 'source_h' => $height, 'quality' => $this->getConfig('quality'), 'overwrite' => $self, 'target' => sprintf('%s-exif-%s', $file->name(), $exif['orientation'] ?: 0));
     switch ($exif['orientation']) {
         case 2:
             // Flip horizontally
             $options['source_x'] = $width;
             $options['source_w'] = -$width;
             break;
         case 3:
             // Rotate 180 degrees
             $this->setConfig('degrees', 180);
             break;
         case 4:
         case 5:
         case 7:
             // Flip vertically
             $options['source_y'] = $height;
             $options['source_h'] = -$height;
             // Also rotate -90 degrees for orientation 5
             if ($exif['orientation'] == 5) {
                 $this->setConfig('degrees', -90);
             }
             // Or rotate 90 degrees for orientation 7
             if ($exif['orientation'] == 7) {
                 $this->setConfig('degrees', 90);
             }
             break;
         case 6:
             $this->setConfig('degrees', -90);
             break;
         case 8:
             $this->setConfig('degrees', 90);
             break;
         default:
             // Correct, strip exif only
             break;
     }
     if ($degrees = $this->getConfig('degrees')) {
         $options['postCallback'] = array($this, 'rotate');
     }
     return $this->_process($file, $options);
 }
 /**
  * Transport the file to Amazon Glacier and return the archive ID.
  *
  * @param \Transit\File $file
  * @return string
  * @throws \Transit\Exception\TransportationException
  */
 public function transport(File $file)
 {
     $config = $this->_config;
     $response = null;
     // If larger then 100MB, split upload into parts
     if ($file->size() >= 100 * Size::MB) {
         $uploader = UploadBuilder::newInstance()->setClient($this->getClient())->setSource($file->path())->setVaultName($config['vault'])->setAccountId($config['accountId'] ?: '-')->setPartSize(10 * Size::MB)->build();
         try {
             $response = $uploader->upload();
         } catch (MultipartUploadException $e) {
             $uploader->abort();
         }
     } else {
         $response = $this->getClient()->uploadArchive(array_filter(array('vaultName' => $config['vault'], 'accountId' => $config['accountId'], 'body' => EntityBody::factory(fopen($file->path(), 'r')))));
     }
     // Return archive ID if successful
     if ($response) {
         $file->delete();
         return $response->getPath('archiveId');
     }
     throw new TransportationException(sprintf('Failed to transport %s to Amazon Glacier', $file->basename()));
 }
 /**
  * Transport the file to a remote location.
  *
  * @param \Transit\File $file
  * @return string
  * @throws \Transit\Exception\TransportationException
  */
 public function transport(File $file)
 {
     $config = $this->_config;
     $key = ltrim($config['folder'], '/') . $file->basename();
     $response = null;
     // If larger then 100MB, split upload into parts
     if ($file->size() >= 100 * Size::MB) {
         $uploader = UploadBuilder::newInstance()->setClient($this->getClient())->setSource($file->path())->setBucket($config['bucket'])->setKey($key)->setMinPartSize(10 * Size::MB)->build();
         try {
             $response = $uploader->upload();
         } catch (MultipartUploadException $e) {
             $uploader->abort();
         }
     } else {
         $response = $this->getClient()->putObject(array_filter(array('Key' => $key, 'Bucket' => $config['bucket'], 'Body' => EntityBody::factory(fopen($file->path(), 'r')), 'ACL' => $config['acl'], 'ContentType' => $file->type(), 'ServerSideEncryption' => $config['encryption'], 'StorageClass' => $config['storage'], 'Metadata' => $config['meta'])));
     }
     // Return S3 URL if successful
     if ($response) {
         $file->delete();
         return sprintf('%s/%s/%s', S3Client::getEndpoint($this->getClient()->getDescription(), $config['region'], $config['scheme']), $config['bucket'], $key);
     }
     throw new TransportationException(sprintf('Failed to transport %s to Amazon S3', $file->basename()));
 }
 /**
  * Attempt to delete a file using the attachment settings.
  *
  * @uses Transit\File
  *
  * @param Model $model
  * @param string $field
  * @param string $path
  * @return bool
  */
 protected function _deleteFile(Model $model, $field, $path)
 {
     if (empty($this->settings[$model->alias][$field])) {
         return false;
     }
     $attachment = $this->_settingsCallback($model, $this->settings[$model->alias][$field]);
     $basePath = $attachment['uploadDir'] ?: $attachment['tempDir'];
     try {
         // Delete remote file
         if ($attachment['transport']) {
             $transporter = $this->_getTransporter($attachment['transport']);
             return $transporter->delete($path);
             // Delete local file
         } else {
             $file = new File($basePath . basename($path));
             return $file->delete();
         }
     } catch (Exception $e) {
         $this->log($e->getMessage(), LOG_DEBUG);
     }
     return false;
 }
Exemple #11
0
 /**
  * Find a valid target path taking into account file existence and overwriting.
  *
  * @param \Transit\File|string $file
  * @param bool $overwrite
  * @return string
  */
 public function findDestination($file, $overwrite = false)
 {
     if ($file instanceof File) {
         $name = $file->name();
         $ext = '.' . $file->ext();
     } else {
         $name = $file;
         $ext = '';
         if ($pos = mb_strrpos($name, '.')) {
             $ext = mb_substr($name, $pos, mb_strlen($name) - $pos);
             $name = mb_substr($name, 0, $pos);
         }
     }
     $target = $this->_directory . $name . $ext;
     if (!$overwrite) {
         $no = 1;
         while (file_exists($target)) {
             $target = sprintf('%s%s-%s%s', $this->_directory, $name, $no, $ext);
             $no++;
         }
     }
     return $target;
 }
 /**
  * Transform the image using the defined options.
  *
  * @param \Transit\File $file
  * @param array $options
  * @return \Transit\File
  * @throws \DomainException
  */
 protected function _process(File $file, array $options)
 {
     if (!$file->isImage()) {
         throw new DomainException(sprintf('%s is not a valid image', $file->basename()));
     }
     $sourcePath = $file->path();
     $mimeType = $file->type();
     // Create an image to work with
     switch ($mimeType) {
         case 'image/gif':
             $sourceImage = imagecreatefromgif($sourcePath);
             break;
         case 'image/png':
             $sourceImage = imagecreatefrompng($sourcePath);
             break;
         case 'image/jpg':
         case 'image/jpeg':
         case 'image/pjpeg':
             $sourceImage = imagecreatefromjpeg($sourcePath);
             break;
         default:
             throw new DomainException(sprintf('%s can not be transformed', $mimeType));
             break;
     }
     // Gather options
     $options = $options + array('dest_x' => 0, 'dest_y' => 0, 'dest_w' => null, 'dest_h' => null, 'source_x' => 0, 'source_y' => 0, 'source_w' => $file->width(), 'source_h' => $file->height(), 'quality' => 100, 'overwrite' => false, 'target' => '');
     $targetImage = imagecreatetruecolor($options['dest_w'], $options['dest_h']);
     // If gif/png allow transparencies
     if ($mimeType === 'image/gif' || $mimeType === 'image/png') {
         imagealphablending($targetImage, false);
         imagesavealpha($targetImage, true);
         imagefilledrectangle($targetImage, 0, 0, $options['dest_w'], $options['dest_h'], imagecolorallocatealpha($targetImage, 255, 255, 255, 127));
     }
     // Lets take our source and apply it to the temporary file and resize
     imagecopyresampled($targetImage, $sourceImage, $options['dest_x'], $options['dest_y'], $options['source_x'], $options['source_y'], $options['dest_w'], $options['dest_h'], $options['source_w'], $options['source_h']);
     // Now write the transformed image to the server
     if ($options['overwrite']) {
         $options['target'] = $file->name();
     } else {
         if (!$options['target']) {
             $class = explode('\\', get_class($this));
             $class = str_replace('transformer', '', strtolower(end($class)));
             $options['target'] = sprintf('%s-%s-%sx%s', $file->name(), $class, round($options['dest_w']), round($options['dest_h']));
         }
     }
     $targetPath = sprintf('%s%s.%s', $file->dir(), $options['target'], $file->ext());
     switch ($mimeType) {
         case 'image/gif':
             imagegif($targetImage, $targetPath);
             break;
         case 'image/png':
             imagepng($targetImage, $targetPath);
             break;
         case 'image/jpg':
         case 'image/jpeg':
         case 'image/pjpeg':
             imagejpeg($targetImage, $targetPath, $options['quality']);
             break;
     }
     // Clear memory
     imagedestroy($sourceImage);
     imagedestroy($targetImage);
     return new File($targetPath);
 }
 /**
  * Test that move() doesn't overwrite files but appends an incremented number.
  */
 public function testMoveNoOverwrite()
 {
     $testPath = TEST_DIR . '/test.jpg';
     $movePath = TEMP_DIR . '/test-1.jpg';
     copy($this->baseFile, $testPath);
     $this->assertFalse(file_exists($movePath));
     $file = new File($testPath);
     $file->move(TEMP_DIR);
     $this->assertTrue(file_exists($movePath));
     $file->delete();
 }
Exemple #14
0
 /**
  * Test for this bug: https://bugs.php.net/bug.php?id=53035
  */
 public function testTypeDetectionForMagicBugs()
 {
     $file = new File(TEMP_DIR . '/magic-mime-verify.js');
     // This will actually return text/plain because magic cant determine a text/javascript file
     // It can also return text/x-c in some weird corner cases
     // If either of these happen, fall back to the extension derived mimetype (or from $_FILES)
     $this->assertEquals('application/javascript', $file->type());
 }