/** * Before saving the data, try uploading the image, if successful save to database. * * @access public * @param Model $model * @return mixed */ public function beforeSave(Model $model) { if (empty($model->data[$model->alias])) { return true; } foreach ($model->data[$model->alias] as $field => $file) { if (empty($this->_attachments[$model->alias][$field])) { continue; } $attachment = $this->_attachments[$model->alias][$field]; $attachment = $this->callback($model, 'beforeUpload', $attachment); $data = array(); // Not a form upload, so lets treat it as an import if (is_string($file) && !empty($file)) { $attachment['importFrom'] = $file; } // Should we continue if a file threw errors during upload? if (empty($file['tmp_name']) || isset($file['error']) && $file['error'] == UPLOAD_ERR_NO_FILE || is_string($file) && empty($attachment['importFrom'])) { if ($attachment['stopSave'] && !$attachment['allowEmpty']) { return false; } else { if ($attachment['allowEmpty']) { if (empty($attachment['defaultPath'])) { unset($model->data[$model->alias][$attachment['dbColumn']]); } else { $model->data[$model->alias][$attachment['dbColumn']] = $attachment['defaultPath']; } continue; } } } // Save model method for formatting function if (!empty($attachment['name']) && method_exists($model, $attachment['name'])) { $attachment['name'] = array($model, $attachment['name']); } // Setup instances $this->uploader->setup($attachment); $this->s3 = $this->s3($attachment['s3']); // Upload or import the file and attach to model data $uploadResponse = $this->upload($file, $attachment, array('overwrite' => $attachment['overwrite'], 'name' => $attachment['name'], 'append' => $attachment['append'], 'prepend' => $attachment['prepend'])); $uploaderOptions = array('uploadDir' => $this->uploader->uploadDir, 'baseDir' => $this->uploader->baseDir, 'tempDir' => $this->uploader->tempDir); if (empty($uploadResponse)) { $model->invalidate($field, __d('uploader', 'There was an error uploading this file, please try again.')); return false; } $basePath = $this->transfer($uploadResponse['path']); $data[$attachment['dbColumn']] = $attachment['saveAsFilename'] && $this->s3 === null ? basename($basePath) : $basePath; $toDelete = array(); $lastPath = $basePath; // Apply image transformations if ($attachment['transforms']) { foreach ($attachment['transforms'] as $options) { $options['field'] = $field; $options = $this->callback($model, 'beforeTransform', $options); $method = $options['method']; if (!method_exists($this->uploader, $method)) { trigger_error(sprintf('Uploader.Attachment::beforeSave(): "%s" is not a defined transformation method.', $method), E_USER_WARNING); return false; } // Apply custom options for transform $this->uploader->setup($options); // Transform image $transformResponse = $this->uploader->{$method}($options); // Rollback uploaded files if one fails if (empty($transformResponse)) { foreach ($data as $path) { $this->delete($path); } $model->invalidate($field, __d('uploader', 'An error occured during image %s transformation.', $method)); return false; } // Transform successful $transformPath = $this->transfer($transformResponse); $data[$options['dbColumn']] = $attachment['saveAsFilename'] && $this->s3 === null ? basename($transformPath) : $transformPath; // Delete original if same column name and transform name are not the same file if ($options['dbColumn'] == $attachment['dbColumn'] && $lastPath != $transformPath) { $toDelete[] = $lastPath; } $lastPath = $transformPath; // Reset to default settings $this->uploader->setup($uploaderOptions); } } // Delete old files if replacing them if ($toDelete) { foreach ($toDelete as $deleteFile) { $this->delete($deleteFile); } } // Apply meta columns if ($attachment['metaColumns']) { foreach ($attachment['metaColumns'] as $field => $column) { if (isset($uploadResponse[$field]) && !empty($column)) { $data[$column] = $uploadResponse[$field]; } } } // Reset S3 and delete original files if ($this->s3 !== null) { foreach ($this->s3->uploads as $path) { $this->delete($path); } $this->s3 = null; } // Merge upload data with model data $model->data[$model->alias] = $data + $model->data[$model->alias]; } return true; }