public function RegistrationForm() { if ($this->request->getVar('key') && $this->request->getVar('token')) { $key = $this->request->getVar('key'); $token = $this->request->getVar('token'); } else { if ($this->request->isPOST()) { $key = $this->request->requestVar('Key'); $token = $this->request->requestVar('Token'); } } if ($key && $token) { $memory = ContributorMaps_Data::get()->filter(array('Unique_Key' => $key, 'EditToken' => $token, 'EditTokenExpires:GreaterThanOrEqual' => date('Y-m-d')))->First(); if (!$memory) { return $this->redirect($this->Link("?action=edit&status=2")); } } else { if (Session::get("FormInfo.RegistrationForm_Edit.data")) { $memory = Session::get("FormInfo.RegistrationForm_Edit.data"); } } $fields = new FieldList(new TextField('Name', 'Name*'), new TextField('Surname', 'Surname*'), new EmailField('Email', 'Email*'), new TextField('Location', 'Location* (e.g. Berlin, Deutschland)'), new HeaderField('Skills'), new CheckboxField('Skills_Design', 'Design'), new CheckboxField('Skills_Dev', 'Development'), new CheckboxField('Skills_Doc', 'Documentation'), new CheckboxField('Skills_Infra', 'Infrastructure'), new CheckboxField('Skills_l10n', 'Localisation'), new CheckboxField('Skills_Marketing', 'Marketing'), new CheckboxField('Skills_QA', 'Quality Assurance'), new CheckboxField('Skills_Base', 'Support - Base'), new CheckboxField('Skills_Calc', 'Support - Calc'), new CheckboxField('Skills_Draw', 'Support - Draw'), new CheckboxField('Skills_Impress', 'Support - Impress'), new CheckboxField('Skills_Math', 'Support - Math'), new CheckboxField('Skills_Writer', 'Support - Writer')); if ($memory) { $fields->push(new HiddenField('Key', '', $key)); $fields->push(new HiddenField('Token', '', $token)); $actions = new FieldList(new FormAction('processEditForm', 'Update')); } else { $recaptcha = new RecaptchaField('Captcha'); $recaptcha->jsOptions = array('theme' => 'white'); $fields->push($recaptcha); $actions = new FieldList(new FormAction('processForm', 'Register')); } $validator = new RequiredFields('Name', 'Surname', 'Email', 'Location'); $form = new Form($this, 'RegistrationForm', $fields, $actions, $validator); //Load previously submitted data if ($memory) { $form->loadDataFrom($memory); Session::clear("FormInfo.{$form->FormName()}_Edit.data"); } else { if (Session::get("FormInfo.{$form->FormName()}.data")) { $form->loadDataFrom(Session::get("FormInfo.{$form->FormName()}.data")); Session::clear("FormInfo.{$form->FormName()}.data"); } } return $form; }
/** * Returns the HTML ID of the field - used in the template by label tags. * The ID is generated as FormName_FieldName. All Field functions should ensure * that this ID is included in the field. */ public function ID() { $name = preg_replace('/(^-)|(-$)/', '', preg_replace('/[^A-Za-z0-9_-]+/', '-', $this->name)); if ($this->form) { return $this->form->FormName() . '_' . $name; } else { return $name; } }
protected function getTicketsError(Form $form) { $errors = Session::get("FormInfo.{$form->FormName()}.errors"); if ($errors) { foreach ($errors as $error) { if ($error['fieldName'] == 'Tickets') { return $this->getErrorTypeForMessage($error['message']); } } } }
public function validateStep($data, Form $form) { Session::set("FormInfo.{$form->FormName()}.data", $form->getData()); $datetime = $this->getForm()->getController()->getDateTime(); $session = $this->getForm()->getSession(); $data = $form->getData(); $has = false; if ($datetime->Event()->OneRegPerEmail) { if (Member::currentUserID()) { $email = Member::currentUser()->Email; } else { $email = $data['Email']; } $existing = DataObject::get_one('EventRegistration', sprintf('"Email" = \'%s\' AND "Status" <> \'Canceled\' AND "TimeID" = %d', Convert::raw2sql($email), $datetime->ID)); if ($existing) { $form->addErrorMessage('Email', 'A registration for this email address already exists', 'required'); return false; } } // Ensure that the entered ticket data is valid. if (!$this->form->validateTickets($data['Tickets'], $form)) { return false; } // Finally add the tickets to the actual registration. $registration = $this->form->getSession()->getRegistration(); $hasLimit = (bool) $this->form->getController()->getDateTime()->Event()->RegistrationTimeLimit; if ($hasLimit && !$registration->isInDB()) { $registration->write(); } $total = $this->getTotal(); $registration->Total->setCurrency($total->getCurrency()); $registration->Total->setAmount($total->getAmount()); $registration->Name = $data['Name']; $registration->Email = $data['Email']; $registration->write(); $registration->Tickets()->removeAll(); foreach ($data['Tickets'] as $id => $quantity) { if ($quantity) { $registration->Tickets()->add($id, array('Quantity' => $quantity)); } } return true; }
/** * User Defined Form. Feature of the user defined form is if you want the * form to appear in a custom location on the page you can use $UserDefinedForm * in the content area to describe where you want the form * * @return Form */ public function Form() { $fields = new FieldSet(); $fieldValidation = array(); $fieldValidationRules = array(); $CustomDisplayRules = ""; $defaults = ""; $this->SubmitButtonText = ($this->SubmitButtonText) ? $this->SubmitButtonText : _t('UserDefinedForm.SUBMITBUTTON', 'Submit'); if($this->Fields()) { foreach($this->Fields() as $field) { $fieldToAdd = $field->getFormField(); if(!$fieldToAdd) break; $fieldValidationOptions = array(); // Set the Error Messages $errorMessage = sprintf(_t('Form.FIELDISREQUIRED').'.', strip_tags("'". ($field->Title ? $field->Title : $field->Name) . "'")); $errorMessage = ($field->CustomErrorMessage) ? $field->CustomErrorMessage : $errorMessage; $fieldToAdd->setCustomValidationMessage($errorMessage); // Is this field required if($field->Required) { $fieldValidation[$field->Name] = $errorMessage; $fieldValidationOptions['required'] = true; } // Add field to the form $fields->push($fieldToAdd); // Ask our form field for some more information on hour it should be validated $fieldValidationOptions = array_merge($fieldValidationOptions, $field->getValidation()); // Check if we have need to update the global validation if($fieldValidationOptions) { $fieldValidationRules[$field->Name] = $fieldValidationOptions; } $fieldId = $field->Name; if($field->ClassName == 'EditableFormHeading') { $fieldId = 'Form_Form_'.$field->Name; } // Is this Field Show by Default if(!$field->ShowOnLoad()) { $defaults .= "$(\"#" . $fieldId . "\").hide();\n"; } // Check for field dependencies / default if($field->Dependencies()) { foreach($field->Dependencies() as $dependency) { if(is_array($dependency) && isset($dependency['ConditionField']) && $dependency['ConditionField'] != "") { // get the field which is effected $formName = Convert::raw2sql($dependency['ConditionField']); $formFieldWatch = DataObject::get_one("EditableFormField", "Name = '$formName'"); if(!$formFieldWatch) break; // watch out for multiselect options - radios and check boxes if(is_a($formFieldWatch, 'EditableDropdown')) { $fieldToWatch = "$(\"select[name='".$dependency['ConditionField']."']\")"; } // watch out for checkboxs as the inputs don't have values but are 'checked else if(is_a($formFieldWatch, 'EditableCheckboxGroupField')) { $fieldToWatch = "$(\"input[name='".$dependency['ConditionField']."[".$dependency['Value']."]']\")"; } else { $fieldToWatch = "$(\"input[name='".$dependency['ConditionField']."']\")"; } // show or hide? $view = (isset($dependency['Display']) && $dependency['Display'] == "Hide") ? "hide" : "show"; $opposite = ($view == "show") ? "hide" : "show"; // what action do we need to keep track of. Something nicer here maybe? // @todo encapulsation $action = "change"; if($formFieldWatch->ClassName == "EditableTextField" || $formFieldWatch->ClassName == "EditableDateField") { $action = "keyup"; } // is this field a special option field $checkboxField = false; if(in_array($formFieldWatch->ClassName, array('EditableCheckboxGroupField', 'EditableCheckbox'))) { $checkboxField = true; } // and what should we evaluate switch($dependency['ConditionOption']) { case 'IsNotBlank': $expression = ($checkboxField) ? '$(this).attr("checked")' :'$(this).val() != ""'; break; case 'IsBlank': $expression = ($checkboxField) ? '!($(this).attr("checked"))' : '$(this).val() == ""'; break; case 'HasValue': $expression = ($checkboxField) ? '$(this).attr("checked")' : '$(this).val() == "'. $dependency['Value'] .'"'; break; default: $expression = ($checkboxField) ? '!($(this).attr("checked"))' : '$(this).val() != "'. $dependency['Value'] .'"'; break; } // put it all together $CustomDisplayRules .= $fieldToWatch.".$action(function() { if(". $expression ." ) { $(\"#". $fieldId ."\").".$view."(); } else { $(\"#". $fieldId ."\").".$opposite."(); } });"; } } } } } $referer = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : ''; // Keep track of the referer $fields->push( new HiddenField( "Referrer", "", $referer ) ); // Build actions $actions = new FieldSet( new FormAction("process", $this->SubmitButtonText) ); // Do we want to add a clear form. if($this->ShowClearButton) { $actions->push(new ResetFormAction("clearForm")); } // return the form $form = new Form( $this, "Form", $fields, $actions, new RequiredFields(array_keys($fieldValidation))); $form->loadDataFrom($this->failover); $FormName = $form->FormName(); // Set the Form Name $rules = $this->array2json($fieldValidationRules); $messages = $this->array2json($fieldValidation); // set the custom script for this form Requirements::customScript(<<<JS (function($) { $(document).ready(function() { $defaults $("#$FormName").validate({ errorClass: "required", messages: $messages , rules: $rules }); $CustomDisplayRules }); })(jQuery); JS ); return $form; }
function includeJavascriptValidation() { if ($this->getJavascriptValidationHandler() == 'prototype') { Requirements::javascript(SAPPHIRE_DIR . "/thirdparty/prototype/prototype.js"); Requirements::javascript(SAPPHIRE_DIR . "/thirdparty/behaviour/behaviour.js"); Requirements::javascript(SAPPHIRE_DIR . "/javascript/prototype_improvements.js"); Requirements::add_i18n_javascript(SAPPHIRE_DIR . '/javascript/lang'); Requirements::javascript(SAPPHIRE_DIR . "/javascript/Validator.js"); $code = $this->javascript(); $formID = $this->form->FormName(); $js = <<<JS Behaviour.register({ \t'#{$formID}': { \t\tvalidate : function(fromAnOnBlur) { \t\t\tinitialiseForm(this, fromAnOnBlur); \t\t\t{$code} \t\t\tvar error = hasHadFormError(); \t\t\tif(!error && fromAnOnBlur) clearErrorMessage(fromAnOnBlur); \t\t\tif(error && !fromAnOnBlur) focusOnFirstErroredField(); \t\t\t \t\t\treturn !error; \t\t}, \t\tonsubmit : function() { \t\t\tif(typeof this.bypassValidation == 'undefined' || !this.bypassValidation) return this.validate(); \t\t} \t}, \t'#{$formID} input' : { \t\tinitialise: function() { \t\t\tif(!this.old_onblur) this.old_onblur = function() { return true; } \t\t\tif(!this.old_onfocus) this.old_onfocus = function() { return true; } \t\t}, \t\tonblur : function() { \t\t\tif(this.old_onblur()) { \t\t\t\t// Don't perform instant validation for CalendarDateField fields; it creates usability wierdness. \t\t\t\tif(this.parentNode.className.indexOf('calendardate') == -1 || this.value) { \t\t\t\t\treturn \$('{$formID}').validate(this); \t\t\t\t} else { \t\t\t\t\treturn true; \t\t\t\t} \t\t\t} \t\t} \t}, \t'#{$formID} textarea' : { \t\tinitialise: function() { \t\t\tif(!this.old_onblur) this.old_onblur = function() { return true; } \t\t\tif(!this.old_onfocus) this.old_onfocus = function() { return true; } \t\t}, \t\tonblur : function() { \t\t\tif(this.old_onblur()) { \t\t\t\treturn \$('{$formID}').validate(this); \t\t\t} \t\t} \t}, \t'#{$formID} select' : { \t\tinitialise: function() { \t\t\tif(!this.old_onblur) this.old_onblur = function() { return true; } \t\t}, \t\tonblur : function() { \t\t\tif(this.old_onblur()) { \t\t\t\treturn \$('{$formID}').validate(this); \t\t\t} \t\t} \t} }); JS; Requirements::customScript($js); // HACK Notify the form that the validators client-side validation code has already been included if ($this->form) { $this->form->jsValidationIncluded = true; } } }
/** * Handles the form submission for the speaker "Update my details" page * @param array $data * @param Form $form * @return [type] [description] */ public function doReviewForm($data, $form) { Session::set("FormInfo.{$form->FormName()}.data", $data); if (empty(strip_tags($data['Bio']))) { $form->addErrorMessage('Bio', 'Please enter a bio', 'bad'); return $this->redirectBack(); } $form->saveInto($this->speaker); $this->speaker->Member()->setSummitState('BUREAU_SEEEN'); if ($data['VideoAgreement'] == 1) { $this->speaker->Member()->setSummitState('VIDEO_AGREEMENT_AGREED', $this->parent->getParent()->LegalAgreement); } else { $this->speaker->Member()->setSummitState('VIDEO_AGREEMENT_DECLINED'); } $this->speaker->write(); $form->sessionMessage('Your details have been updated.', 'good'); Session::clear("FormInfo.{$form->FormName()}.data", $data); return $this->parent->getParent()->redirectBack(); }
/** * 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); }
/** * Get the form for the page. Form can be modified by calling {@link updateForm()} * on a UserDefinedForm extension * * @return Form|false */ public function Form() { $fields = $this->getFormFields(); if (!$fields || !$fields->exists()) { return false; } $actions = $this->getFormActions(); // get the required fields including the validation $required = $this->getRequiredFields(); // generate the conditional logic $this->generateConditionalJavascript(); $form = new Form($this, "Form", $fields, $actions, $required); $data = Session::get("FormInfo.{$form->FormName()}.data"); if (is_array($data)) { $form->loadDataFrom($data); } $this->extend('updateForm', $form); return $form; }
public function Form() { if ($this->URLParams['Action'] === 'completed' || $this->URLParams['Action'] == 'submitted') { return; } $dataFields = singleton('Recipient')->getFrontEndFields()->dataFields(); if ($this->CustomLabel) { $customLabel = Convert::json2array($this->CustomLabel); } $fields = array(); if ($this->Fields) { $fields = explode(",", $this->Fields); } $recipientInfoSection = new CompositeField(); $requiredFields = Convert::json2array($this->Required); if (!empty($fields)) { foreach ($fields as $field) { if (isset($dataFields[$field]) && $dataFields[$field]) { if (is_a($dataFields[$field], "ImageField")) { if (isset($requiredFields[$field])) { $title = $dataFields[$field]->Title() . " * "; } else { $title = $dataFields[$field]->Title(); } $dataFields[$field] = new SimpleImageField($dataFields[$field]->Name(), $title); } else { if (isset($requiredFields[$field])) { if (isset($customLabel[$field])) { $title = $customLabel[$field] . " * "; } else { $title = $dataFields[$field]->Title() . " * "; } } else { if (isset($customLabel[$field])) { $title = $customLabel[$field]; } else { $title = $dataFields[$field]->Title(); } } $dataFields[$field]->setTitle($title); } $recipientInfoSection->push($dataFields[$field]); } } } $formFields = new FieldList(new HeaderField("CustomisedHeading", $this->owner->CustomisedHeading), $recipientInfoSection); $recipientInfoSection->setID("MemberInfoSection"); if ($this->MailingLists) { $mailinglists = DataObject::get("MailingList", "ID IN (" . $this->MailingLists . ")"); } if (isset($mailinglists) && $mailinglists && $mailinglists->count() > 1) { $newsletterSection = new CompositeField(new LabelField("Newsletters", _t("SubscriptionPage.To", "Subscribe to:"), 4), new CheckboxSetField("NewsletterSelection", "", $mailinglists, $mailinglists->getIDList())); $formFields->push($newsletterSection); } $buttonTitle = $this->SubmissionButtonText; $actions = new FieldList(new FormAction('doSubscribe', $buttonTitle)); if (!empty($requiredFields)) { $required = new RequiredFields($requiredFields); } else { $required = null; } $form = new Form($this, "Form", $formFields, $actions, $required); // using jQuery to customise the validation of the form $FormName = $form->FormName(); $validationMessage = Convert::json2array($this->ValidationMessage); if (!empty($requiredFields)) { $jsonRuleArray = array(); $jsonMessageArray = array(); foreach ($requiredFields as $field => $true) { if ($true) { if (isset($validationMessage[$field]) && $validationMessage[$field]) { $error = $validationMessage[$field]; } else { $label = isset($customLabel[$field]) ? $customLabel[$field] : $dataFields[$field]->Title(); $error = sprintf(_t('Newsletter.PleaseEnter', "Please enter your %s field"), $label); } if ($field === 'Email') { $jsonRuleArray[] = $field . ":{required: true, email: true}"; $message = <<<JSON { required: "<span class='exclamation'></span><span class='validation-bubble'> {$error}<span></span></span>", email: "<span class='exclamation'></span><span class='validation-bubble'> Please enter a valid email address<span></span></span>" } JSON; $jsonMessageArray[] = $field . ":{$message}"; } else { $jsonRuleArray[] = $field . ":{required: true}"; $message = <<<HTML <span class='exclamation'></span><span class='validation-bubble'>{$error}<span></span></span> HTML; $jsonMessageArray[] = $field . ":\"{$message}\""; } } } $rules = "{" . implode(", ", $jsonRuleArray) . "}"; $messages = "{" . implode(",", $jsonMessageArray) . "}"; } else { $rules = "{Email:{required: true, email: true}}"; $emailAddrMsg = _t('Newsletter.ValidEmail', 'Please enter your email address'); $messages = <<<JS {Email: { required: "<span class='exclamation'></span><span class='validation-bubble'> {$emailAddrMsg}<span></span></span>", email: "<span class='exclamation'></span><span class='validation-bubble'> {$emailAddrMsg}<span></span></span>" }} JS; } // set the custom script for this form Requirements::customScript(<<<JS (function(\$) { \tjQuery(document).ready(function() { \t\t\$("#{$FormName}").validate({ \t\t\terrorPlacement: function(error, element) { \t\t\t\terror.insertAfter(element); \t\t\t}, \t\t\tfocusCleanup: true, \t\t\tmessages: {$messages}, \t\t\trules: {$rules} \t\t}); \t}); })(jQuery); JS ); return $form; }
/** * 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(); }
function Form() { if ($this->URLParams['Action'] == 'complete') { return; } $dataFields = singleton('Member')->getCMSFields()->dataFields(); if ($this->CustomisedLables) { $customisedLables = Convert::json2array($this->CustomisedLables); } $fields = array(); if ($this->Fields) { $fields = explode(",", $this->Fields); } $memberInfoSection = new CompositeField(); if (!empty($fields)) { foreach ($fields as $field) { if (isset($dataFields[$field]) && $dataFields[$field]) { if (isset($customisedLables[$field])) { $dataFields[$field]->setTitle($customisedLables[$field]); } if (is_a($dataFields[$field], "ImageField")) { $dataFields[$field] = new SimpleImageField($dataFields[$field]->Name(), $dataFields[$field]->Title()); } $memberInfoSection->push($dataFields[$field]); } } } $formFields = new FieldSet(new HeaderField("MemberInfo", _t("SubscriptionPage.Information", "Member Infomation:"), 2), $memberInfoSection); $memberInfoSection->setID("MemberInfoSection"); if ($this->NewsletterTypes) { $newsletters = DataObject::get("NewsletterType", "ID IN (" . $this->NewsletterTypes . ")"); } if (isset($newsletters) && $newsletters && $newsletters->count() > 1) { $newsletterSection = new CompositeField(new LabelField("Newsletters", _t("SubscriptionPage.To", "Subscribe to:"), 4), new CheckboxSetField("NewsletterSelection", "", $newsletters)); $formFields->push($newsletterSection); } $buttonTitle = $this->SubmissionButtonText; $actions = new FieldSet(new FormAction('doSubscribe', $buttonTitle)); $form = new Form($this, "Form", $formFields, $actions); // using jQuery to customise the validation of the form $FormName = $form->FormName(); $messages = $this->CustomisedErrors; if ($this->Required) { $jsonRuleArray = array(); foreach (Convert::json2array($this->Required) as $field => $true) { if ($true) { if ($field === 'Email') { $jsonRuleArray[] = $field . ":{required: true, email: true}"; } else { $jsonRuleArray[] = $field . ":{required: true}"; } } } $rules = "{" . implode(", ", $jsonRuleArray) . "}"; } else { $rules = "{Email:{required: true, email: true}}"; } // set the custom script for this form Requirements::customScript(<<<JS \t\t\t(function(\$) { \t\t\t\tjQuery(document).ready(function() { \t\t\t\t\tjQuery("#{$FormName}").validate({ \t\t\t\t\t\terrorClass: "required", \t\t\t\t\t\tfocusCleanup: true, \t\t\t\t\t\tmessages: {$messages}, \t\t\t\t\t\trules: {$rules} \t\t\t\t\t}); \t\t\t\t}); \t\t\t})(jQuery); JS ); return $form; }
/** * Returns a representation of the provided {@link Form} as structured data, * based on the request data. * * @param Form $form * @return array */ protected function getSchemaForForm(Form $form) { $request = $this->getRequest(); $return = null; // Valid values for the "X-Formschema-Request" header are "schema" and "state". // If either of these values are set they will be stored in the $schemaParst array // and used to construct the response body. if ($schemaHeader = $request->getHeader('X-Formschema-Request')) { $schemaParts = array_filter(explode(',', $schemaHeader), function ($value) { $validHeaderValues = ['schema', 'state']; return in_array(trim($value), $validHeaderValues); }); } else { $schemaParts = ['schema']; } $return = ['id' => $form->FormName()]; if (in_array('schema', $schemaParts)) { $return['schema'] = $this->schema->getSchema($form); } if (in_array('state', $schemaParts)) { $return['state'] = $this->schema->getState($form); } return $return; }
/** * Register a new member. This action is deigned to be intercepted at 2 * points: * * - Modify the initial member filter (so that you can perfom bespoke * member filtering * * - Modify the member user before saving (so we can add extra permissions * etc) * * @param array $data User submitted data * @param Form $form Registration form */ public function doRegister($data, $form) { $filter = array(); if (isset($data['Email'])) { $filter['Email'] = $data['Email']; } $this->extend("updateMemberFilter", $filter); // Check if a user already exists if ($member = Member::get()->filter($filter)->first()) { if ($member) { $form->addErrorMessage("Blurb", "Sorry, an account already exists with those details.", "bad"); // Load errors into session and post back unset($data["Password"]); Session::set("Form.{$form->FormName()}.data", $data); return $this->redirectBack(); } } $member = Member::create(); $form->saveInto($member); // Set verification code for this user $member->VerificationCode = sha1(mt_rand() . mt_rand()); $member->write(); $this->extend("updateNewMember", $member, $data); // Add member to any groups that have been specified if (count(Users::config()->new_user_groups)) { $groups = Group::get()->filter(array("Code" => Users::config()->new_user_groups)); foreach ($groups as $group) { $group->Members()->add($member); $group->write(); } } // Send a verification email, if needed if (Users::config()->send_verification_email) { $sent = $this->send_verification_email($member); } else { $sent = false; } // Login (if enabled) if (Users::config()->login_after_register) { $member->LogIn(isset($data['Remember'])); } // If a back URL is used in session. if (Session::get("BackURL")) { $redirect_url = Session::get("BackURL"); } else { $redirect_url = Controller::join_links(BASE_URL, Users_Account_Controller::config()->url_segment); } return $this->redirect($redirect_url); }
/** * returns a form of the product if it can be purchased. * * @return Form | NULL */ function VariationForm() { if ($this->owner->canPurchase(null, true)) { $farray = array(); $requiredfields = array(); $attributes = $this->owner->VariationAttributes(); if ($attributes) { foreach ($attributes as $attribute) { $options = $this->possibleValuesForAttributeType($attribute); if ($options && $options->count()) { $farray[] = $attribute->getDropDownField(_t("ProductWithVariationDecorator.CHOOSE", "choose") . " {$attribute->Label} " . _t("ProductWithVariationDecorator.DOTDOTDOT", "..."), $options); //new DropDownField("Attribute_".$attribute->ID,$attribute->Name,); $requiredfields[] = "ProductAttributes[{$attribute->ID}]"; } } } $fields = new FieldList($farray); $fields->push(new NumericField('Quantity', 'Quantity', 1)); //TODO: perhaps use a dropdown instead (elimiates need to use keyboard) $actions = new FieldList(new FormAction('addVariation', _t("ProductWithVariationDecorator.ADDLINK", "Add to cart"))); $requiredfields[] = 'Quantity'; $requiredFieldsClass = "RequiredFields"; $validator = new $requiredFieldsClass($requiredfields); $form = new Form($this->owner, 'VariationForm', $fields, $actions, $validator); Requirements::themedCSS('variationsform', "ecommerce_product_variation"); //variation options json generation if (Config::inst()->get('ProductWithVariationDecorator_Controller', 'use_js_validation')) { //TODO: make javascript json inclusion optional Requirements::javascript('ecommerce_product_variation/javascript/SelectEcommerceProductVariations.js'); $jsObjectName = $form->FormName() . "Object"; Requirements::customScript("var {$jsObjectName} = new SelectEcommerceProductVariations('" . $form->FormName() . "')\r\n\t\t\t\t\t\t.setJSON(" . $this->owner->VariationsForSaleJSON() . ")\r\n\t\t\t\t\t\t.init();"); } return $form; } }
/** * 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; } }