mirror of
https://github.com/Terranom674/Piwigo_Bratonien_Tools.git
synced 2026-09-20 14:33:19 +00:00
Compare commits
15 Commits
4e99b42620
...
e8e845e039
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e8e845e039 | ||
|
|
3753ceb20a | ||
|
|
e64257eeca | ||
|
|
81b0366609 | ||
|
|
ee37484dd2 | ||
|
|
da6e9f18d5 | ||
|
|
cce4984ed1 | ||
|
|
b1efa5ca4e | ||
|
|
78dc8a0ad7 | ||
|
|
8c54f8c97d | ||
|
|
1c19760643 | ||
|
|
cf49026f68 | ||
|
|
23d4d1f781 | ||
|
|
d61e239a24 | ||
|
|
0a052ba770 |
15
admin.php
15
admin.php
@@ -78,9 +78,21 @@ $nc_connector = bratonien_tools_nc_connector_status();
|
||||
foreach ($nc_connector['connections'] as &$nc_connection)
|
||||
{
|
||||
$nc_connection['last_sync'] = bratonien_tools_nc_connector_connection_last_status($nc_connection);
|
||||
$nc_connection['display_name'] = $nc_connection['name'];
|
||||
|
||||
$storage_lines = array();
|
||||
$storages = isset($nc_connection['config']['storages']) && is_array($nc_connection['config']['storages'])
|
||||
? $nc_connection['config']['storages']
|
||||
: array();
|
||||
foreach ($storages as $storage)
|
||||
{
|
||||
$storage_lines[] = (string)($storage['storage_id'] ?? '').' | '.(string)($storage['source_prefix'] ?? '').' | '.(string)($storage['local_mount'] ?? '');
|
||||
}
|
||||
$nc_connection['storage_text'] = implode("\n", $storage_lines);
|
||||
|
||||
if (!empty($nc_connection['fallback_stored']))
|
||||
{
|
||||
$nc_connection['name'] .= ' · Fallback gespeichert';
|
||||
$nc_connection['display_name'] .= ' · Fallback gespeichert';
|
||||
$nc_connection['verification_checks'][] = array(
|
||||
'name' => 'Piwigo-Fallback',
|
||||
'ok' => true,
|
||||
@@ -90,6 +102,7 @@ foreach ($nc_connector['connections'] as &$nc_connection)
|
||||
}
|
||||
unset($nc_connection);
|
||||
$nc_connector['piwigo_api_test'] = $nc_piwigo_api_test;
|
||||
$nc_connector['wizard'] = bratonien_tools_nc_wizard_state();
|
||||
$nc_system_defaults = array(
|
||||
'timer_name' => 'bratonien-nc-connector.timer',
|
||||
'timer_active' => false,
|
||||
|
||||
@@ -45,6 +45,15 @@ function bratonien_tools_nc_connector_create_local_api_first()
|
||||
}
|
||||
|
||||
$gallery_root = rtrim(trim((string)$_POST['nc_gallery_root']), '/');
|
||||
if (strpos($gallery_root, './') === 0)
|
||||
{
|
||||
$piwigo_root = realpath(PHPWG_ROOT_PATH);
|
||||
if ($piwigo_root === false)
|
||||
{
|
||||
throw new RuntimeException('Piwigo-Stammverzeichnis konnte nicht aufgelöst werden.');
|
||||
}
|
||||
$gallery_root = rtrim($piwigo_root, '/').'/'.ltrim(substr($gallery_root, 2), '/');
|
||||
}
|
||||
if ($gallery_root === '' || $gallery_root[0] !== '/')
|
||||
{
|
||||
throw new RuntimeException('Der Galerie-Pfad muss ein absoluter Pfad sein.');
|
||||
@@ -68,6 +77,21 @@ function bratonien_tools_nc_connector_create_local_api_first()
|
||||
'piwigo_auth' => 'api-first',
|
||||
);
|
||||
|
||||
foreach (array(
|
||||
'nextcloud_url' => 'nc_nextcloud_url',
|
||||
'showcase_user' => 'nc_showcase_user',
|
||||
'nextcloud_access_user' => 'nc_access_user',
|
||||
'nextcloud_product' => 'nc_product',
|
||||
'nextcloud_version' => 'nc_version',
|
||||
) as $config_key => $post_key)
|
||||
{
|
||||
$value = trim((string)($_POST[$post_key] ?? ''));
|
||||
if ($value !== '')
|
||||
{
|
||||
$config[$config_key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
bratonien_tools_nc_connector_view_name($config['source_view']);
|
||||
bratonien_tools_nc_connector_view_name($config['activity_view']);
|
||||
|
||||
|
||||
694
include/nc_connector_wizard.inc.php
Normal file
694
include/nc_connector_wizard.inc.php
Normal file
@@ -0,0 +1,694 @@
|
||||
<?php
|
||||
if (!defined('PHPWG_ROOT_PATH'))
|
||||
{
|
||||
die('Hacking attempt!');
|
||||
}
|
||||
|
||||
function bratonien_tools_nc_wizard_state()
|
||||
{
|
||||
$state = isset($_SESSION['bratonien_nc_wizard']) && is_array($_SESSION['bratonien_nc_wizard'])
|
||||
? $_SESSION['bratonien_nc_wizard']
|
||||
: array();
|
||||
|
||||
return array_merge(array(
|
||||
'step' => 1,
|
||||
'scan_ok' => false,
|
||||
'base_url' => '',
|
||||
'host_input' => '',
|
||||
'username' => '',
|
||||
'display_name' => '',
|
||||
'version' => '',
|
||||
'product' => 'Nextcloud',
|
||||
'users' => array(),
|
||||
'can_list_users' => false,
|
||||
'showcase_user' => '',
|
||||
'connection_name' => '',
|
||||
'scan_message' => '',
|
||||
'technical_source' => '',
|
||||
'technical_complete' => false,
|
||||
'db_host' => '',
|
||||
'db_port' => '5432',
|
||||
'db_database' => 'nextcloud',
|
||||
'db_user' => '',
|
||||
'db_password_set' => false,
|
||||
'source_view' => 'piwigo_showcase_sources',
|
||||
'activity_view' => 'piwigo_showcase_activity',
|
||||
'gallery_root' => '',
|
||||
'storages' => array(),
|
||||
'storage_candidates' => array(),
|
||||
'api_status' => 'pending',
|
||||
'api_username' => '',
|
||||
'api_error' => '',
|
||||
), $state);
|
||||
}
|
||||
|
||||
function bratonien_tools_nc_wizard_store(array $state)
|
||||
{
|
||||
$_SESSION['bratonien_nc_wizard'] = $state;
|
||||
}
|
||||
|
||||
function bratonien_tools_nc_wizard_reset()
|
||||
{
|
||||
unset($_SESSION['bratonien_nc_wizard']);
|
||||
return array('message'=>'Verbindungsassistent wurde zurückgesetzt.');
|
||||
}
|
||||
|
||||
function bratonien_tools_nc_wizard_normalize_url($host)
|
||||
{
|
||||
$host = trim((string)$host);
|
||||
if ($host === '')
|
||||
{
|
||||
throw new RuntimeException('Nextcloud-Host fehlt.');
|
||||
}
|
||||
|
||||
if (!preg_match('#^https?://#i', $host))
|
||||
{
|
||||
$host = 'https://'.$host;
|
||||
}
|
||||
|
||||
$parts = parse_url($host);
|
||||
if (!is_array($parts) || empty($parts['host']))
|
||||
{
|
||||
throw new RuntimeException('Nextcloud-Host ist ungültig.');
|
||||
}
|
||||
|
||||
$scheme = strtolower((string)($parts['scheme'] ?? 'https'));
|
||||
if (!in_array($scheme, array('http','https'), true))
|
||||
{
|
||||
throw new RuntimeException('Nextcloud muss per HTTP oder HTTPS erreichbar sein.');
|
||||
}
|
||||
|
||||
$url = $scheme.'://'.$parts['host'];
|
||||
if (!empty($parts['port']))
|
||||
{
|
||||
$url .= ':'.(int)$parts['port'];
|
||||
}
|
||||
if (!empty($parts['path']) && $parts['path'] !== '/')
|
||||
{
|
||||
$url .= '/'.trim($parts['path'], '/');
|
||||
}
|
||||
|
||||
return rtrim($url, '/');
|
||||
}
|
||||
|
||||
function bratonien_tools_nc_wizard_http($url, $username = '', $password = '', array $headers = array())
|
||||
{
|
||||
if (!function_exists('curl_init'))
|
||||
{
|
||||
throw new RuntimeException('cURL ist in PHP nicht verfügbar. Der Nextcloud-Scan kann nicht ausgeführt werden.');
|
||||
}
|
||||
|
||||
$ch = curl_init($url);
|
||||
$http_headers = array_merge(array('Accept: application/json'), $headers);
|
||||
$options = array(
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_FOLLOWLOCATION => true,
|
||||
CURLOPT_MAXREDIRS => 3,
|
||||
CURLOPT_CONNECTTIMEOUT => 8,
|
||||
CURLOPT_TIMEOUT => 15,
|
||||
CURLOPT_HTTPHEADER => $http_headers,
|
||||
CURLOPT_USERAGENT => 'Bratonien-Tools-NC-Wizard/'.(function_exists('bratonien_tools_current_version') ? bratonien_tools_current_version() : 'dev'),
|
||||
);
|
||||
if ($username !== '')
|
||||
{
|
||||
$options[CURLOPT_HTTPAUTH] = CURLAUTH_BASIC;
|
||||
$options[CURLOPT_USERPWD] = $username.':'.$password;
|
||||
}
|
||||
curl_setopt_array($ch, $options);
|
||||
|
||||
$body = curl_exec($ch);
|
||||
$errno = curl_errno($ch);
|
||||
$error = curl_error($ch);
|
||||
$status = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
curl_close($ch);
|
||||
|
||||
if ($body === false || $errno !== 0)
|
||||
{
|
||||
throw new RuntimeException('Nextcloud konnte nicht erreicht werden: '.$error);
|
||||
}
|
||||
|
||||
return array('status'=>$status, 'body'=>(string)$body);
|
||||
}
|
||||
|
||||
function bratonien_tools_nc_wizard_ocs_data($body)
|
||||
{
|
||||
$decoded = json_decode((string)$body, true);
|
||||
if (!is_array($decoded))
|
||||
{
|
||||
throw new RuntimeException('Nextcloud hat keine gültige JSON-Antwort geliefert.');
|
||||
}
|
||||
|
||||
if (isset($decoded['ocs']['meta']['statuscode']) && (int)$decoded['ocs']['meta']['statuscode'] !== 100)
|
||||
{
|
||||
$message = (string)($decoded['ocs']['meta']['message'] ?? 'Nextcloud hat die Anfrage abgelehnt.');
|
||||
throw new RuntimeException($message);
|
||||
}
|
||||
|
||||
return isset($decoded['ocs']['data']) && is_array($decoded['ocs']['data']) ? $decoded['ocs']['data'] : array();
|
||||
}
|
||||
|
||||
function bratonien_tools_nc_wizard_fill_profile(array &$state)
|
||||
{
|
||||
$url_host = strtolower((string)parse_url($state['base_url'], PHP_URL_HOST));
|
||||
$state['db_host'] = $url_host;
|
||||
$state['db_port'] = '5432';
|
||||
$state['db_database'] = 'nextcloud';
|
||||
$state['source_view'] = 'piwigo_showcase_sources';
|
||||
$state['activity_view'] = 'piwigo_showcase_activity';
|
||||
$state['gallery_root'] = rtrim(PHPWG_ROOT_PATH, '/').'/galleries/nextcloud';
|
||||
$state['technical_source'] = 'Standardwerte vorbereitet';
|
||||
|
||||
foreach (bratonien_tools_nc_connector_connections() as $candidate)
|
||||
{
|
||||
$config = isset($candidate['config']) && is_array($candidate['config']) ? $candidate['config'] : array();
|
||||
$candidate_url = trim((string)($config['nextcloud_url'] ?? ''));
|
||||
$candidate_host = strtolower(trim((string)($config['host'] ?? '')));
|
||||
$match = false;
|
||||
|
||||
if ($candidate_url !== '')
|
||||
{
|
||||
try
|
||||
{
|
||||
$match = bratonien_tools_nc_wizard_normalize_url($candidate_url) === $state['base_url'];
|
||||
}
|
||||
catch (Throwable $ignored)
|
||||
{
|
||||
$match = false;
|
||||
}
|
||||
}
|
||||
if (!$match && $candidate_host !== '' && $candidate_host === $url_host)
|
||||
{
|
||||
$match = true;
|
||||
}
|
||||
if (!$match)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$full = bratonien_tools_nc_connector_connection((int)$candidate['id'], true);
|
||||
if (!$full)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
$credentials = bratonien_tools_nc_connector_credentials_from_blob($full['secret_blob'] ?? '');
|
||||
|
||||
$state['db_host'] = (string)($config['host'] ?? $state['db_host']);
|
||||
$state['db_port'] = (string)($config['port'] ?? $state['db_port']);
|
||||
$state['db_database'] = (string)($config['database'] ?? $state['db_database']);
|
||||
$state['db_user'] = (string)($config['user'] ?? '');
|
||||
$state['_db_password'] = (string)($credentials['db_password'] ?? '');
|
||||
$state['db_password_set'] = $state['_db_password'] !== '';
|
||||
$state['source_view'] = (string)($config['source_view'] ?? $state['source_view']);
|
||||
$state['activity_view'] = (string)($config['activity_view'] ?? $state['activity_view']);
|
||||
$state['gallery_root'] = (string)($config['gallery_root'] ?? $state['gallery_root']);
|
||||
$state['storages'] = isset($config['storages']) && is_array($config['storages']) ? $config['storages'] : array();
|
||||
$state['technical_source'] = 'Passende vorhandene Connector-Konfiguration erkannt';
|
||||
break;
|
||||
}
|
||||
|
||||
$state['technical_complete'] = $state['db_host'] !== ''
|
||||
&& $state['db_port'] !== ''
|
||||
&& $state['db_database'] !== ''
|
||||
&& $state['db_user'] !== ''
|
||||
&& !empty($state['db_password_set'])
|
||||
&& $state['source_view'] !== ''
|
||||
&& $state['activity_view'] !== ''
|
||||
&& $state['gallery_root'] !== ''
|
||||
&& !empty($state['storages']);
|
||||
}
|
||||
|
||||
function bratonien_tools_nc_wizard_scan()
|
||||
{
|
||||
$host_input = trim((string)($_POST['nc_wizard_host'] ?? ''));
|
||||
$username = trim((string)($_POST['nc_wizard_user'] ?? ''));
|
||||
$password = (string)($_POST['nc_wizard_password'] ?? '');
|
||||
if ($username === '' || $password === '')
|
||||
{
|
||||
throw new RuntimeException('Nextcloud-Benutzer und Passwort werden für den Scan benötigt.');
|
||||
}
|
||||
|
||||
$base_url = bratonien_tools_nc_wizard_normalize_url($host_input);
|
||||
$status_response = bratonien_tools_nc_wizard_http($base_url.'/status.php');
|
||||
if ($status_response['status'] < 200 || $status_response['status'] >= 300)
|
||||
{
|
||||
throw new RuntimeException('Unter diesem Host wurde keine erreichbare Nextcloud-Instanz erkannt (HTTP '.$status_response['status'].').');
|
||||
}
|
||||
$status_data = json_decode($status_response['body'], true);
|
||||
if (!is_array($status_data) || empty($status_data['installed']))
|
||||
{
|
||||
throw new RuntimeException('Der Host antwortet, wurde aber nicht als installierte Nextcloud-Instanz erkannt.');
|
||||
}
|
||||
|
||||
$user_response = bratonien_tools_nc_wizard_http(
|
||||
$base_url.'/ocs/v2.php/cloud/user?format=json',
|
||||
$username,
|
||||
$password,
|
||||
array('OCS-APIRequest: true')
|
||||
);
|
||||
if ($user_response['status'] === 401 || $user_response['status'] === 403)
|
||||
{
|
||||
throw new RuntimeException('Nextcloud hat Benutzername oder Passwort abgelehnt.');
|
||||
}
|
||||
if ($user_response['status'] < 200 || $user_response['status'] >= 300)
|
||||
{
|
||||
throw new RuntimeException('Nextcloud-Benutzerprüfung ist fehlgeschlagen (HTTP '.$user_response['status'].').');
|
||||
}
|
||||
$user_data = bratonien_tools_nc_wizard_ocs_data($user_response['body']);
|
||||
|
||||
$users = array();
|
||||
$can_list_users = false;
|
||||
try
|
||||
{
|
||||
$users_response = bratonien_tools_nc_wizard_http(
|
||||
$base_url.'/ocs/v2.php/cloud/users?format=json',
|
||||
$username,
|
||||
$password,
|
||||
array('OCS-APIRequest: true')
|
||||
);
|
||||
if ($users_response['status'] >= 200 && $users_response['status'] < 300)
|
||||
{
|
||||
$users_data = bratonien_tools_nc_wizard_ocs_data($users_response['body']);
|
||||
if (isset($users_data['users']) && is_array($users_data['users']))
|
||||
{
|
||||
$users = array_values(array_filter(array_map('strval', $users_data['users'])));
|
||||
sort($users, SORT_NATURAL | SORT_FLAG_CASE);
|
||||
$can_list_users = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Throwable $ignored)
|
||||
{
|
||||
$users = array();
|
||||
$can_list_users = false;
|
||||
}
|
||||
|
||||
$url_host = (string)parse_url($base_url, PHP_URL_HOST);
|
||||
$state = array(
|
||||
'step' => 2,
|
||||
'scan_ok' => true,
|
||||
'base_url' => $base_url,
|
||||
'host_input' => $host_input,
|
||||
'username' => (string)($user_data['id'] ?? $username),
|
||||
'display_name' => (string)($user_data['display-name'] ?? $user_data['displayname'] ?? ''),
|
||||
'version' => (string)($status_data['versionstring'] ?? $status_data['version'] ?? ''),
|
||||
'product' => (string)($status_data['productname'] ?? 'Nextcloud'),
|
||||
'users' => $users,
|
||||
'can_list_users' => $can_list_users,
|
||||
'showcase_user' => '',
|
||||
'connection_name' => $url_host !== '' ? $url_host : 'Nextcloud',
|
||||
'scan_message' => 'Nextcloud wurde erkannt und der Benutzerzugriff wurde bestätigt.',
|
||||
'_password' => $password,
|
||||
'api_status' => 'pending',
|
||||
'api_username' => '',
|
||||
'api_error' => '',
|
||||
);
|
||||
bratonien_tools_nc_wizard_fill_profile($state);
|
||||
bratonien_tools_nc_wizard_store($state);
|
||||
|
||||
return array('message'=>'Nextcloud-Scan erfolgreich. Erkannte Werte wurden übernommen; fehlende Angaben werden jetzt gezielt abgefragt.');
|
||||
}
|
||||
|
||||
function bratonien_tools_nc_wizard_save_technical()
|
||||
{
|
||||
$state = bratonien_tools_nc_wizard_state();
|
||||
if (empty($state['scan_ok']))
|
||||
{
|
||||
throw new RuntimeException('Bitte zuerst Nextcloud erfolgreich scannen.');
|
||||
}
|
||||
|
||||
$state['connection_name'] = trim((string)($_POST['nc_wizard_connection_name'] ?? $state['connection_name']));
|
||||
$state['db_host'] = trim((string)($_POST['nc_wizard_db_host'] ?? $state['db_host']));
|
||||
$state['db_port'] = (string)max(1, min(65535, (int)($_POST['nc_wizard_db_port'] ?? $state['db_port'])));
|
||||
$state['db_database'] = trim((string)($_POST['nc_wizard_db_database'] ?? $state['db_database']));
|
||||
$state['db_user'] = trim((string)($_POST['nc_wizard_db_user'] ?? $state['db_user']));
|
||||
$db_password = (string)($_POST['nc_wizard_db_password'] ?? '');
|
||||
if ($db_password !== '')
|
||||
{
|
||||
$state['_db_password'] = $db_password;
|
||||
$state['db_password_set'] = true;
|
||||
}
|
||||
|
||||
if ($state['connection_name'] === '' || $state['db_host'] === '' || $state['db_database'] === '' || $state['db_user'] === '' || empty($state['db_password_set']))
|
||||
{
|
||||
bratonien_tools_nc_wizard_store($state);
|
||||
throw new RuntimeException('Die noch fehlenden Datenbankangaben müssen vollständig angegeben werden.');
|
||||
}
|
||||
|
||||
$config = array(
|
||||
'host'=>$state['db_host'],
|
||||
'port'=>$state['db_port'],
|
||||
'database'=>$state['db_database'],
|
||||
'user'=>$state['db_user'],
|
||||
);
|
||||
$password = (string)($state['_db_password'] ?? '');
|
||||
bratonien_tools_nc_connector_psql($config, $password, 'SELECT 1');
|
||||
|
||||
$source_view = bratonien_tools_nc_connector_view_name($state['source_view']);
|
||||
$activity_view = bratonien_tools_nc_connector_view_name($state['activity_view']);
|
||||
bratonien_tools_nc_connector_psql($config, $password, 'SELECT COUNT(*) FROM '.$source_view);
|
||||
bratonien_tools_nc_connector_psql($config, $password, 'SELECT 1 FROM '.$activity_view.' LIMIT 1');
|
||||
|
||||
$rows = bratonien_tools_nc_connector_psql(
|
||||
$config,
|
||||
$password,
|
||||
"SELECT DISTINCT storage_id::text || E'\\t' || source_path FROM ".$source_view." ORDER BY 1"
|
||||
);
|
||||
$candidates = array();
|
||||
foreach (preg_split('/\r\n|\r|\n/', trim($rows)) as $line)
|
||||
{
|
||||
if ($line === '') continue;
|
||||
$parts = explode("\t", $line, 2);
|
||||
if (count($parts) !== 2) continue;
|
||||
$storage_id = trim($parts[0]);
|
||||
$source_path = trim($parts[1], '/');
|
||||
$prefix = $source_path;
|
||||
if (strpos($source_path, '/') !== false)
|
||||
{
|
||||
$prefix = substr($source_path, 0, strpos($source_path, '/'));
|
||||
}
|
||||
if ($storage_id === '') continue;
|
||||
if (!isset($candidates[$storage_id]))
|
||||
{
|
||||
$candidates[$storage_id] = array('storage_id'=>$storage_id, 'source_prefix'=>$prefix, 'local_mount'=>'');
|
||||
}
|
||||
}
|
||||
|
||||
if (!$candidates)
|
||||
{
|
||||
throw new RuntimeException('Die Source-View ist erreichbar, liefert aber keine Storage-Zuordnung.');
|
||||
}
|
||||
|
||||
$known = array();
|
||||
foreach (bratonien_tools_nc_connector_connections() as $connection)
|
||||
{
|
||||
foreach (($connection['config']['storages'] ?? array()) as $storage)
|
||||
{
|
||||
$key = (string)($storage['storage_id'] ?? '').'|'.(string)($storage['source_prefix'] ?? '');
|
||||
if ($key !== '|') $known[$key] = (string)($storage['local_mount'] ?? '');
|
||||
}
|
||||
}
|
||||
foreach ($candidates as &$candidate)
|
||||
{
|
||||
$key = $candidate['storage_id'].'|'.$candidate['source_prefix'];
|
||||
if (!empty($known[$key]))
|
||||
{
|
||||
$candidate['local_mount'] = $known[$key];
|
||||
}
|
||||
}
|
||||
unset($candidate);
|
||||
|
||||
$state['storage_candidates'] = array_values($candidates);
|
||||
$state['storages'] = array_values(array_filter($state['storage_candidates'], function($storage)
|
||||
{
|
||||
return trim((string)($storage['local_mount'] ?? '')) !== '';
|
||||
}));
|
||||
$state['technical_source'] = 'Datenbank und Views erfolgreich geprüft';
|
||||
$state['technical_complete'] = count($state['storages']) === count($state['storage_candidates']);
|
||||
bratonien_tools_nc_wizard_store($state);
|
||||
|
||||
return array('message'=>$state['technical_complete']
|
||||
? 'Technische Verbindung wurde automatisch vervollständigt.'
|
||||
: 'Datenbank und Views wurden erkannt. Für nicht erkannte Storages wird nur noch der lokale Mount abgefragt.');
|
||||
}
|
||||
|
||||
function bratonien_tools_nc_wizard_save_mounts()
|
||||
{
|
||||
$state = bratonien_tools_nc_wizard_state();
|
||||
$candidates = isset($state['storage_candidates']) && is_array($state['storage_candidates']) ? $state['storage_candidates'] : array();
|
||||
$mounts = isset($_POST['nc_wizard_storage_mount']) && is_array($_POST['nc_wizard_storage_mount']) ? $_POST['nc_wizard_storage_mount'] : array();
|
||||
if (!$candidates)
|
||||
{
|
||||
throw new RuntimeException('Es wurden noch keine Storages erkannt.');
|
||||
}
|
||||
|
||||
$storages = array();
|
||||
foreach ($candidates as $index => $candidate)
|
||||
{
|
||||
$mount = trim((string)($candidate['local_mount'] ?? ''));
|
||||
if ($mount === '')
|
||||
{
|
||||
$mount = trim((string)($mounts[$index] ?? ''));
|
||||
}
|
||||
if ($mount === '' || $mount[0] !== '/')
|
||||
{
|
||||
throw new RuntimeException('Für Storage '.(string)$candidate['storage_id'].' fehlt ein absoluter lokaler Mount-Pfad.');
|
||||
}
|
||||
$mount = rtrim($mount, '/');
|
||||
if (!is_dir($mount) || !is_readable($mount))
|
||||
{
|
||||
throw new RuntimeException('Storage-Mount '.$mount.' ist nicht vorhanden oder nicht lesbar.');
|
||||
}
|
||||
$candidate['local_mount'] = $mount;
|
||||
$storages[] = $candidate;
|
||||
}
|
||||
|
||||
$state['storages'] = $storages;
|
||||
$state['storage_candidates'] = $storages;
|
||||
$state['technical_complete'] = true;
|
||||
bratonien_tools_nc_wizard_store($state);
|
||||
return array('message'=>'Storage-Zuordnung ist vollständig.');
|
||||
}
|
||||
|
||||
function bratonien_tools_nc_wizard_select_user()
|
||||
{
|
||||
$state = bratonien_tools_nc_wizard_state();
|
||||
if (empty($state['scan_ok']))
|
||||
{
|
||||
throw new RuntimeException('Bitte zuerst Nextcloud erfolgreich scannen.');
|
||||
}
|
||||
if (empty($state['technical_complete']))
|
||||
{
|
||||
throw new RuntimeException('Die automatische technische Erkennung ist noch nicht vollständig. Bitte nur die noch fehlenden Angaben ergänzen.');
|
||||
}
|
||||
|
||||
$showcase_user = trim((string)($_POST['nc_wizard_showcase_user'] ?? ''));
|
||||
if ($showcase_user === '')
|
||||
{
|
||||
throw new RuntimeException('Bitte einen Nextcloud-Benutzer für die Showcase-Freigaben auswählen.');
|
||||
}
|
||||
$connection_name = trim((string)($_POST['nc_wizard_connection_name'] ?? $state['connection_name']));
|
||||
if ($connection_name === '')
|
||||
{
|
||||
throw new RuntimeException('Bitte einen Namen für die Verbindung angeben.');
|
||||
}
|
||||
|
||||
$state['connection_name'] = $connection_name;
|
||||
$state['showcase_user'] = $showcase_user;
|
||||
$state['step'] = 3;
|
||||
$state['api_error'] = '';
|
||||
bratonien_tools_nc_wizard_store($state);
|
||||
|
||||
return array('message'=>'Showcase-Benutzer übernommen. Jetzt folgt der Piwigo-API-Zugang.');
|
||||
}
|
||||
|
||||
function bratonien_tools_nc_wizard_api_test()
|
||||
{
|
||||
$state = bratonien_tools_nc_wizard_state();
|
||||
if ((int)$state['step'] !== 3)
|
||||
{
|
||||
throw new RuntimeException('Der API-Test ist in diesem Assistentenschritt nicht verfügbar.');
|
||||
}
|
||||
|
||||
$key_id = trim((string)($_POST['nc_wizard_api_key_id'] ?? ''));
|
||||
$secret = trim((string)($_POST['nc_wizard_api_key_secret'] ?? ''));
|
||||
if ($key_id === '' && $secret === '')
|
||||
{
|
||||
$stored = bratonien_tools_nc_api_credentials();
|
||||
$key_id = trim((string)($stored['key_id'] ?? ''));
|
||||
$secret = trim((string)($stored['key_secret'] ?? ''));
|
||||
}
|
||||
if ($key_id === '' || $secret === '')
|
||||
{
|
||||
throw new RuntimeException('API-Schlüssel-ID und API-Geheimnis fehlen.');
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
$status = bratonien_tools_nc_connector_piwigo_api_request($key_id, $secret, 'pwg.session.getStatus');
|
||||
$user_status = strtolower((string)($status['status'] ?? ''));
|
||||
if (!in_array($user_status, array('admin','webmaster'), true))
|
||||
{
|
||||
throw new RuntimeException('Der API-Key gehört keinem Piwigo-Administrator/Webmaster.');
|
||||
}
|
||||
|
||||
$method_result = bratonien_tools_nc_connector_piwigo_api_request($key_id, $secret, 'reflection.getMethodList');
|
||||
$method_map = array();
|
||||
bratonien_tools_nc_connector_collect_method_names($method_result, $method_map);
|
||||
$missing = array_values(array_diff(array('bratonien.nc.syncProductive','bratonien.nc.syncOrphans'), array_keys($method_map)));
|
||||
if ($missing)
|
||||
{
|
||||
throw new RuntimeException('Benötigte Bratonien-Sync-Methoden fehlen: '.implode(', ', $missing).'.');
|
||||
}
|
||||
|
||||
bratonien_tools_nc_api_credentials_store($key_id, $secret);
|
||||
$state['api_status'] = 'ok';
|
||||
$state['api_username'] = (string)($status['username'] ?? $status['user'] ?? '');
|
||||
$state['api_error'] = '';
|
||||
$state['step'] = 4;
|
||||
bratonien_tools_nc_wizard_store($state);
|
||||
return array('message'=>'Piwigo-API erfolgreich geprüft. Zum Abschluss kann jetzt der Fallback festgelegt werden.');
|
||||
}
|
||||
catch (Throwable $e)
|
||||
{
|
||||
$state['api_status'] = 'error';
|
||||
$state['api_error'] = $e->getMessage();
|
||||
bratonien_tools_nc_wizard_store($state);
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
function bratonien_tools_nc_wizard_api_skip()
|
||||
{
|
||||
$state = bratonien_tools_nc_wizard_state();
|
||||
if ((int)$state['step'] !== 3)
|
||||
{
|
||||
throw new RuntimeException('Die API kann in diesem Assistentenschritt nicht übersprungen werden.');
|
||||
}
|
||||
$state['api_status'] = 'skipped';
|
||||
$state['api_error'] = '';
|
||||
$state['step'] = 4;
|
||||
bratonien_tools_nc_wizard_store($state);
|
||||
return array('message'=>'Piwigo-API wurde übersprungen. Für diese Verbindung ist deshalb ein Fallback-Zugang erforderlich.');
|
||||
}
|
||||
|
||||
function bratonien_tools_nc_wizard_finish()
|
||||
{
|
||||
$state = bratonien_tools_nc_wizard_state();
|
||||
if ((int)$state['step'] !== 4 || empty($state['technical_complete']) || trim((string)$state['showcase_user']) === '')
|
||||
{
|
||||
throw new RuntimeException('Der Assistent ist noch nicht vollständig.');
|
||||
}
|
||||
|
||||
$fallback_user = trim((string)($_POST['nc_wizard_fallback_user'] ?? ''));
|
||||
$fallback_password = (string)($_POST['nc_wizard_fallback_password'] ?? '');
|
||||
if (($fallback_user === '') !== ($fallback_password === ''))
|
||||
{
|
||||
throw new RuntimeException('Fallback-Benutzer und Fallback-Passwort müssen entweder beide angegeben oder beide leer gelassen werden.');
|
||||
}
|
||||
if ($state['api_status'] !== 'ok' && $fallback_user === '')
|
||||
{
|
||||
throw new RuntimeException('Da die Piwigo-API übersprungen wurde, ist ein Fallback-Zugang erforderlich.');
|
||||
}
|
||||
|
||||
$storage_lines = array();
|
||||
foreach ($state['storages'] as $storage)
|
||||
{
|
||||
$storage_lines[] = (string)$storage['storage_id'].' | '.(string)$storage['source_prefix'].' | '.(string)$storage['local_mount'];
|
||||
}
|
||||
|
||||
$_POST['nc_name'] = (string)$state['connection_name'];
|
||||
$_POST['nc_host'] = (string)$state['db_host'];
|
||||
$_POST['nc_port'] = (string)$state['db_port'];
|
||||
$_POST['nc_database'] = (string)$state['db_database'];
|
||||
$_POST['nc_user'] = (string)$state['db_user'];
|
||||
$_POST['nc_db_password'] = (string)($state['_db_password'] ?? '');
|
||||
$_POST['nc_source_view'] = (string)$state['source_view'];
|
||||
$_POST['nc_activity_view'] = (string)$state['activity_view'];
|
||||
$_POST['nc_gallery_root'] = (string)$state['gallery_root'];
|
||||
$_POST['nc_storages'] = implode("\n", $storage_lines);
|
||||
$_POST['nc_quiet_seconds'] = '120';
|
||||
$_POST['nc_max_wait_seconds'] = '900';
|
||||
$_POST['nc_full_sync_seconds'] = '86400';
|
||||
$_POST['nc_piwigo_user'] = $fallback_user;
|
||||
$_POST['nc_piwigo_password'] = $fallback_password;
|
||||
$_POST['nc_nextcloud_url'] = (string)$state['base_url'];
|
||||
$_POST['nc_showcase_user'] = (string)$state['showcase_user'];
|
||||
$_POST['nc_access_user'] = (string)$state['username'];
|
||||
$_POST['nc_product'] = (string)$state['product'];
|
||||
$_POST['nc_version'] = (string)$state['version'];
|
||||
|
||||
$result = bratonien_tools_nc_connector_create_local_api_first();
|
||||
unset($_SESSION['bratonien_nc_wizard']);
|
||||
$result['message'] = 'Verbindung wurde vollständig durch den Assistenten angelegt. '.$result['message'];
|
||||
return $result;
|
||||
}
|
||||
|
||||
function bratonien_tools_nc_connector_update_name()
|
||||
{
|
||||
$id = (int)($_POST['connection_id'] ?? 0);
|
||||
$name = trim((string)($_POST['connection_name'] ?? ''));
|
||||
if ($id < 1 || $name === '')
|
||||
{
|
||||
throw new RuntimeException('Verbindung oder Name fehlt.');
|
||||
}
|
||||
|
||||
$connection = bratonien_tools_nc_connector_connection($id, false);
|
||||
if (!$connection)
|
||||
{
|
||||
throw new RuntimeException('Connector-Verbindung wurde nicht gefunden.');
|
||||
}
|
||||
|
||||
$table = bratonien_tools_nc_connector_table();
|
||||
$now = date('Y-m-d H:i:s');
|
||||
pwg_query("UPDATE `$table` SET name='".pwg_db_real_escape_string($name)."', updated='".pwg_db_real_escape_string($now)."' WHERE id=".$id." LIMIT 1");
|
||||
|
||||
return array('message'=>'Verbindungsname wurde aktualisiert.');
|
||||
}
|
||||
|
||||
function bratonien_tools_nc_connector_update_technical()
|
||||
{
|
||||
$id = (int)($_POST['connection_id'] ?? 0);
|
||||
$connection = bratonien_tools_nc_connector_connection($id, true);
|
||||
if (!$connection)
|
||||
{
|
||||
throw new RuntimeException('Connector-Verbindung wurde nicht gefunden.');
|
||||
}
|
||||
if (!empty($connection['enabled']) || (string)$connection['takeover_state'] === 'active')
|
||||
{
|
||||
throw new RuntimeException('Technische Einstellungen einer aktiven Verbindung können nicht geändert werden. Bitte zuerst deaktivieren.');
|
||||
}
|
||||
|
||||
$config = $connection['config'];
|
||||
$port = (int)($_POST['nc_port'] ?? ($config['port'] ?? 5432));
|
||||
if ($port < 1 || $port > 65535)
|
||||
{
|
||||
throw new RuntimeException('Ungültiger PostgreSQL-Port.');
|
||||
}
|
||||
|
||||
$gallery_root = rtrim(trim((string)($_POST['nc_gallery_root'] ?? ($config['gallery_root'] ?? ''))), '/');
|
||||
if ($gallery_root === '' || $gallery_root[0] !== '/')
|
||||
{
|
||||
throw new RuntimeException('Der Galerie-Pfad muss ein absoluter Pfad sein.');
|
||||
}
|
||||
|
||||
$config['host'] = trim((string)($_POST['nc_host'] ?? ($config['host'] ?? '')));
|
||||
$config['port'] = (string)$port;
|
||||
$config['database'] = trim((string)($_POST['nc_database'] ?? ($config['database'] ?? '')));
|
||||
$config['user'] = trim((string)($_POST['nc_user'] ?? ($config['user'] ?? '')));
|
||||
$config['source_view'] = trim((string)($_POST['nc_source_view'] ?? ($config['source_view'] ?? '')));
|
||||
$config['activity_view'] = trim((string)($_POST['nc_activity_view'] ?? ($config['activity_view'] ?? '')));
|
||||
$config['gallery_root'] = $gallery_root;
|
||||
$config['quiet_seconds'] = max(0, (int)($_POST['nc_quiet_seconds'] ?? ($config['quiet_seconds'] ?? 120)));
|
||||
$config['max_wait_seconds'] = max(60, (int)($_POST['nc_max_wait_seconds'] ?? ($config['max_wait_seconds'] ?? 900)));
|
||||
$config['full_sync_seconds'] = max(300, (int)($_POST['nc_full_sync_seconds'] ?? ($config['full_sync_seconds'] ?? 86400)));
|
||||
$config['storages'] = bratonien_tools_nc_connector_parse_storages($_POST['nc_storages'] ?? '');
|
||||
unset($config['verification']);
|
||||
|
||||
bratonien_tools_nc_connector_view_name($config['source_view']);
|
||||
bratonien_tools_nc_connector_view_name($config['activity_view']);
|
||||
|
||||
$credentials = bratonien_tools_nc_connector_credentials_from_blob($connection['secret_blob'] ?? '');
|
||||
$db_password = (string)($_POST['nc_db_password'] ?? '');
|
||||
if ($db_password === '')
|
||||
{
|
||||
$db_password = $credentials['db_password'];
|
||||
}
|
||||
|
||||
$secret_blob = bratonien_tools_nc_connector_encrypt_credentials(
|
||||
$db_password,
|
||||
$credentials['piwigo_user'],
|
||||
$credentials['piwigo_password']
|
||||
);
|
||||
|
||||
$config_json = json_encode($config, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
||||
if (!is_string($config_json))
|
||||
{
|
||||
throw new RuntimeException('Connector-Konfiguration konnte nicht serialisiert werden.');
|
||||
}
|
||||
|
||||
$table = bratonien_tools_nc_connector_table();
|
||||
$now = date('Y-m-d H:i:s');
|
||||
pwg_query("UPDATE `$table` SET takeover_state='disabled', enabled=0, config_json='".pwg_db_real_escape_string($config_json)."', secret_blob='".pwg_db_real_escape_string($secret_blob)."', updated='".pwg_db_real_escape_string($now)."' WHERE id=".$id." LIMIT 1");
|
||||
|
||||
return array('message'=>'Technische Verbindungseinstellungen wurden gespeichert. Die Verbindung muss erneut geprüft werden.');
|
||||
}
|
||||
@@ -14,6 +14,53 @@ function bratonien_tools_current_version()
|
||||
return '0.0.0';
|
||||
}
|
||||
|
||||
function bratonien_tools_self_update_fetch_text($url, &$body, &$details)
|
||||
{
|
||||
$body = '';
|
||||
$details = '';
|
||||
|
||||
if (function_exists('curl_init'))
|
||||
{
|
||||
$ch = curl_init($url);
|
||||
curl_setopt_array($ch, array(
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_FOLLOWLOCATION => true,
|
||||
CURLOPT_MAXREDIRS => 3,
|
||||
CURLOPT_CONNECTTIMEOUT => 10,
|
||||
CURLOPT_TIMEOUT => 20,
|
||||
CURLOPT_USERAGENT => 'Bratonien-Tools-Updater/'.bratonien_tools_current_version(),
|
||||
CURLOPT_HTTPHEADER => array('Accept: application/vnd.github+json, text/plain;q=0.9, */*;q=0.8'),
|
||||
));
|
||||
$response = curl_exec($ch);
|
||||
$errno = curl_errno($ch);
|
||||
$error = curl_error($ch);
|
||||
$http = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
curl_close($ch);
|
||||
|
||||
if ($response === false || $errno !== 0)
|
||||
{
|
||||
$details = 'cURL-Fehler '.$errno.': '.$error;
|
||||
return false;
|
||||
}
|
||||
if ($http < 200 || $http >= 300)
|
||||
{
|
||||
$details = 'HTTP '.$http;
|
||||
return false;
|
||||
}
|
||||
|
||||
$body = (string)$response;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (function_exists('fetchRemote') && fetchRemote($url, $body))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
$details = 'Remote-Inhalt konnte nicht geladen werden.';
|
||||
return false;
|
||||
}
|
||||
|
||||
function bratonien_tools_remote_update_info($force = false)
|
||||
{
|
||||
$cache_key = 'bratonien_self_update_status';
|
||||
@@ -28,28 +75,68 @@ function bratonien_tools_remote_update_info($force = false)
|
||||
}
|
||||
|
||||
$current = bratonien_tools_current_version();
|
||||
$remote_main = '';
|
||||
$ok = function_exists('fetchRemote') && fetchRemote('https://raw.githubusercontent.com/Terranom674/Piwigo_Bratonien_Tools/main/main.inc.php', $remote_main);
|
||||
if (!$ok || !preg_match('/Version:\s*([\w.-]+)/i', (string)$remote_main, $m))
|
||||
$commit_json = '';
|
||||
$details = '';
|
||||
$commit_url = 'https://api.github.com/repos/Terranom674/Piwigo_Bratonien_Tools/commits/main';
|
||||
|
||||
if (!bratonien_tools_self_update_fetch_text($commit_url, $commit_json, $details))
|
||||
{
|
||||
$data = array(
|
||||
'checked_at' => time(),
|
||||
'current' => $current,
|
||||
'remote' => null,
|
||||
'signature' => null,
|
||||
'main_sha256' => null,
|
||||
'update_available' => false,
|
||||
'error' => 'GitHub konnte nicht erreicht oder die Versionsnummer nicht gelesen werden.',
|
||||
'error' => 'GitHub konnte nicht erreicht oder der aktuelle Commit nicht ermittelt werden.'.($details !== '' ? ' Details: '.$details : ''),
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
$remote = trim($m[1]);
|
||||
$data = array(
|
||||
'checked_at' => time(),
|
||||
'current' => $current,
|
||||
'remote' => $remote,
|
||||
'update_available' => version_compare($remote, $current, '>'),
|
||||
'error' => null,
|
||||
);
|
||||
$commit = json_decode($commit_json, true);
|
||||
$signature = is_array($commit) ? strtolower(trim((string)($commit['sha'] ?? ''))) : '';
|
||||
if (!preg_match('/^[a-f0-9]{40}$/', $signature))
|
||||
{
|
||||
$data = array(
|
||||
'checked_at' => time(),
|
||||
'current' => $current,
|
||||
'remote' => null,
|
||||
'signature' => null,
|
||||
'main_sha256' => null,
|
||||
'update_available' => false,
|
||||
'error' => 'GitHub lieferte keine gültige Commit-Signatur für main.',
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
$remote_main = '';
|
||||
$raw_url = 'https://raw.githubusercontent.com/Terranom674/Piwigo_Bratonien_Tools/'.$signature.'/main.inc.php';
|
||||
if (!bratonien_tools_self_update_fetch_text($raw_url, $remote_main, $details) || !preg_match('/Version:\s*([\w.-]+)/i', (string)$remote_main, $m))
|
||||
{
|
||||
$data = array(
|
||||
'checked_at' => time(),
|
||||
'current' => $current,
|
||||
'remote' => null,
|
||||
'signature' => $signature,
|
||||
'main_sha256' => null,
|
||||
'update_available' => false,
|
||||
'error' => 'Die Plugin-Version des ermittelten GitHub-Commits konnte nicht gelesen werden.'.($details !== '' ? ' Details: '.$details : ''),
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
$remote = trim($m[1]);
|
||||
$data = array(
|
||||
'checked_at' => time(),
|
||||
'current' => $current,
|
||||
'remote' => $remote,
|
||||
'signature' => $signature,
|
||||
'main_sha256' => hash('sha256', (string)$remote_main),
|
||||
'update_available' => version_compare($remote, $current, '>'),
|
||||
'error' => null,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (function_exists('conf_update_param'))
|
||||
@@ -72,16 +159,17 @@ function bratonien_tools_self_update_check()
|
||||
throw new RuntimeException($info['error']);
|
||||
}
|
||||
|
||||
$signature_label = !empty($info['signature']) ? substr($info['signature'], 0, 12) : 'unbekannt';
|
||||
if (!empty($info['update_available']))
|
||||
{
|
||||
return array(
|
||||
'message' => 'Update verfügbar: '.$info['current'].' → '.$info['remote'].'.',
|
||||
'message' => 'Update verfügbar: '.$info['current'].' → '.$info['remote'].' · Signatur '.$signature_label.'.',
|
||||
'self_update' => $info,
|
||||
);
|
||||
}
|
||||
|
||||
return array(
|
||||
'message' => 'Bratonien Tools ist aktuell (Version '.$info['current'].').',
|
||||
'message' => 'Bratonien Tools ist aktuell (Version '.$info['current'].', Signatur '.$signature_label.').',
|
||||
'self_update' => $info,
|
||||
);
|
||||
}
|
||||
@@ -172,6 +260,23 @@ function bratonien_tools_download_update_archive($url, &$data, &$details)
|
||||
return true;
|
||||
}
|
||||
|
||||
function bratonien_tools_self_update_find_source($extract_dir, $signature)
|
||||
{
|
||||
$expected = rtrim($extract_dir, '/').'/Piwigo_Bratonien_Tools-'.$signature;
|
||||
if (is_dir($expected))
|
||||
{
|
||||
return $expected;
|
||||
}
|
||||
|
||||
$candidates = glob(rtrim($extract_dir, '/').'/Piwigo_Bratonien_Tools-*', GLOB_ONLYDIR);
|
||||
if (is_array($candidates) && count($candidates) === 1)
|
||||
{
|
||||
return $candidates[0];
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
function bratonien_tools_self_update_run()
|
||||
{
|
||||
global $template;
|
||||
@@ -202,6 +307,13 @@ function bratonien_tools_self_update_run()
|
||||
);
|
||||
}
|
||||
|
||||
$signature = strtolower(trim((string)($info['signature'] ?? '')));
|
||||
$expected_main_sha256 = strtolower(trim((string)($info['main_sha256'] ?? '')));
|
||||
if (!preg_match('/^[a-f0-9]{40}$/', $signature) || !preg_match('/^[a-f0-9]{64}$/', $expected_main_sha256))
|
||||
{
|
||||
throw new RuntimeException('Update abgebrochen: Version oder Signatur des Zielstands ist unvollständig.');
|
||||
}
|
||||
|
||||
$work_root = rtrim(PHPWG_ROOT_PATH, '/').'/_data/bratonien-updater';
|
||||
if (!is_dir($work_root) && !@mkdir($work_root, 0755, true))
|
||||
{
|
||||
@@ -216,7 +328,7 @@ function bratonien_tools_self_update_run()
|
||||
|
||||
$zip_data = '';
|
||||
$download_details = '';
|
||||
$archive_url = 'https://codeload.github.com/Terranom674/Piwigo_Bratonien_Tools/zip/refs/heads/main';
|
||||
$archive_url = 'https://codeload.github.com/Terranom674/Piwigo_Bratonien_Tools/zip/'.$signature;
|
||||
if (!bratonien_tools_download_update_archive($archive_url, $zip_data, $download_details))
|
||||
{
|
||||
bratonien_tools_self_update_rrmdir($run_dir);
|
||||
@@ -245,12 +357,12 @@ function bratonien_tools_self_update_run()
|
||||
}
|
||||
$zip->close();
|
||||
|
||||
$source = $extract_dir.'/Piwigo_Bratonien_Tools-main';
|
||||
$source_main = $source.'/main.inc.php';
|
||||
if (!is_file($source_main))
|
||||
$source = bratonien_tools_self_update_find_source($extract_dir, $signature);
|
||||
$source_main = $source !== '' ? $source.'/main.inc.php' : '';
|
||||
if ($source === '' || !is_file($source_main))
|
||||
{
|
||||
bratonien_tools_self_update_rrmdir($run_dir);
|
||||
throw new RuntimeException('Das geladene Archiv enthält kein gültiges Bratonien-Tools-Plugin. Erwartet wurde: '.$source_main);
|
||||
throw new RuntimeException('Das geladene Archiv enthält kein gültiges Bratonien-Tools-Plugin für die erwartete Signatur '.substr($signature, 0, 12).'.');
|
||||
}
|
||||
|
||||
$remote_main = @file_get_contents($source_main);
|
||||
@@ -259,11 +371,18 @@ function bratonien_tools_self_update_run()
|
||||
bratonien_tools_self_update_rrmdir($run_dir);
|
||||
throw new RuntimeException('Die geladene Plugin-Version konnte nicht verifiziert werden. main.inc.php fehlt oder enthält keine lesbare Plugin-/Versionsangabe.');
|
||||
}
|
||||
|
||||
$package_version = trim($vm[1]);
|
||||
$package_main_sha256 = hash('sha256', (string)$remote_main);
|
||||
if (!hash_equals($expected_main_sha256, $package_main_sha256))
|
||||
{
|
||||
bratonien_tools_self_update_rrmdir($run_dir);
|
||||
throw new RuntimeException('Signaturprüfung fehlgeschlagen: Das geladene Paket gehört nicht exakt zum zuvor geprüften GitHub-Stand '.substr($signature, 0, 12).'.');
|
||||
}
|
||||
if ($package_version !== $info['remote'])
|
||||
{
|
||||
bratonien_tools_self_update_rrmdir($run_dir);
|
||||
throw new RuntimeException('Versionsprüfung fehlgeschlagen: Erwartet '.$info['remote'].', erhalten '.$package_version.'.');
|
||||
throw new RuntimeException('Versionsprüfung fehlgeschlagen: Erwartet '.$info['remote'].', erhalten '.$package_version.'; Signatur '.substr($signature, 0, 12).'.');
|
||||
}
|
||||
|
||||
$plugin_dir = rtrim(BRATONIEN_TOOLS_PATH, '/');
|
||||
@@ -320,11 +439,13 @@ function bratonien_tools_self_update_run()
|
||||
'checked_at' => time(),
|
||||
'current' => $package_version,
|
||||
'remote' => $package_version,
|
||||
'signature' => $signature,
|
||||
'main_sha256' => $package_main_sha256,
|
||||
'update_available' => false,
|
||||
'error' => null,
|
||||
);
|
||||
return array(
|
||||
'message' => 'Bratonien Tools wurde auf Version '.$package_version.' aktualisiert. Backup: '.$backup_dir,
|
||||
'message' => 'Bratonien Tools wurde auf Version '.$package_version.' aktualisiert. Signatur '.substr($signature, 0, 12).'. Backup: '.$backup_dir,
|
||||
'self_update' => $updated_info,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -21,109 +21,54 @@ require_once(BRATONIEN_TOOLS_PATH . 'include/nc_connector_takeover.inc.php');
|
||||
require_once(BRATONIEN_TOOLS_PATH . 'include/nc_connector_auth.inc.php');
|
||||
require_once(BRATONIEN_TOOLS_PATH . 'include/nc_connector_create_api.inc.php');
|
||||
require_once(BRATONIEN_TOOLS_PATH . 'include/nc_connector_piwigo_api.inc.php');
|
||||
require_once(BRATONIEN_TOOLS_PATH . 'include/nc_connector_wizard.inc.php');
|
||||
|
||||
function bratonien_tools_get_tools()
|
||||
{
|
||||
return array(
|
||||
'image_cache_clear' => array(
|
||||
'handler' => 'bratonien_tools_clear_image_cache',
|
||||
),
|
||||
'image_cache_build' => array(
|
||||
'handler' => 'bratonien_tools_start_main_cache_build',
|
||||
),
|
||||
'image_cache_cancel' => array(
|
||||
'handler' => 'bratonien_tools_cancel_main_cache_build',
|
||||
),
|
||||
'image_cache_worker_settings' => array(
|
||||
'handler' => 'bratonien_tools_save_cache_worker_settings',
|
||||
),
|
||||
'watermark_save' => array(
|
||||
'handler' => 'bratonien_tools_save_watermark',
|
||||
),
|
||||
'watermark_file_delete' => array(
|
||||
'handler' => 'bratonien_tools_delete_watermark_file',
|
||||
),
|
||||
'watermark_engine' => array(
|
||||
'handler' => 'bratonien_tools_handle_watermark_engine',
|
||||
),
|
||||
'watermark_profile_save' => array(
|
||||
'handler' => 'bratonien_tools_save_watermark_profile',
|
||||
),
|
||||
'watermark_profile_delete' => array(
|
||||
'handler' => 'bratonien_tools_delete_watermark_profile',
|
||||
),
|
||||
'watermark_profile_duplicate' => array(
|
||||
'handler' => 'bratonien_tools_duplicate_watermark_profile',
|
||||
),
|
||||
'watermark_defaults' => array(
|
||||
'handler' => 'bratonien_tools_save_watermark_defaults',
|
||||
),
|
||||
'watermark_rule' => array(
|
||||
'handler' => 'bratonien_tools_save_album_rule',
|
||||
),
|
||||
'public_selection_settings' => array(
|
||||
'handler' => 'bratonien_tools_save_public_selection_settings',
|
||||
),
|
||||
'asset_upload' => array(
|
||||
'handler' => 'bratonien_tools_upload_asset',
|
||||
),
|
||||
'asset_delete' => array(
|
||||
'handler' => 'bratonien_tools_delete_asset',
|
||||
),
|
||||
'asset_upload_limits' => array(
|
||||
'handler' => 'bratonien_tools_save_upload_limits',
|
||||
),
|
||||
'album_lock_toggle' => array(
|
||||
'handler' => 'bratonien_tools_toggle_album_lock',
|
||||
),
|
||||
'album_share_create' => array(
|
||||
'handler' => 'bratonien_tools_create_album_share',
|
||||
),
|
||||
'album_share_regenerate_link' => array(
|
||||
'handler' => 'bratonien_tools_regenerate_album_share_link',
|
||||
),
|
||||
'album_share_revoke' => array(
|
||||
'handler' => 'bratonien_tools_revoke_album_share',
|
||||
),
|
||||
'nc_connector_create_local' => array(
|
||||
'handler' => 'bratonien_tools_nc_connector_create_local_api_first',
|
||||
),
|
||||
'nc_connector_delete' => array(
|
||||
'handler' => 'bratonien_tools_nc_connector_delete',
|
||||
),
|
||||
'nc_connector_import_legacy' => array(
|
||||
'handler' => 'bratonien_tools_nc_connector_import_legacy',
|
||||
),
|
||||
'nc_connector_verify' => array(
|
||||
'handler' => 'bratonien_tools_nc_connector_verify_managed',
|
||||
),
|
||||
'nc_connector_prepare_takeover' => array(
|
||||
'handler' => 'bratonien_tools_nc_connector_prepare_takeover',
|
||||
),
|
||||
'nc_connector_cancel_takeover' => array(
|
||||
'handler' => 'bratonien_tools_nc_connector_cancel_takeover',
|
||||
),
|
||||
'nc_connector_piwigo_api_test' => array(
|
||||
'handler' => 'bratonien_tools_nc_connector_piwigo_api_test',
|
||||
),
|
||||
'nc_connector_piwigo_api_delete' => array(
|
||||
'handler' => 'bratonien_tools_nc_connector_api_delete',
|
||||
),
|
||||
'nc_connector_fallback_save' => array(
|
||||
'handler' => 'bratonien_tools_nc_connector_fallback_save',
|
||||
),
|
||||
'nc_connector_fallback_delete' => array(
|
||||
'handler' => 'bratonien_tools_nc_connector_fallback_delete',
|
||||
),
|
||||
'nc_connector_fallback_once' => array(
|
||||
'handler' => 'bratonien_tools_nc_connector_fallback_once',
|
||||
),
|
||||
'self_update_check' => array(
|
||||
'handler' => 'bratonien_tools_self_update_check',
|
||||
),
|
||||
'self_update_run' => array(
|
||||
'handler' => 'bratonien_tools_self_update_run',
|
||||
),
|
||||
'image_cache_clear' => array('handler' => 'bratonien_tools_clear_image_cache'),
|
||||
'image_cache_build' => array('handler' => 'bratonien_tools_start_main_cache_build'),
|
||||
'image_cache_cancel' => array('handler' => 'bratonien_tools_cancel_main_cache_build'),
|
||||
'image_cache_worker_settings' => array('handler' => 'bratonien_tools_save_cache_worker_settings'),
|
||||
'watermark_save' => array('handler' => 'bratonien_tools_save_watermark'),
|
||||
'watermark_file_delete' => array('handler' => 'bratonien_tools_delete_watermark_file'),
|
||||
'watermark_engine' => array('handler' => 'bratonien_tools_handle_watermark_engine'),
|
||||
'watermark_profile_save' => array('handler' => 'bratonien_tools_save_watermark_profile'),
|
||||
'watermark_profile_delete' => array('handler' => 'bratonien_tools_delete_watermark_profile'),
|
||||
'watermark_profile_duplicate' => array('handler' => 'bratonien_tools_duplicate_watermark_profile'),
|
||||
'watermark_defaults' => array('handler' => 'bratonien_tools_save_watermark_defaults'),
|
||||
'watermark_rule' => array('handler' => 'bratonien_tools_save_album_rule'),
|
||||
'public_selection_settings' => array('handler' => 'bratonien_tools_save_public_selection_settings'),
|
||||
'asset_upload' => array('handler' => 'bratonien_tools_upload_asset'),
|
||||
'asset_delete' => array('handler' => 'bratonien_tools_delete_asset'),
|
||||
'asset_upload_limits' => array('handler' => 'bratonien_tools_save_upload_limits'),
|
||||
'album_lock_toggle' => array('handler' => 'bratonien_tools_toggle_album_lock'),
|
||||
'album_share_create' => array('handler' => 'bratonien_tools_create_album_share'),
|
||||
'album_share_regenerate_link' => array('handler' => 'bratonien_tools_regenerate_album_share_link'),
|
||||
'album_share_revoke' => array('handler' => 'bratonien_tools_revoke_album_share'),
|
||||
'nc_connector_create_local' => array('handler' => 'bratonien_tools_nc_connector_create_local_api_first'),
|
||||
'nc_connector_delete' => array('handler' => 'bratonien_tools_nc_connector_delete'),
|
||||
'nc_connector_update_name' => array('handler' => 'bratonien_tools_nc_connector_update_name'),
|
||||
'nc_connector_update_technical' => array('handler' => 'bratonien_tools_nc_connector_update_technical'),
|
||||
'nc_connector_wizard_scan' => array('handler' => 'bratonien_tools_nc_wizard_scan'),
|
||||
'nc_connector_wizard_save_technical' => array('handler' => 'bratonien_tools_nc_wizard_save_technical'),
|
||||
'nc_connector_wizard_save_mounts' => array('handler' => 'bratonien_tools_nc_wizard_save_mounts'),
|
||||
'nc_connector_wizard_select_user' => array('handler' => 'bratonien_tools_nc_wizard_select_user'),
|
||||
'nc_connector_wizard_api_test' => array('handler' => 'bratonien_tools_nc_wizard_api_test'),
|
||||
'nc_connector_wizard_api_skip' => array('handler' => 'bratonien_tools_nc_wizard_api_skip'),
|
||||
'nc_connector_wizard_finish' => array('handler' => 'bratonien_tools_nc_wizard_finish'),
|
||||
'nc_connector_wizard_reset' => array('handler' => 'bratonien_tools_nc_wizard_reset'),
|
||||
'nc_connector_import_legacy' => array('handler' => 'bratonien_tools_nc_connector_import_legacy'),
|
||||
'nc_connector_verify' => array('handler' => 'bratonien_tools_nc_connector_verify_managed'),
|
||||
'nc_connector_prepare_takeover' => array('handler' => 'bratonien_tools_nc_connector_prepare_takeover'),
|
||||
'nc_connector_cancel_takeover' => array('handler' => 'bratonien_tools_nc_connector_cancel_takeover'),
|
||||
'nc_connector_piwigo_api_test' => array('handler' => 'bratonien_tools_nc_connector_piwigo_api_test'),
|
||||
'nc_connector_piwigo_api_delete' => array('handler' => 'bratonien_tools_nc_connector_api_delete'),
|
||||
'nc_connector_fallback_save' => array('handler' => 'bratonien_tools_nc_connector_fallback_save'),
|
||||
'nc_connector_fallback_delete' => array('handler' => 'bratonien_tools_nc_connector_fallback_delete'),
|
||||
'nc_connector_fallback_once' => array('handler' => 'bratonien_tools_nc_connector_fallback_once'),
|
||||
'self_update_check' => array('handler' => 'bratonien_tools_self_update_check'),
|
||||
'self_update_run' => array('handler' => 'bratonien_tools_self_update_run'),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
/*
|
||||
Plugin Name: Bratonien Tools
|
||||
Version: 0.9.3.32
|
||||
Version: 0.9.3.36
|
||||
Description: Erweiterbare Administrationswerkzeuge fuer die Bratonien-Piwigo-Installation.
|
||||
Plugin URI: https://github.com/Terranom674/Piwigo_Bratonien_Tools
|
||||
Author: Bratonien
|
||||
|
||||
@@ -40,90 +40,206 @@
|
||||
</div>
|
||||
|
||||
<div class="bratonien-card" style="grid-column:1/-1">
|
||||
<h4>Piwigo API – bevorzugter Sync-Zugang</h4>
|
||||
<p class="bratonien-base-note">Der NC Connector versucht bei jedem produktiven Lauf zuerst die Piwigo-API. Ein erfolgreich geprüfter API-Key wird verschlüsselt gespeichert. Die produktive API-Synchronisierung ist ausdrücklich an die im Plugin freigegebene Piwigo-Version gebunden. Ist diese Version nicht freigegeben oder die API nicht nutzbar, darf nur der Benutzername/Passwort-Fallback übernehmen.</p>
|
||||
<form method="post">
|
||||
<input type="hidden" name="pwg_token" value="{$PWG_TOKEN|escape:html}">
|
||||
<div class="bratonien-form-grid">
|
||||
<label class="bratonien-label" for="nc_piwigo_api_key_id">API-Schlüssel-ID</label>
|
||||
<input id="nc_piwigo_api_key_id" name="nc_piwigo_api_key_id" type="text" autocomplete="off" placeholder="pkid-..." required>
|
||||
<label class="bratonien-label" for="nc_piwigo_api_key_secret">API-Geheimnis</label>
|
||||
<input id="nc_piwigo_api_key_secret" name="nc_piwigo_api_key_secret" type="password" autocomplete="off" required>
|
||||
</div>
|
||||
<div class="bratonien-actions">
|
||||
<button class="buttonLike" type="submit" name="bratonien_tool" value="nc_connector_piwigo_api_test">API prüfen und speichern</button>
|
||||
<button class="buttonLike bratonien-delete-button" type="submit" name="bratonien_tool" value="nc_connector_piwigo_api_delete" formnovalidate onclick="return confirm('Gespeicherte Piwigo-API-Zugangsdaten wirklich löschen?');">Gespeicherte API löschen</button>
|
||||
</div>
|
||||
</form>
|
||||
<h4>Neue Verbindung</h4>
|
||||
<p class="bratonien-base-note">Wähle den geführten Assistenten oder öffne die technische Einrichtung bewusst manuell.</p>
|
||||
<div class="bratonien-actions">
|
||||
<button class="buttonLike" type="button" id="bratonien-nc-wizard-open">Mit Assistent anlegen</button>
|
||||
<button class="buttonLike" type="button" id="bratonien-nc-technical-open">Ohne Assistent anlegen</button>
|
||||
</div>
|
||||
|
||||
{if isset($NC_CONNECTOR.piwigo_api_test) && $NC_CONNECTOR.piwigo_api_test}
|
||||
<hr>
|
||||
<h5>Prüfergebnis</h5>
|
||||
<div class="bratonien-form-grid">
|
||||
<span class="bratonien-label">Benutzer</span><strong>{$NC_CONNECTOR.piwigo_api_test.username|escape:html}</strong>
|
||||
<span class="bratonien-label">Piwigo-Status</span><strong>{$NC_CONNECTOR.piwigo_api_test.status|escape:html}</strong>
|
||||
<span class="bratonien-label">Administrator/Webmaster</span><strong>{if $NC_CONNECTOR.piwigo_api_test.admin}Ja{else}Nein{/if}</strong>
|
||||
<span class="bratonien-label">Sichtbare API-Methoden</span><strong>{$NC_CONNECTOR.piwigo_api_test.method_count|escape:html}</strong>
|
||||
<span class="bratonien-label">Bratonien-Sync-API</span><strong>{if $NC_CONNECTOR.piwigo_api_test.sync_api_detected}Bereit{else}Nicht bereit{/if}</strong>
|
||||
</div>
|
||||
<p class="bratonien-base-note"><strong>Bewertung:</strong> {$NC_CONNECTOR.piwigo_api_test.conclusion|escape:html}</p>
|
||||
{/if}
|
||||
</div>
|
||||
<dialog id="bratonien-nc-wizard-dialog" style="width:min(1100px,calc(100vw - 3rem));max-height:88vh;overflow:auto;background:#444;color:inherit;border:1px solid #777;border-radius:4px;padding:0;box-shadow:0 18px 60px rgba(0,0,0,.55)">
|
||||
<div style="padding:1.25rem 1.5rem">
|
||||
<div style="display:flex;align-items:center;justify-content:space-between;gap:1rem;margin-bottom:1rem">
|
||||
<div>
|
||||
<h4 style="margin:0">Neue Verbindung</h4>
|
||||
<p class="bratonien-base-note" style="margin:.35rem 0 0"><strong>Assistent · Schritt {$NC_CONNECTOR.wizard.step|escape:html} von 4</strong></p>
|
||||
</div>
|
||||
<button class="buttonLike" type="button" id="bratonien-nc-wizard-close">Schließen</button>
|
||||
</div>
|
||||
|
||||
<div class="bratonien-card" style="grid-column:1/-1">
|
||||
<h4>Benutzername/Passwort-Fallback</h4>
|
||||
<p class="bratonien-base-note">Dieser Zugang wird nur verwendet, wenn die bevorzugte API nicht genutzt werden kann. Zugangsdaten können einmalig für einen manuellen Fallback verwendet, verschlüsselt dauerhaft hinterlegt oder vollständig gelöscht werden.</p>
|
||||
{if $NC_CONNECTOR.connection_count > 0}
|
||||
{if $NC_CONNECTOR.wizard.step == 1}
|
||||
<p class="bratonien-base-note">Wir beginnen nur mit der Adresse der Nextcloud und einem Benutzer, mit dem die Instanz auf den Scan antworten kann.</p>
|
||||
<form method="post" data-bratonien-wizard-form>
|
||||
<input type="hidden" name="pwg_token" value="{$PWG_TOKEN|escape:html}">
|
||||
<div class="bratonien-form-grid">
|
||||
<label class="bratonien-label" for="nc_wizard_host">Nextcloud-Host</label>
|
||||
<input id="nc_wizard_host" name="nc_wizard_host" type="text" placeholder="cloud.example.de" required>
|
||||
<label class="bratonien-label" for="nc_wizard_user">Nextcloud-Benutzer</label>
|
||||
<input id="nc_wizard_user" name="nc_wizard_user" type="text" autocomplete="username" required>
|
||||
<label class="bratonien-label" for="nc_wizard_password">Passwort</label>
|
||||
<input id="nc_wizard_password" name="nc_wizard_password" type="password" autocomplete="current-password" required>
|
||||
</div>
|
||||
<p><button class="buttonLike" type="submit" name="bratonien_tool" value="nc_connector_wizard_scan">Verbinden und scannen</button></p>
|
||||
</form>
|
||||
|
||||
{elseif $NC_CONNECTOR.wizard.step == 2}
|
||||
<p class="bratonien-base-note"><strong>Nextcloud erkannt.</strong> Alles, was zuverlässig ermittelt werden konnte, wurde bereits übernommen.</p>
|
||||
<div class="bratonien-form-grid">
|
||||
<span class="bratonien-label">Nextcloud</span><strong>{$NC_CONNECTOR.wizard.base_url|escape:html}</strong>
|
||||
<span class="bratonien-label">Produkt</span><strong>{$NC_CONNECTOR.wizard.product|escape:html}</strong>
|
||||
<span class="bratonien-label">Version</span><strong>{if $NC_CONNECTOR.wizard.version}{$NC_CONNECTOR.wizard.version|escape:html}{else}nicht gemeldet{/if}</strong>
|
||||
<span class="bratonien-label">Zugriff als</span><strong>{$NC_CONNECTOR.wizard.username|escape:html}{if $NC_CONNECTOR.wizard.display_name} · {$NC_CONNECTOR.wizard.display_name|escape:html}{/if}</strong>
|
||||
<span class="bratonien-label">Technische Erkennung</span><strong>{$NC_CONNECTOR.wizard.technical_source|escape:html}</strong>
|
||||
<span class="bratonien-label">Piwigo-Ziel</span><strong>{$NC_CONNECTOR.wizard.gallery_root|escape:html}</strong>
|
||||
</div>
|
||||
|
||||
{if !$NC_CONNECTOR.wizard.db_password_set || !$NC_CONNECTOR.wizard.db_user}
|
||||
<hr>
|
||||
<h5>Für den Datenabgleich fehlt noch der Datenbankzugang</h5>
|
||||
<p class="bratonien-base-note">Der Assistent konnte diese Angaben nicht sicher aus Nextcloud ableiten. Deshalb werden nur die fehlenden Werte abgefragt.</p>
|
||||
<form method="post" data-bratonien-wizard-form>
|
||||
<input type="hidden" name="pwg_token" value="{$PWG_TOKEN|escape:html}">
|
||||
<div class="bratonien-form-grid">
|
||||
<label class="bratonien-label">Verbindungsname</label><input name="nc_wizard_connection_name" type="text" value="{$NC_CONNECTOR.wizard.connection_name|escape:html}" required>
|
||||
<label class="bratonien-label">Datenbank-Host</label><input name="nc_wizard_db_host" type="text" value="{$NC_CONNECTOR.wizard.db_host|escape:html}" required>
|
||||
<label class="bratonien-label">Port</label><input name="nc_wizard_db_port" type="number" min="1" max="65535" value="{$NC_CONNECTOR.wizard.db_port|escape:html}" required>
|
||||
<label class="bratonien-label">Datenbank</label><input name="nc_wizard_db_database" type="text" value="{$NC_CONNECTOR.wizard.db_database|escape:html}" required>
|
||||
<label class="bratonien-label">Reader-Benutzer</label><input name="nc_wizard_db_user" type="text" value="{$NC_CONNECTOR.wizard.db_user|escape:html}" required>
|
||||
<label class="bratonien-label">Reader-Passwort</label><input name="nc_wizard_db_password" type="password" autocomplete="new-password" required>
|
||||
</div>
|
||||
<p><button class="buttonLike" type="submit" name="bratonien_tool" value="nc_connector_wizard_save_technical">Prüfen und automatisch ergänzen</button></p>
|
||||
</form>
|
||||
|
||||
{elseif !$NC_CONNECTOR.wizard.technical_complete && $NC_CONNECTOR.wizard.storage_candidates|@count > 0}
|
||||
<hr>
|
||||
<h5>Einige Storages konnten nicht automatisch zugeordnet werden</h5>
|
||||
<p class="bratonien-main-cache__warning">Mount-Pfade werden nur hier abgefragt, weil sie nicht sicher erkannt werden konnten. Bereits erkannte Zuordnungen sind gesperrt.</p>
|
||||
<form method="post" data-bratonien-wizard-form>
|
||||
<input type="hidden" name="pwg_token" value="{$PWG_TOKEN|escape:html}">
|
||||
<div class="bratonien-form-grid">
|
||||
{foreach from=$NC_CONNECTOR.wizard.storage_candidates item=storage key=storage_index}
|
||||
<span class="bratonien-label">Storage {$storage.storage_id|escape:html} · {$storage.source_prefix|escape:html}</span>
|
||||
{if $storage.local_mount}
|
||||
<strong>{$storage.local_mount|escape:html}</strong>
|
||||
<input type="hidden" name="nc_wizard_storage_mount[{$storage_index|escape:html}]" value="{$storage.local_mount|escape:html}">
|
||||
{else}
|
||||
<input name="nc_wizard_storage_mount[{$storage_index|escape:html}]" type="text" placeholder="/mnt/nextcloud/..." required>
|
||||
{/if}
|
||||
{/foreach}
|
||||
</div>
|
||||
<p><button class="buttonLike" type="submit" name="bratonien_tool" value="nc_connector_wizard_save_mounts">Zuordnung prüfen</button></p>
|
||||
</form>
|
||||
|
||||
{elseif $NC_CONNECTOR.wizard.technical_complete}
|
||||
<hr>
|
||||
<h5>Erkannte Verbindung</h5>
|
||||
<div class="bratonien-form-grid">
|
||||
<span class="bratonien-label">Datenbank</span><strong>{$NC_CONNECTOR.wizard.db_host|escape:html}:{$NC_CONNECTOR.wizard.db_port|escape:html} / {$NC_CONNECTOR.wizard.db_database|escape:html}</strong>
|
||||
<span class="bratonien-label">Reader</span><strong>{$NC_CONNECTOR.wizard.db_user|escape:html}</strong>
|
||||
<span class="bratonien-label">Source-View</span><strong>{$NC_CONNECTOR.wizard.source_view|escape:html}</strong>
|
||||
<span class="bratonien-label">Activity-View</span><strong>{$NC_CONNECTOR.wizard.activity_view|escape:html}</strong>
|
||||
<span class="bratonien-label">Storages</span><strong>{$NC_CONNECTOR.wizard.storages|@count}</strong>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
<h5>Welcher Benutzer stellt die Bilder bereit?</h5>
|
||||
<p class="bratonien-base-note"><strong>Empfehlung:</strong> ein eigener Showcase-Benutzer. So bleibt die Connector-Quelle unabhängig von persönlichen Konten.</p>
|
||||
<form method="post" data-bratonien-wizard-form>
|
||||
<input type="hidden" name="pwg_token" value="{$PWG_TOKEN|escape:html}">
|
||||
<div class="bratonien-form-grid">
|
||||
<label class="bratonien-label" for="nc_wizard_connection_name">Verbindungsname</label>
|
||||
<input id="nc_wizard_connection_name" name="nc_wizard_connection_name" type="text" value="{$NC_CONNECTOR.wizard.connection_name|escape:html}" required>
|
||||
<label class="bratonien-label" for="nc_wizard_showcase_user">Showcase-Benutzer</label>
|
||||
{if $NC_CONNECTOR.wizard.can_list_users && $NC_CONNECTOR.wizard.users|@count > 0}
|
||||
<select id="nc_wizard_showcase_user" name="nc_wizard_showcase_user" required>
|
||||
{foreach from=$NC_CONNECTOR.wizard.users item=nc_user}
|
||||
<option value="{$nc_user|escape:html}"{if $nc_user == 'showcase'} selected{/if}>{$nc_user|escape:html}{if $nc_user == 'showcase'} · empfohlen{/if}</option>
|
||||
{/foreach}
|
||||
</select>
|
||||
{else}
|
||||
<input id="nc_wizard_showcase_user" name="nc_wizard_showcase_user" type="text" value="showcase" required>
|
||||
{/if}
|
||||
</div>
|
||||
<p><button class="buttonLike" type="submit" name="bratonien_tool" value="nc_connector_wizard_select_user">Weiter zur Piwigo-API</button></p>
|
||||
</form>
|
||||
{/if}
|
||||
|
||||
<form method="post" style="margin-top:1rem" data-bratonien-wizard-form>
|
||||
<input type="hidden" name="pwg_token" value="{$PWG_TOKEN|escape:html}">
|
||||
<button class="buttonLike" type="submit" name="bratonien_tool" value="nc_connector_wizard_reset" data-bratonien-wizard-end>Neu beginnen</button>
|
||||
</form>
|
||||
|
||||
{elseif $NC_CONNECTOR.wizard.step == 3}
|
||||
<p class="bratonien-base-note"><strong>Nextcloud verbunden.</strong> Showcase-Benutzer: <strong>{$NC_CONNECTOR.wizard.showcase_user|escape:html}</strong></p>
|
||||
<h5>Piwigo-API</h5>
|
||||
<p class="bratonien-base-note">Die API ist der bevorzugte Weg. Du kannst neue Zugangsdaten eingeben, einen bereits gespeicherten API-Zugang testen oder diesen Schritt überspringen.</p>
|
||||
{if $NC_CONNECTOR.wizard.api_error}
|
||||
<p class="bratonien-main-cache__warning"><strong>Letzter API-Test:</strong> {$NC_CONNECTOR.wizard.api_error|escape:html}</p>
|
||||
{/if}
|
||||
<form method="post" data-bratonien-wizard-form>
|
||||
<input type="hidden" name="pwg_token" value="{$PWG_TOKEN|escape:html}">
|
||||
<div class="bratonien-form-grid">
|
||||
<label class="bratonien-label" for="nc_wizard_api_key_id">API-Schlüssel-ID</label>
|
||||
<input id="nc_wizard_api_key_id" name="nc_wizard_api_key_id" type="text" autocomplete="off" placeholder="leer = gespeicherten Zugang verwenden">
|
||||
<label class="bratonien-label" for="nc_wizard_api_key_secret">API-Geheimnis</label>
|
||||
<input id="nc_wizard_api_key_secret" name="nc_wizard_api_key_secret" type="password" autocomplete="off" placeholder="leer = gespeicherten Zugang verwenden">
|
||||
</div>
|
||||
<div class="bratonien-actions">
|
||||
<button class="buttonLike" type="submit" name="bratonien_tool" value="nc_connector_wizard_api_test">API testen</button>
|
||||
<button class="buttonLike" type="submit" name="bratonien_tool" value="nc_connector_wizard_api_skip" formnovalidate>API überspringen</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
{elseif $NC_CONNECTOR.wizard.step == 4}
|
||||
<p class="bratonien-base-note"><strong>Abschluss.</strong> Nextcloud und technische Verbindung sind vorbereitet.</p>
|
||||
<div class="bratonien-form-grid">
|
||||
<span class="bratonien-label">Verbindung</span><strong>{$NC_CONNECTOR.wizard.connection_name|escape:html}</strong>
|
||||
<span class="bratonien-label">Nextcloud</span><strong>{$NC_CONNECTOR.wizard.base_url|escape:html}</strong>
|
||||
<span class="bratonien-label">Showcase-Benutzer</span><strong>{$NC_CONNECTOR.wizard.showcase_user|escape:html}</strong>
|
||||
<span class="bratonien-label">Piwigo-API</span><strong>{if $NC_CONNECTOR.wizard.api_status == 'ok'}Erfolgreich getestet{if $NC_CONNECTOR.wizard.api_username} · {$NC_CONNECTOR.wizard.api_username|escape:html}{/if}{else}Übersprungen{/if}</strong>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
<h5>Fallback</h5>
|
||||
{if $NC_CONNECTOR.wizard.api_status == 'ok'}
|
||||
<p class="bratonien-base-note">Optional. Der Fallback wird nur benötigt, wenn die API später nicht nutzbar ist.</p>
|
||||
{else}
|
||||
<p class="bratonien-main-cache__warning">Die API wurde übersprungen. Deshalb ist ein Fallback-Zugang erforderlich.</p>
|
||||
{/if}
|
||||
<form method="post" data-bratonien-wizard-form>
|
||||
<input type="hidden" name="pwg_token" value="{$PWG_TOKEN|escape:html}">
|
||||
<div class="bratonien-form-grid">
|
||||
<label class="bratonien-label" for="nc_wizard_fallback_user">Piwigo-Benutzer</label>
|
||||
<input id="nc_wizard_fallback_user" name="nc_wizard_fallback_user" type="text" autocomplete="username"{if $NC_CONNECTOR.wizard.api_status != 'ok'} required{/if}>
|
||||
<label class="bratonien-label" for="nc_wizard_fallback_password">Piwigo-Passwort</label>
|
||||
<input id="nc_wizard_fallback_password" name="nc_wizard_fallback_password" type="password" autocomplete="current-password"{if $NC_CONNECTOR.wizard.api_status != 'ok'} required{/if}>
|
||||
</div>
|
||||
<div class="bratonien-actions">
|
||||
<button class="buttonLike" type="submit" name="bratonien_tool" value="nc_connector_wizard_finish" data-bratonien-wizard-end>Verbindung anlegen</button>
|
||||
<button class="buttonLike" type="submit" name="bratonien_tool" value="nc_connector_wizard_reset" formnovalidate data-bratonien-wizard-end>Abbrechen</button>
|
||||
</div>
|
||||
</form>
|
||||
{/if}
|
||||
</div>
|
||||
</dialog>
|
||||
|
||||
<details id="bratonien-nc-technical-create" style="margin-top:1.5rem">
|
||||
<summary style="display:none">Ohne Assistent anlegen</summary>
|
||||
<p class="bratonien-main-cache__warning">Technische Einrichtung. Falsche Storage- oder Galeriepfade können die Synchronisierung auf den falschen Datenbestand richten.</p>
|
||||
<form method="post">
|
||||
<input type="hidden" name="pwg_token" value="{$PWG_TOKEN|escape:html}">
|
||||
<div class="bratonien-form-grid">
|
||||
<label class="bratonien-label" for="nc_fallback_connection">Verbindung</label>
|
||||
<select id="nc_fallback_connection" name="connection_id" required>
|
||||
{foreach from=$NC_CONNECTOR.connections item=connection}
|
||||
<option value="{$connection.id|escape:html}">{$connection.name|escape:html}</option>
|
||||
{/foreach}
|
||||
</select>
|
||||
<label class="bratonien-label" for="nc_fallback_user">Piwigo-Benutzer</label>
|
||||
<input id="nc_fallback_user" name="nc_fallback_user" type="text" autocomplete="username">
|
||||
<label class="bratonien-label" for="nc_fallback_password">Piwigo-Passwort</label>
|
||||
<input id="nc_fallback_password" name="nc_fallback_password" type="password" autocomplete="current-password">
|
||||
</div>
|
||||
<div class="bratonien-actions">
|
||||
<button class="buttonLike" type="submit" name="bratonien_tool" value="nc_connector_fallback_once">Einmalig verwenden</button>
|
||||
<button class="buttonLike" type="submit" name="bratonien_tool" value="nc_connector_fallback_save">Fest speichern</button>
|
||||
<button class="buttonLike bratonien-delete-button" type="submit" name="bratonien_tool" value="nc_connector_fallback_delete" formnovalidate onclick="return confirm('Gespeicherten Benutzername/Passwort-Fallback wirklich löschen?');">Gespeicherten Fallback löschen</button>
|
||||
<label class="bratonien-label" for="nc_name">Name</label><input id="nc_name" name="nc_name" type="text" required>
|
||||
<label class="bratonien-label" for="nc_host">PostgreSQL-Host</label><input id="nc_host" name="nc_host" type="text" required>
|
||||
<label class="bratonien-label" for="nc_port">PostgreSQL-Port</label><input id="nc_port" name="nc_port" type="number" min="1" max="65535" value="5432" required>
|
||||
<label class="bratonien-label" for="nc_database">Datenbank</label><input id="nc_database" name="nc_database" type="text" value="nextcloud" required>
|
||||
<label class="bratonien-label" for="nc_user">Reader-Benutzer</label><input id="nc_user" name="nc_user" type="text" required>
|
||||
<label class="bratonien-label" for="nc_db_password">Reader-Passwort</label><input id="nc_db_password" name="nc_db_password" type="password" autocomplete="new-password" required>
|
||||
<label class="bratonien-label" for="nc_source_view">Source-View</label><input id="nc_source_view" name="nc_source_view" type="text" value="piwigo_showcase_sources" required>
|
||||
<label class="bratonien-label" for="nc_activity_view">Activity-View</label><input id="nc_activity_view" name="nc_activity_view" type="text" value="piwigo_showcase_activity" required>
|
||||
<label class="bratonien-label" for="nc_gallery_root">Piwigo-Galeriepfad</label><input id="nc_gallery_root" name="nc_gallery_root" type="text" placeholder="/var/www/piwigo/galleries/nextcloud" required>
|
||||
<label class="bratonien-label" for="nc_piwigo_user">Piwigo-Fallback-Benutzer</label><input id="nc_piwigo_user" name="nc_piwigo_user" type="text">
|
||||
<label class="bratonien-label" for="nc_piwigo_password">Piwigo-Fallback-Passwort</label><input id="nc_piwigo_password" name="nc_piwigo_password" type="password" autocomplete="new-password">
|
||||
<label class="bratonien-label" for="nc_quiet_seconds">Ruhezeit</label><input id="nc_quiet_seconds" name="nc_quiet_seconds" type="number" min="0" value="120">
|
||||
<label class="bratonien-label" for="nc_max_wait_seconds">Maximale Wartezeit</label><input id="nc_max_wait_seconds" name="nc_max_wait_seconds" type="number" min="60" value="900">
|
||||
<label class="bratonien-label" for="nc_full_sync_seconds">Vollprüfung nach</label><input id="nc_full_sync_seconds" name="nc_full_sync_seconds" type="number" min="300" value="86400">
|
||||
</div>
|
||||
<p><label for="nc_storages"><strong>Storage-Zuordnungen</strong></label></p>
|
||||
<p class="bratonien-base-note">Eine Zeile pro Storage: <code>storage_id | source_prefix | /lokaler/mount</code></p>
|
||||
<textarea id="nc_storages" name="nc_storages" rows="4" style="width:100%" required></textarea>
|
||||
<p><button class="buttonLike" type="submit" name="bratonien_tool" value="nc_connector_create_local">Verbindung anlegen</button></p>
|
||||
</form>
|
||||
{else}
|
||||
<p class="bratonien-base-note">Noch keine Connector-Verbindung vorhanden.</p>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<div class="bratonien-card" style="grid-column:1/-1">
|
||||
<h4>Neue lokale Verbindung</h4>
|
||||
<form method="post">
|
||||
<input type="hidden" name="pwg_token" value="{$PWG_TOKEN|escape:html}">
|
||||
<div class="bratonien-form-grid">
|
||||
<label class="bratonien-label" for="nc_name">Name</label><input id="nc_name" name="nc_name" type="text" required>
|
||||
<label class="bratonien-label" for="nc_host">PostgreSQL-Host</label><input id="nc_host" name="nc_host" type="text" required>
|
||||
<label class="bratonien-label" for="nc_port">PostgreSQL-Port</label><input id="nc_port" name="nc_port" type="number" min="1" max="65535" value="5432" required>
|
||||
<label class="bratonien-label" for="nc_database">Datenbank</label><input id="nc_database" name="nc_database" type="text" value="nextcloud" required>
|
||||
<label class="bratonien-label" for="nc_user">Reader-Benutzer</label><input id="nc_user" name="nc_user" type="text" required>
|
||||
<label class="bratonien-label" for="nc_db_password">Reader-Passwort</label><input id="nc_db_password" name="nc_db_password" type="password" autocomplete="new-password" required>
|
||||
<label class="bratonien-label" for="nc_source_view">Source-View</label><input id="nc_source_view" name="nc_source_view" type="text" value="piwigo_showcase_sources" required>
|
||||
<label class="bratonien-label" for="nc_activity_view">Activity-View</label><input id="nc_activity_view" name="nc_activity_view" type="text" value="piwigo_showcase_activity" required>
|
||||
<label class="bratonien-label" for="nc_gallery_root">Piwigo-Galeriepfad</label><input id="nc_gallery_root" name="nc_gallery_root" type="text" placeholder="/var/www/piwigo/galleries/nextcloud" required>
|
||||
<label class="bratonien-label" for="nc_piwigo_user">Piwigo-Fallback-Benutzer</label><input id="nc_piwigo_user" name="nc_piwigo_user" type="text" required>
|
||||
<label class="bratonien-label" for="nc_piwigo_password">Piwigo-Fallback-Passwort</label><input id="nc_piwigo_password" name="nc_piwigo_password" type="password" autocomplete="new-password" required>
|
||||
<label class="bratonien-label" for="nc_quiet_seconds">Ruhezeit</label><input id="nc_quiet_seconds" name="nc_quiet_seconds" type="number" min="0" value="120">
|
||||
<label class="bratonien-label" for="nc_max_wait_seconds">Maximale Wartezeit</label><input id="nc_max_wait_seconds" name="nc_max_wait_seconds" type="number" min="60" value="900">
|
||||
<label class="bratonien-label" for="nc_full_sync_seconds">Vollprüfung nach</label><input id="nc_full_sync_seconds" name="nc_full_sync_seconds" type="number" min="300" value="86400">
|
||||
</div>
|
||||
<p><label for="nc_storages"><strong>Storage-Zuordnungen</strong></label></p>
|
||||
<p class="bratonien-base-note">Eine Zeile pro Storage: <code>storage_id | source_prefix | /lokaler/mount</code></p>
|
||||
<textarea id="nc_storages" name="nc_storages" rows="4" style="width:100%" required></textarea>
|
||||
<p><button class="buttonLike" type="submit" name="bratonien_tool" value="nc_connector_create_local">Verbindung anlegen</button></p>
|
||||
</form>
|
||||
</details>
|
||||
</div>
|
||||
|
||||
<div class="bratonien-card" style="grid-column:1/-1">
|
||||
@@ -131,100 +247,80 @@
|
||||
{if $NC_CONNECTOR.connection_count > 0}
|
||||
<table class="table2">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Adapter</th>
|
||||
<th>Host</th>
|
||||
<th>Quelle</th>
|
||||
<th>Storages</th>
|
||||
<th>Status</th>
|
||||
<th>Aktion</th>
|
||||
</tr>
|
||||
<tr><th>Name</th><th>Adapter</th><th>Host</th><th>Quelle</th><th>Storages</th><th>Status</th><th>Aktion</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{foreach from=$NC_CONNECTOR.connections item=connection}
|
||||
<tr>
|
||||
<td>{$connection.name|escape:html}</td>
|
||||
<td>{$connection.display_name|escape:html}</td>
|
||||
<td>{$connection.adapter|escape:html}</td>
|
||||
<td>{if $connection.host}{$connection.host|escape:html}{else}—{/if}</td>
|
||||
<td>{if $connection.source_view}{$connection.source_view|escape:html}{else}—{/if}</td>
|
||||
<td>{$connection.storage_count|escape:html}</td>
|
||||
<td>{$connection.takeover_state|escape:html}{if $connection.enabled} · aktiv{/if}</td>
|
||||
<td>
|
||||
{if $connection.takeover_state == 'active'}
|
||||
<code>php /var/www/piwigo/plugins/bratonien_tools/nc-connector-disable.php {$connection.id|escape:html}</code>
|
||||
{elseif $connection.takeover_state == 'verified' && isset($connection.config.origin) && $connection.config.origin == 'native'}
|
||||
<code>php /var/www/piwigo/plugins/bratonien_tools/nc-connector-install.php {$connection.id|escape:html}</code>
|
||||
<form method="post" class="bratonien-actions">
|
||||
<details>
|
||||
<summary>Verwalten</summary>
|
||||
<form method="post" class="bratonien-actions" style="margin-top:.75rem">
|
||||
<input type="hidden" name="pwg_token" value="{$PWG_TOKEN|escape:html}">
|
||||
<input type="hidden" name="connection_id" value="{$connection.id|escape:html}">
|
||||
<button class="buttonLike" type="submit" name="bratonien_tool" value="nc_connector_verify">Erneut prüfen</button>
|
||||
<input name="connection_name" type="text" value="{$connection.name|escape:html}" required>
|
||||
<button class="buttonLike" type="submit" name="bratonien_tool" value="nc_connector_update_name">Name speichern</button>
|
||||
</form>
|
||||
{elseif $connection.takeover_state == 'ready'}
|
||||
<form method="post" class="bratonien-actions">
|
||||
<input type="hidden" name="pwg_token" value="{$PWG_TOKEN|escape:html}">
|
||||
<input type="hidden" name="connection_id" value="{$connection.id|escape:html}">
|
||||
<button class="buttonLike" type="submit" name="bratonien_tool" value="nc_connector_cancel_takeover">Vorbereitung zurücknehmen</button>
|
||||
</form>
|
||||
{elseif $connection.takeover_state == 'verified' && !$connection.enabled}
|
||||
<form method="post" class="bratonien-actions">
|
||||
<input type="hidden" name="pwg_token" value="{$PWG_TOKEN|escape:html}">
|
||||
<input type="hidden" name="connection_id" value="{$connection.id|escape:html}">
|
||||
<button class="buttonLike" type="submit" name="bratonien_tool" value="nc_connector_prepare_takeover">Übergabe vorbereiten</button>
|
||||
</form>
|
||||
{elseif $connection.adapter == 'local' && !$connection.enabled}
|
||||
<form method="post" class="bratonien-actions">
|
||||
<input type="hidden" name="pwg_token" value="{$PWG_TOKEN|escape:html}">
|
||||
<input type="hidden" name="connection_id" value="{$connection.id|escape:html}">
|
||||
<button class="buttonLike" type="submit" name="bratonien_tool" value="nc_connector_verify">Verbindung prüfen</button>
|
||||
</form>
|
||||
<form method="post" class="bratonien-actions">
|
||||
<input type="hidden" name="pwg_token" value="{$PWG_TOKEN|escape:html}">
|
||||
<input type="hidden" name="connection_id" value="{$connection.id|escape:html}">
|
||||
<button class="buttonLike" type="submit" name="bratonien_tool" value="nc_connector_delete">Löschen</button>
|
||||
</form>
|
||||
{else}
|
||||
—
|
||||
{/if}
|
||||
|
||||
<div class="bratonien-actions">
|
||||
{if $connection.adapter == 'local' && !$connection.enabled}
|
||||
<form method="post">
|
||||
<input type="hidden" name="pwg_token" value="{$PWG_TOKEN|escape:html}">
|
||||
<input type="hidden" name="connection_id" value="{$connection.id|escape:html}">
|
||||
<button class="buttonLike" type="submit" name="bratonien_tool" value="nc_connector_verify">Verbindung prüfen</button>
|
||||
</form>
|
||||
{/if}
|
||||
{if !$connection.enabled && $connection.takeover_state != 'active'}
|
||||
<form method="post">
|
||||
<input type="hidden" name="pwg_token" value="{$PWG_TOKEN|escape:html}">
|
||||
<input type="hidden" name="connection_id" value="{$connection.id|escape:html}">
|
||||
<button class="buttonLike bratonien-delete-button" type="submit" name="bratonien_tool" value="nc_connector_delete" onclick="return confirm('Verbindung wirklich löschen? Es werden nur die Connector-Einstellungen entfernt, keine Nextcloud- oder Piwigo-Bilder.');">Löschen</button>
|
||||
</form>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<details style="margin-top:.75rem">
|
||||
<summary>Technische Einstellungen</summary>
|
||||
{if $connection.enabled || $connection.takeover_state == 'active'}
|
||||
<p class="bratonien-main-cache__warning">Eine aktive Verbindung muss vor technischen Änderungen deaktiviert werden.</p>
|
||||
{else}
|
||||
<p class="bratonien-main-cache__warning">Nur ändern, wenn die technische Zuordnung bekannt ist. Storage- und Galeriepfade sind sicherheitskritisch.</p>
|
||||
<form method="post">
|
||||
<input type="hidden" name="pwg_token" value="{$PWG_TOKEN|escape:html}">
|
||||
<input type="hidden" name="connection_id" value="{$connection.id|escape:html}">
|
||||
<div class="bratonien-form-grid">
|
||||
<label class="bratonien-label">PostgreSQL-Host</label><input name="nc_host" type="text" value="{$connection.config.host|escape:html}" required>
|
||||
<label class="bratonien-label">Port</label><input name="nc_port" type="number" min="1" max="65535" value="{$connection.config.port|escape:html}" required>
|
||||
<label class="bratonien-label">Datenbank</label><input name="nc_database" type="text" value="{$connection.config.database|escape:html}" required>
|
||||
<label class="bratonien-label">Reader-Benutzer</label><input name="nc_user" type="text" value="{$connection.config.user|escape:html}" required>
|
||||
<label class="bratonien-label">Reader-Passwort</label><input name="nc_db_password" type="password" placeholder="leer = unverändert">
|
||||
<label class="bratonien-label">Source-View</label><input name="nc_source_view" type="text" value="{$connection.config.source_view|escape:html}" required>
|
||||
<label class="bratonien-label">Activity-View</label><input name="nc_activity_view" type="text" value="{$connection.config.activity_view|escape:html}" required>
|
||||
<label class="bratonien-label">Piwigo-Galeriepfad</label><input name="nc_gallery_root" type="text" value="{$connection.config.gallery_root|escape:html}" required>
|
||||
<label class="bratonien-label">Ruhezeit</label><input name="nc_quiet_seconds" type="number" min="0" value="{$connection.config.quiet_seconds|escape:html}">
|
||||
<label class="bratonien-label">Maximale Wartezeit</label><input name="nc_max_wait_seconds" type="number" min="60" value="{$connection.config.max_wait_seconds|escape:html}">
|
||||
<label class="bratonien-label">Vollprüfung nach</label><input name="nc_full_sync_seconds" type="number" min="300" value="{$connection.config.full_sync_seconds|escape:html}">
|
||||
</div>
|
||||
<p><strong>Storage-Zuordnungen</strong></p>
|
||||
<textarea name="nc_storages" rows="4" style="width:100%" required>{$connection.storage_text|escape:html}</textarea>
|
||||
<p><button class="buttonLike" type="submit" name="bratonien_tool" value="nc_connector_update_technical">Technische Einstellungen speichern</button></p>
|
||||
</form>
|
||||
{/if}
|
||||
</details>
|
||||
</details>
|
||||
</td>
|
||||
</tr>
|
||||
{if $connection.verification_checks|@count > 0}
|
||||
<tr>
|
||||
<td colspan="7">
|
||||
<strong>Letzte Verifikation{if $connection.verified_at} · {$connection.verified_at|escape:html}{/if}</strong>
|
||||
<ul>
|
||||
{foreach from=$connection.verification_checks item=check}
|
||||
<li>{if $check.ok}✓{else}✗{/if} <strong>{$check.name|escape:html}:</strong> {$check.detail|escape:html}</li>
|
||||
{/foreach}
|
||||
</ul>
|
||||
{if $connection.takeover_state == 'active'}
|
||||
<p class="bratonien-base-note"><strong>Connector aktiv.</strong> State: <code>{$connection.config.state_dir|escape:html}</code></p>
|
||||
{elseif $connection.takeover_state == 'verified' && isset($connection.config.origin) && $connection.config.origin == 'native'}
|
||||
<p class="bratonien-base-note">Verifiziert. Der angezeigte Root-Befehl richtet Runtime-Konfiguration, State-Verzeichnis und gemeinsamen systemd-Timer ein und führt vor der Aktivierung einen Testlauf aus.</p>
|
||||
{/if}
|
||||
</td>
|
||||
</tr>
|
||||
<tr><td colspan="7"><strong>Letzte Verifikation{if $connection.verified_at} · {$connection.verified_at|escape:html}{/if}</strong><ul>{foreach from=$connection.verification_checks item=check}<li>{if $check.ok}✓{else}✗{/if} <strong>{$check.name|escape:html}:</strong> {$check.detail|escape:html}</li>{/foreach}</ul></td></tr>
|
||||
{/if}
|
||||
{if isset($connection.last_sync) && $connection.last_sync.timestamp > 0}
|
||||
<tr>
|
||||
<td colspan="7">
|
||||
<strong>Letzter Sync · {$connection.last_sync.label|escape:html}</strong>
|
||||
<p class="bratonien-base-note"><strong>Ergebnis:</strong> {$connection.last_sync.message|escape:html}</p>
|
||||
{if $connection.last_sync.api_state == 'ok'}
|
||||
<p class="bratonien-base-note"><strong>API:</strong> erfolgreich</p>
|
||||
{elseif $connection.last_sync.api_state == 'error'}
|
||||
<p class="bratonien-main-cache__warning"><strong>API fehlgeschlagen:</strong> {$connection.last_sync.api_message|escape:html}</p>
|
||||
{/if}
|
||||
{if $connection.last_sync.fallback_state == 'ok'}
|
||||
<p class="bratonien-base-note"><strong>Fallback:</strong> erfolgreich</p>
|
||||
{elseif $connection.last_sync.fallback_state == 'error'}
|
||||
<p class="bratonien-main-cache__warning"><strong>Fallback fehlgeschlagen:</strong> {$connection.last_sync.fallback_message|escape:html}</p>
|
||||
{/if}
|
||||
{if $connection.last_sync.error_detail}
|
||||
<p class="bratonien-main-cache__warning"><strong>Technischer Fehler:</strong> {$connection.last_sync.error_detail|escape:html}</p>
|
||||
{/if}
|
||||
</td>
|
||||
</tr>
|
||||
<tr><td colspan="7"><strong>Letzter Sync · {$connection.last_sync.label|escape:html}</strong><p class="bratonien-base-note"><strong>Ergebnis:</strong> {$connection.last_sync.message|escape:html}</p>{if $connection.last_sync.api_state == 'error'}<p class="bratonien-main-cache__warning"><strong>API fehlgeschlagen:</strong> {$connection.last_sync.api_message|escape:html}</p>{/if}{if $connection.last_sync.fallback_state == 'error'}<p class="bratonien-main-cache__warning"><strong>Fallback fehlgeschlagen:</strong> {$connection.last_sync.fallback_message|escape:html}</p>{/if}{if $connection.last_sync.error_detail}<p class="bratonien-main-cache__warning"><strong>Technischer Fehler:</strong> {$connection.last_sync.error_detail|escape:html}</p>{/if}</td></tr>
|
||||
{/if}
|
||||
{/foreach}
|
||||
</tbody>
|
||||
@@ -234,32 +330,99 @@
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<div class="bratonien-card">
|
||||
<h4>Sync-Zustand</h4>
|
||||
<div class="bratonien-form-grid">
|
||||
<span class="bratonien-label">Connector-Timer</span><strong>{if $nc_system_available && $NC_CONNECTOR.system.timer_active}Aktiv{else}Nicht aktiv{/if}</strong>
|
||||
<span class="bratonien-label">Letzter Lauf</span><strong>{if $nc_system_available}{$NC_CONNECTOR.system.last_run_label|escape:html}{else}Nicht verfügbar{/if}</strong>
|
||||
<span class="bratonien-label">Nächster Lauf</span><strong>{if $nc_system_available}{$NC_CONNECTOR.system.next_run_label|escape:html}{else}Nicht verfügbar{/if}</strong>
|
||||
</div>
|
||||
{if $nc_system_available && $NC_CONNECTOR.system.last_run_message}
|
||||
<p class="bratonien-base-note"><strong>Ergebnis:</strong> {$NC_CONNECTOR.system.last_run_message|escape:html}</p>
|
||||
{/if}
|
||||
{if $nc_system_available && $NC_CONNECTOR.system.last_run_api_state == 'error'}
|
||||
<p class="bratonien-main-cache__warning"><strong>API fehlgeschlagen:</strong> {$NC_CONNECTOR.system.last_run_api_message|escape:html}</p>
|
||||
{/if}
|
||||
{if $nc_system_available && $NC_CONNECTOR.system.last_run_fallback_state == 'ok'}
|
||||
<p class="bratonien-base-note"><strong>Fallback:</strong> erfolgreich</p>
|
||||
{elseif $nc_system_available && $NC_CONNECTOR.system.last_run_fallback_state == 'error'}
|
||||
<p class="bratonien-main-cache__warning"><strong>Fallback fehlgeschlagen:</strong> {$NC_CONNECTOR.system.last_run_fallback_message|escape:html}</p>
|
||||
{/if}
|
||||
{if $nc_system_available && $NC_CONNECTOR.system.last_run_error_detail}
|
||||
<p class="bratonien-main-cache__warning"><strong>Technischer Fehler:</strong> {$NC_CONNECTOR.system.last_run_error_detail|escape:html}</p>
|
||||
<div class="bratonien-card" style="grid-column:1/-1">
|
||||
<h4>Piwigo API – bevorzugter Sync-Zugang</h4>
|
||||
<p class="bratonien-base-note">Hier kann der globale API-Zugang unabhängig vom Assistenten geprüft, ersetzt oder gelöscht werden.</p>
|
||||
<form method="post">
|
||||
<input type="hidden" name="pwg_token" value="{$PWG_TOKEN|escape:html}">
|
||||
<div class="bratonien-form-grid">
|
||||
<label class="bratonien-label" for="nc_piwigo_api_key_id">API-Schlüssel-ID</label><input id="nc_piwigo_api_key_id" name="nc_piwigo_api_key_id" type="text" autocomplete="off" placeholder="pkid-..." required>
|
||||
<label class="bratonien-label" for="nc_piwigo_api_key_secret">API-Geheimnis</label><input id="nc_piwigo_api_key_secret" name="nc_piwigo_api_key_secret" type="password" autocomplete="off" required>
|
||||
</div>
|
||||
<div class="bratonien-actions">
|
||||
<button class="buttonLike" type="submit" name="bratonien_tool" value="nc_connector_piwigo_api_test">API prüfen und speichern</button>
|
||||
<button class="buttonLike bratonien-delete-button" type="submit" name="bratonien_tool" value="nc_connector_piwigo_api_delete" formnovalidate onclick="return confirm('Gespeicherte Piwigo-API-Zugangsdaten wirklich löschen?');">Gespeicherte API löschen</button>
|
||||
</div>
|
||||
</form>
|
||||
{if isset($NC_CONNECTOR.piwigo_api_test) && $NC_CONNECTOR.piwigo_api_test}
|
||||
<p class="bratonien-base-note"><strong>Bewertung:</strong> {$NC_CONNECTOR.piwigo_api_test.conclusion|escape:html}</p>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<div class="bratonien-card">
|
||||
<h4>Neuinstallation</h4>
|
||||
<p class="bratonien-base-note">Eine frische Installation benötigt keinen Legacy-Sync. Ablauf: Verbindung anlegen → prüfen → Root-Aktivierung ausführen. Danach arbeitet ausschließlich die Plugin-Runtime.</p>
|
||||
<div class="bratonien-card" style="grid-column:1/-1">
|
||||
<h4>Benutzername/Passwort-Fallback</h4>
|
||||
{if $NC_CONNECTOR.connection_count > 0}
|
||||
<form method="post">
|
||||
<input type="hidden" name="pwg_token" value="{$PWG_TOKEN|escape:html}">
|
||||
<div class="bratonien-form-grid">
|
||||
<label class="bratonien-label" for="nc_fallback_connection">Verbindung</label><select id="nc_fallback_connection" name="connection_id" required>{foreach from=$NC_CONNECTOR.connections item=connection}<option value="{$connection.id|escape:html}">{$connection.name|escape:html}</option>{/foreach}</select>
|
||||
<label class="bratonien-label" for="nc_fallback_user">Piwigo-Benutzer</label><input id="nc_fallback_user" name="nc_fallback_user" type="text" autocomplete="username">
|
||||
<label class="bratonien-label" for="nc_fallback_password">Piwigo-Passwort</label><input id="nc_fallback_password" name="nc_fallback_password" type="password" autocomplete="current-password">
|
||||
</div>
|
||||
<div class="bratonien-actions">
|
||||
<button class="buttonLike" type="submit" name="bratonien_tool" value="nc_connector_fallback_once">Einmalig verwenden</button>
|
||||
<button class="buttonLike" type="submit" name="bratonien_tool" value="nc_connector_fallback_save">Fest speichern</button>
|
||||
<button class="buttonLike bratonien-delete-button" type="submit" name="bratonien_tool" value="nc_connector_fallback_delete" formnovalidate onclick="return confirm('Gespeicherten Benutzername/Passwort-Fallback wirklich löschen?');">Gespeicherten Fallback löschen</button>
|
||||
</div>
|
||||
</form>
|
||||
{else}<p class="bratonien-base-note">Noch keine Connector-Verbindung vorhanden.</p>{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
var dialog = document.getElementById('bratonien-nc-wizard-dialog');
|
||||
var openButton = document.getElementById('bratonien-nc-wizard-open');
|
||||
var closeButton = document.getElementById('bratonien-nc-wizard-close');
|
||||
var technicalButton = document.getElementById('bratonien-nc-technical-open');
|
||||
var technical = document.getElementById('bratonien-nc-technical-create');
|
||||
var storageKey = 'bratonienNcWizardOpen';
|
||||
|
||||
if (openButton && dialog) {
|
||||
openButton.addEventListener('click', function () {
|
||||
sessionStorage.setItem(storageKey, '1');
|
||||
if (typeof dialog.showModal === 'function') dialog.showModal();
|
||||
else dialog.setAttribute('open', 'open');
|
||||
});
|
||||
}
|
||||
|
||||
if (closeButton && dialog) {
|
||||
closeButton.addEventListener('click', function () {
|
||||
sessionStorage.removeItem(storageKey);
|
||||
if (typeof dialog.close === 'function') dialog.close();
|
||||
else dialog.removeAttribute('open');
|
||||
});
|
||||
}
|
||||
|
||||
if (dialog) {
|
||||
dialog.addEventListener('cancel', function () {
|
||||
sessionStorage.removeItem(storageKey);
|
||||
});
|
||||
dialog.addEventListener('click', function (event) {
|
||||
if (event.target === dialog) {
|
||||
sessionStorage.removeItem(storageKey);
|
||||
if (typeof dialog.close === 'function') dialog.close();
|
||||
}
|
||||
});
|
||||
dialog.querySelectorAll('form[data-bratonien-wizard-form]').forEach(function (form) {
|
||||
form.addEventListener('submit', function (event) {
|
||||
var submitter = event.submitter;
|
||||
if (submitter && submitter.hasAttribute('data-bratonien-wizard-end')) sessionStorage.removeItem(storageKey);
|
||||
else sessionStorage.setItem(storageKey, '1');
|
||||
});
|
||||
});
|
||||
if (sessionStorage.getItem(storageKey) === '1') {
|
||||
if (typeof dialog.showModal === 'function' && !dialog.open) dialog.showModal();
|
||||
else dialog.setAttribute('open', 'open');
|
||||
}
|
||||
}
|
||||
|
||||
if (technicalButton && technical) {
|
||||
technicalButton.addEventListener('click', function () {
|
||||
technical.open = !technical.open;
|
||||
if (technical.open) technical.scrollIntoView({behavior:'smooth', block:'start'});
|
||||
});
|
||||
}
|
||||
}());
|
||||
</script>
|
||||
</section>
|
||||
Reference in New Issue
Block a user