After a lot of frickling, I managed to get a sort of solution. As long upload works fine and images are not too different in size it works.
Just in case someone else can use it or for ideas how to solve this better, I upload here the two files of the plugin:
index.php
<?php
Kirby::plugin('sehfelder/ebid-upload-sort', [
'areas' => [
'site' => function () {
return [
'buttons' => [
'page.sort-anti-alpha' => function ($page) {
if ($page->intendedTemplate()->name() !== 'album') {
return null;
}
return [
'component' => 'k-sort-anti-alpha-view-button',
'icon' => 'sort',
'text' => 'Z-A',
'title' => 'Bilder anti-alphabetisch sortieren',
'pageId' => $page->id(),
];
}
]
];
}
],
'api' => [
'routes' => [
[
'pattern' => 'ebid-upload-sort/multiupload-finished',
'method' => 'POST',
'action' => function () {
$pageId = $this->requestBody('pageId');
$count = (int)$this->requestBody('count');
// Sicherheitsabfragen
if (is_string($pageId) !== true || $pageId === '') { throw new Exception('Missing pageId'); }
if ($count <= 0) { throw new Exception('Invalid count'); }
$page = page($pageId);
if (($page instanceof \Kirby\Cms\Page) === false) { throw new Exception('Page not found'); }
if ($page->intendedTemplate()->name() !== 'album') { throw new Exception('Not an album page'); }
$line = sprintf(
"[%s] page=%s uploaded=%d%s",
date('Y-m-d H:i:s'),
$page->id(),
$count,
PHP_EOL
);
file_put_contents(
$page->root() . '/.multiupload.log',
$line,
FILE_APPEND
);
// Sortierung ändern
$sortedFiles = $page->files()->sortBy('sort', 'asc');
$fileIds = [];
foreach ($sortedFiles as $file) {
$fileIds[] = $file->id();
}
$count = min($count, count($fileIds));
if ($count > 0) {
$front = array_slice($fileIds, -$count);
$back = array_slice($fileIds, 0, count($fileIds) - $count);
$sortedFiles->changeSort([...$front, ...$back]);
}
return [
'status' => 'ok',
'page' => $page->id(),
'count' => $count
];
}
],
[
'pattern' => 'ebid-upload-sort/sort-anti-alpha',
'method' => 'POST',
'action' => function () {
$pageId = $this->requestBody('pageId');
if (is_string($pageId) !== true || $pageId === '') {
throw new Exception('Missing pageId');
}
$page = page($pageId);
if (($page instanceof \Kirby\Cms\Page) === false) {
throw new Exception('Page not found');
}
if ($page->intendedTemplate()->name() !== 'album') {
throw new Exception('Not an album page');
}
$sortedFiles = $page->files()->sortBy('filename', 'desc');
$fileIds = [];
foreach ($sortedFiles as $file) {
$fileIds[] = $file->id();
}
if (count($fileIds) > 0) {
$sortedFiles->changeSort($fileIds);
}
return [
'status' => 'ok',
'page' => $page->id(),
'count' => count($fileIds)
];
}
]
]
]
]);
index.js
const uploadState = new Map();
const FLUSH_DELAY_MS = 10000;
function currentPage(panel) {
return panel.$panel?.view?.props?.model ?? null;
}
function scheduleFlush(panel, pageId) {
const state = uploadState.get(pageId);
if (!state) { return; }
if (state.timer) { clearTimeout(state.timer); }
state.timer = window.setTimeout(async () => {
uploadState.delete(pageId);
try {
await panel.$api.post("ebid-upload-sort/multiupload-finished", {
pageId,
count: state.count,
});
panel.$events.emit("model.update");
panel.$panel.notification.success({
message: `${state.count} Bild(er) hochgeladen und umsortiert`,
});
} catch (error) {
console.error(
"[ebid-upload-sort] Batch-Ende konnte nicht gemeldet werden",
error,
);
}
}, FLUSH_DELAY_MS);
}
panel.plugin("sehfelder/ebid-upload-sort", {
viewButtons: {
"sort-anti-alpha": {
props: {
icon: String,
pageId: String,
text: String,
title: String,
},
methods: {
async sortAntiAlpha() {
try {
await this.$api.post("ebid-upload-sort/sort-anti-alpha", {
pageId: this.pageId,
});
this.$events.emit("model.update");
this.$panel.notification.success({
message: "Bilder anti-alphabetisch sortiert",
});
} catch (error) {
this.$panel.notification.error({
message: error.message ?? "Sortierung fehlgeschlagen",
});
}
},
},
template: `
<k-view-button
:icon="icon"
:text="text"
:title="title"
@click="sortAntiAlpha"
/>
`,
},
},
created(panel) {
panel.$events.on("file.upload", () => {
const page = currentPage(panel);
if (!page?.id) { return; }
if (page.template && page.template !== "album") { return; }
if (!uploadState.has(page.id)) { uploadState.set(page.id, { count: 0, timer: null }); }
const state = uploadState.get(page.id);
state.count += 1;
scheduleFlush(panel, page.id);
});
},
});
I would greatly appreciate it if Kirby could do something to better sort uploaded images.