Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ebe1fa2aa6
|
||
|
|
bccee89c13
|
||
|
|
8bf495c89b
|
||
|
|
74cb576a2e
|
||
|
|
4283bc9bb1
|
||
|
|
fc4c3234a7
|
||
|
|
8d490e48aa
|
||
|
|
1dcab1abe2
|
||
|
|
bda12177eb
|
||
|
|
f037de014e
|
||
|
|
8a1820275d
|
||
|
|
da2801560d
|
||
|
|
dd855a6d6b
|
||
|
|
25548176bb
|
||
|
|
f31b801c03
|
||
|
|
346b1a0ca9
|
||
|
|
6fdd25ae4b
|
||
|
|
754a23706a
|
No files matched your search
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
||||||
@@ -115,7 +149,7 @@ class PersistentDataManager implements IPersistentDataManager
|
|||||||
|
|
||||||
if (count($modified) > 0) {
|
if (count($modified) > 0) {
|
||||||
if ($model instanceof ModelWithSlug && isset($modified['slug'])) {
|
if ($model instanceof ModelWithSlug && isset($modified['slug'])) {
|
||||||
$modified['slug'] = $this->generateUniqueSlug($model, $modified['slug']);
|
$diff['slug']['new'] = $modified['slug'] = $this->generateUniqueSlug($model, $modified['slug']);
|
||||||
}
|
}
|
||||||
|
|
||||||
$modify->setId($id);
|
$modify->setId($id);
|
||||||
@@ -278,7 +312,10 @@ class PersistentDataManager implements IPersistentDataManager
|
|||||||
$method = 'set' . str_replace('_', '', ucwords($relation, '_'));
|
$method = 'set' . str_replace('_', '', ucwords($relation, '_'));
|
||||||
$model->$method($relationModel);
|
$model->$method($relationModel);
|
||||||
} else {
|
} else {
|
||||||
|
while (substr($key, 0, strlen($relation . '__')) === $relation . '__') {
|
||||||
next($data);
|
next($data);
|
||||||
|
$key = key($data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
next($relations);
|
next($relations);
|
||||||
|
|||||||
+6
-1
@@ -97,8 +97,13 @@ class Linker
|
|||||||
|
|
||||||
fwrite($outputFileHandle, $extra[0]);
|
fwrite($outputFileHandle, $extra[0]);
|
||||||
while (($line = fgets($inputFileHandle)) !== false) {
|
while (($line = fgets($inputFileHandle)) !== false) {
|
||||||
|
if (preg_match('/^\s*@include\((.*)\)\s*$/', $line, $matches) === 1) {
|
||||||
|
$include = file_get_contents(ROOT . '/views/' . $matches[1] . '.php');
|
||||||
|
fwrite($outputFileHandle, $include);
|
||||||
|
} else {
|
||||||
fwrite($outputFileHandle, $line);
|
fwrite($outputFileHandle, $line);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
fwrite($outputFileHandle, $extra[1]);
|
fwrite($outputFileHandle, $extra[1]);
|
||||||
|
|
||||||
fclose($inputFileHandle);
|
fclose($inputFileHandle);
|
||||||
@@ -134,7 +139,7 @@ class Linker
|
|||||||
{
|
{
|
||||||
$output = [];
|
$output = [];
|
||||||
|
|
||||||
if (preg_match('/^[\w\/\.]+$/', $asset) === 1) {
|
if (preg_match('/^http(s)?/', $asset) !== 1) {
|
||||||
if (
|
if (
|
||||||
empty($_ENV['DEV']) &&
|
empty($_ENV['DEV']) &&
|
||||||
filesize(ROOT . '/public/static/' . $asset) < self::INLINE_ASSET_LIMIT
|
filesize(ROOT . '/public/static/' . $asset) < self::INLINE_ASSET_LIMIT
|
||||||
|
|||||||
Reference in new issue
Block a user