This commit is contained in:
2025-08-01 18:29:11 +03:00
parent 2f3dd81d0a
commit ccdcc3e047
10 changed files with 1226 additions and 51 deletions

View File

@@ -0,0 +1,205 @@
<?php
/**
* @noinspection SqlNoDataSourceInspection
*/
namespace goodboyalex\php_db_components_pack\classes;
use goodboyalex\php_components_pack\classes\Tuple;
use goodboyalex\php_components_pack\interfaces\IArrayable;
/**
* Группа условий запроса выборки по условию.
*
* @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");
}
}