/** * @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); }
/** * Sets the content from post data, calling prepValueFromPost() on the field types. * * @param array|string $content * * @return null */ public function setContentFromPost($content) { if (is_string($content)) { // Keep track of where the post data is coming from, in case any field types need to know where to // look in $_FILES $this->setContentPostLocation($content); $content = craft()->request->getPost($content, array()); } if (!isset($this->_rawPostContent)) { $this->_rawPostContent = array(); } $fieldLayout = $this->getFieldLayout(); if ($fieldLayout) { // Make sure $this->_content is set $this->getContent(); foreach ($fieldLayout->getFields() as $fieldLayoutField) { $field = $fieldLayoutField->getField(); if ($field) { $handle = $field->handle; // Do we have any post data for this field? if (isset($content[$handle])) { $value = $content[$handle]; $this->setRawPostContent($handle, $value); } else { if (!empty($this->_contentPostLocation) && UploadedFile::getInstancesByName($this->_contentPostLocation . '.' . $handle)) { $value = null; } else { // No data was submitted so just skip this field continue; } } // Give the field type a chance to make changes $fieldType = $field->getFieldType(); if ($fieldType) { $fieldType->element = $this; $value = $fieldType->prepValueFromPost($value); } // Now set the prepped value on the ContentModel $this->_content->{$handle} = $value; } } } }
/** * @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; }
/** * 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]); } } } // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ }