コード例 #1
0
 /**
  * @inheritDoc BaseAssetSourceType::getLocalCopy()
  *
  * @param AssetFileModel $file
  *
  * @return mixed
  */
 public function getLocalCopy(AssetFileModel $file)
 {
     $location = AssetsHelper::getTempFilePath($file->getExtension());
     $this->_prepareForRequests();
     $this->_googleCloud->getObject($this->getSettings()->bucket, $this->_getGCPath($file), $location);
     return $location;
 }
コード例 #2
0
 public function resize($sourceId, $path, $width, $height)
 {
     try {
         $settings = craft()->imageResizer->getSettings();
         $image = craft()->images->loadImage($path);
         $filename = basename($path);
         // We can have settings globally, or per asset source. Check!
         // Our maximum width/height for assets from plugin settings
         $imageWidth = craft()->imageResizer->getSettingForAssetSource($sourceId, 'imageWidth');
         $imageHeight = craft()->imageResizer->getSettingForAssetSource($sourceId, 'imageHeight');
         // Allow for overrides passed on-demand
         $imageWidth = $width ? $width : $imageWidth;
         $imageHeight = $height ? $height : $imageHeight;
         // Lets check to see if this image needs resizing. Split into two steps to ensure
         // proper aspect ratio is preserved and no upscaling occurs.
         $hasResized = false;
         if ($image->getWidth() > $imageWidth) {
             $hasResized = true;
             $this->_resizeImage($image, $imageWidth, null);
         }
         if ($image->getHeight() > $imageHeight) {
             $hasResized = true;
             $this->_resizeImage($image, null, $imageHeight);
         }
         if ($hasResized) {
             // Set image quality - but normalise (for PNG)!
             $image->setQuality(craft()->imageResizer->getImageQuality($filename));
             // If we're checking for larger images
             if ($settings->skipLarger) {
                 // Save this resized image in a temporary location - we need to test filesize difference
                 $tempPath = AssetsHelper::getTempFilePath($filename);
                 $image->saveAs($tempPath);
                 clearstatcache();
                 // Lets check to see if this resize resulted in a larger file - revert if so.
                 if (filesize($tempPath) < filesize($path)) {
                     $image->saveAs($path);
                     // Its a smaller file - properly save
                 } else {
                     ImageResizerPlugin::log('Did not resize ' . $filename . ' as it would result in a larger file.', LogLevel::Info, true);
                 }
                 // Delete our temp file we test filesize with
                 IOHelper::deleteFile($tempPath, true);
             } else {
                 $image->saveAs($path);
             }
         }
         return true;
     } catch (\Exception $e) {
         ImageResizerPlugin::log($e->getMessage(), LogLevel::Error, true);
         return false;
     }
 }
コード例 #3
0
 /**
  * Upload file and process it for mapping.
  */
 public function actionUpload()
 {
     // Get import post
     $import = craft()->request->getRequiredPost('import');
     // Get file
     $file = \CUploadedFile::getInstanceByName('file');
     // Is file valid?
     if (!is_null($file)) {
         // Is asset source valid?
         if (isset($import['assetsource']) && !empty($import['assetsource'])) {
             // Get source
             $source = craft()->assetSources->getSourceTypeById($import['assetsource']);
             // Get folder to save to
             $folderId = craft()->assets->getRootFolderBySourceId($import['assetsource']);
             // Save file to Craft's temp folder for later use
             $fileName = AssetsHelper::cleanAssetName($file->name);
             $filePath = AssetsHelper::getTempFilePath($file->extensionName);
             $file->saveAs($filePath);
             // Move the file by source type implementation
             $response = $source->insertFileByPath($filePath, $folderId, $fileName, true);
             // Prevent sensitive information leak. Just in case.
             $response->deleteDataItem('filePath');
             // Get file id
             $fileId = $response->getDataItem('fileId');
             // Put vars in model
             $model = new ImportModel();
             $model->filetype = $file->getType();
             // Validate filetype
             if ($model->validate()) {
                 // Get columns
                 $columns = craft()->import->columns($fileId);
                 // Send variables to template and display
                 $this->renderTemplate('import/_map', array('import' => $import, 'file' => $fileId, 'columns' => $columns));
             } else {
                 // Not validated, show error
                 craft()->userSession->setError(Craft::t('This filetype is not valid') . ': ' . $model->filetype);
             }
         } else {
             // No asset source selected
             craft()->userSession->setError(Craft::t('Please select an asset source.'));
         }
     } else {
         // No file uploaded
         craft()->userSession->setError(Craft::t('Please upload a file.'));
     }
 }
コード例 #4
0
 /**
  * Upload a file.
  *
  * @param AssetFolderModel $folder The assetFolderModel where the file should be uploaded to.
  *
  * @throws Exception
  * @return AssetOperationResponseModel
  */
 public function uploadFile(AssetFolderModel $folder)
 {
     // Upload the file and drop it in the temporary folder
     $file = $_FILES['assets-upload'];
     // Make sure a file was uploaded
     if (empty($file['name'])) {
         throw new Exception(Craft::t('No file was uploaded'));
     }
     $size = $file['size'];
     // Make sure the file isn't empty
     if (!$size) {
         throw new Exception(Craft::t('Uploaded file was empty'));
     }
     $fileName = AssetsHelper::cleanAssetName($file['name']);
     // Save the file to a temp location and pass this on to the source type implementation
     $filePath = AssetsHelper::getTempFilePath(IOHelper::getExtension($fileName));
     move_uploaded_file($file['tmp_name'], $filePath);
     $response = $this->insertFileByPath($filePath, $folder, $fileName);
     // Prevent sensitive information leak. Just in case.
     $response->deleteDataItem('filePath');
     return $response;
 }
コード例 #5
0
 /**
  * Create a transform for the file by the transform index.
  *
  * @param AssetFileModel           $file
  * @param AssetTransformIndexModel $index
  *
  * @throws Exception if the AssetTransformIndexModel cannot be determined to have a transform
  * @return null
  */
 private function _createTransformForFile(AssetFileModel $file, AssetTransformIndexModel $index)
 {
     if (!ImageHelper::isImageManipulatable(IOHelper::getExtension($file->filename))) {
         return;
     }
     if (empty($index->transform)) {
         $transform = $this->normalizeTransform(mb_substr($index->location, 1));
         if (empty($transform)) {
             throw new Exception(Craft::t("Unable to recognize the transform for this transform index!"));
         }
     } else {
         $transform = $index->transform;
     }
     if (!isset($index->detectedFormat)) {
         $index->detectedFormat = !empty($index->format) ? $index->format : $this->detectAutoTransformFormat($file);
     }
     $sourceType = craft()->assetSources->populateSourceType($file->getSource());
     $imageSource = $file->getTransformSource();
     $quality = $transform->quality ? $transform->quality : craft()->config->get('defaultImageQuality');
     $image = craft()->images->loadImage($imageSource, $transform->width, $transform->height);
     $image->setQuality($quality);
     switch ($transform->mode) {
         case 'fit':
             $image->scaleToFit($transform->width, $transform->height);
             break;
         case 'stretch':
             $image->resize($transform->width, $transform->height);
             break;
         default:
             $image->scaleAndCrop($transform->width, $transform->height, true, $transform->position);
             break;
     }
     $createdTransform = AssetsHelper::getTempFilePath($index->detectedFormat);
     $image->saveAs($createdTransform);
     clearstatcache(true, $createdTransform);
     $sourceType->putImageTransform($file, $index, $createdTransform);
     IOHelper::deleteFile($createdTransform);
     if (craft()->assetSources->populateSourceType($file->getSource())->isRemote()) {
         $this->queueSourceForDeletingIfNecessary($imageSource);
     }
     return;
 }
コード例 #6
0
 /**
  * @inheritDoc IFieldType::prepValueFromPost()
  *
  * @param mixed $value
  *
  * @return mixed
  */
 public function prepValueFromPost($value)
 {
     $dataFiles = array();
     // Grab data strings
     if (isset($value['data']) && is_array($value['data'])) {
         foreach ($value['data'] as $index => $dataString) {
             if (preg_match('/^data:(?<type>[a-z0-9]+\\/[a-z0-9]+);base64,(?<data>.+)/i', $dataString, $matches)) {
                 $type = $matches['type'];
                 $data = base64_decode($matches['data']);
                 if (!$data) {
                     continue;
                 }
                 if (!empty($value['filenames'][$index])) {
                     $filename = $value['filenames'][$index];
                 } else {
                     $extension = FileHelper::getExtensionByMimeType($type);
                     $filename = 'Uploaded file.' . $extension;
                 }
                 $dataFiles[] = array('filename' => $filename, 'data' => $data);
             }
         }
     }
     // Remove these so they don't interfere.
     if (isset($value['data']) && isset($value['filenames'])) {
         unset($value['data'], $value['filenames']);
     }
     $uploadedFiles = array();
     // See if we have uploaded file(s).
     $contentPostLocation = $this->getContentPostLocation();
     if ($contentPostLocation) {
         $files = UploadedFile::getInstancesByName($contentPostLocation);
         foreach ($files as $file) {
             $uploadedFiles[] = array('filename' => $file->getName(), 'location' => $file->getTempName());
         }
     }
     // See if we have to validate against fileKinds
     $settings = $this->getSettings();
     $allowedExtensions = false;
     if (isset($settings->restrictFiles) && !empty($settings->restrictFiles) && !empty($settings->allowedKinds)) {
         $allowedExtensions = static::_getAllowedExtensions($settings->allowedKinds);
     }
     if (is_array($allowedExtensions)) {
         foreach ($dataFiles as $file) {
             $extension = StringHelper::toLowerCase(IOHelper::getExtension($file['filename']));
             if (!in_array($extension, $allowedExtensions)) {
                 $this->_failedFiles[] = $file['filename'];
             }
         }
         foreach ($uploadedFiles as $file) {
             $extension = StringHelper::toLowerCase(IOHelper::getExtension($file['filename']));
             if (!in_array($extension, $allowedExtensions)) {
                 $this->_failedFiles[] = $file['filename'];
             }
         }
     }
     if (!empty($this->_failedFiles)) {
         return true;
     }
     // If we got here either there are no restrictions or all files are valid so let's turn them into Assets
     // Unless there are no files at all.
     if (empty($value) && empty($dataFiles) && empty($uploadedFiles)) {
         return array();
     }
     if (empty($value)) {
         $value = array();
     }
     $fileIds = array();
     if (!empty($dataFiles) || !empty($uploadedFiles)) {
         $targetFolderId = $this->_determineUploadFolderId($settings);
         foreach ($dataFiles as $file) {
             $tempPath = AssetsHelper::getTempFilePath($file['filename']);
             IOHelper::writeToFile($tempPath, $file['data']);
             $response = craft()->assets->insertFileByLocalPath($tempPath, $file['filename'], $targetFolderId);
             $fileIds[] = $response->getDataItem('fileId');
             IOHelper::deleteFile($tempPath, true);
         }
         foreach ($uploadedFiles as $file) {
             $tempPath = AssetsHelper::getTempFilePath($file['filename']);
             move_uploaded_file($file['location'], $tempPath);
             $response = craft()->assets->insertFileByLocalPath($tempPath, $file['filename'], $targetFolderId);
             $fileIds[] = $response->getDataItem('fileId');
             IOHelper::deleteFile($tempPath, true);
         }
     }
     $fileIds = array_merge($value, $fileIds);
     // Make it look like the actual POST data contained these file IDs as well,
     // so they make it into entry draft/version data
     $this->element->setRawPostContent($this->model->handle, $fileIds);
     return $fileIds;
 }
コード例 #7
0
 /**
  * Upload a file.
  *
  * @param AssetFolderModel $folder
  * @return object
  * @throws Exception
  */
 public function uploadFile($folder)
 {
     // Upload the file and drop it in the temporary folder
     $uploader = new \qqFileUploader();
     // Make sure a file was uploaded
     if (!$uploader->file) {
         throw new Exception(Craft::t('No file was uploaded'));
     }
     $size = $uploader->file->getSize();
     // Make sure the file isn't empty
     if (!$size) {
         throw new Exception(Craft::t('Uploaded file was empty'));
     }
     $fileName = IOHelper::cleanFilename($uploader->file->getName());
     // Save the file to a temp location and pass this on to the source type implementation
     $filePath = AssetsHelper::getTempFilePath(IOHelper::getExtension($fileName));
     $uploader->file->save($filePath);
     // We hate Javascript and PHP in our image files.
     if (IOHelper::getFileKind(IOHelper::getExtension($filePath)) == 'image') {
         craft()->images->cleanImage($filePath);
     }
     $response = $this->_insertFileInFolder($folder, $filePath, $fileName);
     // Naming conflict. create a new file and ask the user what to do with it
     if ($response->isConflict()) {
         $newFileName = $this->_getNameReplacement($folder, $fileName);
         $conflictResponse = $response;
         $response = $this->_insertFileInFolder($folder, $filePath, $newFileName);
     }
     if ($response->isSuccess()) {
         $filename = IOHelper::getFileName($response->getDataItem('filePath'));
         $fileModel = new AssetFileModel();
         $fileModel->sourceId = $this->model->id;
         $fileModel->folderId = $folder->id;
         $fileModel->filename = IOHelper::getFileName($filename);
         $fileModel->kind = IOHelper::getFileKind(IOHelper::getExtension($filename));
         $fileModel->size = filesize($filePath);
         $fileModel->dateModified = IOHelper::getLastTimeModified($filePath);
         if ($fileModel->kind == 'image') {
             list($width, $height) = getimagesize($filePath);
             $fileModel->width = $width;
             $fileModel->height = $height;
         }
         craft()->assets->storeFile($fileModel);
         if (!$this->isSourceLocal() && $fileModel->kind == 'image') {
             // Store copy locally for all sorts of operations.
             IOHelper::copyFile($filePath, craft()->path->getAssetsImageSourcePath() . $fileModel->id . '.' . IOHelper::getExtension($fileModel->filename));
         }
         // Check if we stored a conflict response originally - send that back then.
         if (isset($conflictResponse)) {
             $response = $conflictResponse->setDataItem('additionalInfo', $folder->id . ':' . $fileModel->id)->setDataItem('newFileId', $fileModel->id);
         }
         $response->setDataItem('fileId', $fileModel->id);
     }
     IOHelper::deleteFile($filePath);
     // Prevent sensitive information leak. Just in case.
     $response->deleteDataItem('filePath');
     return $response;
 }
コード例 #8
0
 /**
  * Upload a file.
  *
  * @param array $file
  * @param int   $folderId
  *
  * @return bool|int
  */
 private function _uploadFile($file, $folderId)
 {
     $fileName = AssetsHelper::cleanAssetName($file['name']);
     // Save the file to a temp location and pass this on to the source type implementation
     $filePath = AssetsHelper::getTempFilePath(IOHelper::getExtension($fileName));
     move_uploaded_file($file['tmp_name'], $filePath);
     $response = craft()->assets->insertFileByLocalPath($filePath, $fileName, $folderId);
     // Make sure the file is removed.
     IOHelper::deleteFile($filePath, true);
     // Prevent sensitive information leak. Just in case.
     $response->deleteDataItem('filePath');
     // Return file ID
     return $response->getDataItem('fileId');
 }
コード例 #9
0
 /**
  * @inheritDoc IFieldType::prepValueFromPost()
  *
  * @param mixed $value
  *
  * @return mixed
  */
 public function prepValueFromPost($value)
 {
     // See if we have uploaded file(s).
     $contentPostLocation = $this->getContentPostLocation();
     if ($contentPostLocation) {
         $uploadedFiles = UploadedFile::getInstancesByName($contentPostLocation);
         if (!empty($uploadedFiles)) {
             // See if we have to validate against fileKinds
             $settings = $this->getSettings();
             if (isset($settings->restrictFiles) && !empty($settings->restrictFiles) && !empty($settings->allowedKinds)) {
                 $allowedExtensions = static::_getAllowedExtensions($settings->allowedKinds);
                 $failedFiles = array();
                 foreach ($uploadedFiles as $uploadedFile) {
                     $extension = mb_strtolower(IOHelper::getExtension($uploadedFile->getName()));
                     if (!in_array($extension, $allowedExtensions)) {
                         $failedFiles[] = $uploadedFile;
                     }
                 }
                 // If any files failed the validation, make a note of it.
                 if (!empty($failedFiles)) {
                     $this->_failedFiles = $failedFiles;
                     return true;
                 }
             }
             // If we got here either there are no restrictions or all files are valid so let's turn them into Assets
             $fileIds = array();
             $targetFolderId = $this->_determineUploadFolderId($settings);
             if (!empty($targetFolderId)) {
                 foreach ($uploadedFiles as $file) {
                     $tempPath = AssetsHelper::getTempFilePath($file->getName());
                     move_uploaded_file($file->getTempName(), $tempPath);
                     $response = craft()->assets->insertFileByLocalPath($tempPath, $file->getName(), $targetFolderId);
                     $fileIds[] = $response->getDataItem('fileId');
                     IOHelper::deleteFile($tempPath, true);
                 }
                 if (is_array($value) && is_array($fileIds)) {
                     $fileIds = array_merge($value, $fileIds);
                 }
                 // Make it look like the actual POST data contained these file IDs as well,
                 // so they make it into entry draft/version data
                 $this->element->setRawPostContent($this->model->handle, $fileIds);
                 return $fileIds;
             }
         }
     }
     return parent::prepValueFromPost($value);
 }
コード例 #10
0
 /**
  * @inheritDoc BaseAssetSourceType::getLocalCopy()
  *
  * @param AssetFileModel $file
  *
  * @return mixed
  */
 public function getLocalCopy(AssetFileModel $file)
 {
     $location = AssetsHelper::getTempFilePath($file->getExtension());
     IOHelper::copyFile($this->_getFileSystemPath($file), $location);
     clearstatcache();
     return $location;
 }
コード例 #11
0
 /**
  * @inheritDoc BaseAssetSourceType::getLocalCopy()
  *
  * @param AssetFileModel $file
  *
  * @return mixed
  */
 public function getLocalCopy(AssetFileModel $file)
 {
     $location = AssetsHelper::getTempFilePath($file->getExtension());
     $this->_downloadFile($this->_getRackspacePath($file), $location);
     return $location;
 }
コード例 #12
0
 /**
  * Update the asset transforms for the FileModel.
  *
  * @param AssetFileModel $fileModel
  * @param array|object|string $transformsToUpdate
  * @return bool
  */
 public function updateTransforms(AssetFileModel $fileModel, $transformsToUpdate)
 {
     if (!in_array(IOHelper::getExtension($fileModel->filename), ImageHelper::getAcceptedExtensions())) {
         return true;
     }
     $sourceType = craft()->assetSources->getSourceTypeById($fileModel->sourceId);
     $imageSource = $sourceType->getImageSourcePath($fileModel);
     if (!IOHelper::fileExists($imageSource)) {
         return false;
     }
     if (!is_array($transformsToUpdate)) {
         $transformsToUpdate = array($transformsToUpdate);
     }
     foreach ($transformsToUpdate as $transform) {
         $transform = $this->normalizeTransform($transform);
         $transformLocation = $this->_getTransformLocation($transform);
         $timeModified = $sourceType->getTimeTransformModified($fileModel, $transformLocation);
         // Create the transform if the file doesn't exist, or if it was created before the image was last updated
         // or if the transform dimensions have changed since it was last created
         if (!$timeModified || $timeModified < $fileModel->dateModified || $timeModified < $transform->dimensionChangeTime) {
             $targetFile = AssetsHelper::getTempFilePath(IOHelper::getExtension($fileModel->filename));
             switch ($transform->mode) {
                 case 'fit':
                     craft()->images->loadImage($imageSource)->scaleToFit($transform->width, $transform->height)->saveAs($targetFile);
                     break;
                 case 'stretch':
                     craft()->images->loadImage($imageSource)->resize($transform->width, $transform->height)->saveAs($targetFile);
                     break;
                 default:
                     craft()->images->loadImage($imageSource)->scaleAndCrop($transform->width, $transform->height, true, $transform->position)->saveAs($targetFile);
                     break;
             }
             clearstatcache(true, $targetFile);
             $sourceType->putImageTransform($fileModel, $transformLocation, $targetFile);
             IOHelper::deleteFile($targetFile);
         }
     }
     return true;
 }
コード例 #13
0
ファイル: AssetsController.php プロジェクト: kant312/sop
 /**
  * Uploads a file directly to a field for an entry.
  *
  * @throws Exception
  * @return null
  */
 public function actionExpressUpload()
 {
     $this->requireAjaxRequest();
     $fieldId = craft()->request->getPost('fieldId');
     $elementId = craft()->request->getPost('elementId');
     if (empty($_FILES['files']) || !isset($_FILES['files']['error'][0]) || $_FILES['files']['error'][0] != 0) {
         throw new Exception(Craft::t('The upload failed.'));
     }
     $field = craft()->fields->populateFieldType(craft()->fields->getFieldById($fieldId));
     if (!$field instanceof AssetsFieldType) {
         throw new Exception(Craft::t('That is not an Assets field.'));
     }
     if ($elementId) {
         $field->element = craft()->elements->getElementById($elementId);
     }
     $targetFolderId = $field->resolveSourcePath();
     try {
         $this->_checkUploadPermissions($targetFolderId);
     } catch (Exception $e) {
         $this->returnErrorJson($e->getMessage());
     }
     $fileName = $_FILES['files']['name'][0];
     $fileLocation = AssetsHelper::getTempFilePath(pathinfo($fileName, PATHINFO_EXTENSION));
     move_uploaded_file($_FILES['files']['tmp_name'][0], $fileLocation);
     $response = craft()->assets->insertFileByLocalPath($fileLocation, $fileName, $targetFolderId, AssetConflictResolution::KeepBoth);
     $fileId = $response->getDataItem('fileId');
     // Render and return
     $element = craft()->elements->getElementById($fileId);
     $html = craft()->templates->render('_elements/element', array('element' => $element));
     $css = craft()->templates->getHeadHtml();
     $this->returnJson(array('html' => $html, 'css' => $css));
 }
コード例 #14
0
 /**
  * Replace a file
  *
  * @throws Exception
  * @return null
  */
 public function actionReplaceFile()
 {
     $this->requireAjaxRequest();
     $fileId = craft()->request->getPost('fileId');
     try {
         if (empty($_FILES['replaceFile']) || !isset($_FILES['replaceFile']['error']) || $_FILES['replaceFile']['error'] != 0) {
             throw new Exception(Craft::t('The upload failed.'));
         }
         $existingFile = craft()->assets->getFileById($fileId);
         if (!$existingFile) {
             throw new Exception(Craft::t('The file to be replaced cannot be found.'));
         }
         $targetFolderId = $existingFile->folderId;
         try {
             $this->_checkUploadPermissions($targetFolderId);
         } catch (Exception $e) {
             $this->returnErrorJson($e->getMessage());
         }
         // Fire an 'onBeforeReplaceFile' event
         $event = new Event($this, array('asset' => $existingFile));
         craft()->assets->onBeforeReplaceFile($event);
         // Is the event preventing this from happening?
         if (!$event->performAction) {
             throw new Exception(Craft::t('The file could not be replaced.'));
         }
         $fileName = AssetsHelper::cleanAssetName($_FILES['replaceFile']['name']);
         $fileLocation = AssetsHelper::getTempFilePath(pathinfo($fileName, PATHINFO_EXTENSION));
         move_uploaded_file($_FILES['replaceFile']['tmp_name'], $fileLocation);
         $response = craft()->assets->insertFileByLocalPath($fileLocation, $fileName, $targetFolderId, AssetConflictResolution::KeepBoth);
         $insertedFileId = $response->getDataItem('fileId');
         $newFile = craft()->assets->getFileById($insertedFileId);
         if ($newFile && $existingFile) {
             $source = craft()->assetSources->populateSourceType($newFile->getSource());
             if (StringHelper::toLowerCase($existingFile->filename) == StringHelper::toLowerCase($fileName)) {
                 $filenameToUse = $existingFile->filename;
             } else {
                 // If the file uploaded had to resolve a conflict, grab the final filename
                 if ($response->getDataItem('filename')) {
                     $filenameToUse = $response->getDataItem('filename');
                 } else {
                     $filenameToUse = $fileName;
                 }
             }
             $source->replaceFile($existingFile, $newFile, $filenameToUse);
             IOHelper::deleteFile($fileLocation, true);
         } else {
             throw new Exception(Craft::t('Something went wrong with the replace operation.'));
         }
     } catch (Exception $exception) {
         $this->returnErrorJson($exception->getMessage());
     }
     // Fire an 'onReplaceFile' event
     craft()->assets->onReplaceFile(new Event($this, array('asset' => $existingFile)));
     $this->returnJson(array('success' => true, 'fileId' => $fileId));
 }
 /**
  * Submit Entry
  *
  */
 public function actionSubmitEntry()
 {
     $this->requirePostRequest();
     // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     // VARIABLES
     // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     $files = '';
     $ajax = false;
     $passedValidation = true;
     $validationErrors = [];
     $submissionErrorMessage = [];
     $customSuccessMessage = '';
     $customErrorMessage = '';
     // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     // FORM
     // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     $form = craft()->formBuilder2_entry->getFormByHandle(craft()->request->getPost('formHandle'));
     // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     // FORM SUBMISSION
     // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     $formFields = $form->fieldLayout->getFieldLayout()->getFields();
     // Get all form fields
     $submission = craft()->request->getPost();
     // Get all values from the submitted form
     $submissionData = $this->filterSubmissionKeys($submission);
     // Fillter out unused submission data
     // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     // FORM ATTRIBUTES
     // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     $attributes = $form->getAttributes();
     $formSettings = $attributes['formSettings'];
     $spamProtectionSettings = $attributes['spamProtectionSettings'];
     $messageSettings = $attributes['messageSettings'];
     $notificationSettings = $attributes['notificationSettings'];
     // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     // FORM SETTINGS ||| (1) Custom Redirect, (2) File Uploads, (3) Ajax Submissions
     // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     // (1) Custom Redirect
     if ($formSettings['formRedirect']['customRedirect'] != '') {
         $redirectUrl = $formSettings['formRedirect']['customRedirectUrl'];
     }
     // (2) File Uploads
     if ($formSettings['hasFileUploads'] == '1') {
         foreach ($formFields as $key => $value) {
             $field = $value->getField();
             switch ($field->type) {
                 case 'Assets':
                     $uploadedFiles = UploadedFile::getInstancesByName($field->handle);
                     $allowedKinds = [];
                     if ($field->settings['restrictFiles']) {
                         $allowedKinds = $field->settings['allowedKinds'];
                     }
                     foreach ($uploadedFiles as $file) {
                         $fileKind = IOHelper::getFileKind(IOHelper::getExtension($file->getName()));
                         if (in_array($fileKind, $allowedKinds)) {
                             $files[] = array('folderId' => $field->settings['singleUploadLocationSource'][0], 'sourceId' => $field->settings['singleUploadLocationSource'][0], 'filename' => $file->getName(), 'location' => $file->getTempName(), 'type' => $file->getType(), 'kind' => $fileKind);
                         } else {
                             $submissionErrorMessage[] = Craft::t('File type is not allowed!');
                         }
                     }
                     break;
             }
         }
     }
     // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     // FORM CUSTOM MESSAGES ||| (1) Success Message (2) Error Message
     // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     // (1) Success Message
     $customSuccessMessage = $messageSettings['successMessage'] ? $messageSettings['successMessage'] : Craft::t('Submission was successful.');
     // (2) Error Message
     $customErrorMessage = $messageSettings['errorMessage'] ? $messageSettings['errorMessage'] : Craft::t('There was a problem with your submission.');
     // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     // (3) Ajax Submissions
     if ($formSettings['ajaxSubmit'] == '1') {
         $this->requireAjaxRequest();
         $ajax = true;
     }
     // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     // FORM SPAM PROTECTION ||| (1) Timed Method (2) Honeypot Method
     // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     // (1) Timed Method
     if ($spamProtectionSettings['spamTimeMethod'] == '1') {
         $formSubmissionTime = (int) craft()->request->getPost('spamTimeMethod');
         $submissionDuration = time() - $formSubmissionTime;
         $allowedTime = (int) $spamProtectionSettings['spamTimeMethodTime'];
         if ($submissionDuration < $allowedTime) {
             if ($ajax) {
                 $this->returnJson(['validationErrors' => [Craft::t('You submitted too fast, you are robot!')], 'customErrorMessage' => $customErrorMessage]);
             } else {
                 $spamTimedMethod = false;
                 $submissionErrorMessage[] = Craft::t('You submitted too fast, you are robot!');
             }
         } else {
             $spamTimedMethod = true;
         }
     } else {
         $spamTimedMethod = true;
     }
     // (2) Honeypot Method
     if ($spamProtectionSettings['spamHoneypotMethod'] == '1') {
         $honeypotField = craft()->request->getPost('email-address-new');
         if ($honeypotField != '') {
             if ($ajax) {
                 $this->returnJson(['validationErrors' => [Craft::t('You tried the honey, you are robot bear!')], 'customErrorMessage' => $customErrorMessage]);
             } else {
                 $spamHoneypotMethod = false;
                 $submissionErrorMessage[] = Craft::t('You tried the honey, you are robot bear!');
             }
         } else {
             $spamHoneypotMethod = true;
         }
     } else {
         $spamHoneypotMethod = true;
     }
     // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     // NEW FORM MODEL
     // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     $submissionEntry = new FormBuilder2_EntryModel();
     $submissionEntry->formId = $form->id;
     $submissionEntry->title = $form->name;
     $submissionEntry->submission = $submissionData;
     // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     // FAILED SUBMISSION REDIRECT W/MESSAGES (Spam Protection)
     // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     if ($submissionErrorMessage) {
         craft()->userSession->setFlash('error', $customErrorMessage);
         craft()->urlManager->setRouteVariables(array('errors' => $submissionErrorMessage));
     }
     // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     // VALIDATE SUBMISSION DATA
     // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     $validation = craft()->formBuilder2_entry->validateEntry($form, $submissionData, $files);
     // if ($validation != '') {
     if (!empty($validation)) {
         if ($ajax) {
             $this->returnJson(['passedValidation' => false, 'validationErrors' => $validation, 'customErrorMessage' => $customErrorMessage]);
         } else {
             craft()->userSession->setFlash('error', $customErrorMessage);
             $passedValidation = false;
             return craft()->urlManager->setRouteVariables(['value' => $submissionData, 'errors' => $validation]);
         }
     }
     // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     // PROCESS SUBMISSION ENTRY
     // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     if (!$submissionErrorMessage && $passedValidation && $spamTimedMethod && $spamHoneypotMethod) {
         // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
         // FILE UPLOADS
         // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
         $fileIds = [];
         $fileCollection = [];
         $tempPath = [];
         if ($files) {
             foreach ($files as $key => $file) {
                 $tempPath = AssetsHelper::getTempFilePath($file['filename']);
                 move_uploaded_file($file['location'], $tempPath);
                 $response = craft()->assets->insertFileByLocalPath($tempPath, $file['filename'], $file['folderId'], AssetConflictResolution::KeepBoth);
                 $fileIds[] = $response->getDataItem('fileId');
                 $fileCollection[] = ['tempPath' => $tempPath, 'filename' => $file['filename'], 'type' => $file['type']];
             }
             $submissionEntry->files = $fileIds;
         }
         $submissionResponseId = craft()->formBuilder2_entry->processSubmissionEntry($submissionEntry);
         if ($submissionResponseId) {
             // Notify Admin of Submission
             if (isset($notificationSettings['notifySubmission'])) {
                 if ($notificationSettings['notifySubmission'] == '1') {
                     $this->notifyAdminOfSubmission($submissionResponseId, $fileCollection, $form);
                 }
             }
             // Notify Submitter of Submission
             if (isset($notificationSettings['notifySubmitter'])) {
                 if ($notificationSettings['notifySubmitter'] == '1') {
                     $this->notifySubmitterOfSubmission($submissionResponseId, $form);
                 }
             }
             foreach ($fileCollection as $file) {
                 IOHelper::deleteFile($file['tempPath'], true);
             }
             // Successful Submission Messages
             if ($ajax) {
                 $this->returnJson(['success' => true, 'customSuccessMessage' => $customSuccessMessage]);
             } else {
                 craft()->userSession->setFlash('success', $customSuccessMessage);
                 $cookie = new HttpCookie('formBuilder2SubmissionId', $submissionEntry->attributes['id']);
                 craft()->request->getCookies()->add($cookie->name, $cookie);
                 $this->redirectToPostedUrl();
             }
         } else {
             // Submission Error Messages
             if ($ajax) {
                 $this->returnJson(['error' => true, 'customErrorMessage' => $customErrorMessage]);
             } else {
                 craft()->userSession->setFlash('error', $customErrorMessage);
                 return craft()->urlManager->setRouteVariables(['value' => $submissionData, 'errors' => $validation]);
             }
         }
     }
     // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 }