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;
 }
Example #2
0
 /**
  * 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;
     }
 }