Инициализация
This commit is contained in:
commit
e7cabb7522
|
@ -0,0 +1,39 @@
|
|||
{
|
||||
"name": "mirzaev/yii2-arangodb-sessions",
|
||||
"description": "Yii\\web\\DbSession implementation for use with ArangoDB",
|
||||
"keywords": [
|
||||
"Yii2",
|
||||
"ArangoDB",
|
||||
"DbSession"
|
||||
],
|
||||
"type": "yii2-extension",
|
||||
"license": "AGPL-3.0-or-later",
|
||||
"homepage": "https://git.hood.su/mirzaev/yii2/arangodb/sessions",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Arsen Mirzaev Tatyano-Muradovich",
|
||||
"email": "red@hood.su",
|
||||
"homepage": "https://hood.su/mirzaev",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": "^8.0.0",
|
||||
"yiisoft/yii2": "2.*",
|
||||
"triagens/arangodb": "~3.2",
|
||||
"mirzaev/yii2-arangodb": "~2.1.x-dev"
|
||||
},
|
||||
"require-dev": {
|
||||
"yiisoft/yii2-debug": "*"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"mirzaev\\yii2\\arangodb\\sessions\\": "mirzaev/yii2-arangodb-sessions"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"mirzaev\\yii2\\arangodb\\sessions\\tests\\": "mirzaev/yii2-arangodb-sessions/tests"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,288 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace mirzaev\yii2\arangodb\sessions;
|
||||
|
||||
use yii;
|
||||
use yii\web\DbSession;
|
||||
use yii\db\PdoValue;
|
||||
use yii\di\Instance;
|
||||
use yii\base\InvalidConfigException;
|
||||
|
||||
use mirzaev\yii2\arangodb\Connection;
|
||||
use mirzaev\yii2\arangodb\Query;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* Реализация DbSession под ArangoDB
|
||||
*
|
||||
* @package Yii2\ArangoDB
|
||||
* @author Arsen Mirzaev Tatyano-Muradovich <red@hood.su>
|
||||
*/
|
||||
final class ArangoDbSession extends DbSession {
|
||||
|
||||
/**
|
||||
* Идентификатор компонента (Component ID)
|
||||
*/
|
||||
public Connection|array|string $db = 'arangodb';
|
||||
|
||||
/**
|
||||
* Название документа для хранения данных сеанса (Document name for storing session data)
|
||||
*/
|
||||
public string $sessions = 'sessions';
|
||||
|
||||
/**
|
||||
* Буфер данных для записи в документ сессий (Data buffer for write to session document)
|
||||
*/
|
||||
protected array $buffer = [];
|
||||
|
||||
|
||||
/**
|
||||
* Инициализация компонента (Component initialization)
|
||||
*
|
||||
* @throws InvalidConfigException if $this->db is invalid.
|
||||
*/
|
||||
public function init(): self
|
||||
{
|
||||
parent::init();
|
||||
|
||||
return $this->db = Instance::ensure($this->db, Connection::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Открыть сессию (Open session)
|
||||
*
|
||||
* @param string $path session save path
|
||||
* @param string $name session name
|
||||
*
|
||||
* @return bool Статус открытия сессии (Session opening status)
|
||||
*
|
||||
* @internal Do not call this method directly
|
||||
*/
|
||||
public function openSession($path, $name): bool
|
||||
// public function openSession(string $save, string $session_name): bool
|
||||
{
|
||||
if ($this->getUseStrictMode()) {
|
||||
$id = $this->getId();
|
||||
if (!$this->getReadQuery($id)->exists()) {
|
||||
// This session id does not exist, mark it for forced regeneration
|
||||
$this->_forceRegenerateId = $id;
|
||||
}
|
||||
}
|
||||
|
||||
return parent::openSession($path, $name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Метод не создаст эффект пока сессия неактивна (getIsActive()). Убедитесь, что открыли (open()) перед вызовом
|
||||
* This method has no effect when session is not [[getIsActive()|active]]. Make sure to call [[open()]] before calling it.
|
||||
*
|
||||
* @param bool $delete Удалить прошлую сессию (Delete old session)
|
||||
*
|
||||
* @see $this->open()
|
||||
* @see $this->getIsActive()
|
||||
* @see https://secure.php.net/session_regenerate_id
|
||||
*/
|
||||
public function regenerateID($delete = false): void
|
||||
// public function regenerateID(bool $delete = false): void
|
||||
{
|
||||
$oldID = session_id();
|
||||
|
||||
// if no session is started, there is nothing to regenerate
|
||||
if (empty($oldID)) {
|
||||
return;
|
||||
}
|
||||
|
||||
parent::regenerateID(false);
|
||||
|
||||
$newID = session_id();
|
||||
|
||||
// if session id regeneration failed, no need to create/update it.
|
||||
if (empty($newID)) {
|
||||
Yii::warning('Failed to generate new session ID', __METHOD__);
|
||||
return;
|
||||
}
|
||||
|
||||
$row = $this->db->useMaster(function() use ($oldID) {
|
||||
return (new Query())->from($this->sessionTable)
|
||||
->where(['id' => $oldID])
|
||||
->createCommand($this->db)
|
||||
->queryOne();
|
||||
});
|
||||
|
||||
if ($row !== false) {
|
||||
if ($delete) {
|
||||
$this->db->createCommand()
|
||||
->update($this->sessionTable, ['id' => $newID], ['id' => $oldID])
|
||||
->execute();
|
||||
} else {
|
||||
$row['id'] = $newID;
|
||||
$this->db->createCommand()
|
||||
->insert($this->sessionTable, $row)
|
||||
->execute();
|
||||
}
|
||||
} else {
|
||||
// shouldn't reach here normally
|
||||
$this->db->createCommand()
|
||||
->insert($this->sessionTable, $this->composeFields($newID, ''))
|
||||
->execute();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Закрыть сессию (Close session)
|
||||
*
|
||||
* Закрывает текущую сессию и сохраняет данные
|
||||
* Ends the current session and store session data
|
||||
*/
|
||||
public function close(): void
|
||||
{
|
||||
if ($this->getIsActive()) {
|
||||
// prepare writeCallback fields before session closes
|
||||
$this->fields = $this->composeFields();
|
||||
YII_DEBUG ? session_write_close() : @session_write_close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Прочитать сессию (Read session)
|
||||
*
|
||||
* @param string $id Идентификатор сессии (Session ID)
|
||||
*
|
||||
* @return string Данные сессии (The session data)
|
||||
*
|
||||
* @internal Do not call this method directly
|
||||
*/
|
||||
public function readSession($id): string
|
||||
// public function readSession(string $id): string
|
||||
{
|
||||
$query = $this->getReadQuery($id);
|
||||
|
||||
if ($this->readCallback !== null) {
|
||||
$fields = $query->one($this->db);
|
||||
return $fields === false ? '' : $this->extractData($fields);
|
||||
}
|
||||
|
||||
$data = $query->select(['data'])->scalar($this->db);
|
||||
return $data === false ? '' : $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Записать сессию (Write session)
|
||||
*
|
||||
* @param string $id Идентификатор сессии (Session ID)
|
||||
* @param string $data Данные сессии (Session data)
|
||||
*
|
||||
* @return bool Статус записи сессии (Session writing status)
|
||||
*
|
||||
* @internal Do not call this method directly
|
||||
*/
|
||||
public function writeSession($id, $data): bool
|
||||
// public function writeSession(string $id, string $data): bool
|
||||
{
|
||||
if ($this->getUseStrictMode() && $id === $this->_forceRegenerateId) {
|
||||
//Ignore write when forceRegenerate is active for this id
|
||||
return true;
|
||||
}
|
||||
|
||||
// exception must be caught in session write handler
|
||||
// https://secure.php.net/manual/en/function.session-set-save-handler.php#refsect1-function.session-set-save-handler-notes
|
||||
try {
|
||||
// ensure backwards compatability (fixed #9438)
|
||||
if ($this->writeCallback && !$this->fields) {
|
||||
$this->fields = $this->composeFields();
|
||||
}
|
||||
// ensure data consistency
|
||||
if (!isset($this->fields['data'])) {
|
||||
$this->fields['data'] = $data;
|
||||
} else {
|
||||
$_SESSION = $this->fields['data'];
|
||||
}
|
||||
// ensure 'id' and 'expire' are never affected by [[writeCallback]]
|
||||
$this->fields = array_merge($this->fields, [
|
||||
'id' => $id,
|
||||
'expire' => time() + $this->getTimeout(),
|
||||
]);
|
||||
$this->fields = $this->typecastFields($this->fields);
|
||||
$this->db->createCommand()->upsert($this->sessionTable, $this->fields)->execute();
|
||||
$this->fields = [];
|
||||
} catch (Exception $e) {
|
||||
Yii::$app->errorHandler->handleException($e);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Удалить сессию (Delete session)
|
||||
*
|
||||
* @param string $id Идентификатор сессии (Session ID)
|
||||
*
|
||||
* @return bool Статус удаления сессии (Session deleting status)
|
||||
*
|
||||
* @internal Do not call this method directly
|
||||
*/
|
||||
public function destroySession($id)
|
||||
{
|
||||
$this->db->createCommand()
|
||||
->delete($this->sessionTable, ['id' => $id])
|
||||
->execute();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Удалить неиспользуемые данные (Delete garbage)
|
||||
*.
|
||||
* @param int $max Периодичность очистки в секундах (Cleaning frequency in seconds)
|
||||
*
|
||||
* @return bool Статус очистки неиспользуемых данных сессии (Session garbage deleting status)
|
||||
*
|
||||
* @internal Do not call this method directly
|
||||
*/
|
||||
public function gcSession($max): bool
|
||||
// public function gcSession(int $max): bool
|
||||
{
|
||||
$this->db->createCommand()
|
||||
->delete($this->sessionTable, '[[expire]]<:expire', [':expire' => time()])
|
||||
->execute();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Генерация запроса для чтения сеанса (Generating a query to read a session)
|
||||
*
|
||||
* @param string $id Идентификатор сессии (Session ID)
|
||||
*/
|
||||
protected function getReadQuery($id): Query
|
||||
// protected function getReadQuery(string $id): Query
|
||||
{
|
||||
return (new Query())
|
||||
->from($this->sessionTable)
|
||||
->where('[[expire]]>:expire AND [[id]]=:id', [':expire' => time(), ':id' => $id]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Конвертация для отправки в PDO (Convertation for sending to PDO)
|
||||
*
|
||||
* Default implementation casts field `data` to `\PDO::PARAM_LOB`.
|
||||
* You can override this method in case you need special type casting.
|
||||
*
|
||||
* @param array $data Данные для конвертации (Data for convertation) [name => value]
|
||||
*/
|
||||
protected function typecastFields($data): array
|
||||
// protected function typecastFields(array $data): array
|
||||
{
|
||||
// if (isset($data['data']) && !is_array($data['data']) && !is_object($data['data'])) {
|
||||
// $data['data'] = new PdoValue($data['data'], \PDO::PARAM_LOB);
|
||||
// }
|
||||
|
||||
// return $data;
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue