You are here

protected function PullForm::buildEntitiesSelectTable in Entity Share 8.3

Same name and namespace in other branches
  1. 8 modules/entity_share_client/src/Form/PullForm.php \Drupal\entity_share_client\Form\PullForm::buildEntitiesSelectTable()
  2. 8.2 modules/entity_share_client/src/Form/PullForm.php \Drupal\entity_share_client\Form\PullForm::buildEntitiesSelectTable()

Helper function to generate entities table.

Parameters

array $form: The form array.

\Drupal\Core\Form\FormStateInterface $form_state: The form state object.

1 call to PullForm::buildEntitiesSelectTable()
PullForm::buildChannelSelect in modules/entity_share_client/src/Form/PullForm.php
Helper function to generate channel select.

File

modules/entity_share_client/src/Form/PullForm.php, line 478

Class

PullForm
Form controller to pull entities.

Namespace

Drupal\entity_share_client\Form

Code

protected function buildEntitiesSelectTable(array &$form, FormStateInterface $form_state) {
  $triggering_element = $form_state
    ->getTriggeringElement();

  // Form state by default, else from query.
  $selected_import_config = $form_state
    ->getValue('import_config', $this->query
    ->get('import_config'));
  $selected_remote_id = $form_state
    ->getValue('remote', $this->query
    ->get('remote'));
  $selected_channel = $form_state
    ->getValue('channel', $this->query
    ->get('channel'));

  // If Ajax was triggered set offset to default value: 0.
  $offset = !is_array($triggering_element) ? $this->query
    ->get('offset', 0) : 0;
  if (!is_array($triggering_element) && is_numeric($this->query
    ->get('page'))) {
    $offset = $this->query
      ->get('page') * 50;
  }
  if (empty($this->remoteWebsites[$selected_remote_id]) || empty($this->channelsInfos[$selected_channel])) {
    return;
  }
  $channel_entity_type = $this->channelsInfos[$selected_channel]['channel_entity_type'];
  $channel_bundle = $this->channelsInfos[$selected_channel]['channel_bundle'];
  $selected_remote = $this->remoteWebsites[$selected_remote_id];
  $this->fieldMappings = $this->remoteManager
    ->getfieldMappings($selected_remote);
  $entity_storage = $this->entityTypeManager
    ->getStorage($channel_entity_type);
  $entity_keys = $entity_storage
    ->getEntityType()
    ->getKeys();
  $parsed_url = UrlHelper::parse($this->channelsInfos[$selected_channel]['url']);

  // Add offset to the selected channel.
  $parsed_url['query']['page']['offset'] = $offset;

  // Handle search.
  $searched_text = $form_state
    ->getValue('search', '');
  if (empty($searched_text)) {
    $get_searched_text = $this->query
      ->get('search', '');

    // If it is not an ajax trigger, check if it is in the GET parameters.
    if (!is_array($triggering_element) && !empty($get_searched_text)) {
      $searched_text = $get_searched_text;
    }
  }
  if (!empty($searched_text)) {
    $search_filter_and_group = [
      'channel_searched_text_group' => [
        'group' => [
          'conjunction' => 'OR',
        ],
      ],
    ];
    foreach ($this->channelsInfos[$selected_channel]['search_configuration'] as $search_key => $search_info) {
      $search_filter_and_group['search_filter_' . $search_key] = [
        'condition' => [
          'path' => $search_info['path'],
          'operator' => 'CONTAINS',
          'value' => $searched_text,
          'memberOf' => 'channel_searched_text_group',
        ],
      ];
    }
    $parsed_url['query']['filter'] = isset($parsed_url['query']['filter']) ? array_merge_recursive($parsed_url['query']['filter'], $search_filter_and_group) : $search_filter_and_group;
  }

  // Change the sort if a sort had been selected.
  $sort_field = $this->query
    ->get('order', '');
  $sort_direction = $this->query
    ->get('sort', '');
  $sort_context = [
    'name' => $sort_field,
    'sort' => $sort_direction,
    'query' => [
      'remote' => $selected_remote_id,
      'channel' => $selected_channel,
      'import_config' => $selected_import_config,
      'search' => $searched_text,
    ],
  ];
  if (!empty($sort_field) && !empty($sort_direction) && isset($this->fieldMappings[$channel_entity_type][$channel_bundle][$sort_field])) {
    $parsed_url['query']['sort'] = [
      $sort_field => [
        'path' => $this->fieldMappings[$channel_entity_type][$channel_bundle][$sort_field],
        'direction' => strtoupper($sort_direction),
      ],
    ];
  }
  $query = UrlHelper::buildQuery($parsed_url['query']);
  $prepared_url = $parsed_url['path'] . '?' . $query;
  $response = $this->remoteManager
    ->jsonApiRequest($selected_remote, 'GET', $prepared_url);
  $json = Json::decode((string) $response
    ->getBody());

  // Search.
  $form['channel_wrapper']['entities_wrapper']['search'] = [
    '#type' => 'textfield',
    '#title' => $this
      ->t('Search'),
    '#default_value' => $searched_text,
    '#weight' => -20,
    '#ajax' => [
      'callback' => [
        get_class($this),
        'buildAjaxEntitiesSelectTable',
      ],
      'disable-refocus' => TRUE,
      'effect' => 'fade',
      'keypress' => TRUE,
      'method' => 'replace',
      'wrapper' => 'entities-wrapper',
    ],
  ];
  if (isset($this->channelsInfos[$selected_channel]['search_configuration']) && !empty($this->channelsInfos[$selected_channel]['search_configuration'])) {
    $search_list = [
      '#theme' => 'item_list',
      '#items' => [],
    ];
    foreach ($this->channelsInfos[$selected_channel]['search_configuration'] as $search_info) {
      $search_list['#items'][] = $search_info['label'];
    }
    $search_list = $this->renderer
      ->render($search_list);
    $search_description = $this
      ->t('The search (CONTAINS operator) will occur on the following fields:') . $search_list;
  }
  else {
    $search_description = $this
      ->t('There is no field on the server site to search on this channel.');
  }
  $form['channel_wrapper']['entities_wrapper']['search']['#description'] = $search_description;

  // Full pager.
  if (isset($json['meta']['count'])) {
    $this->pagerManager
      ->createPager($json['meta']['count'], 50);
    $form['channel_wrapper']['entities_wrapper']['pager'] = [
      '#type' => 'pager',
      '#route_name' => 'entity_share_client.admin_content_pull_form',
      '#parameters' => [
        'remote' => $selected_remote_id,
        'channel' => $selected_channel,
        'import_config' => $selected_import_config,
        'search' => $searched_text,
        'order' => $sort_field,
        'sort' => $sort_direction,
      ],
      '#attached' => [
        'library' => [
          'entity_share_client/full-pager',
        ],
      ],
    ];
  }
  else {

    // Store the JSON:API links to use its in the pager submit handlers.
    $storage = $form_state
      ->getStorage();
    $storage['links'] = $json['links'];
    $form_state
      ->setStorage($storage);

    // Pager.
    $form['channel_wrapper']['entities_wrapper']['pager'] = [
      '#type' => 'actions',
      '#weight' => -10,
    ];
    $pager_links = $this
      ->getBasicPagerLinks();
    foreach ($pager_links as $key => $label) {
      if (isset($json['links'][$key]['href'])) {
        $form['channel_wrapper']['entities_wrapper']['pager'][$key] = [
          '#type' => 'submit',
          '#value' => $label,
          '#submit' => [
            '::goToPage',
          ],
        ];
      }
    }
  }
  if (!empty($sort_field) || !empty($sort_direction)) {
    $form['channel_wrapper']['entities_wrapper']['reset_sort'] = [
      '#type' => 'actions',
      '#weight' => -15,
      'reset_sort' => [
        '#type' => 'submit',
        '#value' => $this
          ->t('Reset sort'),
        '#submit' => [
          '::resetSort',
        ],
      ],
    ];
  }
  $label_header_machine_name = isset($entity_keys['label']) ? $entity_keys['label'] : 'label';

  // Table to select entities.
  $header = [
    'label' => $this
      ->getHeader($this
      ->t('Label'), $label_header_machine_name, $sort_context),
    'type' => $this
      ->t('Type'),
    'bundle' => $this
      ->t('Bundle'),
    'language' => $this
      ->t('Language'),
    'changed' => $this
      ->getHeader($this
      ->t('Remote entity changed date'), 'changed', $sort_context),
    'status' => $this
      ->t('Status'),
  ];
  $form['channel_wrapper']['entities_wrapper']['entities'] = [
    '#type' => 'tableselect',
    '#header' => $header,
    '#options' => $this->formHelper
      ->buildEntitiesOptions($json['data'], $selected_remote, $selected_channel),
    '#empty' => $this
      ->t('No entities to be pulled have been found.'),
    '#attached' => [
      'library' => [
        'entity_share_client/admin',
      ],
    ],
  ];
  if ($this->moduleHandler
    ->moduleExists('entity_share_diff')) {
    $form['channel_wrapper']['entities_wrapper']['entities']['#attached']['library'][] = 'core/drupal.dialog.ajax';
  }

  // Actions bottom.
  $form['channel_wrapper']['entities_wrapper']['actions_bottom']['#type'] = 'actions';

  // The button for importing selected entities always appears.
  $synchronize_button = [
    '#type' => 'submit',
    '#value' => $this
      ->t('Synchronize entities'),
    '#button_type' => 'primary',
    '#validate' => [
      '::validateSelectedEntities',
    ],
    '#submit' => [
      '::submitForm',
      '::synchronizeSelectedEntities',
    ],
  ];
  $form['channel_wrapper']['entities_wrapper']['actions_bottom']['synchronize'] = $synchronize_button;

  // The button for importing the whole channel appears only if JSON:API
  // option "Include count in collection queries" is activated on remote.
  if (isset($json['meta']['count'])) {
    $import_channel_button = [
      '#type' => 'submit',
      '#value' => $this
        ->t('Import the whole channel'),
      '#button_type' => 'primary',
      '#submit' => [
        '::submitForm',
        '::importChannel',
      ],
    ];
    $form['channel_wrapper']['entities_wrapper']['actions_bottom']['import_channel'] = $import_channel_button;

    // Remember the remote channel count.
    $storage = $form_state
      ->getStorage();
    $storage['remote_channel_count'] = $json['meta']['count'];
    $form_state
      ->setStorage($storage);
  }

  // Actions on top are the same as the actions at the bottom.
  $form['channel_wrapper']['entities_wrapper']['actions_top'] = $form['channel_wrapper']['entities_wrapper']['actions_bottom'];
  $form['channel_wrapper']['entities_wrapper']['actions_top']['#weight'] = -1;
}