View source
<?php
namespace Drupal\entity_share_client\Form;
use Drupal\Component\Serialization\Json;
use Drupal\Component\Utility\UrlHelper;
use Drupal\Core\Entity\EntityDefinitionUpdateManagerInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Language\LanguageManagerInterface;
use Drupal\entity_share_client\Service\JsonapiHelperInterface;
use Drupal\entity_share_client\Service\RemoteManagerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\RequestStack;
class PullForm extends FormBase {
protected $remoteWebsites;
protected $channelsInfos;
protected $entityTypeManager;
protected $entityDefinitionUpdateManager;
protected $remoteManager;
protected $jsonapiHelper;
protected $query;
protected $languageManager;
public function __construct(EntityTypeManagerInterface $entity_type_manager, EntityDefinitionUpdateManagerInterface $entity_definition_update_manager, RemoteManagerInterface $remote_manager, JsonapiHelperInterface $jsonapi_helper, RequestStack $request_stack, LanguageManagerInterface $language_manager) {
$this->entityTypeManager = $entity_type_manager;
$this->entityDefinitionUpdateManager = $entity_definition_update_manager;
$this->remoteWebsites = $entity_type_manager
->getStorage('remote')
->loadMultiple();
$this->remoteManager = $remote_manager;
$this->jsonapiHelper = $jsonapi_helper;
$this->query = $request_stack
->getCurrentRequest()->query;
$this->languageManager = $language_manager;
}
public static function create(ContainerInterface $container) {
return new static($container
->get('entity_type.manager'), $container
->get('entity.definition_update_manager'), $container
->get('entity_share_client.remote_manager'), $container
->get('entity_share_client.jsonapi_helper'), $container
->get('request_stack'), $container
->get('language_manager'));
}
public function getFormId() {
return 'entity_share_client_pull_form';
}
public function buildForm(array $form, FormStateInterface $form_state) {
$form['remote'] = [
'#type' => 'select',
'#title' => $this
->t('Remote website'),
'#options' => $this
->prepareRemoteOptions(),
'#default_value' => $this->query
->get('remote'),
'#empty_value' => '',
'#required' => TRUE,
'#ajax' => [
'callback' => [
get_class($this),
'buildAjaxChannelSelect',
],
'wrapper' => 'channel-wrapper',
'method' => 'replace',
'effect' => 'fade',
],
];
$form['channel_wrapper'] = [
'#type' => 'container',
'#attributes' => [
'id' => 'channel-wrapper',
],
];
$this
->buildChannelSelect($form, $form_state);
return $form;
}
public function validateForm(array &$form, FormStateInterface $form_state) {
}
public function submitForm(array &$form, FormStateInterface $form_state) {
}
public function validateSelectedEntities(array &$form, FormStateInterface $form_state) {
$selected_entities = $form_state
->getValue('entities');
if (!is_null($selected_entities)) {
$selected_entities = array_filter($selected_entities);
if (empty($selected_entities)) {
$form_state
->setErrorByName('entities', $this
->t('You must select at least one entity.'));
}
}
}
public function synchronizeSelectedEntities(array &$form, FormStateInterface $form_state) {
$selected_entities = $form_state
->getValue('entities');
$selected_entities = array_filter($selected_entities);
$selected_remote = $form_state
->getValue('remote');
$selected_channel = $form_state
->getValue('channel');
$form_state
->setRedirect('entity_share_client.admin_content_pull_form', [], [
'query' => [
'remote' => $selected_remote,
'channel' => $selected_channel,
],
]);
$url = $this->channelsInfos[$selected_channel]['url'];
$parsed_url = UrlHelper::parse($url);
$query = $parsed_url['query'];
$query['filter']['uuid-filter'] = [
'condition' => [
'path' => 'uuid',
'operator' => 'IN',
'value' => array_values($selected_entities),
],
];
$query = UrlHelper::buildQuery($query);
$prepared_url = $parsed_url['path'] . '?' . $query;
$selected_remote = $this->remoteWebsites[$selected_remote];
$http_client = $this->remoteManager
->prepareJsonApiClient($selected_remote);
$json_response = $http_client
->get($prepared_url)
->getBody()
->getContents();
$json = Json::decode($json_response);
if (!isset($json['errors'])) {
$batch = [
'title' => $this
->t('Synchronize entities'),
'operations' => [
[
'\\Drupal\\entity_share_client\\JsonapiBatchHelper::importEntityListBatch',
[
$selected_remote,
$this->jsonapiHelper
->prepareData($json['data']),
],
],
],
'finished' => '\\Drupal\\entity_share_client\\JsonapiBatchHelper::importEntityListBatchBatchFinished',
];
batch_set($batch);
}
}
protected function prepareRemoteOptions() {
$options = [];
foreach ($this->remoteWebsites as $id => $remote_website) {
$options[$id] = $remote_website
->label();
}
return $options;
}
protected function getChannelOptions() {
$options = [];
foreach ($this->channelsInfos as $channel_id => $channel_infos) {
$options[$channel_id] = $channel_infos['label'];
}
return $options;
}
public static function buildAjaxChannelSelect(array $form, FormStateInterface $form_state) {
return $form['channel_wrapper'];
}
public static function buildAjaxEntitiesSelectTable(array $form, FormStateInterface $form_state) {
return $form['channel_wrapper']['entities_wrapper'];
}
protected function buildChannelSelect(array &$form, FormStateInterface $form_state) {
$selected_remote = $form_state
->getValue('remote');
if (empty($selected_remote)) {
$triggering_element = $form_state
->getTriggeringElement();
$get_remote = $this->query
->get('remote');
if (!is_array($triggering_element) && !is_null($get_remote) && isset($this->remoteWebsites[$get_remote])) {
$selected_remote = $get_remote;
}
else {
return;
}
}
$selected_remote = $this->remoteWebsites[$selected_remote];
$this->channelsInfos = $this->remoteManager
->getChannelsInfos($selected_remote);
$form['channel_wrapper']['channel'] = [
'#type' => 'select',
'#title' => $this
->t('Channel'),
'#options' => $this
->getChannelOptions(),
'#default_value' => $this->query
->get('channel'),
'#empty_value' => '',
'#required' => TRUE,
'#ajax' => [
'callback' => [
get_class($this),
'buildAjaxEntitiesSelectTable',
],
'wrapper' => 'entities-wrapper',
'method' => 'replace',
'effect' => 'fade',
],
];
$form['channel_wrapper']['entities_wrapper'] = [
'#type' => 'container',
'#attributes' => [
'id' => 'entities-wrapper',
],
];
$this
->buildEntitiesSelectTable($form, $form_state);
}
protected function buildEntitiesSelectTable(array &$form, FormStateInterface $form_state) {
$selected_remote = $form_state
->getValue('remote');
$selected_channel = $form_state
->getValue('channel');
$offset = '0';
if (empty($selected_remote) || empty($selected_channel) || !isset($this->channelsInfos[$selected_channel])) {
$triggering_element = $form_state
->getTriggeringElement();
$get_remote = $this->query
->get('remote');
$get_channel = $this->query
->get('channel');
$get_offset = $this->query
->get('offset');
if (!is_array($triggering_element) && !is_null($get_remote) && isset($this->remoteWebsites[$get_remote]) && !is_null($get_channel) && isset($this->channelsInfos[$get_channel])) {
$selected_remote = $get_remote;
$selected_channel = $get_channel;
if (!is_null($get_offset) && is_int((int) $get_offset)) {
$offset = $get_offset;
}
}
else {
return;
}
}
$selected_remote = $this->remoteWebsites[$selected_remote];
$http_client = $this->remoteManager
->prepareJsonApiClient($selected_remote);
$parsed_url = UrlHelper::parse($this->channelsInfos[$selected_channel]['url']);
$parsed_url['query']['page']['offset'] = $offset;
$query = UrlHelper::buildQuery($parsed_url['query']);
$prepared_url = $parsed_url['path'] . '?' . $query;
$json_response = $http_client
->get($prepared_url)
->getBody()
->getContents();
$json = Json::decode($json_response);
$storage = $form_state
->getStorage();
$storage['links'] = $json['links'];
$form_state
->setStorage($storage);
$form['channel_wrapper']['entities_wrapper']['pager'] = [
'#type' => 'actions',
'#weight' => -10,
];
if (isset($json['links']['first'])) {
$form['channel_wrapper']['entities_wrapper']['pager']['first'] = [
'#type' => 'submit',
'#value' => $this
->t('First'),
'#submit' => [
'::firstPage',
],
];
}
if (isset($json['links']['prev'])) {
$form['channel_wrapper']['entities_wrapper']['pager']['prev'] = [
'#type' => 'submit',
'#value' => $this
->t('Previous'),
'#submit' => [
'::prevPage',
],
];
}
if (isset($json['links']['next'])) {
$form['channel_wrapper']['entities_wrapper']['pager']['next'] = [
'#type' => 'submit',
'#value' => $this
->t('Next'),
'#submit' => [
'::nextPage',
],
];
}
if (isset($json['links']['last'])) {
$form['channel_wrapper']['entities_wrapper']['pager']['last'] = [
'#type' => 'submit',
'#value' => $this
->t('Last'),
'#submit' => [
'::lastPage',
],
];
}
$form['channel_wrapper']['entities_wrapper']['actions_top']['#type'] = 'actions';
$form['channel_wrapper']['entities_wrapper']['actions_top']['#weight'] = -1;
$form['channel_wrapper']['entities_wrapper']['actions_top']['synchronize'] = [
'#type' => 'submit',
'#value' => $this
->t('Synchronize entities'),
'#button_type' => 'primary',
'#validate' => [
'::validateSelectedEntities',
],
'#submit' => [
'::synchronizeSelectedEntities',
],
];
$header = [
'label' => $this
->t('Label'),
'type' => $this
->t('Type'),
'bundle' => $this
->t('Bundle'),
'language' => $this
->t('Language'),
'status' => $this
->t('Status'),
];
$form['channel_wrapper']['entities_wrapper']['entities'] = [
'#type' => 'tableselect',
'#header' => $header,
'#options' => $this->jsonapiHelper
->buildEntitiesOptions($json['data']),
'#empty' => $this
->t('No entities to be pulled have been found.'),
'#attached' => [
'library' => [
'entity_share_client/admin',
],
],
];
$form['channel_wrapper']['entities_wrapper']['actions_bottom']['#type'] = 'actions';
$form['channel_wrapper']['entities_wrapper']['actions_bottom']['synchronize'] = [
'#type' => 'submit',
'#value' => $this
->t('Synchronize entities'),
'#button_type' => 'primary',
'#validate' => [
'::validateSelectedEntities',
],
'#submit' => [
'::synchronizeSelectedEntities',
],
];
}
public function firstPage(array &$form, FormStateInterface $form_state) {
$this
->pagerRedirect($form_state, 'first');
}
public function prevPage(array &$form, FormStateInterface $form_state) {
$this
->pagerRedirect($form_state, 'prev');
}
public function nextPage(array &$form, FormStateInterface $form_state) {
$this
->pagerRedirect($form_state, 'next');
}
public function lastPage(array &$form, FormStateInterface $form_state) {
$this
->pagerRedirect($form_state, 'last');
}
protected function pagerRedirect(FormStateInterface $form_state, $link_name) {
$storage = $form_state
->getStorage();
if (isset($storage['links'][$link_name])) {
$selected_remote = $form_state
->getValue('remote');
$selected_channel = $form_state
->getValue('channel');
$parsed_url = UrlHelper::parse($storage['links'][$link_name]);
if (isset($parsed_url['query']['page']) && isset($parsed_url['query']['page']['offset'])) {
$form_state
->setRedirect('entity_share_client.admin_content_pull_form', [], [
'query' => [
'remote' => $selected_remote,
'channel' => $selected_channel,
'offset' => $parsed_url['query']['page']['offset'],
],
]);
}
}
}
}