You are here

protected function FlowForm::renderFields in CMS Content Sync 8

Same name and namespace in other branches
  1. 2.1.x src/Form/FlowForm.php \Drupal\cms_content_sync\Form\FlowForm::renderFields()
  2. 2.0.x src/Form/FlowForm.php \Drupal\cms_content_sync\Form\FlowForm::renderFields()

Render the fields of the given entity type; either all of them or only those that either have:

  • advanced handler settings available
  • a handler that was intentionally disabled.

Parameters

$type_key:

$entity_bundle_name:

bool $expanded:

Return value

array

Throws

\Drupal\Component\Plugin\Exception\PluginException

1 call to FlowForm::renderFields()
FlowForm::renderEnabledBundle in src/Form/FlowForm.php
Render the bundle edit form.

File

src/Form/FlowForm.php, line 1543

Class

FlowForm
Form handler for the Flow add and edit forms.

Namespace

Drupal\cms_content_sync\Form

Code

protected function renderFields(FormStateInterface $form_state, $type_key, $entity_bundle_name, $expanded = false) {
  $bundle_id = $type_key . '-' . $entity_bundle_name;
  $settings_id = 'sync-entities-' . $bundle_id;
  $field_settings_id = $settings_id . '-fields';
  $form_type = $this
    ->getCurrentFormType();
  $allow_push = Flow::TYPE_PUSH === $form_type || Flow::TYPE_BOTH === $form_type;
  $allow_pull = Flow::TYPE_PULL === $form_type || Flow::TYPE_BOTH === $form_type;
  $current_values = $this
    ->getCurrentValues($form_state);
  $push_option_labels_fields = [
    PushIntent::PUSH_DISABLED => $this
      ->t('No')
      ->render(),
    PushIntent::PUSH_AUTOMATICALLY => $this
      ->t('Yes')
      ->render(),
  ];
  $pull_option_labels_fields = [
    PullIntent::PULL_DISABLED => $this
      ->t('No')
      ->render(),
    PullIntent::PULL_AUTOMATICALLY => $this
      ->t('Yes')
      ->render(),
  ];
  $field_map = $this->entityFieldManager
    ->getFieldMap();
  $def_sync_entities = $this
    ->getCurrentValues($form_state)['sync_entities'];
  $entity_handlers = $this->entityPluginManager
    ->getHandlerOptions($type_key, $entity_bundle_name, true);
  $entity_handler_names = array_keys($entity_handlers);
  $handler_id = empty($current_values['sync_entities'][$bundle_id]['handler']) || 'ignore' === $current_values['sync_entities'][$bundle_id]['handler'] ? reset($entity_handler_names) : $current_values['sync_entities'][$bundle_id]['handler'];
  $handler = $this->entityPluginManager
    ->createInstance($handler_id, [
    'entity_type_name' => $type_key,
    'bundle_name' => $entity_bundle_name,
    'settings' => empty($current_values['sync_entities'][$bundle_id]) ? [] : $current_values['sync_entities'][$bundle_id],
    'sync' => null,
  ]);
  if (isset($field_map[$type_key])) {
    $entity_field_table = [
      '#type' => 'table',
      '#prefix' => '<div id="' . $field_settings_id . '"><h3>' . $this
        ->t('Fields') . '</h3>',
      '#suffix' => '</div>',
      '#header' => array_merge([
        $this
          ->t('Name'),
        $this
          ->t('Handler'),
        $this
          ->t('Handler settings'),
      ], $allow_push && Flow::TYPE_BOTH === !$form_type ? [
        $this
          ->t('Push'),
      ] : [], $allow_pull && Flow::TYPE_BOTH === !$form_type ? [
        $this
          ->t('Pull'),
      ] : []),
    ];
    $forbidden_fields = $handler
      ->getForbiddenFields();
    $pools = Pool::getAll();
    if (count($pools)) {
      $reserved = reset($pools)
        ->getClient()
        ->getReservedPropertyNames();
      $forbidden_fields = array_merge($forbidden_fields, $reserved);
    }
    $entityFieldManager = $this->entityFieldManager;

    /**
     * @var \Drupal\Core\Field\FieldDefinitionInterface[] $fields
     */
    $fields = $entityFieldManager
      ->getFieldDefinitions($type_key, $entity_bundle_name);
    foreach ($fields as $key => $field) {
      $field_id = $type_key . '-' . $entity_bundle_name . '-' . $key;
      $field_row = [];
      $title = $key;
      $referenced_type = null;
      $referenced_bundles = 'all';
      $bundles = '';
      $show_enable_all = false;
      if (in_array($field
        ->getType(), [
        'entity_reference',
        'entity_reference_revisions',
        'webform',
      ])) {
        $referenced_type = $field
          ->getSetting('target_type');
      }
      elseif (in_array($field
        ->getType(), [
        'image',
        'file',
        'file_uri',
      ])) {
        $referenced_type = 'file';
      }
      elseif (in_array($field
        ->getType(), [
        'bricks',
      ])) {
        $referenced_type = 'brick';
      }
      elseif (in_array($field
        ->getType(), [
        'field_collection',
      ])) {
        $referenced_type = 'field_collection_item';
      }
      $field_settings = $field
        ->getSettings();
      if ((!empty($field_settings['handler_settings']) || 'brick' === $referenced_type) && !empty($field_settings['handler_settings']['target_bundles'])) {
        $bundles .= '<ul>';
        $referenced_bundles = [];
        foreach ($field_settings['handler_settings']['target_bundles'] as $bundle) {
          $bundles .= '<li>' . $bundle . '</li>';
          $referenced_bundles[] = $bundle;
          if (empty($current_values['sync_entities'][$referenced_type . '-' . $bundle]['handler']) || Flow::HANDLER_IGNORE == $current_values['sync_entities'][$referenced_type . '-' . $bundle]['handler']) {
            if ('1' != $form_state
              ->getValue([
              $referenced_type,
              $bundle,
              'edit',
            ])) {
              $entity_handlers = $this->entityPluginManager
                ->getHandlerOptions($referenced_type, $bundle, true);
              if (!empty($entity_handlers)) {
                $show_enable_all = true;
              }
            }
          }
        }
        $bundles .= '</ul>';
      }
      if ($referenced_type) {
        $title .= '<br><small>Reference to ' . $referenced_type;
        $title .= !empty($bundles) ? ':' . $bundles : '';
        $title .= '</small>';
        if (empty($bundles)) {
          $entity_types = $this->bundleInfoService
            ->getAllBundleInfo();
          foreach ($entity_types[$referenced_type] as $bundle => $set) {
            if (empty($current_values['sync_entities'][$referenced_type . '-' . $bundle]['handler']) || Flow::HANDLER_IGNORE == $current_values['sync_entities'][$referenced_type . '-' . $bundle]['handler']) {
              if ('1' != $form_state
                ->getValue([
                $referenced_type,
                $bundle,
                'edit',
              ])) {
                $entity_handlers = $this->entityPluginManager
                  ->getHandlerOptions($referenced_type, $bundle, true);
                if (!empty($entity_handlers)) {
                  $show_enable_all = true;
                }
              }
              break;
            }
          }
        }
      }
      $field_row['bundle'] = [
        '#markup' => $title,
      ];
      if ($show_enable_all) {
        $field_row['bundle']['enable-all'] = [
          '#type' => 'submit',
          '#value' => $this
            ->t('Enable all'),
          '#name' => 'enable_all-' . $type_key . '-' . $entity_bundle_name . '-' . $key,
          '#submit' => [
            '::enableAllReferenced',
          ],
          '#entity_type' => $type_key,
          '#bundle' => $entity_bundle_name,
          '#field' => $key,
          '#referenced_type' => $referenced_type,
          '#referenced_bundles' => $referenced_bundles,
          '#limit_validation_errors' => [],
          '#ajax' => [
            'callback' => '::enableAllReferencedReturn',
            'progress' => [
              'type' => 'throbber',
              'message' => 'loading settings...',
            ],
          ],
        ];
      }
      if (!isset($def_sync_entities[$field_id])) {
        $field_default_values = [
          'id' => $field_id,
          'export' => null,
          'import' => null,
          'preview' => null,
          'entity_type' => $type_key,
          'entity_bundle' => $entity_bundle_name,
        ];
      }
      else {
        $field_default_values = $def_sync_entities[$field_id];
      }
      if (!empty($input[$field_id])) {
        $field_default_values = array_merge($field_default_values, $input[$field_id]);
      }
      if (false !== in_array($key, $forbidden_fields)) {
        $handler_id = 'ignore';
        $field_handlers = [
          'ignore' => $this
            ->t('Default')
            ->render(),
        ];
      }
      else {
        $field_handlers = $this->fieldPluginManager
          ->getHandlerOptions($type_key, $entity_bundle_name, $key, $field, true);
        if (empty($field_handlers)) {
          $handler_id = 'ignore';
        }
        else {
          reset($field_handlers);
          $handler_id = empty($field_default_values['handler']) ? key($field_handlers) : $field_default_values['handler'];
        }
      }
      $options = count($field_handlers) ? $field
        ->isRequired() ? $field_handlers : array_merge([
        'ignore' => $this
          ->t('Ignore')
          ->render(),
      ], $field_handlers) : [
        'ignore' => $this
          ->t('Not supported')
          ->render(),
      ];
      $field_row['handler'] = [
        '#type' => 'select',
        '#title' => $this
          ->t('Handler'),
        '#title_display' => 'invisible',
        '#options' => $options,
        '#disabled' => !count($field_handlers) || 1 == count($field_handlers) && isset($field_handlers['ignore']),
        '#default_value' => $handler_id,
        '#limit_validation_errors' => [],
      ];
      if ('ignore' == $handler_id) {

        // Disabled means we don't syndicate it as a normal field handler. Instead, the entity handler will already take care of it as it's a required property.
        // But saying "no" will be confusing to users as it's actually syndicated. So we use DISABLED => YES for the naming.
        $push_options = [
          PushIntent::PUSH_DISABLED => $this
            ->t('Yes')
            ->render(),
        ];
      }
      else {

        /**
         * @var \Drupal\cms_content_sync\Plugin\FieldHandlerInterface $handler
         */
        $handler = $this->fieldPluginManager
          ->createInstance($handler_id, [
          'entity_type_name' => $type_key,
          'bundle_name' => $entity_bundle_name,
          'field_name' => $key,
          'field_definition' => $field,
          'settings' => $field_default_values,
          'sync' => $this->entity,
        ]);
        $allowed_push_options = $handler
          ->getAllowedPushOptions();
        $push_options = [];
        foreach ($allowed_push_options as $option) {
          $push_options[$option] = $push_option_labels_fields[$option];
        }
      }
      $field_row['handler_settings'] = [
        '#markup' => '',
      ];
      if ('ignore' != $handler_id) {
        $advanced_settings = $handler
          ->getHandlerSettings(isset($current_values['sync_entities'][$field_id]['handler_settings']) ? $current_values['sync_entities'][$field_id]['handler_settings'] : [], $form_type);
        if (count($advanced_settings)) {
          $field_row['handler_settings'] = array_merge([
            '#type' => 'container',
          ], $advanced_settings);
        }
        elseif (!$expanded && !$referenced_type) {
          continue;
        }
      }
      elseif (!$expanded && 1 === count($options) && !$referenced_type) {
        continue;
      }
      if ($allow_push) {
        $field_row['export'] = [
          '#type' => 'select',
          '#title' => $this
            ->t('Push'),
          '#title_display' => 'invisible',
          '#disabled' => count($push_options) < 2,
          '#options' => $push_options,
          '#default_value' => $field_default_values['export'] ? $field_default_values['export'] : (isset($push_options[PushIntent::PUSH_AUTOMATICALLY]) ? PushIntent::PUSH_AUTOMATICALLY : null),
          '#access' => Flow::TYPE_BOTH === $form_type ? true : false,
        ];
      }
      if ('ignore' == $handler_id) {

        // Disabled means we don't syndicate it as a normal field handler. Instead, the entity handler will already take care of it as it's a required property.
        // But saying "no" will be confusing to users as it's actually syndicated. So we use DISABLED => YES for the naming.
        $pull_options = [
          PullIntent::PULL_DISABLED => $this
            ->t('Yes')
            ->render(),
        ];
      }
      else {
        $allowed_pull_options = $handler
          ->getAllowedPullOptions();
        $pull_options = [];
        foreach ($allowed_pull_options as $option) {
          $pull_options[$option] = $pull_option_labels_fields[$option];
        }
      }
      if ($allow_pull) {
        $field_row['import'] = [
          '#type' => 'select',
          '#title' => $this
            ->t('Pull'),
          '#title_display' => 'invisible',
          '#options' => $pull_options,
          '#disabled' => count($pull_options) < 2,
          '#default_value' => !empty($field_default_values['import']) ? $field_default_values['import'] : (isset($pull_options[PullIntent::PULL_AUTOMATICALLY]) ? PullIntent::PULL_AUTOMATICALLY : null),
          '#access' => Flow::TYPE_BOTH === $form_type ? true : false,
        ];
      }
      $entity_field_table[$field_id] = $field_row;
    }
    if (!$expanded) {
      $entity_field_table['advanced']['show-all-action'] = [
        '#type' => 'submit',
        '#value' => $this
          ->t('Show all fields'),
        '#name' => 'show_all-' . $type_key . '-' . $entity_bundle_name,
        '#submit' => [
          '::showAllFields',
        ],
        '#entity_type' => $type_key,
        '#bundle' => $entity_bundle_name,
        '#limit_validation_errors' => [],
        '#ajax' => [
          'callback' => '::ajaxReturn',
          'wrapper' => $field_settings_id,
          'method' => 'replace',
          'effect' => 'fade',
          'progress' => [
            'type' => 'throbber',
            'message' => 'loading settings...',
          ],
        ],
      ];
    }
    $entity_field_table['advanced']['show-all'] = [
      '#type' => 'hidden',
      '#value' => $expanded ? '1' : '0',
    ];
    return $entity_field_table;
  }
}