diff --git a/runtime/lib/webdav-warmup.php b/runtime/lib/webdav-warmup.php deleted file mode 100644 index 755d923..0000000 --- a/runtime/lib/webdav-warmup.php +++ /dev/null @@ -1,714 +0,0 @@ - $value) - { - if (is_bool($value)) $value = $value ? '1' : '0'; - elseif ($value === null) $value = 'NULL'; - elseif (is_array($value) || is_object($value)) $value = json_encode($value, JSON_UNESCAPED_SLASHES); - $parts[] = $key.'='.str_replace(array("\r", "\n"), array('\\r', '\\n'), (string)$value); - } - fwrite(STDOUT, implode(' ', $parts)."\n"); -} - -function bratonien_tools_warmup_absolute_source_path(array $image_row) -{ - $path = (string)($image_row['path'] ?? ''); - if ($path === '') return null; - if (strpos($path, '/') === 0) return $path; - return PHPWG_ROOT_PATH.ltrim(preg_replace('#^\./#', '', $path), '/'); -} - -function bratonien_tools_warmup_connection_credentials($connection_id) -{ - $connection = bratonien_tools_nc_connector_connection((int)$connection_id, true); - if (!$connection || empty($connection['enabled'])) return null; - - $plain = bratonien_tools_nc_connector_decrypt_secret((string)($connection['secret_blob'] ?? '')); - $credentials = json_decode($plain, true); - if (!is_array($credentials)) return null; - - $config = isset($connection['config']) && is_array($connection['config']) ? $connection['config'] : array(); - $base_url = rtrim((string)($config['nextcloud_url'] ?? ''), '/'); - $user = trim((string)($credentials['nextcloud_user'] ?? '')); - $password = (string)($credentials['nextcloud_password'] ?? ''); - if ($base_url === '' || $user === '' || $password === '') return null; - - return array( - 'connection'=>$connection, - 'config'=>$config, - 'base_url'=>$base_url, - 'user'=>$user, - 'password'=>$password, - ); -} - -function bratonien_tools_warmup_quote_path($path) -{ - $parts = array_values(array_filter(explode('/', trim((string)$path, '/')), 'strlen')); - return implode('/', array_map('rawurlencode', $parts)); -} - -function bratonien_tools_warmup_download(array $source, array $credentials, $destination, &$detail=null) -{ - $detail = ''; - $webdav_path = trim((string)($source['webdav_path'] ?? ''), '/'); - if ($webdav_path === '') - { - $detail = 'WebDAV-Pfad fehlt.'; - return false; - } - - $fp = @fopen($destination, 'xb'); - if (!$fp) - { - $detail = 'Temporaere Datei konnte nicht angelegt werden.'; - return false; - } - - $url = $credentials['base_url'].'/remote.php/dav/files/'.rawurlencode($credentials['user']).'/'.bratonien_tools_warmup_quote_path($webdav_path); - $ch = curl_init($url); - curl_setopt_array($ch, array( - CURLOPT_FOLLOWLOCATION => false, - CURLOPT_CONNECTTIMEOUT => 10, - CURLOPT_TIMEOUT => 300, - CURLOPT_HTTPAUTH => CURLAUTH_BASIC, - CURLOPT_USERPWD => $credentials['user'].':'.$credentials['password'], - CURLOPT_RETURNTRANSFER => false, - CURLOPT_FAILONERROR => false, - CURLOPT_FILE => $fp, - CURLOPT_USERAGENT => 'Bratonien-WebDAV-Warmup/0.9.7.1.8', - )); - $ok = curl_exec($ch); - $errno = curl_errno($ch); - $error = curl_error($ch); - $http = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE); - curl_close($ch); - fclose($fp); - - if ($ok === false || $errno !== 0 || $http < 200 || $http >= 300) - { - @unlink($destination); - $detail = 'Nextcloud-Download fehlgeschlagen (HTTP '.$http.', cURL '.$errno.($error !== '' ? ': '.$error : '').').'; - return false; - } - if (!is_file($destination) || filesize($destination) < 1 || @getimagesize($destination) === false) - { - @unlink($destination); - $detail = 'Geladene Datei ist kein lesbares Bild.'; - return false; - } - return true; -} - -function bratonien_tools_warmup_state_file($connection_id) -{ - return PHPWG_ROOT_PATH.PWG_LOCAL_DIR.'bratonien-webdav-warmup.connection-'.(int)$connection_id.'.json'; -} - -function bratonien_tools_warmup_load_state($connection_id) -{ - $file = bratonien_tools_warmup_state_file($connection_id); - if (!is_file($file) || !is_readable($file)) - { - return array('albums'=>array(), 'images'=>array(), 'updated_at'=>0); - } - $raw = @file_get_contents($file); - $state = $raw !== false ? json_decode($raw, true) : null; - if (!is_array($state)) return array('albums'=>array(), 'images'=>array(), 'updated_at'=>0); - if (!isset($state['albums']) || !is_array($state['albums'])) $state['albums'] = array(); - if (!isset($state['images']) || !is_array($state['images'])) $state['images'] = array(); - return $state; -} - -function bratonien_tools_warmup_save_state($connection_id, array $state) -{ - $file = bratonien_tools_warmup_state_file($connection_id); - $directory = dirname($file); - if (!is_dir($directory) && !@mkdir($directory, 0775, true) && !is_dir($directory)) - { - throw new RuntimeException('Warmup-State-Verzeichnis konnte nicht angelegt werden.'); - } - $state['updated_at'] = time(); - $json = json_encode($state, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT); - if ($json === false) throw new RuntimeException('Warmup-State konnte nicht serialisiert werden.'); - $tmp = $file.'.tmp-'.bin2hex(random_bytes(4)); - if (@file_put_contents($tmp, $json."\n", LOCK_EX) === false) throw new RuntimeException('Warmup-State konnte nicht geschrieben werden.'); - @chmod($tmp, 0664); - if (!@rename($tmp, $file)) - { - @unlink($tmp); - throw new RuntimeException('Warmup-State konnte nicht atomar gespeichert werden.'); - } -} - -function bratonien_tools_warmup_scan_connection($connection_id) -{ - $images = array(); - $albums = array(); - $result = pwg_query('SELECT id, path, width, height, rotation, coi FROM '.IMAGES_TABLE.' ORDER BY id'); - while ($row = pwg_db_fetch_assoc($result)) - { - $image_id = (int)$row['id']; - $source = bratonien_tools_webdav_materialize_source_info($image_id); - if (!$source || (int)$source['connection_id'] !== (int)$connection_id) continue; - - $row['id'] = $image_id; - $images[$image_id] = array('row'=>$row, 'source'=>$source, 'albums'=>array()); - } - - if (!$images) return array('images'=>array(), 'albums'=>array()); - - $ids = array_keys($images); - foreach (array_chunk($ids, 500) as $chunk) - { - $sql = 'SELECT image_id, category_id FROM '.IMAGE_CATEGORY_TABLE.' WHERE image_id IN ('.implode(',', array_map('intval', $chunk)).')'; - $rel = pwg_query($sql); - while ($item = pwg_db_fetch_assoc($rel)) - { - $image_id = (int)$item['image_id']; - $category_id = (int)$item['category_id']; - if (!isset($images[$image_id]) || $category_id < 1) continue; - $images[$image_id]['albums'][$category_id] = true; - $albums[$category_id] = true; - } - } - - foreach ($images as &$image) - { - $image['albums'] = array_map('intval', array_keys($image['albums'])); - } - unset($image); - - return array('images'=>$images, 'albums'=>array_map('intval', array_keys($albums))); -} - -function bratonien_tools_warmup_signature(array $source) -{ - return sha1(implode('|', array( - (int)($source['connection_id'] ?? 0), - (int)($source['root_fileid'] ?? 0), - (int)($source['fileid'] ?? 0), - trim((string)($source['webdav_path'] ?? ''), '/'), - (string)($source['etag'] ?? ''), - (int)($source['size'] ?? 0), - (int)($source['width'] ?? 0), - (int)($source['height'] ?? 0), - ))); -} - -function bratonien_tools_warmup_select_ids(array $scan, array $state, $mode) -{ - $new_albums = array(); - $known_albums = array_fill_keys(array_map('intval', array_keys((array)$state['albums'])), true); - foreach ($scan['albums'] as $category_id) - { - if (!isset($known_albums[(int)$category_id])) $new_albums[(int)$category_id] = true; - } - - $selected = array(); - foreach ($scan['images'] as $image_id => $image) - { - $signature = bratonien_tools_warmup_signature($image['source']); - $known_signature = (string)($state['images'][(string)$image_id]['signature'] ?? ''); - $in_new_album = false; - foreach ($image['albums'] as $category_id) - { - if (isset($new_albums[(int)$category_id])) - { - $in_new_album = true; - break; - } - } - - if ($mode === 'sync') - { - if ($in_new_album) $selected[$image_id] = $image; - } - else - { - if ($known_signature === '' || !hash_equals($known_signature, $signature)) $selected[$image_id] = $image; - } - } - - return array('images'=>$selected, 'new_albums'=>array_map('intval', array_keys($new_albums))); -} - -function bratonien_tools_warmup_variants_for_stage(array $image_row, $stage) -{ - $src = new SrcImage($image_row); - $variants = array(); - foreach (ImageStdParams::get_defined_type_map() as $type => $params) - { - $derivative = new DerivativeImage($params, $src); - if ($derivative->same_as_source()) continue; - $size = $derivative->get_size(); - $max_edge = max((int)($size[0] ?? 0), (int)($size[1] ?? 0)); - $is_priority = $max_edge > 0 && $max_edge <= 1920; - if (($stage === 1 && $is_priority) || ($stage === 2 && !$is_priority)) - { - $variants[] = array('name'=>'standard:'.$type, 'derivative'=>$derivative); - } - } - foreach (ImageStdParams::$custom as $custom_key => $last_used) - { - $params = bratonien_tools_webdav_materialize_custom_params($custom_key); - if (!$params) continue; - $derivative = new DerivativeImage($params, $src); - if ($derivative->same_as_source()) continue; - $size = $derivative->get_size(); - $max_edge = max((int)($size[0] ?? 0), (int)($size[1] ?? 0)); - $is_priority = $max_edge > 0 && $max_edge <= 1920; - if (($stage === 1 && $is_priority) || ($stage === 2 && !$is_priority)) - { - $variants[] = array('name'=>'custom:'.$custom_key, 'derivative'=>$derivative); - } - } - return $variants; -} - -function bratonien_tools_warmup_i_url($target_path, $base_url) -{ - $derivative_root = PHPWG_ROOT_PATH.PWG_DERIVATIVE_DIR; - if (strpos($target_path, $derivative_root) !== 0) return null; - $location = ltrim(substr($target_path, strlen($derivative_root)), '/'); - if ($location === '') return null; - $segments = array_map('rawurlencode', explode('/', $location)); - return rtrim((string)$base_url, '/').'/i.php?/'.implode('/', $segments); -} - -function bratonien_tools_warmup_call_piwigo($url, &$detail=null) -{ - $detail = ''; - $ch = curl_init($url); - curl_setopt_array($ch, array( - CURLOPT_FOLLOWLOCATION => false, - CURLOPT_CONNECTTIMEOUT => 10, - CURLOPT_TIMEOUT => 300, - CURLOPT_RETURNTRANSFER => false, - CURLOPT_FAILONERROR => false, - CURLOPT_WRITEFUNCTION => function($ch, $data) { return strlen($data); }, - CURLOPT_USERAGENT => 'Bratonien-WebDAV-Warmup/0.9.7.1.8', - )); - $ok = curl_exec($ch); - $errno = curl_errno($ch); - $error = curl_error($ch); - $http = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE); - curl_close($ch); - if ($ok === false || $errno !== 0) - { - $detail = 'Piwigo-Aufruf fehlgeschlagen (cURL '.$errno.($error !== '' ? ': '.$error : '').').'; - return false; - } - if ($http < 200 || $http >= 400) - { - $detail = 'Piwigo i.php antwortete mit HTTP '.$http.'.'; - return false; - } - return true; -} - -function bratonien_tools_warmup_acquire_sync_guard(array $credentials, &$handle=null, &$detail=null) -{ - $handle = null; - $detail = ''; - $state_dir = rtrim((string)($credentials['config']['state_dir'] ?? ''), '/'); - if ($state_dir === '') - { - $detail = 'State-Verzeichnis der Verbindung fehlt.'; - return false; - } - $lock_path = $state_dir.'/webdav-sync.lock'; - $handle = @fopen($lock_path, 'c'); - if (!$handle) - { - $detail = 'WebDAV-Sync-Lock konnte nicht geöffnet werden.'; - return false; - } - if (!@flock($handle, LOCK_SH | LOCK_NB)) - { - fclose($handle); - $handle = null; - $detail = 'WebDAV-Synchronisierung läuft; Warmup wird später fortgesetzt.'; - return false; - } - return true; -} - -function bratonien_tools_warmup_source_lock($image_id, &$handle=null) -{ - $dir = PHPWG_ROOT_PATH.'upload/bratonien-webdav-materialize'; - if (!is_dir($dir) && !@mkdir($dir, 0775, true) && !is_dir($dir)) return false; - $path = $dir.'/image-'.(int)$image_id.'.lock'; - $handle = @fopen($path, 'c'); - if (!$handle) return false; - return @flock($handle, LOCK_EX); -} - -function bratonien_tools_warmup_release_lock(&$handle) -{ - if (is_resource($handle)) - { - @flock($handle, LOCK_UN); - fclose($handle); - } - $handle = null; -} - -function bratonien_tools_warmup_validate_source(array $image_row, array $source, $temp_file, &$resolved=null, &$logical=null, &$detail=null) -{ - $resolved = null; - $logical = bratonien_tools_warmup_absolute_source_path($image_row); - $detail = ''; - if (!$logical) - { - $detail = 'Piwigo-Quellpfad fehlt.'; - return false; - } - $resolved = realpath($logical); - if ($resolved === false || !is_file($resolved)) - { - $detail = 'Piwigo-Placeholder konnte nicht aufgelöst werden.'; - return false; - } - $normalized = str_replace('\\', '/', $resolved); - $expected = '/nc-webdav-source/connection-'.(int)$source['connection_id'].'/root-'.(int)$source['root_fileid'].'/'; - if (strpos($normalized, $expected) === false) - { - $detail = 'Aufgelöster Quellpfad gehört nicht zur erwarteten Verbindung/Wurzel.'; - return false; - } - if (!is_file($temp_file) || !is_readable($temp_file) || @getimagesize($temp_file) === false) - { - $detail = 'Batch-Quelldatei ist nicht vollständig lesbar.'; - return false; - } - return true; -} - -function bratonien_tools_warmup_restore_placeholder($resolved, $backup, $staging, &$detail=null) -{ - $detail = ''; - @unlink($staging); - if (is_file($resolved) || is_link($resolved)) - { - if (!@unlink($resolved)) - { - $detail = 'Temporäre Quelle konnte beim Restore nicht entfernt werden.'; - return false; - } - } - if (!is_file($backup)) - { - $detail = 'Placeholder-Backup fehlt beim Restore.'; - return false; - } - if (!@rename($backup, $resolved)) - { - $detail = 'Placeholder konnte nicht restauriert werden.'; - return false; - } - clearstatcache(true, $resolved); - if (!is_file($resolved) || filesize($resolved) < 1) - { - $detail = 'Restaurierter Placeholder ist nicht lesbar.'; - return false; - } - return true; -} - -function bratonien_tools_warmup_process_image(array $image, $temp_file, array $credentials, $stage, array $settings) -{ - $image_row = $image['row']; - $image_id = (int)$image_row['id']; - - $source = bratonien_tools_webdav_materialize_source_info($image_id); - if (!$source || (int)$source['connection_id'] !== (int)$credentials['connection']['id']) - { - return array('ok'=>false, 'fatal'=>false, 'message'=>'Quellzuordnung hat sich seit Batchbeginn geändert.'); - } - - $image_lock = null; - if (!bratonien_tools_warmup_source_lock($image_id, $image_lock)) - { - return array('ok'=>false, 'fatal'=>false, 'message'=>'Bild-Lock konnte nicht gesetzt werden.'); - } - - $sync_lock = null; - $detail = ''; - if (!bratonien_tools_warmup_acquire_sync_guard($credentials, $sync_lock, $detail)) - { - bratonien_tools_warmup_release_lock($image_lock); - return array('ok'=>false, 'fatal'=>false, 'defer'=>true, 'message'=>$detail); - } - - $logical = null; - $resolved = null; - if (!bratonien_tools_warmup_validate_source($image_row, $source, $temp_file, $resolved, $logical, $detail)) - { - bratonien_tools_warmup_release_lock($sync_lock); - bratonien_tools_warmup_release_lock($image_lock); - return array('ok'=>false, 'fatal'=>false, 'message'=>$detail); - } - - $variants = bratonien_tools_warmup_variants_for_stage($image_row, $stage); - $pending = array(); - foreach ($variants as $variant) - { - $target = $variant['derivative']->get_path(); - if ($target !== '' && is_file($target) && is_readable($target)) continue; - $url = bratonien_tools_warmup_i_url($target, $settings['piwigo_base_url']); - if ($url !== null) $pending[] = array('name'=>$variant['name'], 'target'=>$target, 'url'=>$url); - } - - if (!$pending) - { - bratonien_tools_warmup_release_lock($sync_lock); - bratonien_tools_warmup_release_lock($image_lock); - return array('ok'=>true, 'generated'=>0, 'message'=>'Alle Derivate der Stufe bereits vorhanden.'); - } - - $request_id = substr(bin2hex(random_bytes(8)), 0, 8); - $backup = $resolved.'.bratonien-placeholder-'.$request_id; - $staging = $logical.'.bratonien-source-'.$request_id; - @unlink($backup); - @unlink($staging); - - if (!@copy($temp_file, $staging)) - { - bratonien_tools_warmup_release_lock($sync_lock); - bratonien_tools_warmup_release_lock($image_lock); - return array('ok'=>false, 'fatal'=>false, 'message'=>'Batch-Quelle konnte nicht am Piwigo-Pfad bereitgestellt werden.'); - } - - $swapped = false; - $generated = 0; - try - { - if (!@rename($resolved, $backup)) throw new RuntimeException('Placeholder konnte nicht gesichert werden.'); - if (!@rename($staging, $resolved)) - { - @rename($backup, $resolved); - throw new RuntimeException('Temporäre Quelle konnte nicht eingesetzt werden.'); - } - $swapped = true; - clearstatcache(true, $resolved); - if (@getimagesize($resolved) === false) throw new RuntimeException('Temporäre Quelle ist am Piwigo-Pfad nicht als Bild lesbar.'); - - foreach ($pending as $variant) - { - $call_detail = ''; - if (!bratonien_tools_warmup_call_piwigo($variant['url'], $call_detail)) - { - throw new RuntimeException($variant['name'].': '.$call_detail); - } - clearstatcache(true, $variant['target']); - if (!is_file($variant['target']) || !is_readable($variant['target'])) - { - throw new RuntimeException($variant['name'].': Piwigo hat kein Cache-Derivat erzeugt.'); - } - $generated++; - } - } - catch (Throwable $e) - { - $restore_detail = ''; - $restored = $swapped ? bratonien_tools_warmup_restore_placeholder($resolved, $backup, $staging, $restore_detail) : true; - if (!$swapped) @unlink($staging); - bratonien_tools_warmup_release_lock($sync_lock); - bratonien_tools_warmup_release_lock($image_lock); - if (!$restored) - { - return array('ok'=>false, 'fatal'=>true, 'message'=>$e->getMessage().' Restore fehlgeschlagen: '.$restore_detail); - } - return array('ok'=>false, 'fatal'=>false, 'message'=>$e->getMessage()); - } - - $restore_detail = ''; - $restored = bratonien_tools_warmup_restore_placeholder($resolved, $backup, $staging, $restore_detail); - bratonien_tools_warmup_release_lock($sync_lock); - bratonien_tools_warmup_release_lock($image_lock); - if (!$restored) - { - return array('ok'=>false, 'fatal'=>true, 'message'=>$restore_detail); - } - - return array('ok'=>true, 'generated'=>$generated, 'message'=>'Piwigo-Derivate erzeugt.'); -} - -function bratonien_tools_warmup_run($connection_id, $mode) -{ - $settings = bratonien_tools_get_webdav_warmup_settings(); - if (empty($settings['enabled'])) - { - bratonien_tools_warmup_log('disabled', array('connection_id'=>$connection_id)); - return 0; - } - - $credentials = bratonien_tools_warmup_connection_credentials($connection_id); - if (!$credentials) throw new RuntimeException('WebDAV-Verbindung oder Zugangsdaten konnten nicht geladen werden.'); - - $state = bratonien_tools_warmup_load_state($connection_id); - $scan = bratonien_tools_warmup_scan_connection($connection_id); - $selection = bratonien_tools_warmup_select_ids($scan, $state, $mode); - $selected = $selection['images']; - - bratonien_tools_warmup_log('scan', array( - 'connection_id'=>$connection_id, - 'mode'=>$mode, - 'albums'=>count($scan['albums']), - 'new_albums'=>count($selection['new_albums']), - 'images'=>count($scan['images']), - 'selected'=>count($selected), - 'batch_size'=>$settings['batch_size'], - )); - - if (!$selected) - { - foreach ($scan['albums'] as $category_id) $state['albums'][(string)$category_id] = array('seen_at'=>time()); - bratonien_tools_warmup_save_state($connection_id, $state); - return 0; - } - - $temp_root = PHPWG_ROOT_PATH.'upload/bratonien-webdav-warmup'; - if (!is_dir($temp_root) && !@mkdir($temp_root, 0775, true) && !is_dir($temp_root)) throw new RuntimeException('Warmup-Temp-Verzeichnis konnte nicht angelegt werden.'); - - $successful = array(); - $failed = 0; - $ids = array_keys($selected); - $batch_number = 0; - - foreach (array_chunk($ids, max(1, (int)$settings['batch_size'])) as $batch_ids) - { - $batch_number++; - $batch_dir = $temp_root.'/connection-'.(int)$connection_id.'-'.date('YmdHis').'-'.bin2hex(random_bytes(4)); - if (!@mkdir($batch_dir, 0775, true) && !is_dir($batch_dir)) throw new RuntimeException('Batch-Verzeichnis konnte nicht angelegt werden.'); - - $downloaded = array(); - foreach ($batch_ids as $image_id) - { - $image = $selected[$image_id]; - $source = $image['source']; - $temp_file = $batch_dir.'/image-'.(int)$image_id.'.img'; - $detail = ''; - if (bratonien_tools_warmup_download($source, $credentials, $temp_file, $detail)) - { - $downloaded[$image_id] = $temp_file; - } - else - { - $failed++; - bratonien_tools_warmup_log('download_failed', array('image_id'=>$image_id, 'detail'=>$detail)); - } - } - - bratonien_tools_warmup_log('batch_downloaded', array('batch'=>$batch_number, 'requested'=>count($batch_ids), 'downloaded'=>count($downloaded))); - - foreach (array(1, 2) as $stage) - { - foreach ($downloaded as $image_id => $temp_file) - { - $result = bratonien_tools_warmup_process_image($selected[$image_id], $temp_file, $credentials, $stage, $settings); - bratonien_tools_warmup_log('image_stage', array( - 'batch'=>$batch_number, - 'stage'=>$stage, - 'image_id'=>$image_id, - 'ok'=>!empty($result['ok']), - 'generated'=>(int)($result['generated'] ?? 0), - 'message'=>(string)($result['message'] ?? ''), - )); - if (!empty($result['fatal'])) - { - throw new RuntimeException('Sicherheitsabbruch bei Bild #'.$image_id.': '.(string)$result['message']); - } - if (empty($result['ok'])) - { - $failed++; - continue; - } - if ($stage === 2) $successful[$image_id] = true; - } - } - - foreach ($downloaded as $temp_file) @unlink($temp_file); - @rmdir($batch_dir); - } - - foreach ($scan['albums'] as $category_id) $state['albums'][(string)$category_id] = array('seen_at'=>time()); - foreach ($successful as $image_id => $true) - { - if (!isset($scan['images'][$image_id])) continue; - $state['images'][(string)$image_id] = array( - 'signature'=>bratonien_tools_warmup_signature($scan['images'][$image_id]['source']), - 'completed_at'=>time(), - ); - } - bratonien_tools_warmup_save_state($connection_id, $state); - - bratonien_tools_warmup_log('complete', array('connection_id'=>$connection_id, 'successful'=>count($successful), 'failed'=>$failed)); - return $failed > 0 ? 2 : 0; -} - -$connection_id = 0; -$mode = 'periodic'; -foreach ($argv as $arg) -{ - if (preg_match('/^--connection-id=(\d+)$/', $arg, $m)) $connection_id = (int)$m[1]; - elseif (preg_match('/^--mode=(sync|periodic|manual)$/', $arg, $m)) $mode = $m[1]; -} -if ($connection_id < 1) -{ - fwrite(STDERR, "--connection-id fehlt oder ist ungültig.\n"); - exit(1); -} - -try -{ - exit(bratonien_tools_warmup_run($connection_id, $mode)); -} -catch (Throwable $e) -{ - fwrite(STDERR, '[BRAT-WARMUP] fatal '.$e->getMessage()."\n"); - exit(1); -}