19 declare(strict_types=1);
34 private const GLUE =
'|||||';
40 private const TRUE =
'true';
54 $this->data_factory = new \ILIAS\Data\Factory();
56 $this->null_trafo = new \ILIAS\Refinery\Custom\Transformation(
function ($value) {
59 $this->prefix_pattern =
'(' . implode(
'|', [
60 preg_quote(self::STRING_PREFIX,
'/'),
61 preg_quote(self::ARRAY_PREFIX,
'/'),
62 preg_quote(self::INT_PREFIX,
'/'),
63 preg_quote(self::BOOL_PREFIX,
'/'),
64 preg_quote(self::NULL_PREFIX,
'/')
68 private function pack(mixed $value): string
70 if (is_string($value)) {
71 return self::STRING_PREFIX . self::GLUE . $value;
73 if (is_array($value)) {
76 return self::ARRAY_PREFIX . self::GLUE . json_encode($value, JSON_THROW_ON_ERROR);
79 return self::INT_PREFIX . self::GLUE . $value;
81 if (is_bool($value)) {
82 return self::BOOL_PREFIX . self::GLUE . ($value ? self::TRUE : self::FALSE);
84 if (is_null($value)) {
85 return self::NULL_PREFIX . self::GLUE;
88 throw new \InvalidArgumentException(
89 'Only strings, integers and arrays containing those values are allowed, ' . gettype($value) .
' given.' 95 array_walk($value,
function (&$item):
void {
96 if (is_array($item)) {
99 $item = $this->
pack($item);
107 $str =
'/^' . $this->prefix_pattern . preg_quote(self::GLUE,
'/') .
'(.*)/is';
108 if (!preg_match($str, $value, $matches)) {
109 return [self::NULL_PREFIX, null];
112 return [$matches[1], $matches[2]];
115 private function unpack(?
string $value): string|
int|array|bool|null
118 if ($value === null) {
121 if ($value === self::NULL_PREFIX . self::GLUE) {
126 [$type, $unprefixed_value] = $this->
unprefix($value);
129 case self::STRING_PREFIX:
130 return $unprefixed_value;
131 case self::BOOL_PREFIX:
132 return $unprefixed_value === self::TRUE;
133 case self::ARRAY_PREFIX:
134 $unprefixed_value = json_decode($unprefixed_value,
true, 512);
135 if (!is_array($unprefixed_value)) {
140 case self::INT_PREFIX:
141 return (
int) $unprefixed_value;
151 array_walk($value,
function (&$item):
void {
152 if (is_array($item)) {
155 $item = $this->
unpack($item);
177 if ($this->lock_cache !== null && $this->lock_cache > microtime(
true)) {
181 if (!$this->adaptor->has($this->request->getContainerKey(), self::LOCK_UNTIL)) {
182 $this->lock_cache = null;
187 $lock_until = $this->adaptor->get($this->request->getContainerKey(), self::LOCK_UNTIL);
188 $lock_until = $lock_until === null ? null : (float) $lock_until;
190 $this->lock_cache = $lock_until;
192 return $lock_until !== null && $lock_until > microtime(
true);
195 public function lock(
float $seconds): void
197 if ($seconds > 300.0 || $seconds < 0.0) {
198 throw new \InvalidArgumentException(
'Locking for more than 5 minutes is not allowed.');
200 $lock_until = (string) (microtime(
true) + $seconds);
201 $this->adaptor->set($this->request->getContainerKey(), self::LOCK_UNTIL, $lock_until, 300);
204 public function has(
string $key): bool
210 return $this->adaptor->has($this->request->getContainerKey(), $key);
213 public function get(
string $key,
Transformation $transformation):
string|
int|array|
bool|null
218 if (!$this->
has($key)) {
222 $unpacked_values = $this->
unpack(
223 $this->adaptor->get($this->request->getContainerKey(), $key)
229 public function set(
string $key,
string|
int|array|
bool|null $value, ?
int $ttl = null):
void 234 $ttl = $ttl ?? $this->config->getDefaultTTL();
237 $this->request->getContainerKey(),
244 public function delete(
string $key):
void 249 $this->adaptor->delete($this->request->getContainerKey(), $key);
254 $this->adaptor->flushContainer($this->request->getContainerKey());
259 return $this->config->getAdaptorName();
264 return $this->request->getContainerKey();
272 $this->adaptor->delete($this->request->getContainerKey(), self::LOCK_UNTIL);
273 $this->lock_cache = null;
has(string $key)
Returns true if the container contains a value for the given key.
flush()
Deletes all values in the container.
packRecursive(array $value)
Interface Observer Contains several chained tasks and infos about them.
__construct(private Request $request, private Adaptor $adaptor, private Config $config)
lock(float $seconds)
Locks the container for a given amount of seconds (max 300), in this time, get() will return null and...
isLocked()
Returns true if the container is locked.
getAdaptorName()
Returns the name of the adaptop used (such as apc, memcache, phpstatic)
unpackRecursive(array $value)
Transformation $null_trafo
buildFinalTransformation(Transformation $transformation)
ILIAS Data Factory $data_factory
getContainerName()
Returns the name of the container.