Add data export/import under settings

This commit is contained in:
2026-04-17 13:29:11 +02:00
parent 6c793ad41a
commit 96969bb0a2
2 changed files with 290 additions and 1 deletions

View File

@@ -19,6 +19,7 @@ use KGV\VereinManager\Repositories\SectionRepository;
use KGV\VereinManager\Repositories\TenantRepository;
use KGV\VereinManager\Repositories\WorkRepository;
use KGV\VereinManager\Services\ParcelService;
use KGV\VereinManager\DataTransfer;
if ( ! defined( 'ABSPATH' ) ) {
exit;
@@ -46,6 +47,7 @@ class Admin {
private $costs;
private $work;
private $parcel_service;
private $data_transfer;
/**
* Construct admin controller.
@@ -61,7 +63,9 @@ class Admin {
$this->chat = new ChatRepository();
$this->costs = new CostRepository();
$this->work = new WorkRepository();
$this->parcel_service = new ParcelService();
$this->parcel_service = new ParcelService();
global $wpdb;
$this->data_transfer = new DataTransfer( $wpdb );
}
/**
@@ -242,6 +246,9 @@ class Admin {
case 'save_work_log':
$this->save_work_log();
break;
case 'import_plugin_data':
$this->import_plugin_data();
break;
}
}
@@ -312,6 +319,13 @@ class Admin {
case 'export_readings_csv':
$this->export_readings_csv();
break;
case 'export_plugin_data':
$this->require_cap( Roles::SETTINGS_CAP );
if ( ! wp_verify_nonce( $nonce, 'kgvvm_export_plugin_data' ) ) {
$this->redirect_with_notice( 'kgvvm-settings', 'error', __( 'Export wurde aus Sicherheitsgründen abgebrochen.', KGVVM_TEXT_DOMAIN ) );
}
$this->data_transfer->send_download();
break;
case 'delete_work_job':
$this->require_cap( 'manage_kleingarten' );
if ( ! wp_verify_nonce( $nonce, 'kgvvm_delete_work_job_' . $id ) ) {
@@ -684,6 +698,59 @@ class Admin {
$this->redirect_with_notice( 'kgvvm-settings', 'success', __( 'Einstellungen wurden gespeichert.', KGVVM_TEXT_DOMAIN ) );
}
/**
* Handle plugin data import from an uploaded JSON file.
*
* @return void
*/
private function import_plugin_data() {
$this->require_cap( Roles::SETTINGS_CAP );
check_admin_referer( 'kgvvm_import_plugin_data' );
if ( empty( $_FILES['kgvvm_import_file']['tmp_name'] ) ) {
$this->redirect_with_notice( 'kgvvm-settings', 'error', __( 'Bitte eine JSON-Datei auswählen.', KGVVM_TEXT_DOMAIN ) );
}
$file = $_FILES['kgvvm_import_file'];
// Validate MIME type.
$finfo = new \finfo( FILEINFO_MIME_TYPE );
$mimetype = $finfo->file( $file['tmp_name'] );
if ( ! in_array( $mimetype, array( 'application/json', 'text/plain' ), true ) ) {
$this->redirect_with_notice( 'kgvvm-settings', 'error', __( 'Die hochgeladene Datei ist keine gültige JSON-Datei.', KGVVM_TEXT_DOMAIN ) );
}
$raw = file_get_contents( $file['tmp_name'] ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents
if ( false === $raw ) {
$this->redirect_with_notice( 'kgvvm-settings', 'error', __( 'Die Datei konnte nicht gelesen werden.', KGVVM_TEXT_DOMAIN ) );
}
$payload = json_decode( $raw, true );
if ( ! is_array( $payload ) ) {
$this->redirect_with_notice( 'kgvvm-settings', 'error', __( 'Die JSON-Datei konnte nicht verarbeitet werden. Bitte eine gültige Exportdatei hochladen.', KGVVM_TEXT_DOMAIN ) );
}
$result = $this->data_transfer->import( $payload );
if ( ! empty( $result['errors'] ) ) {
$this->redirect_with_notice( 'kgvvm-settings', 'error', implode( ' | ', $result['errors'] ) );
}
$summary = array();
foreach ( $result['imported'] as $key => $count ) {
$summary[] = $key . ': ' . $count;
}
$this->redirect_with_notice(
'kgvvm-settings',
'success',
sprintf(
/* translators: %s: summary of imported rows per table */
__( 'Import erfolgreich. Importierte Datensätze %s', KGVVM_TEXT_DOMAIN ),
implode( ', ', $summary )
)
);
}
/**
* Persist one year for the cost dropdown.
*
@@ -3324,6 +3391,33 @@ class Admin {
</table>
<?php submit_button( __( 'Einstellungen speichern', KGVVM_TEXT_DOMAIN ) ); ?>
</form>
<hr />
<h2><?php echo esc_html__( 'Datensicherung', KGVVM_TEXT_DOMAIN ); ?></h2>
<div class='kgvvm-grid'>
<div class='kgvvm-card'>
<h3><?php echo esc_html__( 'Export', KGVVM_TEXT_DOMAIN ); ?></h3>
<p><?php echo esc_html__( 'Exportiert alle Plugin-Tabellen (Sparten, Parzellen, Zähler, Verbrauch, Kosten, Arbeitsstunden usw.) als JSON-Datei.', KGVVM_TEXT_DOMAIN ); ?></p>
<a href='<?php echo esc_url( wp_nonce_url( $this->admin_url( 'kgvvm-settings', array( 'kgvvm_action' => 'export_plugin_data' ) ), 'kgvvm_export_plugin_data' ) ); ?>'
class='button button-secondary'>
<?php echo esc_html__( 'JSON-Export herunterladen', KGVVM_TEXT_DOMAIN ); ?>
</a>
</div>
<div class='kgvvm-card'>
<h3><?php echo esc_html__( 'Import', KGVVM_TEXT_DOMAIN ); ?></h3>
<p class='notice notice-warning inline' style='margin:0 0 10px;padding:6px 10px;'>
<?php echo esc_html__( 'Achtung: Der Import überschreibt alle vorhandenen Plugin-Daten vollständig. Bitte vorher einen Export erstellen.', KGVVM_TEXT_DOMAIN ); ?>
</p>
<form method='post' enctype='multipart/form-data'>
<?php wp_nonce_field( 'kgvvm_import_plugin_data' ); ?>
<input type='hidden' name='kgvvm_action' value='import_plugin_data' />
<input type='file' name='kgvvm_import_file' accept='.json,application/json' required style='margin-bottom:8px;display:block;' />
<?php submit_button( __( 'Import starten', KGVVM_TEXT_DOMAIN ), 'secondary', 'submit', false ); ?>
</form>
</div>
</div>
</div>
<?php
}