class FlowPull in CMS Content Sync 8
Same name and namespace in other branches
- 2.1.x src/Controller/FlowPull.php \Drupal\cms_content_sync\Controller\FlowPull
- 2.0.x src/Controller/FlowPull.php \Drupal\cms_content_sync\Controller\FlowPull
Pull controller.
Hierarchy
- class \Drupal\Core\Controller\ControllerBase implements ContainerInjectionInterface uses LoggerChannelTrait, MessengerTrait, LinkGeneratorTrait, RedirectDestinationTrait, UrlGeneratorTrait, StringTranslationTrait
- class \Drupal\cms_content_sync\Controller\FlowPull
Expanded class hierarchy of FlowPull
2 files declare their use of FlowPull
- CliService.php in src/
Cli/ CliService.php - PullStatusEntity.php in modules/
cms_content_sync_views/ src/ Plugin/ Action/ PullStatusEntity.php
File
- src/
Controller/ FlowPull.php, line 19
Namespace
Drupal\cms_content_sync\ControllerView source
class FlowPull extends ControllerBase {
/**
* Pull all entities of this Flow.
*
* @param $cms_content_sync_flow
* @param $pull_mode
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
*
* @return null|\Symfony\Component\HttpFoundation\RedirectResponse
*/
public function pull($cms_content_sync_flow, $pull_mode) {
/**
* @var \Drupal\cms_content_sync\Entity\Flow $flow
*/
$flow = \Drupal::entityTypeManager()
->getStorage('cms_content_sync_flow')
->load($cms_content_sync_flow);
$force_pull = false;
if ('all_entities' == $pull_mode) {
$force_pull = true;
}
$result = FlowPull::pullAll($flow, $force_pull);
$operations = [];
foreach ($result as $id => $operation) {
$operations[] = [
'\\Drupal\\cms_content_sync\\Controller\\FlowPull::batch',
[
$operation,
],
];
}
$batch = [
'title' => t('Pull all'),
'operations' => $operations,
'finished' => '\\Drupal\\cms_content_sync\\Controller\\FlowPull::batchFinished',
];
batch_set($batch);
return batch_process(Url::fromRoute('entity.cms_content_sync_flow.collection'));
}
/**
* Force pull an entity for a specific flow.
*
* @param $flow_id
* @param $entity_type
* @param $entity_uuid
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
*/
public static function force_pull_entity($flow_id, $entity_type, $entity_uuid) {
$entity = EntityStatus::getInfosForEntity($entity_type, $entity_uuid, [
'flow' => $flow_id,
]);
$entity = reset($entity);
/** @var \Drupal\cms_content_sync\Entity\EntityStatus $entity */
if ($entity instanceof EntityStatus) {
// If the entity is embedded, we need to pull the parent entity instead.
if ($entity
->wasPulledEmbedded()) {
$parent = $entity
->getParentEntity();
if (!$parent) {
$raw = $entity
->getData(EntityStatus::DATA_PARENT_ENTITY);
\Drupal::messenger()
->addMessage(t("The @type with the ID @uuid was pulled embedded into another entity but that parent @parent_type with ID @parent_uuid doesn't exist.", [
'@type' => $entity
->get('entity_type')
->getValue()[0]['value'],
'@uuid' => $entity
->get('entity_uuid')
->getValue()[0]['value'],
'@parent_type' => $raw['type'],
'@parent_uuid' => $raw['uuid'],
]), 'warning');
return;
}
self::force_pull_entity($flow_id, $parent
->getEntityTypeId(), $parent
->uuid());
}
$source = $entity
->getEntity();
if (empty($source)) {
\Drupal::messenger()
->addMessage(t("The @type with the ID @uuid doesn't exist locally, pull skipped.", [
'@type' => $entity
->get('entity_type')
->getValue()[0]['value'],
'@uuid' => $entity
->get('entity_uuid')
->getValue()[0]['value'],
]), 'warning');
return;
}
$pool = $entity
->getPool();
if (empty($pool)) {
\Drupal::messenger()
->addMessage(t('The Pool for @type %label doesn\'t exist anymore, push skipped.', [
'@type' => $entity
->get('entity_type')
->getValue()[0]['value'],
'%label' => $source
->label(),
]), 'warning');
return;
}
$entity_type_name = $source
->getEntityTypeId();
$entity_bundle = $source
->bundle();
$manual = false;
$flow = $entity
->getFlow();
if (!$flow || !$flow
->canPullEntity($entity_type_name, $entity_bundle, PullIntent::PULL_AUTOMATICALLY, SyncIntent::ACTION_CREATE, true)) {
if ($flow && $flow
->canPullEntity($entity_type_name, $entity_bundle, PullIntent::PULL_MANUALLY, SyncIntent::ACTION_CREATE, true)) {
$manual = true;
}
elseif (!$flow || !$flow
->canPullEntity($entity_type_name, $entity_bundle, PullIntent::PULL_AS_DEPENDENCY, SyncIntent::ACTION_CREATE, true)) {
// The flow from the status entity no longer pulls this entity type / bundle => look for a new Flow to replace it.
$flow = Flow::getFlowForApiAndEntityType($pool, $entity_type_name, $entity_bundle, PullIntent::PULL_AUTOMATICALLY, SyncIntent::ACTION_CREATE, true);
if (!$flow) {
$flow = Flow::getFlowForApiAndEntityType($pool, $entity_type_name, $entity_bundle, PullIntent::PULL_MANUALLY, SyncIntent::ACTION_CREATE, true);
if ($flow) {
$manual = true;
}
else {
$flow = Flow::getFlowForApiAndEntityType($pool, $entity_type_name, $entity_bundle, PullIntent::PULL_AS_DEPENDENCY, SyncIntent::ACTION_CREATE, true);
if (!$flow) {
\Drupal::messenger()
->addMessage(t('No Flow exists to pull @type %label, pull skipped.', [
'@type' => $entity
->get('entity_type')
->getValue()[0]['value'],
'%label' => $source
->label(),
]), 'warning');
return;
}
}
}
}
}
if ($source instanceof ConfigEntityInterface) {
$shared_entity_id = $source
->id();
}
else {
$shared_entity_id = $source
->uuid();
}
try {
$pool
->getClient()
->getSyndicationService()
->pullSingle($flow->id, $entity_type_name, $entity_bundle, $shared_entity_id)
->fromPool($pool->id)
->manually((bool) $manual)
->execute();
\Drupal::messenger()
->addMessage(t('Pull of @type %label has been triggered.', [
'@type' => $entity
->get('entity_type')
->getValue()[0]['value'],
'%label' => $source
->label(),
]));
} catch (SyncCoreException $e) {
\Drupal::messenger()
->addMessage(t('Failed to pull @type %label: @message', [
'@type' => $entity
->get('entity_type')
->getValue()[0]['value'],
'%label' => $source
->label(),
'@message' => $e
->getMessage(),
]), 'warning');
}
}
else {
\Drupal::messenger()
->addMessage(t('No local status entity found for Entity Type: @type having UUID: @uuid.', [
'@type' => $entity_type,
'@uuid' => $entity_uuid,
]), 'warning');
return;
}
}
/**
* Kindly ask the Sync Core to pull all entities that are auto pulled.
*
* @param \Drupal\cms_content_sync\Entity\Flow $flow
* @param bool $force
*
* @return \EdgeBox\SyncCore\Interfaces\Syndication\IPullAll[]
*/
public static function pullAll($flow, $force = false) {
$flow_import = $force ? [
PullIntent::PULL_AUTOMATICALLY,
] : [
PullIntent::PULL_AUTOMATICALLY,
PullIntent::PULL_MANUALLY,
];
$pool_import = $force ? [
Pool::POOL_USAGE_FORCE,
] : [
Pool::POOL_USAGE_FORCE,
Pool::POOL_USAGE_ALLOW,
];
/**
* @var \EdgeBox\SyncCore\Interfaces\Syndication\IPullAll[] $result
*/
$result = [];
$pools = Pool::getAll();
foreach ($flow
->getEntityTypeConfig() as $id => $type) {
$entity_type_name = $type['entity_type_name'];
$bundle_name = $type['bundle_name'];
if (Flow::HANDLER_IGNORE == $type['handler']) {
continue;
}
if (!in_array($type['import'], $flow_import)) {
continue;
}
$entity_type_pools = [];
if (isset($type['import_pools'])) {
foreach ($type['import_pools'] as $pool_id => $state) {
if (!isset($entity_type_pools[$pool_id])) {
$entity_type_pools[$pool_id] = [];
}
$entity_type_pools[$pool_id]['import'] = $state;
}
}
foreach ($entity_type_pools as $pool_id => $definition) {
if (empty($pools[$pool_id])) {
continue;
}
$pool = $pools[$pool_id];
$import = $definition['import'] ?? null;
if (!in_array($import, $pool_import)) {
continue;
}
$result[] = $pool
->getClient()
->getSyndicationService()
->pullAll($flow->id, $entity_type_name, $bundle_name)
->fromPool($pool->id)
->force($force);
}
}
return $result;
}
/**
* Batch pull finished callback.
*
* @param $success
* @param $results
* @param $operations
*/
public static function batchFinished($success, $results, $operations) {
$failed = 0;
$empty = 0;
$synchronized = 0;
foreach ($results as $result) {
if ('FAILURE' == $result['type']) {
++$failed;
}
elseif ('EMPTY' == $result['type']) {
++$empty;
}
else {
$synchronized += $result['total'];
}
}
if ($failed) {
\Drupal::messenger()
->addMessage(t('Failed to pull from %failed entity pools.', [
'%failed' => $failed,
]));
}
if ($empty) {
\Drupal::messenger()
->addMessage(t('%empty entity pools were empty or had no new entities.', [
'%empty' => $empty,
]));
}
if ($synchronized) {
\Drupal::messenger()
->addMessage(t('%synchronized entities have been pulled.', [
'%synchronized' => $synchronized,
]));
}
}
/**
* Batch pull callback for the pull-all operation.
*
* @param \EdgeBox\SyncCore\Interfaces\Syndication\IPullAll $operation
* @param array $context
*
* @throws \EdgeBox\SyncCore\Exception\SyncCoreException
*/
public static function batch($operation, &$context) {
if (empty($context['sandbox']['operation'])) {
$context['sandbox']['operation'] = $operation
->execute();
if (!$operation
->total()) {
$context['results'][] = [
'type' => 'EMPTY',
];
return;
}
}
/**
* @var \EdgeBox\SyncCore\Interfaces\Syndication\IPullAll $operation
*/
$operation = $context['sandbox']['operation'];
$total = $operation
->total();
try {
$progress = $operation
->progress();
if ($progress < $total) {
// Don't spam the Sync Core...
sleep(5);
}
if ($progress == $total) {
$context['results'][] = [
'type' => 'success',
'total' => $total,
];
}
$context['finished'] = $progress / $operation
->total();
$context['message'] = 'Pulled ' . $progress . ' of ' . $operation
->total() . ' ' . $operation
->getTypeMachineName() . '.' . $operation
->getBundleMachineName() . ' from ' . $operation
->getPoolMachineName() . '...';
} catch (TimeoutException $e) {
}
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
ControllerBase:: |
protected | property | The configuration factory. | |
ControllerBase:: |
protected | property | The current user service. | 1 |
ControllerBase:: |
protected | property | The entity form builder. | |
ControllerBase:: |
protected | property | The entity manager. | |
ControllerBase:: |
protected | property | The entity type manager. | |
ControllerBase:: |
protected | property | The form builder. | 2 |
ControllerBase:: |
protected | property | The key-value storage. | 1 |
ControllerBase:: |
protected | property | The language manager. | 1 |
ControllerBase:: |
protected | property | The module handler. | 2 |
ControllerBase:: |
protected | property | The state service. | |
ControllerBase:: |
protected | function | Returns the requested cache bin. | |
ControllerBase:: |
protected | function | Retrieves a configuration object. | |
ControllerBase:: |
private | function | Returns the service container. | |
ControllerBase:: |
public static | function |
Instantiates a new instance of this class. Overrides ContainerInjectionInterface:: |
40 |
ControllerBase:: |
protected | function | Returns the current user. | 1 |
ControllerBase:: |
protected | function | Retrieves the entity form builder. | |
ControllerBase:: |
protected | function | Retrieves the entity manager service. | |
ControllerBase:: |
protected | function | Retrieves the entity type manager. | |
ControllerBase:: |
protected | function | Returns the form builder service. | 2 |
ControllerBase:: |
protected | function | Returns a key/value storage collection. | 1 |
ControllerBase:: |
protected | function | Returns the language manager service. | 1 |
ControllerBase:: |
protected | function | Returns the module handler. | 2 |
ControllerBase:: |
protected | function |
Returns a redirect response object for the specified route. Overrides UrlGeneratorTrait:: |
|
ControllerBase:: |
protected | function | Returns the state storage service. | |
FlowPull:: |
public static | function | Batch pull callback for the pull-all operation. | |
FlowPull:: |
public static | function | Batch pull finished callback. | |
FlowPull:: |
public static | function | Force pull an entity for a specific flow. | |
FlowPull:: |
public | function | Pull all entities of this Flow. | |
FlowPull:: |
public static | function | Kindly ask the Sync Core to pull all entities that are auto pulled. | |
LinkGeneratorTrait:: |
protected | property | The link generator. | 1 |
LinkGeneratorTrait:: |
protected | function | Returns the link generator. | |
LinkGeneratorTrait:: |
protected | function | Renders a link to a route given a route name and its parameters. | |
LinkGeneratorTrait:: |
public | function | Sets the link generator service. | |
LoggerChannelTrait:: |
protected | property | The logger channel factory service. | |
LoggerChannelTrait:: |
protected | function | Gets the logger for a specific channel. | |
LoggerChannelTrait:: |
public | function | Injects the logger channel factory. | |
MessengerTrait:: |
protected | property | The messenger. | 29 |
MessengerTrait:: |
public | function | Gets the messenger. | 29 |
MessengerTrait:: |
public | function | Sets the messenger. | |
RedirectDestinationTrait:: |
protected | property | The redirect destination service. | 1 |
RedirectDestinationTrait:: |
protected | function | Prepares a 'destination' URL query parameter for use with \Drupal\Core\Url. | |
RedirectDestinationTrait:: |
protected | function | Returns the redirect destination service. | |
RedirectDestinationTrait:: |
public | function | Sets the redirect destination service. | |
StringTranslationTrait:: |
protected | property | The string translation service. | 1 |
StringTranslationTrait:: |
protected | function | Formats a string containing a count of items. | |
StringTranslationTrait:: |
protected | function | Returns the number of plurals supported by a given language. | |
StringTranslationTrait:: |
protected | function | Gets the string translation service. | |
StringTranslationTrait:: |
public | function | Sets the string translation service to use. | 2 |
StringTranslationTrait:: |
protected | function | Translates a string to the current language or to a given language. | |
UrlGeneratorTrait:: |
protected | property | The url generator. | |
UrlGeneratorTrait:: |
protected | function | Returns the URL generator service. | |
UrlGeneratorTrait:: |
public | function | Sets the URL generator service. | |
UrlGeneratorTrait:: |
protected | function | Generates a URL or path for a specific route based on the given parameters. |