julienmonnerie/kirby/src/Session/SessionData.php

214 lines
5.2 KiB
PHP
Raw Normal View History

2022-06-17 17:51:59 +02:00
<?php
namespace Kirby\Session;
use Kirby\Exception\LogicException;
2025-04-21 18:57:21 +02:00
use Kirby\Toolkit\A;
2022-06-17 17:51:59 +02:00
/**
* The session object can be used to
* store visitor preferences for your
* site throughout various requests.
*
* @package Kirby Session
* @author Lukas Bestle <lukas@getkirby.com>
* @link https://getkirby.com
* @copyright Bastian Allgeier
* @license https://opensource.org/licenses/MIT
*/
class SessionData
{
2022-08-31 15:02:43 +02:00
/**
* Creates a new SessionData instance
*
* @codeCoverageIgnore
* @param \Kirby\Session\Session $session Session object this data belongs to
* @param array $data Currently stored session data
*/
2025-04-21 18:57:21 +02:00
public function __construct(
protected Session $session,
protected array $data
) {
2022-08-31 15:02:43 +02:00
}
/**
* Sets one or multiple session values by key
*
* @param string|array $key The key to define or a key-value array with multiple values
* @param mixed $value The value for the passed key (only if one $key is passed)
*/
2025-04-21 18:57:21 +02:00
public function set(
string|array $key,
mixed $value = null
): void {
2022-08-31 15:02:43 +02:00
$this->session->ensureToken();
$this->session->prepareForWriting();
2025-04-21 18:57:21 +02:00
if (is_string($key) === true) {
2022-08-31 15:02:43 +02:00
$this->data[$key] = $value;
} else {
2025-04-21 18:57:21 +02:00
$this->data = array_replace($this->data, $key);
2022-08-31 15:02:43 +02:00
}
}
/**
* Increments one or multiple session values by a specified amount
*
* @param string|array $key The key to increment or an array with multiple keys
* @param int $by Increment by which amount?
2025-04-21 18:57:21 +02:00
* @param int|null $max Maximum amount (value is not incremented further)
2022-08-31 15:02:43 +02:00
*/
2025-04-21 18:57:21 +02:00
public function increment(
string|array $key,
int $by = 1,
int|null $max = null
): void {
// if array passed, call method recursively
if (is_array($key) === true) {
foreach ($key as $k) {
$this->increment($k, $by, $max);
}
return;
2022-08-31 15:02:43 +02:00
}
2025-04-21 18:57:21 +02:00
// make sure we have the correct values before getting
$this->session->prepareForWriting();
2022-08-31 15:02:43 +02:00
2025-04-21 18:57:21 +02:00
$value = $this->get($key, 0);
2022-08-31 15:02:43 +02:00
2025-04-21 18:57:21 +02:00
if (is_int($value) === false) {
throw new LogicException([
'key' => 'session.data.increment.nonInt',
'data' => ['key' => $key],
'fallback' => 'Session value "' . $key . '" is not an integer and cannot be incremented',
2022-08-31 15:02:43 +02:00
'translate' => false
]);
}
2025-04-21 18:57:21 +02:00
// increment the value, but ensure $max constraint
if (is_int($max) === true && $value + $by > $max) {
// set the value to $max
// but not if the current $value is already larger than $max
$value = max($value, $max);
} else {
$value += $by;
}
$this->set($key, $value);
2022-08-31 15:02:43 +02:00
}
/**
* Decrements one or multiple session values by a specified amount
*
* @param string|array $key The key to decrement or an array with multiple keys
* @param int $by Decrement by which amount?
2025-04-21 18:57:21 +02:00
* @param int|null $min Minimum amount (value is not decremented further)
2022-08-31 15:02:43 +02:00
*/
2025-04-21 18:57:21 +02:00
public function decrement(
string|array $key,
int $by = 1,
int|null $min = null
): void {
// if array passed, call method recursively
if (is_array($key) === true) {
foreach ($key as $k) {
$this->decrement($k, $by, $min);
}
return;
2022-08-31 15:02:43 +02:00
}
2025-04-21 18:57:21 +02:00
// make sure we have the correct values before getting
$this->session->prepareForWriting();
2022-08-31 15:02:43 +02:00
2025-04-21 18:57:21 +02:00
$value = $this->get($key, 0);
2022-08-31 15:02:43 +02:00
2025-04-21 18:57:21 +02:00
if (is_int($value) === false) {
throw new LogicException([
'key' => 'session.data.decrement.nonInt',
'data' => ['key' => $key],
'fallback' => 'Session value "' . $key . '" is not an integer and cannot be decremented',
2022-08-31 15:02:43 +02:00
'translate' => false
]);
}
2025-04-21 18:57:21 +02:00
// decrement the value, but ensure $min constraint
if (is_int($min) === true && $value - $by < $min) {
// set the value to $min
// but not if the current $value is already smaller than $min
$value = min($value, $min);
} else {
$value -= $by;
}
$this->set($key, $value);
2022-08-31 15:02:43 +02:00
}
/**
* Returns one or all session values by key
*
* @param string|null $key The key to get or null for the entire data array
* @param mixed $default Optional default value to return if the key is not defined
*/
2025-04-21 18:57:21 +02:00
public function get(
string|null $key = null,
mixed $default = null
): mixed {
2022-12-19 14:56:05 +01:00
if ($key === null) {
2022-08-31 15:02:43 +02:00
return $this->data;
}
2022-12-19 14:56:05 +01:00
2025-04-21 18:57:21 +02:00
return $this->data[$key] ?? $default;
2022-08-31 15:02:43 +02:00
}
/**
* Retrieves a value and removes it afterwards
*
* @param string $key The key to get
* @param mixed $default Optional default value to return if the key is not defined
*/
2025-04-21 18:57:21 +02:00
public function pull(string $key, mixed $default = null): mixed
2022-08-31 15:02:43 +02:00
{
// make sure we have the correct value before getting
// we do this here (but not in get) as we need to write anyway
$this->session->prepareForWriting();
$value = $this->get($key, $default);
$this->remove($key);
return $value;
}
/**
* Removes one or multiple session values by key
*
* @param string|array $key The key to remove or an array with multiple keys
*/
2025-04-21 18:57:21 +02:00
public function remove(string|array $key): void
2022-08-31 15:02:43 +02:00
{
$this->session->prepareForWriting();
2025-04-21 18:57:21 +02:00
foreach (A::wrap($key) as $k) {
unset($this->data[$k]);
2022-08-31 15:02:43 +02:00
}
}
/**
* Clears all session data
*/
2025-04-21 18:57:21 +02:00
public function clear(): void
2022-08-31 15:02:43 +02:00
{
$this->session->prepareForWriting();
$this->data = [];
}
/**
* Reloads the data array with the current session data
* Only used internally
*
* @param array $data Currently stored session data
*/
2025-04-21 18:57:21 +02:00
public function reload(array $data): void
2022-08-31 15:02:43 +02:00
{
$this->data = $data;
}
2022-06-17 17:51:59 +02:00
}