. * */ namespace Friendica\Core\Config\Model; use Friendica\Core\Config\Capability\IManageConfigValues; use Friendica\Core\Config\Capability\ISetConfigValuesTransactionally; use Friendica\Core\Config\Exception\ConfigPersistenceException; use Friendica\Core\Config\ValueObject\Cache; /** * Transaction class for configurations, which sets values into a temporary buffer until "save()" is called */ class ConfigTransaction implements ISetConfigValuesTransactionally { /** @var IManageConfigValues */ protected $config; /** @var Cache */ protected $cache; /** @var Cache */ protected $delCache; /** @var bool field to check if something is to save */ protected $changedConfig = false; public function __construct(IManageConfigValues $config) { $this->config = $config; $this->cache = new Cache(); $this->delCache = new Cache(); } /** * Get a particular user's config variable given the category name * ($cat) and a $key from the current transaction. * * Isn't part of the interface because of it's rare use case * * @param string $cat The category of the configuration value * @param string $key The configuration key to query * * @return mixed Stored value or null if it does not exist * * @throws ConfigPersistenceException In case the persistence layer throws errors * */ public function get(string $cat, string $key) { return !$this->delCache->get($cat, $key) ? ($this->cache->get($cat, $key) ?? $this->config->get($cat, $key)) : null; } /** {@inheritDoc} */ public function set(string $cat, string $key, $value): ISetConfigValuesTransactionally { $this->cache->set($cat, $key, $value, Cache::SOURCE_DATA); $this->changedConfig = true; return $this; } /** {@inheritDoc} */ public function delete(string $cat, string $key): ISetConfigValuesTransactionally { $this->cache->delete($cat, $key); $this->delCache->set($cat, $key, 'deleted'); $this->changedConfig = true; return $this; } /** {@inheritDoc} */ public function commit(): void { // If nothing changed, just do nothing :) if (!$this->changedConfig) { return; } try { $newCache = $this->config->getCache()->merge($this->cache); $newCache = $newCache->diff($this->delCache); $this->config->load($newCache); // flush current cache $this->cache = new Cache(); $this->delCache = new Cache(); } catch (\Exception $e) { throw new ConfigPersistenceException('Cannot save config', $e); } } }