Skip to content

Instantly share code, notes, and snippets.

@gaelbillon
Last active July 29, 2020 07:33
Show Gist options
  • Save gaelbillon/b40fcaec270ab3f0d353337fb3e0b1a2 to your computer and use it in GitHub Desktop.
Save gaelbillon/b40fcaec270ab3f0d353337fb3e0b1a2 to your computer and use it in GitHub Desktop.
Modification of Drupal [Content Sync](https://www.drupal.org/project/content_sync) module. It replace the single item export tab. On which it is heavily based. When an an entity is selected, it can be exported as a tar file. Along with the entity's dependencies and attached medias saved as files (not base64) with extensions. Entity type and bund…
/*
* Modification of Drupal [Content Sync](https://www.drupal.org/project/content_sync) module.
* It replace the single item export tab. On which it is heavily based. When an an entity is
* selected, it can be exported as a tar file. Along with the entity's dependencies and attached
* medias saved as files (not base64) with extensions. Entity type and bundle/sub-type are
* hardcoded and are set to "node" and "poi_collection". Quick and dirty but does the job.
*/
<?php
namespace Drupal\content_sync\Form;
use Drupal\content_sync\ContentSyncManagerInterface;
use Drupal\content_sync\Exporter\ContentExporterInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Entity\EntityTypeBundleInfo;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\Core\Entity\ContentEntityType;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Provides a form for exporting a single content file.
*/
class ContentSingleExportForm extends FormBase {
use ContentExportTrait;
/**
* The entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* The entity bundle manager.
*
* @var \Drupal\Core\Entity\EntityTypeBundleInfo
*/
protected $entityBundleManager;
/**
* @var \Drupal\content_sync\Exporter\ContentExporterInterface
*/
protected $contentExporter;
/**
* @var \Drupal\content_sync\ContentSyncManagerInterface
*/
protected $contentSyncManager;
/**
* Constructs a new ContentSingleExportForm.
*
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
*
* @param \Drupal\Core\Entity\EntityTypeBundleInfo $entity_bundle_manager
*
* @param \Drupal\content_sync\Exporter\ContentExporterInterface $content_exporter
*/
public function __construct(EntityTypeManagerInterface $entity_type_manager, EntityTypeBundleInfo $entity_bundle_manager, ContentExporterInterface $content_exporter, ContentSyncManagerInterface $content_sync_manager) {
$this->entityTypeManager = $entity_type_manager;
$this->entityBundleManager = $entity_bundle_manager;
$this->contentExporter = $content_exporter;
$this->contentSyncManager = $content_sync_manager;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('entity_type.manager'),
$container->get('entity_type.bundle.info'),
$container->get('content_sync.exporter'),
$container->get('content_sync.manager')
);
}
/**
* {@inheritdoc}
*/
public function getFormId() {
return 'config_single_export_form';
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state, $content_type = 'node', $content_name = NULL, $content_entity = NULL) {
$default_type = 'node';
$default_name = 'poi_collection';
// Auto-complete field for the content entity
if($default_type && $default_name){
$form['content_entity'] = [
'#title' => $this->t('Content Entity'),
'#type' => 'entity_autocomplete',
'#target_type' => $default_type,
'#selection_handler' => 'default',
'#selection_settings' => [
'target_bundles' => [$default_name],
],
'#ajax' => [
'callback' => '::updateExport',
'wrapper' => 'edit-export-wrapper',
'event' => 'autocompleteclose',
],
];
// Autocomplete doesn't support target bundles parameter on bundle-less entities.
$target_type = \Drupal::entityManager()->getDefinition($default_type);
$target_type_bundles = $target_type->getBundleEntityType();
if(is_null($target_type_bundles)){
unset($form['content_entity']['#selection_settings']);
}
}
$form['export'] = [
'#title' => $this->t('Here is your configuration:'),
'#type' => 'textarea',
'#rows' => 5,
'#prefix' => '<div id="edit-export-wrapper">',
'#suffix' => '</div>',
];
$form['submit'] = [
'#type' => 'submit',
'#value' => $this->t('Export'),
];
return $form;
}
/**
* Handles switching the content type selector.
*/
protected function findContent($content_type) {
$names = [
'' => $this->t('- Select -'),
];
// For a given entity type, load all entities.
if ($content_type) {
$entity_storage = $this->entityBundleManager->getBundleInfo($content_type);
foreach ($entity_storage as $entityKey => $entity) {
$entity_id = $entityKey;
if ($label = $entity['label']) {
$names[$entity_id] = new TranslatableMarkup('@label (@id)', ['@label' => $label, '@id' => $entity_id]);
}
else {
$names[$entity_id] = $entity_id;
}
}
}
return $names;
}
/**
* Handles switching the export textarea.
*/
public function updateExport($form, FormStateInterface $form_state) {
// Get submitted values
// $entity_type = $form_state->getValue('content_type');
$entity_id = $form_state->getValue('content_entity');
$entity_type = 'node';
// $entity_id = 'poi_collection';
// DB entity to YAML
$entity = $this->entityTypeManager->getStorage($entity_type)->load($entity_id);
// Generate the YAML file.
$serializer_context = [];
$language = \Drupal::languageManager()->getCurrentLanguage()->getId();
$entity = $entity->getTranslation($language);
$exported_entity = $this->contentExporter->exportEntity($entity, $serializer_context);
// Create the name
$name = $entity_type . "." . $entity->bundle() . "." . $entity->uuid();
// Return form values
$form['export']['#value'] = $exported_entity;
$form['export']['#description'] = $this->t('Filename: %name', ['%name' => $name . '.yml']);
return $form['export'];
}
public function snapshot() {
//Set batch operations by entity type/bundle
$entities_list = [];
$entity_type_definitions = $this->entityTypeManager->getDefinitions();
foreach ($entity_type_definitions as $entity_type => $definition) {
$reflection = new \ReflectionClass($definition->getClass());
if ($reflection->implementsInterface(ContentEntityInterface::class)) {
$entities = $this->entityTypeManager->getStorage($entity_type)
->getQuery()
->execute();
foreach ($entities as $entity_id) {
$entities_list[] = [
'entity_type' => $entity_type,
'entity_id' => $entity_id,
];
}
}
}
if (!empty($entities_list)) {
$serializer_context['export_type'] = 'snapshot';
$batch = $this->generateExportBatch($entities_list, $serializer_context);
batch_set($batch);
}
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
// drupal_set_message(t('The form has been submitted.'));
// Delete the content tar file in case an older version exist.
file_unmanaged_delete($this->getTempFile());
$entities_list = [];
$entity_type = 'node';
$entity_id = $form_state->getValue('content_entity');
$entities_list[] = [
'entity_type' => $entity_type,
'entity_id' => $entity_id,
];
if (!empty($entities_list)) {
$serializer_context['export_type'] = 'tar';
$serializer_context['include_files'] = 'folder';
$serializer_context['include_dependencies'] = true;
$batch = $this->generateExportBatch($entities_list, $serializer_context);
batch_set($batch);
}
}
/**
* @{@inheritdoc}
*/
protected function getEntityTypeManager() {
return $this->entityTypeManager;
}
/**
* @{@inheritdoc}
*/
protected function getContentExporter() {
return $this->contentExporter;
}
/**
* @{@inheritdoc}
*/
protected function getExportLogger() {
return $this->logger('content_sync');
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment