2025-08-01 18:45:06 +03:00

206 lines
8.4 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/**
* @noinspection SqlNoDataSourceInspection
*/
namespace goodboyalex\php_db_components_pack\classes;
use goodboyalex\php_components_pack\classes\Tuple;
use goodboyalex\php_components_pack\interfaces\IArrayable;
use InvalidArgumentException;
/**
* Группа условий запроса выборки по условию.
*
* @author Александр Бабаев
* @package php_components_pack
* @version 1.0
* @since 1.0
*/
final class ConditionGroup implements IArrayable
{
/**
* @var string $LogicOperator Логический оператор.
*/
private string $LogicOperator;
/**
* @var array $Conditions Условия.
*/
private array $Conditions;
/**
* Конструктор.
*
* @param string $logicOperator Логический оператор.
* @param array $conditions Условия.
*/
public function __construct (string $logicOperator = Condition::LOGIC_AND, array $conditions = [])
{
$this->LogicOperator = $logicOperator;
$this->Conditions = $conditions;
}
/**
* Формирует массив условий.
*
* @param int $index Индекс замены параметров для защиты от SQL-инъекций.
*
* @return Tuple (string, array) Массив условий (строка SQL, параметры SQL).
*/
public function GetConditions (int $index = 0): Tuple
{
// Создаём результирующую строку
$resultString = "";
// Создаём результирующий массив
$resultArray = [];
// Создаём счётчик
$count = $index;
// Проходим по всем элементам, кроме последнего
for ($i = 0; $i < count($this->Conditions) - 1; $i++) {
// - увеличиваем счётчик
$count++;
// - получаем условие
$result = $this->WriteCondition($this->Conditions[$i], $count);
// - записываем условие в строку
$resultString .= $result->Get(0);
// - записываем условие в массив
$resultArray = array_merge($resultArray, $result->Get(1));
// - записываем логический оператор
$resultString .= " $this->LogicOperator ";
}
// Увеличиваем счётчик
$count++;
// Получаем последнее условие
$result = $this->WriteCondition($this->Conditions[count($this->Conditions) - 1], $count);
// Записываем условие в строку
$resultString .= $result->Get(0);
// Записываем условие в массив
$resultArray = array_merge($resultArray, $result->Get(1));
// Очищаем результирующую строку от лишних пробелов
$resultString = '(' . trim($resultString) . ')';
// Возвращаем результат
return new Tuple($resultString, $resultArray);
}
/**
* Возвращает количество условий в группе.
*
* @return int Количество условий в группе.
*/
public function Count (): int
{
// Создаём счетчик
$count = 0;
// Проходим по всем элементам
foreach ($this->Conditions as $condition) {
// - если это условие
if ($condition instanceof Condition)
// -- то увеличиваем счетчик
$count++;
// - если это группа условий
if ($condition instanceof ConditionGroup)
// -- то считаем количество условий в группе и увеличиваем счетчик на это число
$count += $condition->Count();
}
// Возвращаем результат
return $count;
}
/**
* @inheritDoc
*/
public function ToArray (): array
{
// Создаём результирующий массив
$result = [];
// Записываем тип класса
$result["type_class"] = ConditionGroup::class;
// Записываем логический оператор
$result["LogicOperator"] = $this->LogicOperator;
// Перебираем все условия
foreach ($this->Conditions as $condition)
// - записываем условие в массив
$result["Conditions"][] = $condition->ToArray();
// Возвращаем результат
return $result;
}
/**
* @inheritDoc
*/
public function FromArray (array $array): void
{
// Проверяем, существует ли поле LogicOperator
if (isset($array["LogicOperator"]))
// - если да, то записываем его значение
$this->LogicOperator = $array["LogicOperator"];
// Проверяем, существует ли поле Conditions
if (isset($array["Conditions"]))
/**
* -- если да, то проходим по всем элементам массива
*
* @var IArrayable $condition
*/
foreach ($array["Conditions"] as $condition) {
// -- получаем класс по имени
$className = $condition["type_class"];
// -- создаём объект класса
$class = new $className();
// -- заполняем объект
$class->FromArray($condition);
// -- добавляем объект в массив
$this->Conditions[] = $class;
}
}
/**
* Формирует условие.
*
* @param mixed $condition Условие.
* @param int $index Индекс замены параметров для защиты от SQL-инъекций.
*
* @return string Возвращает условие в виде строки SQL.
*/
private function WriteCondition (mixed $condition, int $index = 0): Tuple
{
// Проверяем, является ли условие объектом класса Condition
if ($condition instanceof Condition)
// - если да, то возвращаем его значение
return $condition->Get($index);
// Проверяем, является ли условие объектом класса ConditionGroup
if ($condition instanceof ConditionGroup)
// - если да, то возвращаем его значения
return $condition->GetConditions($index);
// Если условие не является ни классом Condition, ни классом ConditionGroup, то это ошибка. Выбрасываем
// исключение.
throw new InvalidArgumentException("Неверное условие / Invalid condition");
}
}