Exemple #1
0
 /**
  * @param object                              $entity
  * @param \Symfony\Component\Form\FormFactory $formFactory
  * @param null                                $action
  * @param array                               $options
  *
  * @return \Symfony\Component\Form\FormInterface
  */
 public function createForm($entity, $formFactory, $action = null, $options = [])
 {
     $fields = $this->leadFieldModel->getFieldListWithProperties();
     $choices = [];
     foreach ($fields as $alias => $field) {
         if (!isset($choices[$field['group_label']])) {
             $choices[$field['group_label']] = [];
         }
         $choices[$field['group_label']][$alias] = $field['label'];
     }
     // Only show the lead fields not already used
     $usedLeadFields = $this->session->get('mautic.form.' . $entity['formId'] . '.fields.leadfields', []);
     $testLeadFields = array_flip($usedLeadFields);
     $currentLeadField = isset($entity['leadField']) ? $entity['leadField'] : null;
     if (!empty($currentLeadField) && isset($testLeadFields[$currentLeadField])) {
         unset($testLeadFields[$currentLeadField]);
     }
     foreach ($choices as &$group) {
         $group = array_diff_key($group, $testLeadFields);
     }
     $options['leadFields'] = $choices;
     $options['leadFieldProperties'] = $fields;
     if ($action) {
         $options['action'] = $action;
     }
     return $formFactory->create('formfield', $entity, $options);
 }
 /**
  * @param      $post
  * @param      $server
  * @param Form $form
  *
  * @return bool|array
  */
 public function saveSubmission($post, $server, Form $form, Request $request = null, $returnEvent = false)
 {
     $leadFields = $this->leadFieldModel->getFieldListWithProperties(false);
     //everything matches up so let's save the results
     $submission = new Submission();
     $submission->setDateSubmitted(new \DateTime());
     $submission->setForm($form);
     //set the landing page the form was submitted from if applicable
     if (!empty($post['mauticpage'])) {
         $page = $this->pageModel->getEntity((int) $post['mauticpage']);
         if ($page != null) {
             $submission->setPage($page);
         }
     }
     $ipAddress = $this->ipLookupHelper->getIpAddress();
     $submission->setIpAddress($ipAddress);
     if (!empty($post['return'])) {
         $referer = $post['return'];
     } elseif (!empty($server['HTTP_REFERER'])) {
         $referer = $server['HTTP_REFERER'];
     } else {
         $referer = '';
     }
     //clean the referer by removing mauticError and mauticMessage
     $referer = InputHelper::url($referer, null, null, ['mauticError', 'mauticMessage']);
     $submission->setReferer($referer);
     // Create an event to be dispatched through the processes
     $submissionEvent = new SubmissionEvent($submission, $post, $server, $request);
     // Get a list of components to build custom fields from
     $components = $this->formModel->getCustomComponents();
     $fields = $form->getFields();
     $fieldArray = [];
     $results = [];
     $tokens = [];
     $leadFieldMatches = [];
     $validationErrors = [];
     /** @var Field $f */
     foreach ($fields as $f) {
         $id = $f->getId();
         $type = $f->getType();
         $alias = $f->getAlias();
         $value = isset($post[$alias]) ? $post[$alias] : '';
         $fieldArray[$id] = ['id' => $id, 'type' => $type, 'alias' => $alias];
         if ($type == 'captcha') {
             $captcha = $this->fieldHelper->validateFieldValue($type, $value, $f);
             if (!empty($captcha)) {
                 $props = $f->getProperties();
                 //check for a custom message
                 $validationErrors[$alias] = !empty($props['errorMessage']) ? $props['errorMessage'] : implode('<br />', $captcha);
             }
             continue;
         }
         if ($f->isRequired() && empty($value)) {
             //field is required, but hidden from form because of 'ShowWhenValueExists'
             if ($f->getShowWhenValueExists() === false && !isset($post[$alias])) {
                 continue;
             }
             //somehow the user got passed the JS validation
             $msg = $f->getValidationMessage();
             if (empty($msg)) {
                 $msg = $this->translator->trans('mautic.form.field.generic.validationfailed', ['%label%' => $f->getLabel()], 'validators');
             }
             $validationErrors[$alias] = $msg;
             continue;
         }
         if (in_array($type, $components['viewOnlyFields'])) {
             //don't save items that don't have a value associated with it
             continue;
         }
         //clean and validate the input
         if ($f->isCustom()) {
             if (!isset($components['fields'][$f->getType()])) {
                 continue;
             }
             $params = $components['fields'][$f->getType()];
             if (!empty($value)) {
                 if (isset($params['valueFilter'])) {
                     if (is_string($params['valueFilter']) && is_callable(['\\Mautic\\CoreBundle\\Helper\\InputHelper', $params['valueFilter']])) {
                         $value = InputHelper::_($value, $params['valueFilter']);
                     } elseif (is_callable($params['valueFilter'])) {
                         $value = call_user_func_array($params['valueFilter'], [$f, $value]);
                     } else {
                         $value = InputHelper::_($value, 'clean');
                     }
                 } else {
                     $value = InputHelper::_($value, 'clean');
                 }
             }
             // @deprecated - BC support; to be removed in 3.0 - be sure to remove support in FormBuilderEvent as well
             if (isset($params['valueConstraints']) && is_callable($params['valueConstraints'])) {
                 $customErrors = call_user_func_array($params['valueConstraints'], [$f, $value]);
                 if (!empty($customErrors)) {
                     $validationErrors[$alias] = is_array($customErrors) ? implode('<br />', $customErrors) : $customErrors;
                 }
             }
         } elseif (!empty($value)) {
             $filter = $this->fieldHelper->getFieldFilter($type);
             $value = InputHelper::_($value, $filter);
             $isValid = $this->validateFieldValue($f, $value);
             if (true !== $isValid) {
                 $validationErrors[$alias] = is_array($isValid) ? implode('<br />', $isValid) : $isValid;
             }
         }
         // Check for custom validators
         $isValid = $this->validateFieldValue($f, $value);
         if (true !== $isValid) {
             $validationErrors[$alias] = $isValid;
         }
         $leadField = $f->getLeadField();
         if (!empty($leadField)) {
             $leadValue = $value;
             if (is_array($leadValue)) {
                 // Multiselect lead fields store the values with bars
                 $delimeter = 'multiselect' === $leadFields[$leadField]['type'] ? '|' : ', ';
                 $leadValue = implode($delimeter, $leadValue);
             }
             $leadFieldMatches[$leadField] = $leadValue;
         }
         //convert array from checkbox groups and multiple selects
         if (is_array($value)) {
             $value = implode(', ', $value);
         }
         $tokens["{formfield={$alias}}"] = $value;
         //save the result
         if ($f->getSaveResult() !== false) {
             $results[$alias] = $value;
         }
     }
     // Set the results
     $submission->setResults($results);
     // Update the event
     $submissionEvent->setFields($fieldArray)->setTokens($tokens)->setResults($results)->setContactFieldMatches($leadFieldMatches);
     // @deprecated - BC support; to be removed in 3.0 - be sure to remove the validator option from addSubmitAction as well
     $this->validateActionCallbacks($submissionEvent, $validationErrors, $alias);
     //return errors if there any - this should be moved to right after foreach($fields) once validateActionCallbacks support is dropped
     if (!empty($validationErrors)) {
         return ['errors' => $validationErrors];
     }
     // Create/update lead
     if (!empty($leadFieldMatches)) {
         $lead = $this->createLeadFromSubmit($form, $leadFieldMatches, $leadFields);
         $submission->setLead($lead);
     }
     // Get updated lead if applicable with tracking ID
     if ($form->isInKioskMode()) {
         $lead = $this->leadModel->getCurrentLead();
     } else {
         list($lead, $trackingId, $generated) = $this->leadModel->getCurrentLead(true);
         //set tracking ID for stats purposes to determine unique hits
         $submission->setTrackingId($trackingId);
     }
     $submission->setLead($lead);
     // Save the submission
     $this->saveEntity($submission);
     // Now handle post submission actions
     try {
         $this->executeFormActions($submissionEvent);
     } catch (ValidationException $exception) {
         // The action invalidated the form for whatever reason
         $this->deleteEntity($submission);
         if ($validationErrors = $exception->getViolations()) {
             return ['errors' => $validationErrors];
         }
         return ['errors' => [$exception->getMessage()]];
     }
     if (!$form->isStandalone()) {
         // Find and add the lead to the associated campaigns
         $campaigns = $this->campaignModel->getCampaignsByForm($form);
         if (!empty($campaigns)) {
             foreach ($campaigns as $campaign) {
                 $this->campaignModel->addLead($campaign, $lead);
             }
         }
     }
     if ($this->dispatcher->hasListeners(FormEvents::FORM_ON_SUBMIT)) {
         // Reset action config from executeFormActions()
         $submissionEvent->setActionConfig(null, []);
         // Dispatch to on submit listeners
         $this->dispatcher->dispatch(FormEvents::FORM_ON_SUBMIT, $submissionEvent);
     }
     //get callback commands from the submit action
     if ($submissionEvent->hasPostSubmitCallbacks()) {
         return ['callback' => $submissionEvent];
     }
     // made it to the end so return the submission event to give the calling method access to tokens, results, etc
     // otherwise return false that no errors were encountered (to keep BC really)
     return $returnEvent ? ['submission' => $submissionEvent] : false;
 }
Exemple #3
0
 /**
  * Generate the form's html.
  *
  * @param Form $entity
  * @param bool $persist
  *
  * @return string
  */
 public function generateHtml(Form $entity, $persist = true)
 {
     //generate cached HTML
     $theme = $entity->getTemplate();
     $submissions = null;
     $lead = $this->leadModel->getCurrentLead();
     $style = '';
     if (!empty($theme)) {
         $theme .= '|';
     }
     if ($entity->usesProgressiveProfiling()) {
         $submissions = $this->getRepository()->getFormResults($entity, ['leadId' => $lead->getId(), 'limit' => 200]);
     }
     if ($entity->getRenderStyle()) {
         $templating = $this->templatingHelper->getTemplating();
         $styleTheme = $theme . 'MauticFormBundle:Builder:style.html.php';
         $style = $templating->render($this->themeHelper->checkForTwigTemplate($styleTheme));
     }
     // Determine pages
     $fields = $entity->getFields()->toArray();
     // Ensure the correct order in case this is generated right after a form save with new fields
     uasort($fields, function ($a, $b) {
         if ($a->getOrder() === $b->getOrder()) {
             return 0;
         }
         return $a->getOrder() < $b->getOrder() ? -1 : 1;
     });
     $pages = ['open' => [], 'close' => []];
     $openFieldId = $closeFieldId = $previousId = $lastPage = false;
     $pageCount = 1;
     foreach ($fields as $fieldId => $field) {
         if ('pagebreak' == $field->getType() && $openFieldId) {
             // Open the page
             $pages['open'][$openFieldId] = $pageCount;
             $openFieldId = false;
             $lastPage = $fieldId;
             // Close the page at the next page break
             if ($previousId) {
                 $pages['close'][$previousId] = $pageCount;
                 ++$pageCount;
             }
         } else {
             if (!$openFieldId) {
                 $openFieldId = $fieldId;
             }
         }
         $previousId = $fieldId;
     }
     if (!empty($pages)) {
         if ($openFieldId) {
             $pages['open'][$openFieldId] = $pageCount;
         }
         if ($previousId !== $lastPage) {
             $pages['close'][$previousId] = $pageCount;
         }
     }
     $html = $this->templatingHelper->getTemplating()->render($theme . 'MauticFormBundle:Builder:form.html.php', ['fieldSettings' => $this->getCustomComponents()['fields'], 'fields' => $fields, 'contactFields' => $this->leadFieldModel->getFieldListWithProperties(), 'form' => $entity, 'theme' => $theme, 'submissions' => $submissions, 'lead' => $lead, 'formPages' => $pages, 'lastFormPage' => $lastPage, 'style' => $style]);
     if (!$entity->usesProgressiveProfiling()) {
         $entity->setCachedHtml($html);
         if ($persist) {
             //bypass model function as events aren't needed for this
             $this->getRepository()->saveEntity($entity);
         }
     }
     return $html;
 }