206 lines
8.4 KiB
PHP
206 lines
8.4 KiB
PHP
<?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");
|
||
}
|
||
} |