/** * @return bool */ public function Required() { if ($this->form && ($validator = $this->form->getValidator())) { return $validator->fieldIsRequired($this->name); } return false; }
/** * Helper function, which adds the given $cssClass to all * $form fields specified by its requiredfields * * @param Form $form * @param string $cssClass */ public static function add_required_css(Form $form, $cssClass = "required") { if ($requiredFields = $form->getValidator()->getRequired()) { foreach ($requiredFields as $f) { // $form->dataFieldByName($f)->addExtraClass($cssClass); if ($field = $form->Fields()->fieldByName($f)) { $field->addExtraClass($cssClass); } } } }
/** * Process the form that is submitted through the site * * @param array $data * @param Form $form * * @return Redirection */ public function process($data, $form) { Session::set("FormInfo.{$form->FormName()}.data", $data); Session::clear("FormInfo.{$form->FormName()}.errors"); foreach ($this->Fields() as $field) { $messages[$field->Name] = $field->getErrorMessage()->HTML(); $formField = $field->getFormField(); if ($field->Required && $field->CustomRules()->Count() == 0) { if (isset($data[$field->Name])) { $formField->setValue($data[$field->Name]); } if (!isset($data[$field->Name]) || !$data[$field->Name] || !$formField->validate($form->getValidator())) { $form->addErrorMessage($field->Name, $field->getErrorMessage(), 'bad'); } } } if (Session::get("FormInfo.{$form->FormName()}.errors")) { Controller::curr()->redirectBack(); return; } $submittedForm = Object::create('SubmittedForm'); $submittedForm->SubmittedByID = ($id = Member::currentUserID()) ? $id : 0; $submittedForm->ParentID = $this->ID; // if saving is not disabled save now to generate the ID if (!$this->DisableSaveSubmissions) { $submittedForm->write(); } $values = array(); $attachments = array(); $submittedFields = new ArrayList(); foreach ($this->Fields() as $field) { if (!$field->showInReports()) { continue; } $submittedField = $field->getSubmittedFormField(); $submittedField->ParentID = $submittedForm->ID; $submittedField->Name = $field->Name; $submittedField->Title = $field->getField('Title'); // save the value from the data if ($field->hasMethod('getValueFromData')) { $submittedField->Value = $field->getValueFromData($data); } else { if (isset($data[$field->Name])) { $submittedField->Value = $data[$field->Name]; } } if (!empty($data[$field->Name])) { if (in_array("EditableFileField", $field->getClassAncestry())) { if (isset($_FILES[$field->Name])) { $foldername = $field->getFormField()->getFolderName(); // create the file from post data $upload = new Upload(); $file = new File(); $file->ShowInSearch = 0; try { $upload->loadIntoFile($_FILES[$field->Name], $file, $foldername); } catch (ValidationException $e) { $validationResult = $e->getResult(); $form->addErrorMessage($field->Name, $validationResult->message(), 'bad'); Controller::curr()->redirectBack(); return; } // write file to form field $submittedField->UploadedFileID = $file->ID; // attach a file only if lower than 1MB if ($file->getAbsoluteSize() < 1024 * 1024 * 1) { $attachments[] = $file; } } } } $submittedField->extend('onPopulationFromField', $field); if (!$this->DisableSaveSubmissions) { $submittedField->write(); } $submittedFields->push($submittedField); } $emailData = array("Sender" => Member::currentUser(), "Fields" => $submittedFields); $this->extend('updateEmailData', $emailData, $attachments); // email users on submit. if ($recipients = $this->FilteredEmailRecipients($data, $form)) { $email = new UserDefinedForm_SubmittedFormEmail($submittedFields); $mergeFields = $this->getMergeFieldsMap($emailData['Fields']); if ($attachments) { foreach ($attachments as $file) { if ($file->ID != 0) { $email->attachFile($file->Filename, $file->Filename, HTTP::get_mime_type($file->Filename)); } } } foreach ($recipients as $recipient) { $parsedBody = SSViewer::execute_string($recipient->getEmailBodyContent(), $mergeFields); if (!$recipient->SendPlain && $recipient->emailTemplateExists()) { $email->setTemplate($recipient->EmailTemplate); } $email->populateTemplate($recipient); $email->populateTemplate($emailData); $email->setFrom($recipient->EmailFrom); $email->setBody($parsedBody); $email->setTo($recipient->EmailAddress); $email->setSubject($recipient->EmailSubject); if ($recipient->EmailReplyTo) { $email->setReplyTo($recipient->EmailReplyTo); } // check to see if they are a dynamic reply to. eg based on a email field a user selected if ($recipient->SendEmailFromField()) { $submittedFormField = $submittedFields->find('Name', $recipient->SendEmailFromField()->Name); if ($submittedFormField && is_string($submittedFormField->Value)) { $email->setReplyTo($submittedFormField->Value); } } // check to see if they are a dynamic reciever eg based on a dropdown field a user selected if ($recipient->SendEmailToField()) { $submittedFormField = $submittedFields->find('Name', $recipient->SendEmailToField()->Name); if ($submittedFormField && is_string($submittedFormField->Value)) { $email->setTo($submittedFormField->Value); } } // check to see if there is a dynamic subject if ($recipient->SendEmailSubjectField()) { $submittedFormField = $submittedFields->find('Name', $recipient->SendEmailSubjectField()->Name); if ($submittedFormField && trim($submittedFormField->Value)) { $email->setSubject($submittedFormField->Value); } } $this->extend('updateEmail', $email, $recipient, $emailData); if ($recipient->SendPlain) { $body = strip_tags($recipient->getEmailBodyContent()) . "\n"; if (isset($emailData['Fields']) && !$recipient->HideFormData) { foreach ($emailData['Fields'] as $Field) { $body .= $Field->Title . ': ' . $Field->Value . " \n"; } } $email->setBody($body); $email->sendPlain(); } else { $email->send(); } } } $submittedForm->extend('updateAfterProcess'); Session::clear("FormInfo.{$form->FormName()}.errors"); Session::clear("FormInfo.{$form->FormName()}.data"); $referrer = isset($data['Referrer']) ? '?referrer=' . urlencode($data['Referrer']) : ""; // set a session variable from the security ID to stop people accessing // the finished method directly. if (!$this->DisableAuthenicatedFinishAction) { if (isset($data['SecurityID'])) { Session::set('FormProcessed', $data['SecurityID']); } else { // if the form has had tokens disabled we still need to set FormProcessed // to allow us to get through the finshed method if (!$this->Form()->getSecurityToken()->isEnabled()) { $randNum = rand(1, 1000); $randHash = md5($randNum); Session::set('FormProcessed', $randHash); Session::set('FormProcessedNum', $randNum); } } } if (!$this->DisableSaveSubmissions) { Session::set('userformssubmission' . $this->ID, $submittedForm->ID); } return $this->redirect($this->Link('finished') . $referrer . $this->config()->finished_anchor); }
/** * @return ZenValidator */ public function getValidator() { return parent::getValidator(); }
/** * Import the given record */ protected function processRecord($record, $columnMap, &$results, $preview = false) { $rowNumber = $results->currentIndex + (method_exists($this->source, 'getHasHeader') && $this->source->getHasHeader() ? 2 : 1); if (!is_array($record) || empty($record) || !array_filter($record)) { $results->addSkipped("Empty/invalid record data.", $results->currentIndex, $rowNumber); return; } //map incoming record according to the standardisation mapping (columnMap) $record = $this->columnMapRecord($record); //skip if required data is not present if (!$this->hasRequiredData($record)) { $results->addSkipped("Required data is missing.", $results->currentIndex, $rowNumber); return; } $modelClass = $this->objectClass; $placeholder = new $modelClass(); //populate placeholder object with transformed data foreach ($this->mappableFields_cache as $field => $label) { //skip empty fields if (!isset($record[$field]) || empty($record[$field])) { continue; } $this->transformField($placeholder, $field, $record[$field]); } //find existing duplicate of placeholder data $obj = null; $existing = null; if (!$placeholder->ID && !empty($this->duplicateChecks)) { $data = $placeholder->getQueriedDatabaseFields(); //don't match on ID, ClassName or RecordClassName unset($data['ID'], $data['ClassName'], $data['RecordClassName']); $existing = $this->findExistingObject($data); } if ($existing) { $obj = $existing; $obj->update($data); } else { $obj = $placeholder; } //callback access to every object if (is_callable($this->recordCallback)) { $callback = $this->recordCallback; $callback($obj, $record); } $changed = $existing && $obj->isChanged(); //try/catch for potential write() ValidationException try { $bSkip = false; if ($obj->hasMethod('getCMSValidator')) { $doValidator = $obj->getCMSValidator(); $form = new Form($obj, 'EditForm', $obj->getCMSFields(), $obj->getCMSActions(), $doValidator); $form->loadDataFrom($obj); $oValidator = $form->getValidator(); $oValidator->php($obj->toMap()); $arrErrors = $oValidator->getErrors(); if ($arrErrors) { //TODO: at the moment $arrErrors is array of numbers $results->addSkipped(print_r($arrErrors, true), $results->currentIndex, $rowNumber); $bSkip = true; } } if (!$bSkip) { // write obj record $obj->write(); //publish pages if ($this->publishPages && $obj instanceof SiteTree) { $obj->publish('Stage', 'Live'); } // save to results if ($existing) { if ($changed) { $results->addUpdated($obj); } else { $results->addSkipped("No data was changed.", $results->currentIndex, $rowNumber); } } else { $results->addCreated($obj); } } } catch (ValidationException $e) { $results->addSkipped($e->getMessage(), $results->currentIndex, $rowNumber); } $objID = $obj->ID; // reduce memory usage $obj->destroy(); unset($existingObj); unset($obj); return $objID; }
/** * Process the form that is submitted through the site. Note that omnipay fields are NOT saved to the database. * This is intentional (so we don't save credit card details) but should be fixed in future, so we save all fields, * but only save the last 3 digits of the credit card (and not the CVV/exp date) * * @todo: save all fields to database except credit card fields * * @param array $data * @param Form $form * * @return Redirection */ public function process($data, $form) { Session::set("FormInfo.{$form->FormName()}.data", $data); Session::clear("FormInfo.{$form->FormName()}.errors"); foreach ($this->Fields() as $field) { $messages[$field->Name] = $field->getErrorMessage()->HTML(); $formField = $field->getFormField(); if ($field->Required && $field->CustomRules()->Count() == 0) { if (isset($data[$field->Name])) { $formField->setValue($data[$field->Name]); } if (!isset($data[$field->Name]) || !$data[$field->Name] || !$formField->validate($form->getValidator())) { $form->addErrorMessage($field->Name, $field->getErrorMessage(), 'bad'); } } } if (Session::get("FormInfo.{$form->FormName()}.errors")) { Controller::curr()->redirectBack(); return; } // if there are no errors, create the payment $submittedForm = Object::create('SubmittedPaymentForm'); $submittedForm->SubmittedByID = ($id = Member::currentUserID()) ? $id : 0; $submittedForm->ParentID = $this->ID; // if saving is not disabled save now to generate the ID if (!$this->DisableSaveSubmissions) { $submittedForm->write(); } $attachments = array(); $submittedFields = new ArrayList(); foreach ($this->Fields() as $field) { if (!$field->showInReports()) { continue; } $submittedField = $field->getSubmittedFormField(); $submittedField->ParentID = $submittedForm->ID; $submittedField->Name = $field->Name; $submittedField->Title = $field->getField('Title'); // save the value from the data if ($field->hasMethod('getValueFromData')) { $submittedField->Value = $field->getValueFromData($data); } else { if (isset($data[$field->Name])) { $submittedField->Value = $data[$field->Name]; } } if (!empty($data[$field->Name])) { if (in_array("EditableFileField", $field->getClassAncestry())) { if (isset($_FILES[$field->Name])) { $foldername = $field->getFormField()->getFolderName(); // create the file from post data $upload = new Upload(); $file = new File(); $file->ShowInSearch = 0; try { $upload->loadIntoFile($_FILES[$field->Name], $file, $foldername); } catch (ValidationException $e) { $validationResult = $e->getResult(); $form->addErrorMessage($field->Name, $validationResult->message(), 'bad'); Controller::curr()->redirectBack(); return; } // write file to form field $submittedField->UploadedFileID = $file->ID; // attach a file only if lower than 1MB if ($file->getAbsoluteSize() < 1024 * 1024 * 1) { $attachments[] = $file; } } } } $submittedField->extend('onPopulationFromField', $field); if (!$this->DisableSaveSubmissions) { $submittedField->write(); } $submittedFields->push($submittedField); } /** Do the payment **/ // move this up here for our redirect link $referrer = isset($data['Referrer']) ? '?referrer=' . urlencode($data['Referrer']) : ""; // set amount $currency = $this->data()->PaymentCurrency; $paymentfieldname = $this->PaymentAmountField()->Name; $amount = $data[$paymentfieldname]; $postdata = $data; // request payment $payment = Payment::create()->init($this->data()->PaymentGateway, $amount, $currency); $payment->write(); $response = PurchaseService::create($payment)->setReturnUrl($this->Link('finished') . $referrer)->setCancelUrl($this->Link('finished') . $referrer)->purchase($postdata); // save payment to order $submittedForm->PaymentID = $payment->ID; $submittedForm->write(); $emailData = array("Sender" => Member::currentUser(), "Fields" => $submittedFields); $this->extend('updateEmailData', $emailData, $attachments); $submittedForm->extend('updateAfterProcess'); Session::clear("FormInfo.{$form->FormName()}.errors"); Session::clear("FormInfo.{$form->FormName()}.data"); // set a session variable from the security ID to stop people accessing the finished method directly if (isset($data['SecurityID'])) { Session::set('FormProcessed', $data['SecurityID']); } else { // if the form has had tokens disabled we still need to set FormProcessed // to allow us to get through the finshed method if (!$this->Form()->getSecurityToken()->isEnabled()) { $randNum = rand(1, 1000); $randHash = md5($randNum); Session::set('FormProcessed', $randHash); Session::set('FormProcessedNum', $randNum); } } if (!$this->DisableSaveSubmissions) { Session::set('userformssubmission' . $this->ID, $submittedForm->ID); } return $response->redirect(); }
/** * Determine if a check has been applied on a form field * * @package application.helper.smarty * @author Integry Systems */ function smarty_modifier_isRequired(Form $form, $fieldName, $check = 'IsNotEmptyCheck') { $checkData = $form->getValidator()->getValidatorVar($fieldName)->getCheckData(); return isset($checkData[$check]); }
/** * Using custom validateField method * as Spam Protection Field implementations may have their own error messages * and may not be based on the field being required, e.g. Honeypot Field * * @param array $data * @param Form $form * @return void */ public function validateField($data, $form) { $formField = $this->getFormField(); if (isset($data[$this->Name])) { $formField->setValue($data[$this->Name]); } $validator = $form->getValidator(); if (!$formField->validate($validator)) { $errors = $validator->getErrors(); $foundError = false; // field validate implementation may not add error to validator if (count($errors) > 0) { // check if error already added from fields' validate method foreach ($errors as $error) { if ($error['fieldName'] == $this->Name) { $foundError = $error; break; } } } if ($foundError !== false) { // use error messaging already set from validate method $form->addErrorMessage($this->Name, $foundError['message'], $foundError['messageType'], false); } else { // fallback to custom message set in CMS or default message if none set $form->addErrorMessage($this->Name, $this->getErrorMessage()->HTML(), 'error', false); } } }
/** * validate form data * * @param array $data Data to validate * @param Form $form Form * * @return boolean * * @author Sebastian Diel <*****@*****.**>, Ramon Kupper <*****@*****.**> * @since 03.09.2014 */ public function updatePHP($data, $form) { $valid = true; $groups = $data['DirectGroups']; if (!empty($groups)) { $groupObjects = Group::get()->where(sprintf('"Group"."ID" IN (%s)', $groups)); $pricetypes = array(); foreach ($groupObjects as $group) { if (!empty($group->Pricetype) && $group->Pricetype != '---') { $pricetypes[$group->Pricetype] = true; } } if (count($pricetypes) > 1) { $form->getValidator()->validationError('Groups', _t('SilvercartCustomer.ERROR_MULTIPLE_PRICETYPES'), 'bad'); $valid = false; } } return $valid; }
/** * Provides a form with jquery validation. * Generates jquery.validation by required fields attached to $form. * Behaviour/output can be overwritten by $custom, like this: * $validation->generate(array( * 'messages' => array( * 'MyCheckBoxField' => array( * 'required' => 'Some custom message here.' * ) * ), * 'rules' => array( * 'MyCheckBoxField' => array( * 'required' => true' * ) * ), * 'groups' => array( * 'SomeGroup' => "field1 field2"; * ) *)); * CAUTION: this can be tricky and can lead to unexpected behaviour, if done wrong. * * @param Form $form * @param array $config * @return JQueryValidation */ public function generate(array $custom = array()) { // validate input if (!is_array($custom)) { throw new InvalidArgumentException("{$custom} must be an array!"); } // extend config $this->config = self::array_extend($this->config, $custom); $rules = array(); $messages = array(); $groups = array(); $validation = array(); $requireExtraJs = false; $requiredFields = $this->form->getValidator()->getRequired(); $formFields = $this->form->Fields(); // walk over all fields if ($formFields) { $requiredFields = array_values($requiredFields); foreach ($formFields as $formField) { $required = array_search($formField->Name, $requiredFields); $required = is_numeric($required) && $required >= 0; switch ($formField->class) { // composite field, 2 passwordfields, should be equal case 'ConfirmedPasswordField': $field1 = $formField->Name . '[_Password]'; $field2 = $formField->Name . '[_ConfirmPassword]'; $rules[$field1] = array('required' => $required, 'minlength' => $this->config['defaults']['pwMinLength']); $rules[$field2] = array('required' => $required, 'equalTo' => "input[name='{$field1}']"); $messages[$field1] = array('minlength' => sprintf(_t('JQueryValidation.PASSWORD_TOO_SHORT', 'Password should be at least %s characters long.'), $this->config['defaults']['pwMinLength'])); $messages[$field2] = array('equalTo' => _t('JQueryValidation.CONFIRM_PW_ERROR', 'Passwords must be equal!')); if ($required) { $messages[$field1]['required'] = sprintf(_t('JQueryValidation.REQUIRED_MESSAGE', 'This field is required: %s'), $formField->children[0]->Title()); $messages[$field2]['required'] = sprintf(_t('JQueryValidation.REQUIRED_MESSAGE', 'This field is required: %s'), $formField->children[0]->Title()); } $groups[$formField->Name] = "{$field1} {$field2}"; break; case 'DateField': $requireExtraJs = true; $rules[$formField->Name] = array('required' => $required, 'date' => true); $messages[$formField->Name] = array('date' => sprintf(_t('JQueryValidation.INVALID_DATE', 'Please use this format (%s)'), $formField->getConfig('dateformat'))); if ($required) { $messages[$formField->Name]['required'] = sprintf(_t('JQueryValidation.REQUIRED_MESSAGE', 'This field is required: %s'), $formField->Title()); } break; // composite field, timefield & datefield // composite field, timefield & datefield case 'DatetimeField': $requireExtraJs = true; $field1 = $formField->Name . '[date]'; $field2 = $formField->Name . '[time]'; $rules[$field1] = array('required' => $required, 'date' => true); $rules[$field2] = array('required' => $required, 'time' => true); $messages[$field1] = array('date' => sprintf(_t('JQueryValidation.INVALID_DATE', 'Please use this format (%s)'), $formField->getDateField()->getConfig('dateformat'))); $messages[$field2] = array('time' => sprintf(_t('JQueryValidation.INVALID_DATE', 'Please use this format (%s)'), $formField->getTimeField()->getConfig('timeformat'))); if ($required) { $messages[$field1]['required'] = sprintf(_t('JQueryValidation.REQUIRED_MESSAGE', 'This field is required: %s'), $formField->Title()); $messages[$field2]['required'] = sprintf(_t('JQueryValidation.REQUIRED_MESSAGE', 'This field is required: %s'), $formField->Title()); } $groups[$formField->Name] = "{$field1} {$field2}"; break; case 'TimeField': $requireExtraJs = true; $rules[$formField->Name] = array('required' => $required, 'time' => true); $messages[$formField->Name] = array('time' => sprintf(_t('JQueryValidation.INVALID_DATE', 'Please use this format (%s)'), $formField->getConfig('timeformat'))); if ($required) { $messages[$formField->Name]['required'] = sprintf(_t('JQueryValidation.REQUIRED_MESSAGE', 'This field is required: %s'), $formField->Title()); } break; case 'EmailField': $rules[$formField->Name] = array('required' => $required, 'email' => true); $messages[$formField->Name] = array('email' => _t('JQueryValidation.INVALID_EMAIL', 'This email address seems to be invalid.')); if ($required) { $messages[$formField->Name]['required'] = sprintf(_t('JQueryValidation.REQUIRED_MESSAGE', 'This field is required: %s'), $formField->Title()); } break; case 'PasswordField': $rules[$formField->Name] = array('required' => $required, 'minlength' => $this->config['defaults']['pwMinLength']); $messages[$formField->Name] = array('minlength' => sprintf(_t('JQueryValidation.PASSWORD_TOO_SHORT', 'Password should be at least %s characters long.'), $this->config['defaults']['pwMinLength'])); if ($required) { $messages[$formField->Name]['required'] = sprintf(_t('JQueryValidation.REQUIRED_MESSAGE', 'This field is required: %s'), $formField->Title()); } break; case 'UploadField': if ($required) { $field = $formField->Name . '[Uploads][]'; $rules[$field] = array('required' => 'ss-uploadfield'); $messages[$field] = array('ss-uploadfield' => sprintf(_t('JQueryValidation.REQUIRED_MESSAGE', 'This field is required: %s'), $formField->Title())); } break; case 'NumericField': $rules[$formField->Name] = array('required' => $required, 'number' => true); $messages[$formField->Name] = array('number' => _t('JQueryValidation.NAN', 'Please enter an numeric value.')); if ($required) { $messages[$formField->Name]['required'] = sprintf(_t('JQueryValidation.REQUIRED_MESSAGE', 'This field is required: %s'), $formField->Title()); } break; default: $rules[$formField->Name] = array('required' => $required); if ($required) { $messages[$formField->Name]['required'] = sprintf(_t('JQueryValidation.REQUIRED_MESSAGE', 'This field is required: %s'), $formField->Title()); } break; } } $validation['rules'] = $rules; $validation['messages'] = $messages; $validation['groups'] = $groups; // extend $validation with $custom $validation = self::array_extend($validation, $custom); $jsVars = array('FormID' => "#{$this->form->FormName()}", 'Validation' => json_encode($validation), 'Defaults' => json_encode($this->config['validator']), 'DefaultErrorMessage' => $this->config['defaults']['errorMessage']); Requirements::javascript(self::$module . '/javascript/libs/jquery.validate.min.js'); // load extra js files if ($requireExtraJs) { $this->addExtraFiles(); } // inject main js $this->createMainJS($jsVars); return $this; } }