148 lines
5.1 KiB
PHP
148 lines
5.1 KiB
PHP
<?php
|
|
namespace Tests\Extension;
|
|
|
|
use PDO;
|
|
use PDOException;
|
|
use Faker;
|
|
use Tests\Extension\Faker\Provider\Rut;
|
|
|
|
abstract class AbstractSeed implements SeedInterface
|
|
{
|
|
public function __construct(PDO $connection)
|
|
{
|
|
$this->setConnection($connection);
|
|
$this->faker = Faker\Factory::create('es_AR');
|
|
$this->faker->addProvider(new Rut($this->faker));
|
|
}
|
|
|
|
protected PDO $connection;
|
|
protected Faker\Generator $faker;
|
|
public function setConnection(PDO $connection): SeedInterface
|
|
{
|
|
$this->connection = $connection;
|
|
return $this;
|
|
}
|
|
public function getConnection(): PDO
|
|
{
|
|
return $this->connection;
|
|
}
|
|
public function getDependencies(): array
|
|
{
|
|
return [];
|
|
}
|
|
|
|
protected string $table;
|
|
protected function table(string $table): self
|
|
{
|
|
$this->table = $table;
|
|
return $this;
|
|
}
|
|
|
|
protected array $queryQueue = [];
|
|
protected function insertValues(array $valueRows): self
|
|
{
|
|
$columns = array_keys($valueRows[0]);
|
|
$columnsString = implode(', ', array_map(fn($column) => "`{$column}`", $columns));
|
|
$placeholderArray = array_map(fn($column) => ":{$column}", $columns);
|
|
$placeholders = implode(', ', $placeholderArray);
|
|
$query = "INSERT INTO `{$this->table}` ({$columnsString}) VALUES ({$placeholders})";
|
|
$this->queryQueue []= ['query' => $query, 'values' => $valueRows];
|
|
return $this;
|
|
}
|
|
protected function save(): self
|
|
{
|
|
foreach ($this->queryQueue as $entry) {
|
|
$query = $entry['query'];
|
|
$valueRows = $entry['values'];
|
|
|
|
foreach ($valueRows as $valueRow) {
|
|
try {
|
|
$this->connection->beginTransaction();
|
|
$statement = $this->connection->prepare($query);
|
|
if ($statement === false) {
|
|
$this->connection->rollBack();
|
|
continue;
|
|
}
|
|
$statement->execute($valueRow);
|
|
$this->connection->commit();
|
|
} catch (PDOException | \Throwable $exception) {
|
|
$this->connection->rollBack();
|
|
}
|
|
}
|
|
}
|
|
return $this;
|
|
}
|
|
|
|
protected function loadValues(string $table, array $conditions = [], string|array $columns = '*'): array
|
|
{
|
|
$columns = $this->processColumns($columns);
|
|
$query = "SELECT {$columns} FROM `{$table}`";
|
|
if (count($conditions) > 0) {
|
|
$conditionsString = $this->processConditions($conditions);
|
|
$query = "{$query} WHERE {$conditionsString}";
|
|
}
|
|
try {
|
|
$statement = $this->connection->prepare($query);
|
|
$statement->execute();
|
|
} catch (PDOException) {
|
|
return [];
|
|
}
|
|
try {
|
|
if ($columns !== '*' and !str_contains($columns, ',')) {
|
|
return $statement->fetchAll(PDO::FETCH_COLUMN);
|
|
}
|
|
return $statement->fetchAll(PDO::FETCH_ASSOC);
|
|
} catch (PDOException) {
|
|
return [];
|
|
}
|
|
}
|
|
protected function processColumns(string|array $columns): string
|
|
{
|
|
if (is_array($columns)) {
|
|
$columns = implode(',', array_map(fn($column) => "`{$column}`", $columns));
|
|
}
|
|
if ($columns === '*') {
|
|
return $columns;
|
|
}
|
|
$columns = array_map(fn($column) => trim($column), explode(',', $columns));
|
|
return implode(', ', array_map(function($column) {
|
|
if (!str_contains($column, '`')) {
|
|
return "`{$column}`";
|
|
}
|
|
return $column;
|
|
}, $columns));
|
|
}
|
|
protected function processConditions(array $conditions): array
|
|
{
|
|
$processedConditions = [];
|
|
$processedValues = [];
|
|
foreach ($conditions as $condition) {
|
|
if (is_string($condition) and (str_starts_with(strtolower($condition), 'and') or str_starts_with(strtolower($condition), 'or'))) {
|
|
$processedConditions[] = $condition;
|
|
continue;
|
|
}
|
|
$column = $condition['column'];
|
|
$value = $condition['value'];
|
|
$match = $condition['match'] ?? 'AND';
|
|
$operator = $condition['operator'] ?? '=';
|
|
$columnValue = ":{$column}";
|
|
if (is_array($value)) {
|
|
$columnString = [];
|
|
foreach ($value as $idx => $val) {
|
|
$columnValue = ":{$column}_{$idx}";
|
|
$columnString[] = $columnValue;
|
|
$processedValues["{$column}_{$idx}"] = $val;
|
|
}
|
|
$columnValue = '(' . implode(', ', $columnString) . ')';
|
|
if (!str_contains($operator, 'IN')) {
|
|
$operator = 'IN';
|
|
}
|
|
} else {
|
|
$processedValues[$column] = $value;
|
|
}
|
|
$processedConditions[] = "{$match} `{$column}` {$operator} {$columnValue}";
|
|
}
|
|
return ['query' => implode(' ', $processedConditions), 'values' => $processedValues];
|
|
}
|
|
}
|