View source
<?php
namespace Drupal\cms_content_sync\Entity;
use Drupal\cms_content_sync\PushIntent;
use Drupal\cms_content_sync\SyncCoreInterface\SyncCoreFactory;
use Drupal\cms_content_sync\SyncCorePoolExport;
use Drupal\Core\Config\Entity\ConfigEntityBase;
use Drupal\Core\Config\Entity\ConfigEntityInterface;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Site\Settings;
use GuzzleHttp\Exception\RequestException;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
class Pool extends ConfigEntityBase implements PoolInterface {
public const POOL_USAGE_FORBID = 'forbid';
public const POOL_USAGE_ALLOW = 'allow';
public const POOL_USAGE_FORCE = 'force';
public $id;
public $label;
public $backend_url;
public $authentication_type;
public $site_id;
protected $client;
public function getClient() {
if (!$this->client) {
$this->client = SyncCoreFactory::getSyncCore($this
->getSyncCoreUrl());
}
return $this->client;
}
public static function preDelete(EntityStorageInterface $storage, array $entities) {
parent::preDelete($storage, $entities);
try {
foreach ($entities as $entity) {
$handler = new SyncCorePoolExport($entity);
}
} catch (RequestException $e) {
$messenger = \Drupal::messenger();
$messenger
->addError(t('The Sync Core server could not be accessed. Please check the connection.'));
throw new AccessDeniedHttpException();
}
}
public static function getAllSitesWithDifferentEntityTypeVersion($entity_type, $bundle) {
$result = [];
foreach (Pool::getAll() as $pool_id => $pool) {
$diff = $pool
->getClient()
->getSitesWithDifferentEntityTypeVersion($pool->id, $entity_type, $bundle, Flow::getEntityTypeVersion($entity_type, $bundle));
if (empty($diff)) {
continue;
}
$result[$pool_id] = $diff;
}
return $result;
}
public static function getAllExternalUsages($entity) {
$entity_type = $entity
->getEntityTypeId();
$bundle = $entity
->bundle();
$entity_uuid = $entity
->uuid();
$result = [];
foreach (EntityStatus::getInfosForEntity($entity_type, $entity_uuid) as $status) {
$pool = $status
->getPool();
if (empty($pool)) {
continue;
}
$pool_id = $pool->id;
if (isset($result[$pool_id])) {
continue;
}
if ($entity instanceof ConfigEntityInterface) {
$shared_entity_id = $entity
->id();
}
else {
$shared_entity_id = $entity_uuid;
}
$result[$pool_id] = $pool
->getClient()
->getSyndicationService()
->getExternalUsages($pool_id, $entity_type, $bundle, $shared_entity_id);
}
return $result;
}
public function getSyncCoreUrl() {
$cms_content_sync_settings = Settings::get('cms_content_sync');
if (isset($cms_content_sync_settings, $cms_content_sync_settings['pools'][$this->id]['backend_url'])) {
return $cms_content_sync_settings['pools'][$this->id]['backend_url'];
}
return $this->backend_url;
}
public function getNewestTimestamp($entity_type, $entity_uuid, $pull = true) {
$entity_status = EntityStatus::getInfoForPool($entity_type, $entity_uuid, $this);
$timestamp = null;
foreach ($entity_status as $info) {
$item_timestamp = $pull ? $info
->getLastPull() : $info
->getLastPush();
if ($item_timestamp) {
if (!$timestamp || $timestamp < $item_timestamp) {
$timestamp = $item_timestamp;
}
}
}
return $timestamp;
}
public function setTimestamp($entity_type, $entity_uuid, $timestamp, $pull = true) {
$entity_status = EntityStatus::getInfoForPool($entity_type, $entity_uuid, $this);
foreach ($entity_status as $info) {
if ($pull) {
$info
->setLastPull($timestamp);
}
else {
$info
->setLastPush($timestamp);
}
$info
->save();
}
}
public function markDeleted($entity_type, $entity_uuid) {
$entity_status = EntityStatus::getInfoForPool($entity_type, $entity_uuid, $this);
foreach ($entity_status as $info) {
$info
->isDeleted(true);
$info
->save();
}
}
public function isEntityDeleted($entity_type, $entity_uuid) {
$entity_status = EntityStatus::getInfoForPool($entity_type, $entity_uuid, $this);
foreach ($entity_status as $info) {
if ($info
->isDeleted()) {
return true;
}
}
return false;
}
public static function getAll() {
return \Drupal::entityTypeManager()
->getStorage('cms_content_sync_pool')
->loadMultiple();
}
public static function getSelectablePools($entity_type, $bundle, $parent_entity = null, $field_name = null) {
$flows = Flow::getAll();
$configs = [];
$selectable_pools = [];
$selectable_flows = [];
$root_entity = !$parent_entity && !$field_name;
if ($root_entity) {
$allowed_push_options = [
PushIntent::PUSH_FORCED,
PushIntent::PUSH_MANUALLY,
PushIntent::PUSH_AUTOMATICALLY,
];
}
else {
$allowed_push_options = [
PushIntent::PUSH_FORCED,
PushIntent::PUSH_AS_DEPENDENCY,
];
}
foreach ($flows as $flow_id => $flow) {
$flow_entity_config = $flow
->getEntityTypeConfig($entity_type, $bundle);
if (empty($flow_entity_config)) {
continue;
}
if ('ignore' == $flow_entity_config['handler']) {
continue;
}
if (!in_array($flow_entity_config['export'], $allowed_push_options)) {
continue;
}
if ($parent_entity && $field_name) {
$parent_flow_config = $flow->sync_entities[$parent_entity
->getEntityTypeId() . '-' . $parent_entity
->bundle() . '-' . $field_name];
if (!empty($parent_flow_config['handler_settings']['export_referenced_entities'])) {
continue;
}
}
$selectable_flows[$flow_id] = $flow;
$configs[$flow_id] = [
'flow_label' => $flow
->label(),
'flow' => $flow
->getEntityTypeConfig($entity_type, $bundle),
];
}
foreach ($configs as $config_id => $config) {
if (in_array('allow', $config['flow']['export_pools'])) {
$selectable_pools[$config_id]['flow_label'] = $config['flow_label'];
$selectable_pools[$config_id]['widget_type'] = $config['flow']['pool_export_widget_type'];
foreach ($config['flow']['export_pools'] as $pool_id => $push_to_pool) {
if (self::POOL_USAGE_ALLOW == $push_to_pool) {
$pool_entity = \Drupal::entityTypeManager()
->getStorage('cms_content_sync_pool')
->loadByProperties([
'id' => $pool_id,
]);
$pool_entity = reset($pool_entity);
$selectable_pools[$config_id]['pools'][$pool_id] = $pool_entity
->label();
}
}
}
}
return $selectable_pools;
}
public static function resetStatusEntities($pool_id = '') {
$status_storage = \Drupal::entityTypeManager()
->getStorage('cms_content_sync_entity_status');
$connection = \Drupal::database();
if (!empty($pool_id)) {
$connection
->query('UPDATE cms_content_sync_entity_status SET flags=flags|:flag WHERE last_export IS NOT NULL AND pool=:pool', [
':flag' => EntityStatus::FLAG_LAST_PUSH_RESET,
':pool' => $pool_id,
]);
$connection
->query('UPDATE cms_content_sync_entity_status SET flags=flags|:flag WHERE last_import IS NOT NULL AND pool=:pool', [
':flag' => EntityStatus::FLAG_LAST_PULL_RESET,
':pool' => $pool_id,
]);
$db_query = $connection
->update($status_storage
->getBaseTable());
$db_query
->fields([
'last_export' => null,
'last_import' => null,
]);
$db_query
->condition('pool', $pool_id);
$db_query
->execute();
}
else {
$connection
->query('UPDATE cms_content_sync_entity_status SET flags=flags|:flag WHERE last_export IS NOT NULL', [
':flag' => EntityStatus::FLAG_LAST_PUSH_RESET,
]);
$connection
->query('UPDATE cms_content_sync_entity_status SET flags=flags|:flag WHERE last_import IS NOT NULL', [
':flag' => EntityStatus::FLAG_LAST_PULL_RESET,
]);
$db_query = $connection
->update($status_storage
->getBaseTable());
$db_query
->fields([
'last_export' => null,
'last_import' => null,
]);
$db_query
->execute();
}
$status_storage
->resetCache();
\Drupal::service('cache.entity')
->deleteAll();
}
public static function createPool($pool_name, $pool_id, $backend_url, $authentication_type) {
if (empty($pool_id)) {
$pool_id = strtolower($pool_name);
$pool_id = preg_replace('@[^a-z0-9_]+@', '_', $pool_id);
}
$pools = Pool::getAll();
if (array_key_exists($pool_id, $pools)) {
\Drupal::messenger()
->addMessage('A pool with the machine name ' . $pool_id . ' does already exist. Therefor the creation has been skipped.', 'warning');
}
else {
$uuid_service = \Drupal::service('uuid');
$language_manager = \Drupal::service('language_manager');
$default_language = $language_manager
->getDefaultLanguage();
$pool_config = \Drupal::service('config.factory')
->getEditable('cms_content_sync.pool.' . $pool_id);
$pool_config
->set('uuid', $uuid_service
->generate())
->set('langcode', $default_language
->getId())
->set('status', true)
->set('id', $pool_id)
->set('label', $pool_name)
->set('backend_url', $backend_url)
->set('authentication_type', $authentication_type)
->save();
}
return $pool_id;
}
}