98 lines
2.8 KiB
PHP
98 lines
2.8 KiB
PHP
<?php
|
|
|
|
namespace classes;
|
|
|
|
/**
|
|
* Ensures additive schema for department lifecycle metadata.
|
|
*/
|
|
class departments_schema_bootstrap
|
|
{
|
|
private static bool $initialized = false;
|
|
private const ARCHIVED_INDEX = 'idx_departments_archived';
|
|
|
|
public static function ensureTables(): void
|
|
{
|
|
if (self::$initialized) {
|
|
return;
|
|
}
|
|
|
|
global $db;
|
|
|
|
if (!isset($db) || !is_object($db) || !method_exists($db, 'query')) {
|
|
return;
|
|
}
|
|
|
|
if (!self::tableExists($db, 'departments')) {
|
|
return;
|
|
}
|
|
|
|
if (!self::columnExists($db, 'departments', 'archived')) {
|
|
$db->query(
|
|
"ALTER TABLE departments
|
|
ADD COLUMN archived TINYINT(1) NOT NULL DEFAULT 0
|
|
AFTER visible"
|
|
);
|
|
}
|
|
|
|
if (!self::columnExists($db, 'departments', 'custom_pricing_only')) {
|
|
$db->query(
|
|
"ALTER TABLE departments
|
|
ADD COLUMN custom_pricing_only TINYINT(1) NOT NULL DEFAULT 0
|
|
AFTER archived"
|
|
);
|
|
}
|
|
|
|
if (!self::indexExists($db, 'departments', self::ARCHIVED_INDEX)) {
|
|
$db->query(
|
|
"ALTER TABLE departments
|
|
ADD INDEX " . self::ARCHIVED_INDEX . " (archived)"
|
|
);
|
|
}
|
|
|
|
self::$initialized = true;
|
|
}
|
|
|
|
private static function tableExists(object $db, string $table): bool
|
|
{
|
|
$table = self::escapeIdentifier($table);
|
|
$result = $db->query("SHOW TABLES LIKE '{$table}'");
|
|
|
|
if ($result === false || !is_object($result) || !property_exists($result, 'num_rows')) {
|
|
return false;
|
|
}
|
|
|
|
return (int)$result->num_rows > 0;
|
|
}
|
|
|
|
private static function columnExists(object $db, string $table, string $column): bool
|
|
{
|
|
$table = self::escapeIdentifier($table);
|
|
$column = self::escapeIdentifier($column);
|
|
$result = $db->query("SHOW COLUMNS FROM `{$table}` LIKE '{$column}'");
|
|
|
|
if ($result === false || !is_object($result) || !property_exists($result, 'num_rows')) {
|
|
return false;
|
|
}
|
|
|
|
return (int)$result->num_rows > 0;
|
|
}
|
|
|
|
private static function indexExists(object $db, string $table, string $index): bool
|
|
{
|
|
$table = self::escapeIdentifier($table);
|
|
$index = self::escapeIdentifier($index);
|
|
$result = $db->query("SHOW INDEX FROM `{$table}` WHERE Key_name = '{$index}'");
|
|
|
|
if ($result === false || !is_object($result) || !property_exists($result, 'num_rows')) {
|
|
return false;
|
|
}
|
|
|
|
return (int)$result->num_rows > 0;
|
|
}
|
|
|
|
private static function escapeIdentifier(string $value): string
|
|
{
|
|
return str_replace(['\\', "'", '`'], ['\\\\', "\\'", ''], $value);
|
|
}
|
|
}
|