depcalc-8.x-1.x-dev/src/DependencyStack.php
src/DependencyStack.php
<?php
namespace Drupal\depcalc;
use Drupal\Core\Cache\Cache;
/**
* The dependencies stack.
*/
class DependencyStack {
/**
* The dependencies list.
*
* @var \Drupal\depcalc\DependentEntityWrapperInterface[]
*/
protected $dependencies = [];
/**
* The list of dependencies requiring additional processing.
*
* @var array
*/
protected $additionalProcessing = [];
/**
* An indicator whether this stack instances should not load cached values.
*
* @var bool
*/
protected $ignoreCache = FALSE;
/**
* An indicator whether this stack instances should ignore config entities..
*
* @var bool
*/
protected bool $ignoreConfig = FALSE;
/**
* DependencyStack constructor.
*
* @param \Drupal\depcalc\DependentEntityWrapperInterface ...$dependencies
* Any previously built dependency to prevent recalculation.
*/
public function __construct(DependentEntityWrapperInterface ...$dependencies) {
foreach ($dependencies as $dependency) {
$this->dependencies[$dependency->getRemoteUuid()] = $dependency;
}
}
/**
* Set whether this stack should be able to load cached values.
*
* @param bool $value
* TRUE/FALSE.
*/
public function ignoreCache(bool $value = TRUE) {
$this->ignoreCache = $value;
}
/**
* Sets whether this stack should ignore config or not.
*
* @param bool $value
* TRUE if it should ignore.
*/
public function ignoreConfig(bool $value = TRUE): void {
$this->ignoreConfig = $value;
}
/**
* Checks whether config entities should be ignored or not.
*
* @return bool
* Whether config entities should be ignored or not.
*/
public function shouldIgnoreConfig(): bool {
return $this->ignoreConfig;
}
/**
* Add a dependency to the stack.
*
* @param \Drupal\depcalc\DependentEntityWrapperInterface $dependency
* The dependency to add to the stack.
* @param bool $cache
* TRUE if to add to cache (Default), FALSE otherwise.
*/
public function addDependency(DependentEntityWrapperInterface $dependency, $cache = TRUE) {
if ($cache) {
\Drupal::cache('depcalc')->set($dependency->getUuid(), $dependency, Cache::PERMANENT, array_keys($dependency->getDependencies()));
}
$this->dependencies[$dependency->getRemoteUuid()] = $dependency;
if ($dependency->needsAdditionalProcessing()) {
$this->additionalProcessing[$dependency->getRemoteUuid()] = '';
}
else {
unset($this->additionalProcessing[$dependency->getRemoteUuid()]);
}
}
/**
* Get a specific dependency from the stack.
*
* @param string $uuid
* The uuid of the dependency to retrieve.
*
* @return \Drupal\depcalc\DependentEntityWrapperInterface|null
* The dependent entity wrapper.
*/
public function getDependency($uuid) {
if (!empty($this->dependencies[$uuid])) {
return $this->dependencies[$uuid];
}
if (!$this->ignoreCache) {
// Check cached dependencies.
$cache = \Drupal::cache('depcalc')->get($uuid);
if ($cache && $cache->expire === "-1" && $cache->data instanceof DependentEntityWrapperInterface) {
$this->dependencies[$uuid] = $cache->data;
return $this->dependencies[$uuid];
}
}
return NULL;
}
/**
* Checks if a particular dependency exists in the stack.
*
* @param string $uuid
* The uuid of the dependency to check.
*
* @return bool
* TRUE/FALSE.
*/
public function hasDependency($uuid) {
return !empty($this->dependencies[$uuid]);
}
/**
* Checks if a list of dependencies exist within the stack and are processed.
*
* @param array $targets
* An array of UUIDs.
*
* @return bool
* TRUE/FALSE.
*/
public function hasDependencies(array $targets) {
$count = count($targets);
$targets = array_combine($targets, $targets);
$intersection = array_intersect_key($targets, $this->dependencies);
$equal = count($intersection) === $count;
if ($equal) {
$intersection = array_intersect_key($targets, $this->additionalProcessing);
if ($intersection) {
return FALSE;
}
}
return $equal;
}
/**
* Get a specific set of dependencies.
*
* @param string[] $dependencies
* The list of dependencies, by uuid, to retrieve.
*
* @return \Drupal\depcalc\DependentEntityWrapperInterface[]
* The dependencies.
*
* @throws \Exception
*/
public function getDependenciesByUuid(array $dependencies) {
$results = [];
foreach ($dependencies as $uuid) {
$dependency = $this->getDependency($uuid);
if (!$dependency) {
throw new \Exception(sprintf("Missing Dependency requested: %s.", $uuid));
}
$results[$uuid] = $dependency;
}
return $results;
}
/**
* Get a list of dependencies within the stack.
*
* @return \Drupal\depcalc\DependentEntityWrapperInterface[]
* The dependencies.
*/
public function getDependencies() {
return $this->dependencies;
}
/**
* Get a list of processed dependencies within the stack.
*
* This will exclude dependencies that have been created but which still
* require additional processing.
*
* @return \Drupal\depcalc\DependentEntityWrapperInterface[]
* The processed dependencies.
*/
public function getProcessedDependencies() {
return array_diff_key($this->dependencies, $this->additionalProcessing);
}
}
