cms_content_sync-3.0.x-dev/src/SyncCoreInterface/SyncCoreFactory.php
src/SyncCoreInterface/SyncCoreFactory.php
<?php
namespace Drupal\cms_content_sync\SyncCoreInterface;
use Drupal\cms_content_sync\Controller\Embed;
use Drupal\cms_content_sync\Entity\Pool;
use Drupal\Core\Cache\Cache;
use Drupal\Core\Link;
use Drupal\Core\Url;
use EdgeBox\SyncCore\Interfaces\ISyncCore;
use EdgeBox\SyncCore\V2\SyncCore;
use Symfony\Component\HttpFoundation\RedirectResponse;
/**
* Class SyncCoreFactory.
*
* This is the central interface between Drupal and the Sync Core. Drupal will call ::getSyncCore() and then use the
* Sync Core library whereas the Sync Core library in return uses the interface functions provided here.
*/
class SyncCoreFactory {
public const CACHE_ITEM_NAME_SYNC_CORE = 'cms_content_sync/sync-core';
public const CACHE_TAG_SYNC_CORE = 'cms_content_sync:sync-core';
/**
* @var \EdgeBox\SyncCore\Interfaces\ISyncCore[]
*/
protected static $clients = [];
protected static $v2;
/**
* @var \EdgeBox\SyncCore\Interfaces\ISyncCore[]
*/
protected static $allSyncCores;
/**
*
*/
public static function export(string $mode, $wait = FALSE) {
$client = SyncCoreFactory::getSyncCoreV2();
if ($client->featureEnabled(ISyncCore::FEATURE_ASYNC_SITE_CONFIG_AVAILABLE)) {
$syndication = $client->updateSiteConfig($mode, $wait);
if ($wait) {
return TRUE;
}
$messenger = \Drupal::messenger();
$embed = Embed::create(\Drupal::getContainer());
$link = Link::createFromRoute('View progress', 'cms_content_sync.syndication', ['type' => 'config'])->toString();
$message = t('We are exporting your config to your @repository. @view_progress', [
'@repository' => _cms_content_sync_get_repository_name(),
'@view_progress' => $link,
]);
$update_progress = $embed->updateStatusBox($syndication, TRUE);
$messenger->addMessage([
'message' => ['#markup' => $message],
'update_progress' => $update_progress,
]);
return TRUE;
}
return FALSE;
}
/**
*
*/
public static function getSyncCoreV2Url() {
$url = getenv('CONTENT_SYNC_SYNC_CORE_URL');
if (!$url) {
$url = DrupalApplication::get()->getSyncCoreUrl();
if (!$url) {
throw new \Exception('No Sync Core URL set. Please register this site first.');
}
}
return $url;
}
/**
* Allow missing base URL.
*
* @return \EdgeBox\SyncCore\V2\SyncCore
*/
public static function getDummySyncCoreV2() {
try {
return self::getSyncCoreV2();
}
catch (\Exception $e) {
}
return new SyncCore(DrupalApplication::get(), 'https://example.com/sync-core');
}
/**
* @param mixed $based_on_current_setting
*
* @return \EdgeBox\SyncCore\V2\SyncCore
*/
public static function getSyncCoreV2($based_on_current_setting = FALSE) {
if ($based_on_current_setting) {
$url = DrupalApplication::get()->getSyncCoreUrl();
if ($url) {
return new SyncCore(DrupalApplication::get(), $url);
}
}
if (!empty(self::$v2)) {
return self::$v2;
}
return self::$v2 = new SyncCore(DrupalApplication::get(), self::getSyncCoreV2Url());
}
/**
* @return \EdgeBox\SyncCore\Interfaces\ISyncCore[]
*/
public static function getAllSyncCores() {
if (!empty(self::$allSyncCores)) {
return self::$allSyncCores;
}
$cores = [];
foreach (Pool::getAll() as $pool) {
$url = parse_url($pool->getSyncCoreUrl());
$host = $url['host'];
if (isset($cores[$host])) {
continue;
}
$cores[$host] = self::getSyncCoreV2();
}
return self::$allSyncCores = $cores;
}
/**
* Clear cache. Required to be called whenever the Sync Core changes.
*/
public static function clearCache() {
self::$allSyncCores = NULL;
self::$clients = [];
Cache::invalidateTags([self::CACHE_TAG_SYNC_CORE]);
}
/**
* @return null|ISyncCore
*/
public static function getAnySyncCore() {
$cores = self::getAllSyncCores();
if (!count($cores)) {
return NULL;
}
return reset($cores);
}
/**
* Check whether the given feature is enabled at the V2 Sync Core.
*
* @param string $name
* feature name, as taken from the ISyncCore interface.
* @param bool $quick
* request may only take 5s because it's blocking for users.
*
* @return bool
*/
public static function featureEnabled(string $name, bool $quick = FALSE) {
static $features = NULL;
if (NULL === $features) {
$cache = \Drupal::cache();
$cache_item = $cache->get(self::CACHE_ITEM_NAME_SYNC_CORE);
$cache_item_data = $cache_item ? $cache_item->data : NULL;
if ($cache_item_data && isset($cache_item_data->features)) {
$features = $cache_item_data->features;
}
else {
$features = self::getSyncCoreV2()->getFeatures($quick);
if (!$cache_item_data) {
$cache_item_data = new \stdClass();
}
$cache_item_data->features = $features;
$cache->set(self::CACHE_ITEM_NAME_SYNC_CORE, $cache_item_data, time() + 3_600, [self::CACHE_TAG_SYNC_CORE]);
}
}
return !empty($features[$name]) && (bool) $features[$name];
}
}
