Compare commits
20
Commits
v0.12.2
...
redirect-uri
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ee7d9623a3
|
||
|
|
ecec258a64
|
||
|
|
66040d69db
|
||
|
|
fc2de8e1ab
|
||
|
|
6cb90d5ea2
|
||
|
|
e67afc401b
|
||
|
|
e59d627080
|
||
|
|
3acca19d49
|
||
|
|
2226b88a88
|
||
|
|
8e08b09ae8
|
||
|
|
a3bce1f2aa
|
||
|
|
a84d3a3976
|
||
|
|
7210b24aa3
|
||
|
|
2d48f20aed
|
||
|
|
ebe1fa2aa6
|
||
|
|
bccee89c13
|
||
|
|
8bf495c89b
|
||
|
|
74cb576a2e
|
||
|
|
4283bc9bb1
|
||
|
|
fc4c3234a7
|
No files matched your search
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
FROM php:7.4.7-cli-buster
|
FROM php:8.1-cli-bookworm
|
||||||
|
|
||||||
RUN apt-get update && apt-get install -y unzip
|
RUN apt-get update && apt-get install -y unzip
|
||||||
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
|
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
|
||||||
+3
-3
@@ -5,12 +5,12 @@
|
|||||||
"license": "GNU GPL 3.0",
|
"license": "GNU GPL 3.0",
|
||||||
"require": {
|
"require": {
|
||||||
"vlucas/phpdotenv": "^5.5",
|
"vlucas/phpdotenv": "^5.5",
|
||||||
"symfony/console": "^5.4",
|
"symfony/console": "^6.3",
|
||||||
"phpmailer/phpmailer": "^6.8",
|
"phpmailer/phpmailer": "^6.8",
|
||||||
"cocur/slugify": "^4.3"
|
"cocur/slugify": "^4.5"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"phpunit/phpunit": "^9.6",
|
"phpunit/phpunit": "^10.3",
|
||||||
"phpstan/phpstan": "^1.10"
|
"phpstan/phpstan": "^1.10"
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
|
|||||||
Generated
+366
-568
File diff suppressed because it is too large.
Load diff
@@ -7,48 +7,52 @@ use mysqli;
|
|||||||
|
|
||||||
class Connection implements IConnection
|
class Connection implements IConnection
|
||||||
{
|
{
|
||||||
private mysqli $connection;
|
private string $host;
|
||||||
|
private string $user;
|
||||||
|
private string $password;
|
||||||
|
private string $db;
|
||||||
|
private int $port;
|
||||||
|
private string $socket;
|
||||||
|
private ?mysqli $connection = null;
|
||||||
|
|
||||||
public function __construct(string $host, string $user, string $password, string $db, int $port = -1, string $socket = null)
|
public function __construct(string $host, string $user, string $password, string $db, int $port = -1, string $socket = null)
|
||||||
{
|
{
|
||||||
if ($port < 0) {
|
$this->host = $host;
|
||||||
$port = (int) ini_get('mysqli.default_port');
|
$this->user = $user;
|
||||||
}
|
$this->password = $password;
|
||||||
|
$this->db = $db;
|
||||||
if ($socket === null) {
|
$this->port = $port < 0 ? (int) ini_get('mysqli.default_port') : $port;
|
||||||
$socket = (string) ini_get('mysqli.default_socket');
|
$this->socket = $socket === null ? (string) ini_get('mysqli.default_socket') : $socket;
|
||||||
}
|
|
||||||
|
|
||||||
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
|
|
||||||
$this->connection = new mysqli($host, $user, $password, $db, $port, $socket);
|
|
||||||
$this->connection->set_charset('utf8mb4');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __destruct()
|
public function __destruct()
|
||||||
{
|
{
|
||||||
|
if ($this->connection === null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
$this->connection->close();
|
$this->connection->close();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function startTransaction(): void
|
public function startTransaction(): void
|
||||||
{
|
{
|
||||||
$this->connection->autocommit(false);
|
$this->getConnection()->autocommit(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function commit(): void
|
public function commit(): void
|
||||||
{
|
{
|
||||||
$this->connection->commit();
|
$this->getConnection()->commit();
|
||||||
$this->connection->autocommit(true);
|
$this->getConnection()->autocommit(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function rollback(): void
|
public function rollback(): void
|
||||||
{
|
{
|
||||||
$this->connection->rollback();
|
$this->getConnection()->rollback();
|
||||||
$this->connection->autocommit(true);
|
$this->getConnection()->autocommit(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function query(string $query): ?IResultSet
|
public function query(string $query): ?IResultSet
|
||||||
{
|
{
|
||||||
$result = $this->connection->query($query);
|
$result = $this->getConnection()->query($query);
|
||||||
|
|
||||||
if ($result !== true) {
|
if ($result !== true) {
|
||||||
return new ResultSet($result);
|
return new ResultSet($result);
|
||||||
@@ -59,36 +63,51 @@ class Connection implements IConnection
|
|||||||
|
|
||||||
public function multiQuery(string $query): array
|
public function multiQuery(string $query): array
|
||||||
{
|
{
|
||||||
$this->connection->multi_query($query);
|
$this->getConnection()->multi_query($query);
|
||||||
|
|
||||||
$ret = [];
|
$ret = [];
|
||||||
do {
|
do {
|
||||||
if ($result = $this->connection->store_result()) {
|
if ($result = $this->getConnection()->store_result()) {
|
||||||
$ret[] = new ResultSet($result);
|
$ret[] = new ResultSet($result);
|
||||||
} else {
|
} else {
|
||||||
$ret[] = null;
|
$ret[] = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->connection->more_results();
|
$this->getConnection()->more_results();
|
||||||
} while ($this->connection->next_result());
|
} while ($this->getConnection()->next_result());
|
||||||
|
|
||||||
return $ret;
|
return $ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function prepare(string $query): IStatement
|
public function prepare(string $query): IStatement
|
||||||
{
|
{
|
||||||
$stmt = $this->connection->prepare($query);
|
$stmt = $this->getConnection()->prepare($query);
|
||||||
|
|
||||||
return new Statement($stmt);
|
return new Statement($stmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function lastId(): int
|
public function lastId(): int
|
||||||
{
|
{
|
||||||
return $this->connection->insert_id;
|
return $this->getConnection()->insert_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getAffectedRows(): int
|
public function getAffectedRows(): int
|
||||||
{
|
{
|
||||||
return $this->connection->affected_rows;
|
return $this->getConnection()->affected_rows;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getConnection(): mysqli
|
||||||
|
{
|
||||||
|
if ($this->connection === null) {
|
||||||
|
$this->createConnection();
|
||||||
|
}
|
||||||
|
return $this->connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function createConnection(): void
|
||||||
|
{
|
||||||
|
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
|
||||||
|
$this->connection = new mysqli($this->host, $this->user, $this->password, $this->db, $this->port, $this->socket);
|
||||||
|
$this->connection->set_charset('utf8mb4');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -97,28 +97,28 @@ class Select
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function where($column, string $relation = null, $value = null): Select
|
public function where($column, ?string $relation = null, $value = null): Select
|
||||||
{
|
{
|
||||||
$this->addWhereCondition('AND', $column, $relation, $value);
|
$this->addWhereCondition('AND', $column, $relation, $value);
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function orWhere($column, string $relation = null, $value = null): Select
|
public function orWhere($column, ?string $relation = null, $value = null): Select
|
||||||
{
|
{
|
||||||
$this->addWhereCondition('OR', $column, $relation, $value);
|
$this->addWhereCondition('OR', $column, $relation, $value);
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function having($column, string $relation = null, $value = null): Select
|
public function having($column, ?string $relation = null, $value = null): Select
|
||||||
{
|
{
|
||||||
$this->addHavingCondition('AND', $column, $relation, $value);
|
$this->addHavingCondition('AND', $column, $relation, $value);
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function orHaving($column, string $relation = null, $value = null): Select
|
public function orHaving($column, ?string $relation = null, $value = null): Select
|
||||||
{
|
{
|
||||||
$this->addHavingCondition('OR', $column, $relation, $value);
|
$this->addHavingCondition('OR', $column, $relation, $value);
|
||||||
|
|
||||||
@@ -211,12 +211,12 @@ class Select
|
|||||||
$this->joins[] = [$type, $table, $column1, $relation, $column2];
|
$this->joins[] = [$type, $table, $column1, $relation, $column2];
|
||||||
}
|
}
|
||||||
|
|
||||||
private function addWhereCondition(string $logic, $column, string $relation, $value): void
|
private function addWhereCondition(string $logic, $column, ?string $relation, $value): void
|
||||||
{
|
{
|
||||||
$this->conditions[self::CONDITION_WHERE][] = [$logic, $column, $relation, $value];
|
$this->conditions[self::CONDITION_WHERE][] = [$logic, $column, $relation, $value];
|
||||||
}
|
}
|
||||||
|
|
||||||
private function addHavingCondition(string $logic, $column, string $relation, $value): void
|
private function addHavingCondition(string $logic, $column, ?string $relation, $value): void
|
||||||
{
|
{
|
||||||
$this->conditions[self::CONDITION_HAVING][] = [$logic, $column, $relation, $value];
|
$this->conditions[self::CONDITION_HAVING][] = [$logic, $column, $relation, $value];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ interface IPersistentDataManager
|
|||||||
|
|
||||||
public function loadRelationsFromDb(Model $model, bool $recursive = false, array $withRelations = []): void;
|
public function loadRelationsFromDb(Model $model, bool $recursive = false, array $withRelations = []): void;
|
||||||
|
|
||||||
|
public function loadMultiRelationsFromDb(array $models, string $relation, bool $useRelations = false, array $withRelations = []): void;
|
||||||
|
|
||||||
public function saveToDb(Model $model): void;
|
public function saveToDb(Model $model): void;
|
||||||
|
|
||||||
public function deleteFromDb(Model $model): void;
|
public function deleteFromDb(Model $model): void;
|
||||||
|
|||||||
@@ -29,13 +29,6 @@ class Mail
|
|||||||
{
|
{
|
||||||
$this->body = file_get_contents(ROOT . '/mail/' . $template . '.html');
|
$this->body = file_get_contents(ROOT . '/mail/' . $template . '.html');
|
||||||
|
|
||||||
$baseParameters = [
|
|
||||||
'APP_NAME' => $_ENV['APP_NAME'],
|
|
||||||
'BASE_URL' => $_ENV['APP_URL'],
|
|
||||||
];
|
|
||||||
|
|
||||||
$params = array_merge($baseParameters, $params);
|
|
||||||
|
|
||||||
foreach ($params as $key => $param) {
|
foreach ($params as $key => $param) {
|
||||||
$this->body = str_replace('{{' . $key . '}}', $param, $this->body);
|
$this->body = str_replace('{{' . $key . '}}', $param, $this->body);
|
||||||
}
|
}
|
||||||
@@ -51,8 +44,10 @@ class Mail
|
|||||||
if (!empty($_ENV['MAIL_HOST'])) {
|
if (!empty($_ENV['MAIL_HOST'])) {
|
||||||
$mailer->Mailer = 'smtp';
|
$mailer->Mailer = 'smtp';
|
||||||
$mailer->Host = $_ENV['MAIL_HOST'];
|
$mailer->Host = $_ENV['MAIL_HOST'];
|
||||||
$mailer->Port = !empty($_ENV['MAIL_PORT']) ? $_ENV['MAIL_PORT'] : 25;
|
$mailer->Port = !empty($_ENV['MAIL_PORT']) ? $_ENV['MAIL_PORT'] : 587;
|
||||||
$mailer->SMTPSecure = !empty($_ENV['MAIL_SECURE']) ? $_ENV['MAIL_SECURE'] : '';
|
|
||||||
|
$secureMaping = ['none' => '', 'starttls' => PHPMailer::ENCRYPTION_STARTTLS, 'smtps' => PHPMailer::ENCRYPTION_SMTPS];
|
||||||
|
$mailer->SMTPSecure = !empty($_ENV['MAIL_SECURE']) ? $secureMaping[$_ENV['MAIL_SECURE']] : '';
|
||||||
|
|
||||||
if (!empty($_ENV['MAIL_USER'])) {
|
if (!empty($_ENV['MAIL_USER'])) {
|
||||||
$mailer->SMTPAuth = true;
|
$mailer->SMTPAuth = true;
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ abstract class Model
|
|||||||
|
|
||||||
protected static array $relations = [];
|
protected static array $relations = [];
|
||||||
|
|
||||||
|
protected static array $multiRelations = [];
|
||||||
|
|
||||||
protected $id = null;
|
protected $id = null;
|
||||||
|
|
||||||
private array $snapshot = [];
|
private array $snapshot = [];
|
||||||
@@ -27,6 +29,11 @@ abstract class Model
|
|||||||
return static::$relations;
|
return static::$relations;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function getMultiRelations(): array
|
||||||
|
{
|
||||||
|
return static::$multiRelations;
|
||||||
|
}
|
||||||
|
|
||||||
public function setId($id): void
|
public function setId($id): void
|
||||||
{
|
{
|
||||||
$this->id = $id;
|
$this->id = $id;
|
||||||
|
|||||||
@@ -92,6 +92,40 @@ class PersistentDataManager implements IPersistentDataManager
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function loadMultiRelationsFromDb(array $models, string $relation, bool $useRelations = false, array $withRelations = []): void
|
||||||
|
{
|
||||||
|
if (count($models) === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$parentModelType = get_class($models[0]);
|
||||||
|
$relationModelsSetter = 'set' . str_replace('_', '', ucwords($relation, '_'));
|
||||||
|
[$relationModelType, $reverseRelation] = call_user_func([$parentModelType, 'getMultiRelations'])[$relation];
|
||||||
|
$reverseRelationIdGetter = 'get' . str_replace('_', '', ucwords($reverseRelation, '_')) . 'Id';
|
||||||
|
|
||||||
|
$parentModelsById = [];
|
||||||
|
foreach ($models as $model) {
|
||||||
|
$parentModelsById[$model->getId()] = $model;
|
||||||
|
}
|
||||||
|
|
||||||
|
$select = new Select($this->dbConnection);
|
||||||
|
$select->where($reverseRelation . '_id', 'IN', array_keys($parentModelsById));
|
||||||
|
|
||||||
|
$relationsByParentModelId = [];
|
||||||
|
foreach ($this->selectMultipleFromDb($select, $relationModelType, $useRelations, $withRelations) as $relationModel) {
|
||||||
|
$reverseRelationId = $relationModel->$reverseRelationIdGetter();
|
||||||
|
if (!isset($relationsByParentModelId[$reverseRelationId])) {
|
||||||
|
$relationsByParentModelId[$reverseRelationId] = [];
|
||||||
|
}
|
||||||
|
$relationsByParentModelId[$reverseRelationId][] = $relationModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($parentModelsById as $parentModelId => $parentModel) {
|
||||||
|
$relationModels = $relationsByParentModelId[$parentModelId] ?? [];
|
||||||
|
$parentModel->$relationModelsSetter($relationModels);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function saveToDb(Model $model): void
|
public function saveToDb(Model $model): void
|
||||||
{
|
{
|
||||||
$this->syncRelations($model);
|
$this->syncRelations($model);
|
||||||
|
|||||||
@@ -6,12 +6,12 @@ use SokoWeb\Interfaces\Response\IRedirect;
|
|||||||
use SokoWeb\Interfaces\Response\IContent;
|
use SokoWeb\Interfaces\Response\IContent;
|
||||||
use SokoWeb\Interfaces\Authentication\IAuthenticationRequired;
|
use SokoWeb\Interfaces\Authentication\IAuthenticationRequired;
|
||||||
use SokoWeb\Interfaces\Authorization\ISecured;
|
use SokoWeb\Interfaces\Authorization\ISecured;
|
||||||
|
use SokoWeb\Interfaces\Routing\IRouteCollection;
|
||||||
use SokoWeb\Interfaces\Database\IConnection;
|
use SokoWeb\Interfaces\Database\IConnection;
|
||||||
use SokoWeb\Interfaces\Request\IRequest;
|
use SokoWeb\Interfaces\Request\IRequest;
|
||||||
use SokoWeb\Response\Redirect;
|
use SokoWeb\Response\Redirect;
|
||||||
use SokoWeb\Response\HtmlContent;
|
use SokoWeb\Response\HtmlContent;
|
||||||
use SokoWeb\Response\JsonContent;
|
use SokoWeb\Response\JsonContent;
|
||||||
use SokoWeb\Routing\RouteCollection;
|
|
||||||
|
|
||||||
class HttpResponse
|
class HttpResponse
|
||||||
{
|
{
|
||||||
@@ -19,7 +19,7 @@ class HttpResponse
|
|||||||
|
|
||||||
private IConnection $dbConnection;
|
private IConnection $dbConnection;
|
||||||
|
|
||||||
private RouteCollection $routeCollection;
|
private IRouteCollection $routeCollection;
|
||||||
|
|
||||||
private array $appConfig;
|
private array $appConfig;
|
||||||
|
|
||||||
@@ -32,7 +32,7 @@ class HttpResponse
|
|||||||
public function __construct(
|
public function __construct(
|
||||||
IRequest $request,
|
IRequest $request,
|
||||||
IConnection $dbConnection,
|
IConnection $dbConnection,
|
||||||
RouteCollection $routeCollection,
|
IRouteCollection $routeCollection,
|
||||||
array $appConfig,
|
array $appConfig,
|
||||||
string $requestMethod,
|
string $requestMethod,
|
||||||
string $requestUrl
|
string $requestUrl
|
||||||
@@ -55,6 +55,11 @@ class HttpResponse
|
|||||||
|
|
||||||
public function render(): void
|
public function render(): void
|
||||||
{
|
{
|
||||||
|
$this->handleCors();
|
||||||
|
if ($this->method === 'options') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
$match = $this->routeCollection->match($this->method, $this->parsedUrl['path']);
|
$match = $this->routeCollection->match($this->method, $this->parsedUrl['path']);
|
||||||
if ($match === null) {
|
if ($match === null) {
|
||||||
$this->render404();
|
$this->render404();
|
||||||
@@ -94,6 +99,7 @@ class HttpResponse
|
|||||||
$response = call_user_func([$controller, $handler[1]]);
|
$response = call_user_func([$controller, $handler[1]]);
|
||||||
} catch (Exception $exception) {
|
} catch (Exception $exception) {
|
||||||
$this->dbConnection->rollback();
|
$this->dbConnection->rollback();
|
||||||
|
error_log($exception);
|
||||||
$this->render500($exception);
|
$this->render500($exception);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -109,10 +115,63 @@ class HttpResponse
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function handleCors(): void
|
||||||
|
{
|
||||||
|
$origin = $this->request->header('Origin');
|
||||||
|
if (!$origin) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($this->appConfig['cors']['allow_origins'])) {
|
||||||
|
if (in_array($origin, $this->appConfig['cors']['allow_origins']) || in_array('*', $this->appConfig['cors']['allow_origins'])) {
|
||||||
|
header("Access-Control-Allow-Origin: {$origin}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($this->appConfig['cors']['allow_credentials'])) {
|
||||||
|
header('Access-Control-Allow-Credentials: true');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->method !== 'options') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($this->appConfig['cors']['allow_headers'])) {
|
||||||
|
$headers = explode(',', $this->request->header('Access-Control-Request-Headers'));
|
||||||
|
if (in_array('*', $this->appConfig['cors']['allow_headers'])) {
|
||||||
|
$allow_headers = $headers;
|
||||||
|
} else {
|
||||||
|
$allow_headers = array_intersect($this->appConfig['cors']['allow_headers'], $headers);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count($allow_headers) > 0) {
|
||||||
|
header('Access-Control-Allow-Headers: ' . join(', ', $allow_headers));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($this->appConfig['cors']['allow_methods'])) {
|
||||||
|
if (in_array('*', $this->appConfig['cors']['allow_methods'])) {
|
||||||
|
$allow_methods = ['DELETE', 'GET', 'HEAD', 'OPTIONS', 'PATCH', 'POST', 'PUT'];
|
||||||
|
} else {
|
||||||
|
$allow_methods = $this->appConfig['cors']['allow_methods'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count($allow_methods) > 0) {
|
||||||
|
header('Access-Control-Allow-Methods: ' . join(', ', $allow_methods));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$max_age = $this->appConfig['cors']['max_age'] ?? 600;
|
||||||
|
header("Access-Control-Max-Age: {$max_age}");
|
||||||
|
}
|
||||||
|
|
||||||
private function redirectToLogin(): void
|
private function redirectToLogin(): void
|
||||||
{
|
{
|
||||||
$this->request->session()->set('redirect_after_login', $this->rawUrl);
|
$this->request->session()->set('redirect_after_login', $this->rawUrl);
|
||||||
$response = new Redirect($this->routeCollection->getRoute($this->appConfig['loginRouteId'])->generateLink(), IRedirect::TEMPORARY);
|
$response = new Redirect(
|
||||||
|
$this->routeCollection->getRoute($this->appConfig['loginRouteId'])
|
||||||
|
->generateLink(['redirect_after_login' => urlencode($this->rawUrl)]),
|
||||||
|
IRedirect::TEMPORARY);
|
||||||
header('Location: ' . $this->getRedirectUrl($response), true, $response->getHttpCode());
|
header('Location: ' . $this->getRedirectUrl($response), true, $response->getHttpCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -86,12 +86,12 @@ class DatabaseSessionHandler implements ISessionHandler
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function gc($maxlifetime): bool
|
public function gc($maxlifetime): int|false
|
||||||
{
|
{
|
||||||
// empty on purpose
|
// empty on purpose
|
||||||
// old sessions are deleted by MaintainDatabaseCommand
|
// old sessions are deleted by MaintainDatabaseCommand
|
||||||
|
|
||||||
return true;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function create_sid(): string
|
public function create_sid(): string
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ final class GoogleOAuthTest extends TestCase
|
|||||||
$redirectUrl = 'http://example.com/oauth';
|
$redirectUrl = 'http://example.com/oauth';
|
||||||
|
|
||||||
$requestMock = $this->getMockBuilder(IRequest::class)
|
$requestMock = $this->getMockBuilder(IRequest::class)
|
||||||
->setMethods(['setUrl', 'setMethod', 'setQuery', 'setHeaders', 'send'])
|
->onlyMethods(['setUrl', 'setMethod', 'setQuery', 'setHeaders', 'send'])
|
||||||
->getMock();
|
->getMock();
|
||||||
$googleOAuth = new GoogleOAuth($requestMock);
|
$googleOAuth = new GoogleOAuth($requestMock);
|
||||||
|
|
||||||
@@ -48,10 +48,10 @@ final class GoogleOAuthTest extends TestCase
|
|||||||
$redirectUrl = 'http://example.com/oauth';
|
$redirectUrl = 'http://example.com/oauth';
|
||||||
|
|
||||||
$requestMock = $this->getMockBuilder(IRequest::class)
|
$requestMock = $this->getMockBuilder(IRequest::class)
|
||||||
->setMethods(['setUrl', 'setMethod', 'setQuery', 'setHeaders', 'send'])
|
->onlyMethods(['setUrl', 'setMethod', 'setQuery', 'setHeaders', 'send'])
|
||||||
->getMock();
|
->getMock();
|
||||||
$responseMock = $this->getMockBuilder(IResponse::class)
|
$responseMock = $this->getMockBuilder(IResponse::class)
|
||||||
->setMethods(['getBody', 'getHeaders'])
|
->onlyMethods(['getBody', 'getHeaders'])
|
||||||
->getMock();
|
->getMock();
|
||||||
$googleOAuth = new GoogleOAuth($requestMock);
|
$googleOAuth = new GoogleOAuth($requestMock);
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user