80 lines
3.3 KiB
PHP
80 lines
3.3 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
/**
|
|
* Download der Windows- und Android-App für Mitarbeiter.
|
|
*
|
|
* Der Admin legt die Dateien per FTP in app_downloads/ (per .htaccess nicht direkt aufrufbar) ab:
|
|
* DeskHub-Setup.exe (Windows) und DeskHub.apk (Android). Ausgeliefert werden sie nur über staff/app_download.php
|
|
* an angemeldete Mitarbeiter.
|
|
*/
|
|
|
|
/** Unterstützte Plattformen: Dateiendung, feste Dateinamen auf dem Server, Dateikopf-Prüfung, Anzeigename. */
|
|
function app_platforms(): array
|
|
{
|
|
return [
|
|
'windows' => ['label' => 'Windows', 'ext' => 'exe', 'stored' => 'DeskHub-Setup.exe', 'download' => 'DeskHub-Setup.exe', 'magic' => 'MZ', 'mime' => 'application/vnd.microsoft.portable-executable'],
|
|
'android' => ['label' => 'Android', 'ext' => 'apk', 'stored' => 'DeskHub.apk', 'download' => 'DeskHub.apk', 'magic' => 'PK', 'mime' => 'application/vnd.android.package-archive'],
|
|
];
|
|
}
|
|
|
|
function app_downloads_dir(): string
|
|
{
|
|
return rtrim((string) (getenv('DESKHUB_APPS_DIR') ?: dirname(__DIR__) . '/app_downloads'), '/\\');
|
|
}
|
|
|
|
/** Legt den Ordner an und sperrt den Direktzugriff. */
|
|
function app_downloads_prepare_dir(): bool
|
|
{
|
|
$dir = app_downloads_dir();
|
|
if (!is_dir($dir) && !@mkdir($dir, 0755, true)) return false;
|
|
$htaccess = $dir . '/.htaccess';
|
|
if (!is_file($htaccess)) {
|
|
@file_put_contents($htaccess, "# Nur über staff/app_download.php (mit Anmeldung) abrufbar\n<IfModule mod_authz_core.c>\n Require all denied\n</IfModule>\n<IfModule !mod_authz_core.c>\n Order deny,allow\n Deny from all\n</IfModule>\nOptions -Indexes\n");
|
|
}
|
|
if (!is_file($dir . '/index.html')) @file_put_contents($dir . '/index.html', '');
|
|
return is_writable($dir);
|
|
}
|
|
|
|
/**
|
|
* Angaben zu einer App oder null, wenn die Datei nicht im Ordner liegt. Version gibt es nicht: Die Dateien werden
|
|
* per FTP abgelegt, angezeigt werden Datum, Größe und eine berechnete SHA-256-Prüfsumme (zwischengespeichert,
|
|
* solange sich Änderungsdatum und Größe nicht ändern).
|
|
*/
|
|
function app_download_info(string $platform): ?array
|
|
{
|
|
$platforms = app_platforms();
|
|
if (!isset($platforms[$platform])) return null;
|
|
$p = $platforms[$platform];
|
|
$path = app_downloads_dir() . '/' . $p['stored'];
|
|
clearstatcache(true, $path);
|
|
if (!is_file($path) || (int) filesize($path) < 1024) return null;
|
|
$size = (int) filesize($path);
|
|
$mtime = (int) filemtime($path);
|
|
|
|
$cacheKey = "app_{$platform}_hash_cache";
|
|
$cached = explode(':', (string) get_setting($cacheKey, ''), 3);
|
|
if (count($cached) === 3 && (int) $cached[0] === $mtime && (int) $cached[1] === $size) {
|
|
$sha = $cached[2];
|
|
} else {
|
|
$sha = (string) hash_file('sha256', $path);
|
|
set_setting($cacheKey, "{$mtime}:{$size}:{$sha}");
|
|
}
|
|
return [
|
|
'platform' => $platform,
|
|
'label' => $p['label'],
|
|
'size' => $size,
|
|
'sha256' => $sha,
|
|
'modified_at' => date('Y-m-d H:i:s', $mtime),
|
|
'path' => $path,
|
|
'filename' => $p['download'],
|
|
'mime' => $p['mime'],
|
|
];
|
|
}
|
|
|
|
function app_format_size(int $bytes): string
|
|
{
|
|
if ($bytes >= 1048576) return number_format($bytes / 1048576, 1, ',', '.') . ' MB';
|
|
return number_format(max(1, $bytes / 1024), 0, ',', '.') . ' KB';
|
|
}
|