Autosave: 20260416-001254
This commit is contained in:
parent
0965f47f80
commit
4bf27ecfd4
BIN
assets/pasted-20260416-000905-360246be.png
Normal file
BIN
assets/pasted-20260416-000905-360246be.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 766 KiB |
@ -56,6 +56,7 @@ function sccharacters_bootstrap(): void
|
|||||||
cl_sccharacter_notes TEXT DEFAULT NULL,
|
cl_sccharacter_notes TEXT DEFAULT NULL,
|
||||||
cl_sccharacter_share_token VARCHAR(64) NOT NULL,
|
cl_sccharacter_share_token VARCHAR(64) NOT NULL,
|
||||||
cl_sccharacter_share_enabled TINYINT(1) NOT NULL DEFAULT 0,
|
cl_sccharacter_share_enabled TINYINT(1) NOT NULL DEFAULT 0,
|
||||||
|
cl_sccharacter_category_order TEXT DEFAULT NULL,
|
||||||
cl_sccharacter_created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
cl_sccharacter_created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
cl_sccharacter_updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
cl_sccharacter_updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||||
PRIMARY KEY (cl_sccharacter_id),
|
PRIMARY KEY (cl_sccharacter_id),
|
||||||
@ -90,6 +91,13 @@ function sccharacters_bootstrap(): void
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!sccharacters_column_exists($db, 'tbl_sccharacters', 'cl_sccharacter_category_order')) {
|
||||||
|
$db->exec(
|
||||||
|
'ALTER TABLE tbl_sccharacters
|
||||||
|
ADD COLUMN cl_sccharacter_category_order TEXT NULL AFTER cl_sccharacter_share_enabled'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (!sccharacters_index_exists($db, 'tbl_sccharacters', 'idx_sccharacter_owner')) {
|
if (!sccharacters_index_exists($db, 'tbl_sccharacters', 'idx_sccharacter_owner')) {
|
||||||
$db->exec(
|
$db->exec(
|
||||||
'ALTER TABLE tbl_sccharacters
|
'ALTER TABLE tbl_sccharacters
|
||||||
@ -123,11 +131,13 @@ function sccharacters_bootstrap(): void
|
|||||||
cl_sccharacteritem_scitemcustom_id INT(11) DEFAULT NULL,
|
cl_sccharacteritem_scitemcustom_id INT(11) DEFAULT NULL,
|
||||||
cl_sccharacteritem_slot VARCHAR(120) NOT NULL DEFAULT '',
|
cl_sccharacteritem_slot VARCHAR(120) NOT NULL DEFAULT '',
|
||||||
cl_sccharacteritem_note TEXT DEFAULT NULL,
|
cl_sccharacteritem_note TEXT DEFAULT NULL,
|
||||||
|
cl_sccharacteritem_sort_order INT UNSIGNED NOT NULL DEFAULT 0,
|
||||||
cl_sccharacteritem_created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
cl_sccharacteritem_created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
PRIMARY KEY (cl_sccharacteritem_id),
|
PRIMARY KEY (cl_sccharacteritem_id),
|
||||||
KEY idx_sccharacteritem_character (cl_sccharacteritem_character_id),
|
KEY idx_sccharacteritem_character (cl_sccharacteritem_character_id),
|
||||||
KEY idx_sccharacteritem_scobjs (cl_sccharacteritem_scobjs_id),
|
KEY idx_sccharacteritem_scobjs (cl_sccharacteritem_scobjs_id),
|
||||||
KEY idx_sccharacteritem_scitemcustom (cl_sccharacteritem_scitemcustom_id),
|
KEY idx_sccharacteritem_scitemcustom (cl_sccharacteritem_scitemcustom_id),
|
||||||
|
KEY idx_sccharacteritem_character_sort (cl_sccharacteritem_character_id, cl_sccharacteritem_sort_order, cl_sccharacteritem_id),
|
||||||
CONSTRAINT fk_sccharacteritem_character FOREIGN KEY (cl_sccharacteritem_character_id)
|
CONSTRAINT fk_sccharacteritem_character FOREIGN KEY (cl_sccharacteritem_character_id)
|
||||||
REFERENCES tbl_sccharacters (cl_sccharacter_id)
|
REFERENCES tbl_sccharacters (cl_sccharacter_id)
|
||||||
ON DELETE CASCADE
|
ON DELETE CASCADE
|
||||||
@ -157,6 +167,13 @@ function sccharacters_bootstrap(): void
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!sccharacters_column_exists($db, 'tbl_sccharacteritems', 'cl_sccharacteritem_sort_order')) {
|
||||||
|
$db->exec(
|
||||||
|
'ALTER TABLE tbl_sccharacteritems
|
||||||
|
ADD COLUMN cl_sccharacteritem_sort_order INT UNSIGNED NOT NULL DEFAULT 0 AFTER cl_sccharacteritem_note'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (!sccharacters_index_exists($db, 'tbl_sccharacteritems', 'idx_sccharacteritem_character')) {
|
if (!sccharacters_index_exists($db, 'tbl_sccharacteritems', 'idx_sccharacteritem_character')) {
|
||||||
$db->exec(
|
$db->exec(
|
||||||
'ALTER TABLE tbl_sccharacteritems
|
'ALTER TABLE tbl_sccharacteritems
|
||||||
@ -178,6 +195,13 @@ function sccharacters_bootstrap(): void
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!sccharacters_index_exists($db, 'tbl_sccharacteritems', 'idx_sccharacteritem_character_sort')) {
|
||||||
|
$db->exec(
|
||||||
|
'ALTER TABLE tbl_sccharacteritems
|
||||||
|
ADD INDEX idx_sccharacteritem_character_sort (cl_sccharacteritem_character_id, cl_sccharacteritem_sort_order, cl_sccharacteritem_id)'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (!sccharacters_foreign_key_exists($db, 'tbl_sccharacteritems', 'fk_sccharacteritem_character')) {
|
if (!sccharacters_foreign_key_exists($db, 'tbl_sccharacteritems', 'fk_sccharacteritem_character')) {
|
||||||
$db->exec(
|
$db->exec(
|
||||||
'ALTER TABLE tbl_sccharacteritems
|
'ALTER TABLE tbl_sccharacteritems
|
||||||
@ -247,6 +271,76 @@ function sccharacters_generate_share_token(PDO $db): string
|
|||||||
return $token;
|
return $token;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function sccharacters_reindex_character_items(PDO $db, int $character_id): void
|
||||||
|
{
|
||||||
|
if ($character_id <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$stmt = $db->prepare(
|
||||||
|
'SELECT cl_sccharacteritem_id
|
||||||
|
FROM tbl_sccharacteritems
|
||||||
|
WHERE cl_sccharacteritem_character_id = :character_id
|
||||||
|
ORDER BY
|
||||||
|
CASE WHEN cl_sccharacteritem_sort_order <= 0 THEN 0 ELSE 1 END,
|
||||||
|
cl_sccharacteritem_sort_order ASC,
|
||||||
|
cl_sccharacteritem_id ASC'
|
||||||
|
);
|
||||||
|
$stmt->execute(['character_id' => $character_id]);
|
||||||
|
$item_ids = array_map('intval', $stmt->fetchAll(PDO::FETCH_COLUMN));
|
||||||
|
|
||||||
|
if ($item_ids === []) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$stmt_update = $db->prepare(
|
||||||
|
'UPDATE tbl_sccharacteritems
|
||||||
|
SET cl_sccharacteritem_sort_order = :sort_order
|
||||||
|
WHERE cl_sccharacteritem_character_id = :character_id
|
||||||
|
AND cl_sccharacteritem_id = :item_id'
|
||||||
|
);
|
||||||
|
|
||||||
|
$db->beginTransaction();
|
||||||
|
|
||||||
|
try {
|
||||||
|
$position = 1;
|
||||||
|
foreach ($item_ids as $item_id) {
|
||||||
|
$stmt_update->execute([
|
||||||
|
'sort_order' => $position,
|
||||||
|
'character_id' => $character_id,
|
||||||
|
'item_id' => $item_id,
|
||||||
|
]);
|
||||||
|
$position++;
|
||||||
|
}
|
||||||
|
|
||||||
|
$db->commit();
|
||||||
|
} catch (Throwable $exception) {
|
||||||
|
if ($db->inTransaction()) {
|
||||||
|
$db->rollBack();
|
||||||
|
}
|
||||||
|
|
||||||
|
throw $exception;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function sccharacters_next_item_sort_order(PDO $db, int $character_id): int
|
||||||
|
{
|
||||||
|
if ($character_id <= 0) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
sccharacters_reindex_character_items($db, $character_id);
|
||||||
|
|
||||||
|
$stmt = $db->prepare(
|
||||||
|
'SELECT COALESCE(MAX(cl_sccharacteritem_sort_order), 0)
|
||||||
|
FROM tbl_sccharacteritems
|
||||||
|
WHERE cl_sccharacteritem_character_id = :character_id'
|
||||||
|
);
|
||||||
|
$stmt->execute(['character_id' => $character_id]);
|
||||||
|
|
||||||
|
return ((int) $stmt->fetchColumn()) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function sccharacters_item_category_options(): array
|
function sccharacters_item_category_options(): array
|
||||||
{
|
{
|
||||||
@ -265,6 +359,106 @@ function sccharacters_item_category_options(): array
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function sccharacters_default_category_order(): array
|
||||||
|
{
|
||||||
|
return array_keys(sccharacters_item_category_options());
|
||||||
|
}
|
||||||
|
|
||||||
|
function sccharacters_normalize_category_order(array $category_order): array
|
||||||
|
{
|
||||||
|
$known_categories = sccharacters_default_category_order();
|
||||||
|
$known_lookup = array_fill_keys($known_categories, true);
|
||||||
|
$normalized = [];
|
||||||
|
|
||||||
|
foreach ($category_order as $category_key) {
|
||||||
|
$category_key = trim((string) $category_key);
|
||||||
|
if ($category_key === '' || !isset($known_lookup[$category_key]) || isset($normalized[$category_key])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$normalized[$category_key] = $category_key;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($known_categories as $category_key) {
|
||||||
|
if (!isset($normalized[$category_key])) {
|
||||||
|
$normalized[$category_key] = $category_key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return array_values($normalized);
|
||||||
|
}
|
||||||
|
|
||||||
|
function sccharacters_parse_category_order(?string $raw_value): array
|
||||||
|
{
|
||||||
|
$raw_value = trim((string) $raw_value);
|
||||||
|
if ($raw_value === '') {
|
||||||
|
return sccharacters_default_category_order();
|
||||||
|
}
|
||||||
|
|
||||||
|
$decoded = json_decode($raw_value, true);
|
||||||
|
if (!is_array($decoded)) {
|
||||||
|
return sccharacters_default_category_order();
|
||||||
|
}
|
||||||
|
|
||||||
|
return sccharacters_normalize_category_order($decoded);
|
||||||
|
}
|
||||||
|
|
||||||
|
function sccharacters_encode_category_order(array $category_order): string
|
||||||
|
{
|
||||||
|
$encoded = json_encode(
|
||||||
|
sccharacters_normalize_category_order($category_order),
|
||||||
|
JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES
|
||||||
|
);
|
||||||
|
|
||||||
|
return $encoded !== false
|
||||||
|
? $encoded
|
||||||
|
: json_encode(sccharacters_default_category_order(), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
||||||
|
}
|
||||||
|
|
||||||
|
function sccharacters_character_category_order(array $character_row): array
|
||||||
|
{
|
||||||
|
return sccharacters_parse_category_order((string) ($character_row['cl_sccharacter_category_order'] ?? ''));
|
||||||
|
}
|
||||||
|
|
||||||
|
function sccharacters_sort_items_by_category_order(array $items_by_category, array $category_order): array
|
||||||
|
{
|
||||||
|
if ($items_by_category === []) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$sorted = [];
|
||||||
|
foreach (sccharacters_normalize_category_order($category_order) as $category_key) {
|
||||||
|
if (isset($items_by_category[$category_key])) {
|
||||||
|
$sorted[$category_key] = $items_by_category[$category_key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($items_by_category as $category_key => $category_items) {
|
||||||
|
if (!isset($sorted[$category_key])) {
|
||||||
|
$sorted[$category_key] = $category_items;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $sorted;
|
||||||
|
}
|
||||||
|
|
||||||
|
function sccharacters_save_character_category_order(PDO $db, int $character_id, array $category_order): void
|
||||||
|
{
|
||||||
|
if ($character_id <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$stmt = $db->prepare(
|
||||||
|
'UPDATE tbl_sccharacters
|
||||||
|
SET cl_sccharacter_category_order = :category_order
|
||||||
|
WHERE cl_sccharacter_id = :character_id'
|
||||||
|
);
|
||||||
|
$stmt->execute([
|
||||||
|
'category_order' => sccharacters_encode_category_order($category_order),
|
||||||
|
'character_id' => $character_id,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
function sccharacters_item_category_label(string $category): string
|
function sccharacters_item_category_label(string $category): string
|
||||||
{
|
{
|
||||||
$options = sccharacters_item_category_options();
|
$options = sccharacters_item_category_options();
|
||||||
|
|||||||
@ -31,6 +31,8 @@ if ($share_token !== '') {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($character) {
|
if ($character) {
|
||||||
|
sccharacters_reindex_character_items($db, (int) $character['cl_sccharacter_id']);
|
||||||
|
|
||||||
$stmt_items = $db->prepare(
|
$stmt_items = $db->prepare(
|
||||||
"SELECT
|
"SELECT
|
||||||
ci.*,
|
ci.*,
|
||||||
@ -47,11 +49,7 @@ if ($character) {
|
|||||||
LEFT JOIN tbl_scitemcustom co ON co.cl_scitemcustom_id = ci.cl_sccharacteritem_scitemcustom_id
|
LEFT JOIN tbl_scitemcustom co ON co.cl_scitemcustom_id = ci.cl_sccharacteritem_scitemcustom_id
|
||||||
LEFT JOIN tbl_scobjs oo ON oo.cl_scobjs_id = co.cl_scitemcustom_obj_id
|
LEFT JOIN tbl_scobjs oo ON oo.cl_scobjs_id = co.cl_scitemcustom_obj_id
|
||||||
WHERE ci.cl_sccharacteritem_character_id = :character_id
|
WHERE ci.cl_sccharacteritem_character_id = :character_id
|
||||||
ORDER BY
|
ORDER BY ci.cl_sccharacteritem_sort_order ASC, ci.cl_sccharacteritem_id ASC"
|
||||||
CASE WHEN TRIM(ci.cl_sccharacteritem_slot) = '' THEN 1 ELSE 0 END,
|
|
||||||
ci.cl_sccharacteritem_slot ASC,
|
|
||||||
COALESCE(oo.cl_scobjs_name, bo.cl_scobjs_name, 'ZZZ') ASC,
|
|
||||||
ci.cl_sccharacteritem_id ASC"
|
|
||||||
);
|
);
|
||||||
$stmt_items->execute(['character_id' => (int) $character['cl_sccharacter_id']]);
|
$stmt_items->execute(['character_id' => (int) $character['cl_sccharacter_id']]);
|
||||||
$character_items = $stmt_items->fetchAll();
|
$character_items = $stmt_items->fetchAll();
|
||||||
@ -93,10 +91,10 @@ if ($character) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$item_category_options = sccharacters_item_category_options();
|
$item_category_options = sccharacters_item_category_options();
|
||||||
|
$character_category_order = $character
|
||||||
|
? sccharacters_character_category_order($character)
|
||||||
|
: sccharacters_default_category_order();
|
||||||
$character_items_by_category = [];
|
$character_items_by_category = [];
|
||||||
foreach (array_keys($item_category_options) as $category_key) {
|
|
||||||
$character_items_by_category[$category_key] = [];
|
|
||||||
}
|
|
||||||
foreach ($character_items as $item_row) {
|
foreach ($character_items as $item_row) {
|
||||||
$is_custom = ($item_row['cl_sccharacteritem_source'] ?? '') === 'custom';
|
$is_custom = ($item_row['cl_sccharacteritem_source'] ?? '') === 'custom';
|
||||||
$type = $is_custom
|
$type = $is_custom
|
||||||
@ -115,9 +113,9 @@ foreach ($character_items as $item_row) {
|
|||||||
}
|
}
|
||||||
$character_items_by_category[$category_key][] = $item_row;
|
$character_items_by_category[$category_key][] = $item_row;
|
||||||
}
|
}
|
||||||
$character_items_by_category = array_filter(
|
$character_items_by_category = sccharacters_sort_items_by_category_order(
|
||||||
$character_items_by_category,
|
$character_items_by_category,
|
||||||
static fn(array $items): bool => $items !== []
|
$character_category_order
|
||||||
);
|
);
|
||||||
?>
|
?>
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
|
|||||||
1631
sccharacters.php
1631
sccharacters.php
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user