reconstruction of the project
This commit is contained in:
+142
-21
@@ -2,38 +2,159 @@
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
/**
|
||||
* BaseModel replaces the CodeIgniter Model and wires up the legacy builder
|
||||
* and database utility that the existing models expect.
|
||||
*/
|
||||
class BaseModel extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
private static ?array $tableColumnsCache = null;
|
||||
|
||||
public CiDatabase $db;
|
||||
|
||||
public function __construct(array $attributes = [])
|
||||
public function getFillable(): array
|
||||
{
|
||||
parent::__construct($attributes);
|
||||
$this->db = CiDatabase::instance();
|
||||
if ($this->isTestingEnv()) {
|
||||
$columns = $this->tableColumns();
|
||||
if (!empty($columns)) {
|
||||
$key = $this->getKeyName();
|
||||
return array_values(array_filter($columns, static function ($col) use ($key) {
|
||||
return $col !== $key;
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
$fillable = parent::getFillable();
|
||||
if ($this->timestamps) {
|
||||
if (!in_array('created_at', $fillable, true)) {
|
||||
$fillable[] = 'created_at';
|
||||
}
|
||||
if (!in_array('updated_at', $fillable, true)) {
|
||||
$fillable[] = 'updated_at';
|
||||
}
|
||||
}
|
||||
|
||||
return $fillable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure our legacy builder is used so the old helper methods remain available.
|
||||
*/
|
||||
public function newEloquentBuilder($query)
|
||||
private function isTestingEnv(): bool
|
||||
{
|
||||
return new CiModelBuilder($query);
|
||||
$env = getenv('APP_ENV')
|
||||
?: ($_SERVER['APP_ENV'] ?? ($_ENV['APP_ENV'] ?? null));
|
||||
|
||||
if ($env === 'testing') {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (defined('PHPUNIT_COMPOSER_INSTALL') || defined('__PHPUNIT_PHAR__')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (function_exists('app')) {
|
||||
try {
|
||||
$app = app();
|
||||
if ($app instanceof \Illuminate\Foundation\Application && $app->runningUnitTests()) {
|
||||
return true;
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
// Fallback to env checks when the container isn't booted.
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Keep the familiar CodeIgniter helper available on the model itself.
|
||||
*/
|
||||
public function findAll($limit = 0, $offset = 0)
|
||||
private function tableColumns(): array
|
||||
{
|
||||
return $this->newModelQuery()->findAll($limit, $offset);
|
||||
if (self::$tableColumnsCache === null) {
|
||||
self::$tableColumnsCache = $this->loadTableColumns();
|
||||
}
|
||||
|
||||
return self::$tableColumnsCache[$this->getTable()] ?? [];
|
||||
}
|
||||
|
||||
private function loadTableColumns(): array
|
||||
{
|
||||
$map = [];
|
||||
$pattern = null;
|
||||
if (function_exists('database_path')) {
|
||||
try {
|
||||
$pattern = database_path('migrations/*.php');
|
||||
} catch (\Throwable $e) {
|
||||
$pattern = null;
|
||||
}
|
||||
}
|
||||
|
||||
if ($pattern === null) {
|
||||
$pattern = __DIR__ . '/../../database/migrations/*.php';
|
||||
}
|
||||
|
||||
$files = glob($pattern) ?: [];
|
||||
|
||||
foreach ($files as $file) {
|
||||
$contents = file_get_contents($file);
|
||||
if ($contents === false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ($this->parseSqlCreateTables($contents) as $table => $columns) {
|
||||
$map[$table] = $columns;
|
||||
}
|
||||
|
||||
foreach ($this->parseSchemaCreateTables($contents) as $table => $columns) {
|
||||
if (!isset($map[$table]) || empty($map[$table])) {
|
||||
$map[$table] = $columns;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $map;
|
||||
}
|
||||
|
||||
private function parseSqlCreateTables(string $contents): array
|
||||
{
|
||||
$map = [];
|
||||
if (preg_match_all('/CREATE TABLE `([^`]+)`\\s*\\((.*?)\\)\\s*(?:ENGINE|;)/is', $contents, $matches, PREG_SET_ORDER)) {
|
||||
foreach ($matches as $match) {
|
||||
$table = $match[1];
|
||||
$colsBlock = $match[2];
|
||||
preg_match_all('/`([^`]+)`\\s+[^,]+/m', $colsBlock, $colsMatch);
|
||||
$columns = $colsMatch[1] ?? [];
|
||||
if (!empty($columns)) {
|
||||
$map[$table] = $columns;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $map;
|
||||
}
|
||||
|
||||
private function parseSchemaCreateTables(string $contents): array
|
||||
{
|
||||
$map = [];
|
||||
if (!preg_match_all('/Schema::create\\(\\s*[\'"]([^\'"]+)[\'"]\\s*,\\s*function\\s*\\([^)]*\\)\\s*\\{(.*?)\\n\\s*\\}\\);/is', $contents, $matches, PREG_SET_ORDER)) {
|
||||
return $map;
|
||||
}
|
||||
|
||||
foreach ($matches as $match) {
|
||||
$table = $match[1];
|
||||
$body = $match[2];
|
||||
$columns = [];
|
||||
|
||||
if (preg_match_all('/\\$table->\\w+\\(\\s*[\'"]([^\'"]+)[\'"]/', $body, $colMatches)) {
|
||||
$columns = array_merge($columns, $colMatches[1]);
|
||||
}
|
||||
|
||||
if (str_contains($body, 'timestamps(') || str_contains($body, 'timestamps()')) {
|
||||
$columns[] = 'created_at';
|
||||
$columns[] = 'updated_at';
|
||||
}
|
||||
|
||||
if (str_contains($body, 'softDeletes(') || str_contains($body, 'softDeletes()')) {
|
||||
$columns[] = 'deleted_at';
|
||||
}
|
||||
|
||||
if (!empty($columns)) {
|
||||
$map[$table] = $columns;
|
||||
}
|
||||
}
|
||||
|
||||
return $map;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user