View source
<?php
namespace Drupal\content_synchronizer\Entity;
use Drupal\Component\Utility\Environment;
use Drupal\content_synchronizer\Base\JsonWriterTrait;
use Drupal\content_synchronizer\Processors\ExportEntityWriter;
use Drupal\content_synchronizer\Service\GlobalReferenceManager;
use Drupal\Core\Archiver\ArchiveTar;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\Core\Entity\ContentEntityBase;
use Drupal\Core\Entity\EntityChangedTrait;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\File\FileSystem;
use Drupal\file\Entity\File;
use Drupal\user\UserInterface;
use Drupal\Core\Url;
class ImportEntity extends ContentEntityBase implements ImportEntityInterface {
use EntityChangedTrait;
use JsonWriterTrait;
const STATUS_NOT_STARTED = 0;
const STATUS_RUNNING = 1;
const STATUS_DONE = 2;
const FIELD_ARCHIVE = 'archive';
const FIELD_PROCESSING_STATUS = 'processing_status';
const ENTITY_FIELD_IMPORTING_STATUS = 'status';
const ARCHIVE_DESTINATION = 'private://content_synchronizer';
protected $entityTypeData = [];
protected $rootEntities;
protected $globalReferenceManager;
public function __construct(array $values, $entity_type = 'import_entity', $bundle = FALSE, array $translations = []) {
parent::__construct($values, $entity_type, $bundle, $translations);
$this->globalReferenceManager = \Drupal::service(GlobalReferenceManager::SERVICE_NAME);
}
public static function preCreate(EntityStorageInterface $storage_controller, array &$values) {
parent::preCreate($storage_controller, $values);
$values += [
'user_id' => \Drupal::currentUser()
->id(),
];
}
public function getName() {
return $this
->get('name')->value;
}
public function setName($name) {
$this
->set('name', $name);
return $this;
}
public function getCreatedTime() {
return $this
->get('created')->value;
}
public function setCreatedTime($timestamp) {
$this
->set('created', $timestamp);
return $this;
}
public function getOwner() {
return $this
->get('user_id')->entity;
}
public function getOwnerId() {
return $this
->get('user_id')->target_id;
}
public function setOwnerId($uid) {
$this
->set('user_id', $uid);
return $this;
}
public function setOwner(UserInterface $account) {
$this
->set('user_id', $account
->id());
return $this;
}
public function isPublished() {
return (bool) $this
->getEntityKey('status');
}
public function setPublished($published) {
$this
->set('status', $published ? TRUE : FALSE);
return $this;
}
public function getArchive() {
return File::load($this
->get(self::FIELD_ARCHIVE)->target_id);
}
public function getProcessingStatus() {
return intval($this
->get(self::FIELD_PROCESSING_STATUS)->value);
}
public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
$fields = parent::baseFieldDefinitions($entity_type);
$fields['user_id'] = BaseFieldDefinition::create('entity_reference')
->setLabel(t('Authored by'))
->setDescription(t('The user ID of author of the Import entity.'))
->setRevisionable(TRUE)
->setSetting('target_type', 'user')
->setSetting('handler', 'default')
->setTranslatable(TRUE)
->setDisplayOptions('view', [
'label' => 'hidden',
'type' => 'author',
'weight' => 0,
])
->setDisplayConfigurable('view', TRUE);
$fields['name'] = BaseFieldDefinition::create('string')
->setLabel(t('Name'))
->setDescription(t('The name of the Import entity.'))
->setSettings([
'max_length' => 50,
'text_processing' => 0,
])
->setDefaultValue('')
->setDisplayOptions('view', [
'label' => 'above',
'type' => 'string',
'weight' => -4,
])
->setDisplayOptions('form', [
'type' => 'string_textfield',
'weight' => -4,
])
->setDisplayConfigurable('form', TRUE)
->setDisplayConfigurable('view', TRUE);
$fields['status'] = BaseFieldDefinition::create('boolean')
->setLabel(t('Publishing status'))
->setDescription(t('A boolean indicating whether the Import is published.'))
->setDefaultValue(TRUE);
$fields['created'] = BaseFieldDefinition::create('created')
->setLabel(t('Created'))
->setDescription(t('The time that the entity was created.'));
$fields['changed'] = BaseFieldDefinition::create('changed')
->setLabel(t('Changed'))
->setDescription(t('The time that the entity was last edited.'));
$extension = 'gz';
$validators = [
'file_validate_extensions' => [
$extension,
],
'file_validate_size' => [
Environment::getUploadMaxSize(),
],
];
$fields[self::FIELD_ARCHIVE] = BaseFieldDefinition::create('file')
->setLabel(t('Archive'))
->setDescription(t('The archive'))
->setSetting('upload_validators', $validators)
->setSetting('file_extensions', $extension)
->setRequired(TRUE)
->setDisplayOptions('view', [
'label' => 'above',
'type' => 'file',
'weight' => -3,
])
->setDisplayOptions('form', [
'type' => 'file',
'description' => [
'theme' => 'file_upload_help',
'description' => t('A Gettext Portable Object file.'),
],
'settings' => [
'upload_validators' => $validators,
],
'weight' => -3,
])
->setDisplayConfigurable('form', TRUE)
->setDisplayConfigurable('view', TRUE);
$fields[self::FIELD_PROCESSING_STATUS] = BaseFieldDefinition::create('integer')
->setLabel(t('Processing status'))
->setDescription(t('Processing status'))
->setDefaultValue(self::STATUS_NOT_STARTED);
return $fields;
}
public function save() {
$name = $this
->getName();
if (empty($name)) {
$file = $this
->get(static::FIELD_ARCHIVE)
->referencedEntities()[0];
$this
->setName(basename($file
->getFileUri()));
}
return parent::save();
}
public function getRootsEntities() {
if (is_null($this->rootEntities)) {
if (!file_exists($this
->getArchiveFilesPath())) {
$this
->unzipArchive();
}
$this->rootEntities = $this
->getDataFromFile($this
->getArchiveFilesPath() . '/' . ExportEntityWriter::ROOT_FILE_NAME . ExportEntityWriter::TYPE_EXTENSION);
foreach ($this->rootEntities as &$entity) {
$existingEntity = $this->globalReferenceManager
->getExistingEntityByGidAndUuid($entity[ExportEntityWriter::FIELD_GID], $entity[ExportEntityWriter::FIELD_UUID]);
if ($existingEntity) {
$entity['status'] = 'update';
$entity['edit_url'] = Url::fromRoute('entity.' . $existingEntity
->getEntityTypeId() . '.edit_form', [
$existingEntity
->getEntityTypeId() => $existingEntity
->id(),
]);
$entity['view_url'] = $existingEntity
->toUrl();
}
else {
$entity['status'] = 'create';
}
}
}
return $this->rootEntities;
}
public function isRootEntity($gid) {
foreach ($this
->getRootsEntities() as $rootEntity) {
if ($rootEntity[ExportEntityWriter::FIELD_GID] == $gid) {
return TRUE;
}
}
return FALSE;
}
public function getArchiveFilesPath() {
return ExportEntityWriter::getGeneratorDir() . 'import/' . $this
->id();
}
public function getDataFromEntityTypeFile($entityType) {
if (!file_exists($this
->getArchiveFilesPath())) {
$this
->unzipArchive();
}
if (!array_key_exists($entityType, $this->entityTypeData)) {
$this->entityTypeData[$entityType] = $this
->getDataFromFile($this
->getArchiveFilesPath() . '/' . $entityType . ExportEntityWriter::TYPE_EXTENSION);
}
return $this->entityTypeData[$entityType];
}
public function getEntityDataFromGid($gid) {
$entityTypeId = $this->globalReferenceManager
->getEntityTypeFromGid($gid);
return $this
->getDataFromEntityTypeFile($entityTypeId)[$gid];
}
public function gidIsCurrentlyImporting($gid) {
$entityData = $this
->getEntityDataFromGid($gid);
$result = FALSE;
if ($entityData && array_key_exists(self::ENTITY_FIELD_IMPORTING_STATUS, $entityData)) {
$result = $entityData[self::ENTITY_FIELD_IMPORTING_STATUS] == self::STATUS_RUNNING;
}
return $result;
}
public function gidHasAlreadyBeenImported($gid) {
$entityData = $this
->getEntityDataFromGid($gid);
$result = FALSE;
if ($entityData && array_key_exists(self::ENTITY_FIELD_IMPORTING_STATUS, $entityData)) {
$result = $entityData[self::ENTITY_FIELD_IMPORTING_STATUS] == self::STATUS_DONE;
}
return $result;
}
public function tagHasImporting($gid) {
$this
->setGidStatus($gid, self::STATUS_RUNNING);
}
public function tagHasImported($gid) {
$this
->setGidStatus($gid, self::STATUS_DONE);
}
protected function setGidStatus($gid, $status) {
$entityTypeId = $this->globalReferenceManager
->getEntityTypeFromGid($gid);
$allData = $this
->getDataFromEntityTypeFile($entityTypeId);
$this->entityTypeData[$entityTypeId][$gid][self::ENTITY_FIELD_IMPORTING_STATUS] = $allData[$gid][self::ENTITY_FIELD_IMPORTING_STATUS] = $status;
$this
->writeJson($allData, $this
->getArchiveFilesPath() . '/' . $entityTypeId . ExportEntityWriter::TYPE_EXTENSION);
}
protected function unzipArchive() {
if ($file = $this
->getArchive()) {
if ($zipUrl = $file
->getFileUri()) {
$fileSystem = \Drupal::service('file_system');
$realPathUrl = $fileSystem
->realpath($zipUrl);
$dir = $this
->getArchiveFilesPath();
if (!is_dir($dir)) {
$fileSystem
->prepareDirectory($dir, FileSystem::CREATE_DIRECTORY);
}
$archiver = new ArchiveTar($realPathUrl, 'gz');
$files = [];
foreach ($archiver
->listContent() as $file) {
$files[] = $file['filename'];
}
$archiver
->extractList($files, $dir);
}
}
}
public function preSave(EntityStorageInterface $storage) {
$this
->removeArchive();
parent::preSave($storage);
}
public function removeArchive() {
$this
->fileSystem()
->deleteRecursive($this
->getArchiveFilesPath());
}
}