/**
  * Moves an uploaded file from the temp directory to a permanent location
  * 
  * @throws fValidationException  When `$directory` is somehow invalid or ::validate() thows an exception
  * 
  * @param  string|fDirectory $directory  The directory to upload the file to
  * @param  string            $field      The file upload field to get the file from
  * @param  mixed             $index      If the field was an array file upload field, upload the file corresponding to this index
  * @return fFile|NULL  An fFile (or fImage) object, or `NULL` if no file was uploaded
  */
 public function move($directory, $field, $index = NULL)
 {
     if (!is_object($directory)) {
         $directory = new fDirectory($directory);
     }
     if (!$directory->isWritable()) {
         throw new fProgrammerException('The directory specified, %s, is not writable', $directory->getPath());
     }
     if (!self::check($field)) {
         throw new fProgrammerException('The field specified, %s, does not appear to be a file upload field', $field);
     }
     $file_array = $this->extractFileUploadArray($field, $index);
     $error = $this->validateField($file_array);
     if ($error) {
         throw new fValidationException($error);
     }
     // This will only ever be true if the file is optional
     if ($file_array['name'] == '' || $file_array['tmp_name'] == '' || $file_array['size'] == 0) {
         return NULL;
     }
     $file_name = fFilesystem::makeURLSafe($file_array['name']);
     $file_name = $directory->getPath() . $file_name;
     if (!$this->enable_overwrite) {
         $file_name = fFilesystem::makeUniqueName($file_name);
     }
     if (!move_uploaded_file($file_array['tmp_name'], $file_name)) {
         throw new fEnvironmentException('There was an error moving the uploaded file');
     }
     if (!chmod($file_name, 0644)) {
         throw new fEnvironmentException('Unable to change permissions on the uploaded file');
     }
     return fFilesystem::createObject($file_name);
 }
Beispiel #2
0
 /**
  * Moves uploaded files from the temporary directory to the permanent directory
  * 
  * @internal
  * 
  * @param  fActiveRecord $object            The fActiveRecord instance
  * @param  array         &$values           The current values
  * @param  array         &$old_values       The old values
  * @param  array         &$related_records  Any records related to this record
  * @param  array         &$cache            The cache array for the record
  * @return void
  */
 public static function moveFromTemp($object, &$values, &$old_values, &$related_records, &$cache)
 {
     foreach ($values as $column => $value) {
         if (!$value instanceof fFile) {
             continue;
         }
         // If the file is in a temp dir, move it out
         if (strpos($value->getParent()->getPath(), self::TEMP_DIRECTORY . DIRECTORY_SEPARATOR) !== FALSE) {
             $new_filename = str_replace(self::TEMP_DIRECTORY . DIRECTORY_SEPARATOR, '', $value->getPath());
             $new_filename = fFilesystem::makeUniqueName($new_filename);
             $value->rename($new_filename, FALSE);
         }
     }
 }
 /**
  * Renames the current directory
  * 
  * This operation will NOT be performed until the filesystem transaction
  * has been committed, if a transaction is in progress. Any non-Flourish
  * code (PHP or system) will still see this directory (and all contained
  * files/dirs) as existing with the old paths until that point.
  * 
  * @param  string  $new_dirname  The new full path to the directory or a new name in the current parent directory
  * @param  boolean $overwrite    If the new dirname already exists, TRUE will cause the file to be overwritten, FALSE will cause the new filename to change
  * @return void
  */
 public function rename($new_dirname, $overwrite)
 {
     $this->tossIfDeleted();
     if (!$this->getParent()->isWritable()) {
         throw new fEnvironmentException('The directory, %s, can not be renamed because the directory containing it is not writable', $this->directory);
     }
     // If the dirname does not contain any folder traversal, rename the dir in the current parent directory
     if (preg_match('#^[^/\\\\]+$#D', $new_dirname)) {
         $new_dirname = $this->getParent()->getPath() . $new_dirname;
     }
     $info = fFilesystem::getPathInfo($new_dirname);
     if (!file_exists($info['dirname'])) {
         throw new fProgrammerException('The new directory name specified, %s, is inside of a directory that does not exist', $new_dirname);
     }
     if (file_exists($new_dirname)) {
         if (!is_writable($new_dirname)) {
             throw new fEnvironmentException('The new directory name specified, %s, already exists, but is not writable', $new_dirname);
         }
         if (!$overwrite) {
             $new_dirname = fFilesystem::makeUniqueName($new_dirname);
         }
     } else {
         $parent_dir = new fDirectory($info['dirname']);
         if (!$parent_dir->isWritable()) {
             throw new fEnvironmentException('The new directory name specified, %s, is inside of a directory that is not writable', $new_dirname);
         }
     }
     rename($this->directory, $new_dirname);
     // Make the dirname absolute
     $new_dirname = fDirectory::makeCanonical(realpath($new_dirname));
     // Allow filesystem transactions
     if (fFilesystem::isInsideTransaction()) {
         fFilesystem::rename($this->directory, $new_dirname);
     }
     fFilesystem::updateFilenameMapForDirectory($this->directory, $new_dirname);
 }
Beispiel #4
0
 /**
  * Renames the current file
  * 
  * If the filename already exists and the overwrite flag is set to false,
  * a new filename will be created.
  * 
  * This operation will be reverted if a filesystem transaction is in
  * progress and is later rolled back.
  * 
  * @param  string  $new_filename  The new full path to the file or a new filename in the current directory
  * @param  boolean $overwrite     If the new filename already exists, `TRUE` will cause the file to be overwritten, `FALSE` will cause the new filename to change
  * @return fFile  The file object, to allow for method chaining
  */
 public function rename($new_filename, $overwrite)
 {
     $this->tossIfDeleted();
     if (!$this->getParent()->isWritable()) {
         throw new fEnvironmentException('The file, %s, can not be renamed because the directory containing it is not writable', $this->file);
     }
     // If the filename does not contain any folder traversal, rename the file in the current directory
     if (preg_match('#^[^/\\\\]+$#D', $new_filename)) {
         $new_filename = $this->getParent()->getPath() . $new_filename;
     }
     $info = fFilesystem::getPathInfo($new_filename);
     if (!file_exists($info['dirname'])) {
         throw new fProgrammerException('The new filename specified, %s, is inside of a directory that does not exist', $new_filename);
     }
     // Make the filename absolute
     $new_filename = fDirectory::makeCanonical(realpath($info['dirname'])) . $info['basename'];
     if ($this->file == $new_filename && $overwrite) {
         return $this;
     }
     if (file_exists($new_filename) && !$overwrite) {
         $new_filename = fFilesystem::makeUniqueName($new_filename);
     }
     if (file_exists($new_filename)) {
         if (!is_writable($new_filename)) {
             throw new fEnvironmentException('The new filename specified, %s, already exists, but is not writable', $new_filename);
         }
         if (fFilesystem::isInsideTransaction()) {
             fFilesystem::recordWrite(new fFile($new_filename));
         }
         // Windows requires that the existing file be deleted before being replaced
         unlink($new_filename);
     } else {
         $new_dir = new fDirectory($info['dirname']);
         if (!$new_dir->isWritable()) {
             throw new fEnvironmentException('The new filename specified, %s, is inside of a directory that is not writable', $new_filename);
         }
     }
     rename($this->file, $new_filename);
     // Allow filesystem transactions
     if (fFilesystem::isInsideTransaction()) {
         fFilesystem::recordRename($this->file, $new_filename);
     }
     fFilesystem::updateFilenameMap($this->file, $new_filename);
     return $this;
 }
Beispiel #5
0
 /**
  * Moves an uploaded file from the temp directory to a permanent location
  * 
  * @throws fValidationException  When `$directory` is somehow invalid or ::validate() thows an exception
  * 
  * @param  string|fDirectory $directory  The directory to upload the file to
  * @param  string            $field      The file upload field to get the file from
  * @param  integer           $index      If the field was an array file upload field, upload the file corresponding to this index
  * @return fFile  An fFile (or fImage) object
  */
 public function move($directory, $field, $index = NULL, $param_filename = NULL)
 {
     if (!is_object($directory)) {
         $directory = new fDirectory($directory);
     }
     if (!$directory->isWritable()) {
         throw new fProgrammerException('The directory specified, %s, is not writable', $directory->getPath());
     }
     if (!self::check($field)) {
         throw new fProgrammerException('The field specified, %s, does not appear to be a file upload field', $field);
     }
     $file_array = $this->validate($field, $index);
     $file_name = fFilesystem::makeURLSafe($param_filename == NULL ? $file_array['name'] : $param_filename);
     $file_name = $directory->getPath() . $file_name;
     if (!$this->enable_overwrite) {
         $file_name = fFilesystem::makeUniqueName($file_name);
     }
     if (!move_uploaded_file($file_array['tmp_name'], $file_name)) {
         throw new fEnvironmentException('There was an error moving the uploaded file');
     }
     if (!chmod($file_name, 0644)) {
         throw new fEnvironmentException('Unable to change permissions on the uploaded file');
     }
     return fFilesystem::createObject($file_name);
 }
Beispiel #6
0
 /**
  * Saves any changes to the image
  * 
  * If the file type is different than the current one, removes the current
  * file once the new one is created.
  * 
  * This operation will be reverted by a filesystem transaction being rolled
  * back. If a transaction is in progress and the new image type causes a
  * new file to be created, the old file will not be deleted until the
  * transaction is committed.
  * 
  * @param  string  $new_image_type  The new file format for the image: 'NULL` (no change), `'jpg'`, `'gif'`, `'png'`
  * @param  integer $jpeg_quality    The quality setting to use for JPEG images - this may be ommitted
  * @param  boolean $overwrite       If an existing file with the same name and extension should be overwritten
  * @param  string  :$new_image_type
  * @param  boolean :$overwrite
  * @return fImage  The image object, to allow for method chaining
  */
 public function saveChanges($new_image_type = NULL, $jpeg_quality = 90, $overwrite = FALSE)
 {
     // This allows ommitting the $jpeg_quality parameter, which is very useful for non-jpegs
     $args = func_get_args();
     if (count($args) == 2 && is_bool($args[1])) {
         $overwrite = $args[1];
         $jpeg_quality = 90;
     }
     $this->tossIfDeleted();
     self::determineProcessor();
     if (self::$processor == 'none') {
         throw new fEnvironmentException("The changes to the image can't be saved because neither the GD extension or ImageMagick appears to be installed on the server");
     }
     $type = self::getImageType($this->file);
     if ($type == 'tif' && self::$processor == 'gd') {
         throw new fEnvironmentException('The image specified, %s, is a TIFF file and the GD extension can not handle TIFF files. Please install ImageMagick if you wish to manipulate TIFF files.', $this->file);
     }
     $valid_image_types = array('jpg', 'gif', 'png');
     if ($new_image_type !== NULL && !in_array($new_image_type, $valid_image_types)) {
         throw new fProgrammerException('The new image type specified, %1$s, is invalid. Must be one of: %2$s.', $new_image_type, join(', ', $valid_image_types));
     }
     if (is_numeric($jpeg_quality)) {
         $jpeg_quality = (int) round($jpeg_quality);
     }
     if (!is_integer($jpeg_quality) || $jpeg_quality < 1 || $jpeg_quality > 100) {
         throw new fProgrammerException('The JPEG quality specified, %1$s, is either not an integer, less than %2$s or greater than %3$s.', $jpeg_quality, 1, 100);
     }
     if ($new_image_type && fFilesystem::getPathInfo($this->file, 'extension') != $new_image_type) {
         if ($overwrite) {
             $path_info = fFilesystem::getPathInfo($this->file);
             $output_file = $path_info['dirname'] . $path_info['filename'] . '.' . $new_image_type;
         } else {
             $output_file = fFilesystem::makeUniqueName($this->file, $new_image_type);
         }
         if (file_exists($output_file)) {
             if (!is_writable($output_file)) {
                 throw new fEnvironmentException('Changes to the image can not be saved because the file, %s, is not writable', $output_file);
             }
         } else {
             $output_dir = dirname($output_file);
             if (!is_writable($output_dir)) {
                 throw new fEnvironmentException('Changes to the image can not be saved because the directory to save the new file, %s, is not writable', $output_dir);
             }
         }
     } else {
         $output_file = $this->file;
         if (!is_writable($output_file)) {
             throw new fEnvironmentException('Changes to the image can not be saved because the file, %s, is not writable', $output_file);
         }
     }
     // If we don't have any changes and no name change, just exit
     if (!$this->pending_modifications && $output_file == $this->file) {
         return $this;
     }
     // Wrap changes to the image into the filesystem transaction
     if ($output_file == $this->file && fFilesystem::isInsideTransaction()) {
         fFilesystem::recordWrite($this);
     }
     if (self::$processor == 'gd') {
         $this->processWithGD($output_file, $jpeg_quality);
     } elseif (self::$processor == 'imagemagick') {
         $this->processWithImageMagick($output_file, $jpeg_quality);
     }
     $old_file = $this->file;
     fFilesystem::updateFilenameMap($this->file, $output_file);
     // If we created a new image, delete the old one
     if ($output_file != $old_file) {
         $old_image = new fImage($old_file);
         $old_image->delete();
     }
     $this->pending_modifications = array();
     return $this;
 }