content_deploy-1.0.1/src/Form/SingleImportWithDependenciesForm.php
src/Form/SingleImportWithDependenciesForm.php
<?php
namespace Drupal\content_deploy\Form;
use Drupal\Core\Archiver\ArchiveTar;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\content_deploy\Importer\ContentImporterInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Component\Serialization\Yaml;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\File\FileSystemInterface;
/**
* Defines the content import form.
*/
class SingleImportWithDependenciesForm extends FormBase {
/**
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* @var \Drupal\content_deploy\Importer\ContentImporterInterface
*/
protected $contentImporter;
/**
* @var
*/
protected $importedFiles;
/**
* @var
*/
protected $processedEntities;
/**
* ContentImportForm constructor.
*/
public function __construct(EntityTypeManagerInterface $entity_type_manager = NULL, ContentImporterInterface $content_importer = NULL, $importedFiles = [], $processedEntities = []) {
$this->entityTypeManager = $entity_type_manager;
$this->contentImporter = $content_importer;
$this->importedFiles = $importedFiles;
$this->processedEntities = $processedEntities;
}
/**
*
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('entity_type.manager'),
$container->get('content_deploy.importer')
);
}
/**
* {@inheritdoc}
*/
public function getFormId() {
return 'import_with_dependencies_form';
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$directory = \Drupal::service('file_system')->getTempDirectory();
$directory_is_writable = is_writable($directory);
if (!$directory_is_writable) {
$this->logger('content_deploy')->error('The directory %directory is not writable.', ['%directory' => $directory, 'link' => 'Import Archive']);
\Drupal::messenger()->addError(t('The directory %directory is not writable.', ['%directory' => $directory]));
}
$form['import_tarball'] = [
'#type' => 'file',
'#title' => $this->t('Configuration archive'),
'#description' => $this->t('Allowed types: @extensions.', ['@extensions' => 'tar.gz']),
];
$form['submit'] = [
'#type' => 'submit',
'#value' => $this->t('Upload'),
'#disabled' => !$directory_is_writable,
];
return $form;
}
/**
* {@inheritdoc}
*/
public function validateForm(array &$form, FormStateInterface $form_state) {
$all_files = $this->getRequest()->files->get('files', []);
if (!empty($all_files['import_tarball'])) {
$file_upload = $all_files['import_tarball'];
if ($file_upload->isValid()) {
$form_state->setValue('import_tarball', $file_upload->getRealPath());
return;
}
}
$form_state->setErrorByName('import_tarball', $this->t('The file could not be uploaded.'));
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
if ($path = $form_state->getValue('import_tarball')) {
$directory = \Drupal::service('file_system')->getTempDirectory();
try {
$archiver = new ArchiveTar($path, 'gz');
$files = [];
$parentEntity = '';
$attachedFiles = [];
foreach ($archiver->listContent() as $file) {
if (strpos($file['filename'], '/parent/') !== FALSE) {
$parentEntity = $file['filename'];
}
elseif (strpos($file['filename'], '/attached_files/') !== FALSE) {
$attachedFiles[] = $file['filename'];
}
else {
$files[] = $file['filename'];
}
}
$files[] = $parentEntity;
$archiver->extractList($attachedFiles, $directory);
if (!empty($attachedFiles)) {
foreach ($attachedFiles as $singleAttachedFile) {
$fileDestinationArr = explode('attached_files', $singleAttachedFile);
if (isset($fileDestinationArr[1]) && !empty($fileDestinationArr[1])) {
$fileDestinationArr = trim($fileDestinationArr[1], '/');
$fileDestinationArr = explode('/', $fileDestinationArr);
$scheme = $fileDestinationArr[0];
array_shift($fileDestinationArr);
$fileDestination = $scheme . '://' . implode('/', $fileDestinationArr);
$prepareDirPath = str_replace(basename($fileDestination), '', $fileDestination);
$prepareDir = \Drupal::service('file_system')->prepareDirectory($prepareDirPath, FileSystemInterface::CREATE_DIRECTORY);
if ($prepareDir) {
copy($directory . '/' . $singleAttachedFile, $fileDestination);
}
}
}
}
$archiver->extractList($files, $directory);
if (!empty($files)) {
foreach ($files as $file) {
if (!file_exists($directory . '/' . $file) || in_array(basename($file), $this->importedFiles)) {
continue;
}
$data = file_get_contents($directory . '/' . $file);
$ymlData = Yaml::decode($data);
if (!in_array(basename($file), $this->processedEntities)) {
$this->processedEntities[] = basename($file);
if (isset($ymlData['_content_deploy']['entity_dependencies']) && !empty($ymlData['_content_deploy']['entity_dependencies'])) {
$entityDependencies = $ymlData['_content_deploy']['entity_dependencies'];
$this->_import_entity_dependencies($entityDependencies, $files, $directory);
}
}
$entity = $this->contentImporter->importEntity($ymlData);
if ($entity) {
$this->importedFiles[] = basename($file);
\Drupal::messenger()->addStatus($this->t('Entity @label (@entity_type: @id) imported successfully.', [
'@label' => $entity->label(),
'@entity_type' => $entity->getEntityTypeId(),
'@id' => $entity->id(),
]));
}
}
}
\Drupal::messenger()->addStatus($this->t('Your content files are successfully imported.'));
$this->logger('content_deploy')->notice('Your content files are successfully imported.', ['link' => 'Import Archive']);
$form_state->setRedirect('content.import_single_with_dependencies');
}
catch (\Exception $e) {
\Drupal::messenger()->addStatus($this->t('Could not extract the contents of the tar file. The error message is <em>@message</em>', ['@message' => $e->getMessage()]));
$this->logger('content_deploy')->error('Could not extract the contents of the tar file. The error message is <em>@message</em>', ['@message' => $e->getMessage(), 'link' => 'Import Archive']);
}
}
}
/**
* Provides help to import child dependencies.
*/
private function _import_entity_dependencies($entityDependencies, $files, $directory) {
if (empty($entityDependencies) || empty($files) || empty($directory)) {
$this->logger('content_deploy')->error('Entity dependencies or content files or directory name is empty');
return;
}
foreach ($entityDependencies as $entityType => $singleTypeEntityDependency) {
foreach ($singleTypeEntityDependency as $singleEntityDependency) {
$singleEntityDependencyFile = $singleEntityDependency . '.yml';
$matches = array_filter($files, function ($var) use ($singleEntityDependencyFile) {
return preg_match("/\b$singleEntityDependencyFile\b/i", $var);
});
if (!empty($matches)) {
$file = reset($matches);
if (!file_exists($directory . '/' . $file) || in_array(basename($file), $this->importedFiles)) {
continue;
}
$data = file_get_contents($directory . '/' . $file);
$ymlData = Yaml::decode($data);
if (!in_array(basename($file), $this->processedEntities)) {
$this->processedEntities[] = basename($file);
if (isset($ymlData['_content_deploy']['entity_dependencies']) && !empty($ymlData['_content_deploy']['entity_dependencies'])) {
$entityDependencies = $ymlData['_content_deploy']['entity_dependencies'];
$this->_import_entity_dependencies($entityDependencies, $files, $directory);
}
}
$entity = $this->contentImporter->importEntity($ymlData);
if ($entity) {
$this->importedFiles[] = basename($file);
\Drupal::messenger()->addStatus($this->t('Entity @label (@entity_type: @id) imported successfully.', [
'@label' => $entity->label(),
'@entity_type' => $entity->getEntityTypeId(),
'@id' => $entity->id(),
]));
}
}
}
}
}
}
