You are here

public function SalesforceMappingFormCrudBase::buildForm in Salesforce Suite 8.4

Same name and namespace in other branches
  1. 5.0.x modules/salesforce_mapping_ui/src/Form/SalesforceMappingFormCrudBase.php \Drupal\salesforce_mapping_ui\Form\SalesforceMappingFormCrudBase::buildForm()

Form constructor.

Parameters

array $form: An associative array containing the structure of the form.

\Drupal\Core\Form\FormStateInterface $form_state: The current state of the form.

Return value

array The form structure.

Overrides EntityForm::buildForm

File

modules/salesforce_mapping_ui/src/Form/SalesforceMappingFormCrudBase.php, line 20

Class

SalesforceMappingFormCrudBase
Salesforce Mapping Form base.

Namespace

Drupal\salesforce_mapping_ui\Form

Code

public function buildForm(array $form, FormStateInterface $form_state) {
  if (!$this
    ->ensureConnection()) {
    return $form;
  }
  $form = parent::buildForm($form, $form_state);
  $mapping = $this->entity;
  $form['label'] = [
    '#type' => 'textfield',
    '#title' => $this
      ->t('Label'),
    '#default_value' => $mapping
      ->label(),
    '#required' => TRUE,
    '#weight' => -30,
  ];
  $form['id'] = [
    '#type' => 'machine_name',
    '#required' => TRUE,
    '#default_value' => $mapping
      ->id(),
    '#maxlength' => EntityTypeInterface::ID_MAX_LENGTH,
    '#machine_name' => [
      'exists' => [
        'Drupal\\salesforce_mapping\\Entity\\SalesforceMapping',
        'load',
      ],
      'source' => [
        'label',
      ],
    ],
    '#disabled' => !$mapping
      ->isNew(),
    '#weight' => -20,
  ];
  $form['drupal_entity'] = [
    '#title' => $this
      ->t('Drupal entity'),
    '#type' => 'details',
    '#attributes' => [
      'id' => 'edit-drupal-entity',
    ],
    // Gently discourage admins from breaking existing fieldmaps:
    '#open' => $mapping
      ->isNew(),
  ];
  $entity_types = $this
    ->getEntityTypeOptions();
  $form['drupal_entity']['drupal_entity_type'] = [
    '#title' => $this
      ->t('Drupal Entity Type'),
    '#id' => 'edit-drupal-entity-type',
    '#type' => 'select',
    '#description' => $this
      ->t('Select a Drupal entity type to map to a Salesforce object.'),
    '#options' => $entity_types,
    '#default_value' => $mapping->drupal_entity_type,
    '#required' => TRUE,
    '#empty_option' => $this
      ->t('- Select -'),
    '#ajax' => [
      'callback' => [
        $this,
        'bundleCallback',
      ],
      'event' => 'change',
      'wrapper' => 'drupal_bundle',
    ],
  ];
  $form['drupal_entity']['drupal_bundle'] = [
    '#title' => $this
      ->t('Bundle'),
    '#type' => 'select',
    '#default_value' => $mapping->drupal_bundle,
    '#empty_option' => $this
      ->t('- Select -'),
    // Bundle select options will get completely replaced after user selects
    // an entity, but we include all possibilities here for js-free
    // compatibility (for simpletest)
    '#options' => $this
      ->getBundleOptions(),
    '#required' => TRUE,
    '#prefix' => '<div id="drupal_bundle">',
    '#suffix' => '</div>',
    // Don't expose the bundle listing until user has selected an entity.
    '#states' => [
      'visible' => [
        ':input[name="drupal_entity_type"]' => [
          '!value' => '',
        ],
      ],
    ],
  ];
  $input = $form_state
    ->getUserInput();
  if (!empty($input) && !empty($input['drupal_entity_type'])) {
    $entity_type = $input['drupal_entity_type'];
  }
  else {
    $entity_type = $form['drupal_entity']['drupal_entity_type']['#default_value'];
  }
  $bundle_info = $this->bundleInfo
    ->getBundleInfo($entity_type);
  if (!empty($bundle_info)) {
    $form['drupal_entity']['drupal_bundle']['#options'] = [];
    $form['drupal_entity']['drupal_bundle']['#title'] = $this
      ->t('@entity_type Bundle', [
      '@entity_type' => $entity_types[$entity_type],
    ]);
    foreach ($bundle_info as $key => $info) {
      $form['drupal_entity']['drupal_bundle']['#options'][$key] = $info['label'];
    }
  }
  $form['salesforce_object'] = [
    '#title' => $this
      ->t('Salesforce object'),
    '#id' => 'edit-salesforce-object',
    '#type' => 'details',
    // Gently discourage admins from breaking existing fieldmaps:
    '#open' => $mapping
      ->isNew(),
  ];
  $salesforce_object_type = '';
  if (!empty($form_state
    ->getValues()) && !empty($form_state
    ->getValue('salesforce_object_type'))) {
    $salesforce_object_type = $form_state
      ->getValue('salesforce_object_type');
  }
  elseif ($mapping->salesforce_object_type) {
    $salesforce_object_type = $mapping->salesforce_object_type;
  }
  $form['salesforce_object']['salesforce_object_type'] = [
    '#title' => $this
      ->t('Salesforce Object'),
    '#id' => 'edit-salesforce-object-type',
    '#type' => 'select',
    '#description' => $this
      ->t('Select a Salesforce object to map.'),
    '#default_value' => $salesforce_object_type,
    '#options' => $this
      ->getSalesforceObjectTypeOptions(),
    '#required' => TRUE,
    '#empty_option' => $this
      ->t('- Select -'),
  ];

  // @TODO either change sync_triggers to human readable values, or make them work as hex flags again.
  $trigger_options = $this
    ->getSyncTriggerOptions();
  $form['sync_triggers'] = [
    '#title' => $this
      ->t('Action triggers'),
    '#type' => 'details',
    '#open' => TRUE,
    '#tree' => TRUE,
    '#description' => $this
      ->t('Select which actions on Drupal entities and Salesforce
        objects should trigger a synchronization. These settings are used by the
        salesforce_push and salesforce_pull modules.'),
  ];
  if (empty($trigger_options)) {
    $form['sync_triggers']['#description'] .= ' ' . $this
      ->t('<br/><em>No trigger options are available when Salesforce Push and Pull modules are disabled. Enable one or both modules to allow Push or Pull processing.</em>');
  }
  foreach ($trigger_options as $option => $label) {
    $form['sync_triggers'][$option] = [
      '#title' => $label,
      '#type' => 'checkbox',
      '#default_value' => !empty($mapping->sync_triggers[$option]),
    ];
  }
  if ($this->moduleHandler
    ->moduleExists('salesforce_pull')) {

    // @TODO should push and pull settings get moved into push and pull modules?
    $form['pull'] = [
      '#title' => $this
        ->t('Pull Settings'),
      '#type' => 'details',
      '#description' => '',
      '#open' => TRUE,
      '#tree' => FALSE,
      '#states' => [
        'visible' => [
          ':input[name^="sync_triggers[pull"]' => [
            'checked' => TRUE,
          ],
        ],
      ],
    ];
    if (!$mapping
      ->isNew()) {
      $form['pull']['last_pull_date'] = [
        '#type' => 'item',
        '#title' => $this
          ->t('Last Pull Date: %last_pull', [
          '%last_pull' => $mapping
            ->getLastPullTime() ? \Drupal::service('date.formatter')
            ->format($mapping
            ->getLastPullTime()) : 'never',
        ]),
        '#markup' => $this
          ->t('Resetting last pull date will cause salesforce pull module to query for updated records without respect for the pull trigger date. This is useful, for example, to re-pull all records after a purge.'),
      ];
      $form['pull']['last_pull_reset'] = [
        '#type' => 'button',
        '#value' => $this
          ->t('Reset Last Pull Date'),
        '#disabled' => $mapping
          ->getLastPullTime() == NULL,
        '#limit_validation_errors' => [],
        '#validate' => [
          '::lastPullReset',
        ],
      ];
      $form['pull']['last_delete_date'] = [
        '#type' => 'item',
        '#title' => $this
          ->t('Last Delete Date: %last_pull', [
          '%last_pull' => $mapping
            ->getLastDeleteTime() ? \Drupal::service('date.formatter')
            ->format($mapping
            ->getLastDeleteTime()) : 'never',
        ]),
        '#markup' => $this
          ->t('Resetting last delete date will cause salesforce pull module to query for deleted record without respect for the pull trigger date.'),
      ];
      $form['pull']['last_delete_reset'] = [
        '#type' => 'button',
        '#value' => $this
          ->t('Reset Last Delete Date'),
        '#disabled' => $mapping
          ->getLastDeleteTime() == NULL,
        '#limit_validation_errors' => [],
        '#validate' => [
          '::lastDeleteReset',
        ],
      ];

      // This doesn't work until after mapping gets saved.
      // @TODO figure out best way to alert admins about this, or AJAX-ify it.
      $form['pull']['pull_trigger_date'] = [
        '#type' => 'select',
        '#title' => $this
          ->t('Date field to trigger pull'),
        '#description' => $this
          ->t('Poll Salesforce for updated records based on the given date field. Defaults to "Last Modified Date".'),
        '#required' => $mapping->salesforce_object_type,
        '#default_value' => $mapping->pull_trigger_date,
        '#options' => $this
          ->getPullTriggerOptions(),
      ];
    }
    $form['pull']['pull_where_clause'] = [
      '#title' => $this
        ->t('Pull query SOQL "Where" clause'),
      '#type' => 'textarea',
      '#description' => $this
        ->t('Add a "where" SOQL condition clause to limit records pulled from Salesforce. e.g. Email != \'\' AND RecordType.DevelopName = \'ExampleRecordType\''),
      '#default_value' => $mapping->pull_where_clause,
    ];
    $form['pull']['pull_where_clause'] = [
      '#title' => $this
        ->t('Pull query SOQL "Where" clause'),
      '#type' => 'textarea',
      '#description' => $this
        ->t('Add a "where" SOQL condition clause to limit records pulled from Salesforce. e.g. Email != \'\' AND RecordType.DevelopName = \'ExampleRecordType\''),
      '#default_value' => $mapping->pull_where_clause,
    ];
    $form['pull']['pull_frequency'] = [
      '#title' => $this
        ->t('Pull Frequency'),
      '#type' => 'number',
      '#default_value' => $mapping->pull_frequency,
      '#description' => $this
        ->t('Enter a frequency, in seconds, for how often this mapping should be used to pull data to Drupal. Enter 0 to pull as often as possible. FYI: 1 hour = 3600; 1 day = 86400. <em>NOTE: pull frequency is shared per-Salesforce Object. The setting is exposed here for convenience.</em>'),
    ];
    $description = $this
      ->t('Check this box to disable cron pull processing for this mapping, and allow standalone processing only. A URL will be generated after saving the mapping.');
    if ($mapping
      ->id()) {
      $standalone_url = Url::fromRoute('salesforce_pull.endpoint.salesforce_mapping', [
        'salesforce_mapping' => $mapping
          ->id(),
        'key' => \Drupal::state()
          ->get('system.cron_key'),
      ], [
        'absolute' => TRUE,
      ])
        ->toString();
      $description = $this
        ->t('Check this box to disable cron pull processing for this mapping, and allow standalone processing via this URL: <a href=":url">:url</a>', [
        ':url' => $standalone_url,
      ]);
    }
    $form['pull']['pull_standalone'] = [
      '#title' => $this
        ->t('Enable standalone pull queue processing'),
      '#type' => 'checkbox',
      '#description' => $description,
      '#default_value' => $mapping->pull_standalone,
    ];

    // If global standalone is enabled, then we force this mapping's
    // standalone property to true.
    if ($this
      ->config('salesforce.settings')
      ->get('standalone')) {
      $settings_url = Url::fromRoute('salesforce.global_settings')
        ->toString();
      $form['pull']['pull_standalone']['#default_value'] = TRUE;
      $form['pull']['pull_standalone']['#disabled'] = TRUE;
      $form['pull']['pull_standalone']['#description'] .= ' ' . $this
        ->t('See also <a href="@url">global standalone processing settings</a>.', [
        '@url' => $settings_url,
      ]);
    }
  }
  if ($this->moduleHandler
    ->moduleExists('salesforce_push')) {
    $form['push'] = [
      '#title' => $this
        ->t('Push Settings'),
      '#type' => 'details',
      '#description' => $this
        ->t('The asynchronous push queue is always enabled in Drupal 8: real-time push fails are queued for async push. Alternatively, you can choose to disable real-time push and use async-only.'),
      '#open' => TRUE,
      '#tree' => FALSE,
      '#states' => [
        'visible' => [
          ':input[name^="sync_triggers[push"]' => [
            'checked' => TRUE,
          ],
        ],
      ],
    ];
    $form['push']['async'] = [
      '#title' => $this
        ->t('Disable real-time push'),
      '#type' => 'checkbox',
      '#description' => $this
        ->t('When real-time push is disabled, enqueue changes and push to Salesforce asynchronously during cron. When disabled, push changes immediately upon entity CRUD, and only enqueue failures for async push.'),
      '#default_value' => $mapping->async,
    ];
    $form['push']['push_frequency'] = [
      '#title' => $this
        ->t('Push Frequency'),
      '#type' => 'number',
      '#default_value' => $mapping->push_frequency,
      '#description' => $this
        ->t('Enter a frequency, in seconds, for how often this mapping should be used to push data to Salesforce. Enter 0 to push as often as possible. FYI: 1 hour = 3600; 1 day = 86400.'),
      '#min' => 0,
    ];
    $form['push']['push_limit'] = [
      '#title' => $this
        ->t('Push Limit'),
      '#type' => 'number',
      '#default_value' => $mapping->push_limit,
      '#description' => $this
        ->t('Enter the maximum number of records to be pushed to Salesforce during a single queue batch. Enter 0 to process as many records as possible, subject to the global push queue limit.'),
      '#min' => 0,
    ];
    $form['push']['push_retries'] = [
      '#title' => $this
        ->t('Push Retries'),
      '#type' => 'number',
      '#default_value' => $mapping->push_retries,
      '#description' => $this
        ->t("Enter the maximum number of attempts to push a record to Salesforce before it's considered failed. Enter 0 for no limit."),
      '#min' => 0,
    ];
    $form['push']['weight'] = [
      '#title' => $this
        ->t('Weight'),
      '#type' => 'select',
      '#options' => array_combine(range(-50, 50), range(-50, 50)),
      '#description' => $this
        ->t('Not yet in use. During cron, mapping weight determines in which order items will be pushed. Lesser weight items will be pushed before greater weight items.'),
      '#default_value' => $mapping->weight,
    ];
    $description = $this
      ->t('Check this box to disable cron push processing for this mapping, and allow standalone processing. A URL will be generated after saving the mapping.');
    if ($mapping
      ->id()) {
      $standalone_url = Url::fromRoute('salesforce_push.endpoint.salesforce_mapping', [
        'salesforce_mapping' => $mapping
          ->id(),
        'key' => \Drupal::state()
          ->get('system.cron_key'),
      ], [
        'absolute' => TRUE,
      ])
        ->toString();
      $description = $this
        ->t('Check this box to disable cron push processing for this mapping, and allow standalone processing via this URL: <a href=":url">:url</a>', [
        ':url' => $standalone_url,
      ]);
    }
    $form['push']['push_standalone'] = [
      '#title' => $this
        ->t('Enable standalone push queue processing'),
      '#type' => 'checkbox',
      '#description' => $description,
      '#default_value' => $mapping->push_standalone,
    ];

    // If global standalone is enabled, then we force this mapping's
    // standalone property to true.
    if ($this
      ->config('salesforce.settings')
      ->get('standalone')) {
      $settings_url = Url::fromRoute('salesforce.global_settings')
        ->toString();
      $form['push']['push_standalone']['#default_value'] = TRUE;
      $form['push']['push_standalone']['#disabled'] = TRUE;
      $form['push']['push_standalone']['#description'] .= ' ' . $this
        ->t('See also <a href="@url">global standalone processing settings</a>.', [
        '@url' => $settings_url,
      ]);
    }
  }
  $form['meta'] = [
    '#type' => 'details',
    '#open' => TRUE,
    '#tree' => FALSE,
    '#title' => $this
      ->t('Additional properties'),
  ];
  $form['meta']['weight'] = [
    '#title' => $this
      ->t('Weight'),
    '#type' => 'select',
    '#options' => array_combine(range(-50, 50), range(-50, 50)),
    '#description' => $this
      ->t('During cron, mapping weight determines in which order items will be pushed or pulled. Lesser weight items will be pushed or pulled before greater weight items.'),
    '#default_value' => $mapping->weight,
  ];
  return $form;
}