diff --git a/.gitignore b/.gitignore
old mode 100644
new mode 100755
diff --git a/README.md b/README.md
old mode 100644
new mode 100755
index cddb118..5d5d907
--- a/README.md
+++ b/README.md
@@ -3,7 +3,7 @@ Contributors: ronnygrobel
Tags: verein, mitgliederverwaltung, parzellen, zaehler, abrechnung
Requires at least: 6.0
Tested up to: 6.8
-Stable tag: 1.17.5
+Stable tag: 1.17.8
Requires PHP: 7.2
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
@@ -43,6 +43,15 @@ Ja, insbesondere fuer Kleingartenvereine und deren Verwaltungsprozesse.
== Changelog ==
+= 1.17.8 =
+Feat: Verbrauchsauswertung – Ablesung korrigieren (Datum, Zählerstand, Korrekturnotiz) und löschen direkt aus der Tabelle.
+
+= 1.17.7 =
+Feat: Inventarverwaltung – Gegenstände (Werkzeug etc.) erfassen, bearbeiten, löschen. Ausleihe und Rückgabe je Mitglied mit Notiz und Fälligkeitsdatum tracken. Export/Import integriert.
+
+= 1.17.6 =
+Feat: Jahresabrechnung kann festgeschrieben (gesperrt) werden. Alle Schreibzugriffe auf Kosten, Preise und Parzellenzuordnungen prüfen den Sperrstatus serverseitig.
+
= 1.17.5 =
Fix: Spaltenbreiten in Abrechnungstabellen angepasst für bessere Lesbarkeit langer Texte.
diff --git a/assets/css/admin.css b/assets/css/admin.css
old mode 100644
new mode 100755
diff --git a/assets/js/chat.js b/assets/js/chat.js
old mode 100644
new mode 100755
diff --git a/includes/Activator.php b/includes/Activator.php
old mode 100644
new mode 100755
diff --git a/includes/Admin/Admin.php b/includes/Admin/Admin.php
old mode 100644
new mode 100755
index 80a9418..f86b1a4
--- a/includes/Admin/Admin.php
+++ b/includes/Admin/Admin.php
@@ -14,6 +14,7 @@ use KGV\VereinManager\Repositories\ChatRepository;
use KGV\VereinManager\Repositories\CostRepository;
use KGV\VereinManager\Repositories\MeterReadingRepository;
use KGV\VereinManager\Repositories\MeterRepository;
+use KGV\VereinManager\Repositories\InventoryRepository;
use KGV\VereinManager\Repositories\ParcelRepository;
use KGV\VereinManager\Repositories\SectionRepository;
use KGV\VereinManager\Repositories\TenantRepository;
@@ -41,6 +42,7 @@ class Admin {
private $parcels;
private $meters;
private $readings;
+ private $inventory;
private $tenants;
private $assignments;
private $chat;
@@ -58,6 +60,7 @@ class Admin {
$this->parcels = new ParcelRepository();
$this->meters = new MeterRepository();
$this->readings = new MeterReadingRepository();
+ $this->inventory = new InventoryRepository();
$this->tenants = new TenantRepository();
$this->assignments = new AssignmentRepository();
$this->chat = new ChatRepository();
@@ -106,6 +109,7 @@ class Admin {
add_submenu_page( 'kgvvm-dashboard', __( 'Sparten', KGVVM_TEXT_DOMAIN ), __( 'Sparten', KGVVM_TEXT_DOMAIN ), 'edit_sparten', 'kgvvm-sparten', array( $this, 'render_sections_page' ) );
add_submenu_page( 'kgvvm-dashboard', __( 'Parzellen', KGVVM_TEXT_DOMAIN ), __( 'Parzellen', KGVVM_TEXT_DOMAIN ), 'edit_parzellen', 'kgvvm-parzellen', array( $this, 'render_parcels_page' ) );
add_submenu_page( 'kgvvm-dashboard', __( 'Zähler', KGVVM_TEXT_DOMAIN ), __( 'Zähler', KGVVM_TEXT_DOMAIN ), 'edit_zaehler', 'kgvvm-zaehler', array( $this, 'render_meters_page' ) );
+ add_submenu_page( 'kgvvm-dashboard', __( 'Inventar', KGVVM_TEXT_DOMAIN ), __( 'Inventar', KGVVM_TEXT_DOMAIN ), $cap, 'kgvvm-inventory', array( $this, 'render_inventory_page' ) );
add_submenu_page( 'kgvvm-dashboard', __( 'Verbrauch', KGVVM_TEXT_DOMAIN ), __( 'Verbrauch', KGVVM_TEXT_DOMAIN ), $cap, 'kgvvm-consumption', array( $this, 'render_consumption_page' ) );
add_submenu_page( 'kgvvm-dashboard', __( 'Kosten', KGVVM_TEXT_DOMAIN ), __( 'Kosten', KGVVM_TEXT_DOMAIN ), $cap, 'kgvvm-costs', array( $this, 'render_costs_page' ) );
add_submenu_page( 'kgvvm-dashboard', __( 'Arbeitsstunden', KGVVM_TEXT_DOMAIN ), __( 'Arbeitsstunden', KGVVM_TEXT_DOMAIN ), $cap, 'kgvvm-arbeit', array( $this, 'render_work_page' ) );
@@ -234,6 +238,18 @@ class Admin {
case 'save_meter_reading':
$this->save_meter_reading();
break;
+ case 'correct_meter_reading':
+ $this->correct_meter_reading();
+ break;
+ case 'save_inventory_item':
+ $this->save_inventory_item();
+ break;
+ case 'borrow_inventory_item':
+ $this->borrow_inventory_item();
+ break;
+ case 'return_inventory_loan':
+ $this->return_inventory_loan();
+ break;
case 'save_settings':
$this->save_settings();
break;
@@ -252,6 +268,9 @@ class Admin {
case 'toggle_parcel_cost_assignment':
$this->toggle_parcel_cost_assignment();
break;
+ case 'set_statement_lock':
+ $this->set_statement_lock();
+ break;
}
}
@@ -296,6 +315,25 @@ class Admin {
$this->meters->delete( $id );
$this->redirect_with_notice( 'kgvvm-zaehler', 'success', __( 'Zähler wurde gelöscht.', KGVVM_TEXT_DOMAIN ) );
break;
+ case 'delete_meter_reading':
+ $this->require_cap( 'manage_kleingarten' );
+ if ( ! wp_verify_nonce( $nonce, 'kgvvm_delete_meter_reading_' . $id ) ) {
+ $this->redirect_with_notice( 'kgvvm-consumption', 'error', __( 'Der Löschvorgang wurde aus Sicherheitsgründen abgebrochen.', KGVVM_TEXT_DOMAIN ) );
+ }
+ $this->readings->delete( $id );
+ $this->redirect_with_notice( 'kgvvm-consumption', 'success', __( 'Die Ablesung wurde gelöscht.', KGVVM_TEXT_DOMAIN ) );
+ break;
+ case 'delete_inventory_item':
+ $this->require_cap( 'manage_kleingarten' );
+ if ( ! wp_verify_nonce( $nonce, 'kgvvm_delete_inventory_item_' . $id ) ) {
+ $this->redirect_with_notice( 'kgvvm-inventory', 'error', __( 'Der Löschvorgang für den Inventargegenstand wurde aus Sicherheitsgründen abgebrochen.', KGVVM_TEXT_DOMAIN ) );
+ }
+ if ( $this->inventory->has_open_loans( $id ) ) {
+ $this->redirect_with_notice( 'kgvvm-inventory', 'error', __( 'Der Inventargegenstand hat noch offene Ausleihen und kann nicht gelöscht werden.', KGVVM_TEXT_DOMAIN ) );
+ }
+ $this->inventory->delete( $id );
+ $this->redirect_with_notice( 'kgvvm-inventory', 'success', __( 'Inventargegenstand wurde gelöscht.', KGVVM_TEXT_DOMAIN ) );
+ break;
case 'delete_tenant':
$this->require_cap( 'edit_paechter' );
if ( ! wp_verify_nonce( $nonce, 'kgvvm_delete_tenant_' . $id ) ) {
@@ -316,6 +354,9 @@ class Admin {
$this->redirect_with_notice( 'kgvvm-costs', 'error', __( 'Der gewünschte Kostenposten wurde nicht gefunden.', KGVVM_TEXT_DOMAIN ), array( 'year' => $year ) );
}
$year = (int) $cost->entry_year;
+ if ( $this->costs->is_statement_locked( $year ) ) {
+ $this->redirect_with_notice( 'kgvvm-costs', 'error', __( 'Die Jahresabrechnung ist festgeschrieben. Änderungen sind erst nach erneuter Freigabe möglich.', KGVVM_TEXT_DOMAIN ), array( 'year' => $year ) );
+ }
$this->costs->delete_assignments_for_entry( $id );
$this->costs->delete( $id );
$this->redirect_with_notice( 'kgvvm-costs', 'success', __( 'Kostenposten wurde gelöscht.', KGVVM_TEXT_DOMAIN ), array( 'year' => $year ) );
@@ -660,6 +701,52 @@ class Admin {
$this->redirect_with_notice( $return_page, 'success', __( 'Die Ablesung wurde gespeichert.', KGVVM_TEXT_DOMAIN ), $return_args );
}
+ /**
+ * Correct an existing meter reading (admin only).
+ *
+ * @return void
+ */
+ private function correct_meter_reading() {
+ $this->require_cap( 'manage_kleingarten' );
+ check_admin_referer( 'kgvvm_correct_meter_reading' );
+
+ $id = absint( isset( $_POST['reading_id'] ) ? $_POST['reading_id'] : 0 );
+ $value = isset( $_POST['reading_value'] ) ? (float) wp_unslash( $_POST['reading_value'] ) : null;
+ $date = isset( $_POST['reading_date'] ) ? sanitize_text_field( wp_unslash( $_POST['reading_date'] ) ) : '';
+ $note = isset( $_POST['note'] ) ? sanitize_textarea_field( wp_unslash( $_POST['note'] ) ) : '';
+
+ $return_args = array_filter(
+ array(
+ 'section_id' => absint( isset( $_POST['section_id'] ) ? $_POST['section_id'] : 0 ),
+ 'date_from' => sanitize_text_field( wp_unslash( isset( $_POST['date_from'] ) ? $_POST['date_from'] : '' ) ),
+ 'date_to' => sanitize_text_field( wp_unslash( isset( $_POST['date_to'] ) ? $_POST['date_to'] : '' ) ),
+ 'order' => sanitize_key( wp_unslash( isset( $_POST['order'] ) ? $_POST['order'] : 'DESC' ) ),
+ ),
+ static function( $v ) { return '' !== $v && 0 !== $v; }
+ );
+
+ $reading = $id ? $this->readings->find( $id ) : null;
+
+ if ( ! $reading ) {
+ $this->redirect_with_notice( 'kgvvm-consumption', 'error', __( 'Die Ablesung wurde nicht gefunden.', KGVVM_TEXT_DOMAIN ), $return_args );
+ }
+
+ if ( null === $value || '' === $date ) {
+ $this->redirect_with_notice( 'kgvvm-consumption', 'error', __( 'Bitte Zählerstand und Datum angeben.', KGVVM_TEXT_DOMAIN ), $return_args );
+ }
+
+ $this->readings->update_reading(
+ $id,
+ array(
+ 'reading_value' => $value,
+ 'reading_date' => $date,
+ 'note' => $note,
+ )
+ );
+
+ $this->redirect_with_notice( 'kgvvm-consumption', 'success', __( 'Die Ablesung wurde korrigiert.', KGVVM_TEXT_DOMAIN ), $return_args );
+ }
+
/**
* Save general settings.
*
@@ -794,6 +881,10 @@ class Admin {
$this->redirect_with_notice( 'kgvvm-costs', 'error', $errors->get_error_message(), array( 'year' => $data['entry_year'] ) );
}
+ if ( $this->costs->is_statement_locked( (int) $data['entry_year'] ) ) {
+ $this->redirect_with_notice( 'kgvvm-costs', 'error', __( 'Die Jahresabrechnung ist festgeschrieben. Änderungen sind erst nach erneuter Freigabe möglich.', KGVVM_TEXT_DOMAIN ), array( 'year' => $data['entry_year'] ) );
+ }
+
if ( ! $this->costs->save_section_prices( $data ) ) {
$this->redirect_with_notice( 'kgvvm-costs', 'error', __( 'Die Preise für diese Sparte konnten nicht gespeichert werden.', KGVVM_TEXT_DOMAIN ), array( 'year' => $data['entry_year'] ) );
}
@@ -813,11 +904,20 @@ class Admin {
$id = absint( isset( $_POST['id'] ) ? $_POST['id'] : 0 );
$data = $this->validator->sanitize_cost_entry( $_POST );
$errors = $this->validator->validate_cost_entry( $data );
+ $existing = $id > 0 ? $this->costs->find( $id ) : null;
if ( $errors->has_errors() ) {
$this->redirect_with_notice( 'kgvvm-costs', 'error', $errors->get_error_message(), array( 'year' => $data['entry_year'], 'id' => $id ) );
}
+ if ( $existing && $this->costs->is_statement_locked( (int) $existing->entry_year ) ) {
+ $this->redirect_with_notice( 'kgvvm-costs', 'error', __( 'Die Jahresabrechnung ist festgeschrieben. Änderungen sind erst nach erneuter Freigabe möglich.', KGVVM_TEXT_DOMAIN ), array( 'year' => (int) $existing->entry_year, 'id' => $id ) );
+ }
+
+ if ( $this->costs->is_statement_locked( (int) $data['entry_year'] ) ) {
+ $this->redirect_with_notice( 'kgvvm-costs', 'error', __( 'Die Jahresabrechnung ist festgeschrieben. Änderungen sind erst nach erneuter Freigabe möglich.', KGVVM_TEXT_DOMAIN ), array( 'year' => $data['entry_year'], 'id' => $id ) );
+ }
+
$active_parcels = array_values(
array_filter(
$this->parcels->search(),
@@ -857,6 +957,10 @@ class Admin {
$this->redirect_with_notice( 'kgvvm-costs', 'error', __( 'Ungültige Anfrage.', KGVVM_TEXT_DOMAIN ), array( 'view' => 'statement', 'statement_type' => 'parcel', 'subject_id' => $parcel_id, 'year' => $year ) );
}
+ if ( $this->costs->is_statement_locked( $year ) ) {
+ $this->redirect_with_notice( 'kgvvm-costs', 'error', __( 'Die Jahresabrechnung ist festgeschrieben. Änderungen sind erst nach erneuter Freigabe möglich.', KGVVM_TEXT_DOMAIN ), array( 'view' => 'statement', 'statement_type' => 'parcel', 'subject_id' => $parcel_id, 'year' => $year ) );
+ }
+
if ( 'add' === $mode ) {
$this->costs->assign_to_parcel( $parcel_id, $cost_entry_id );
} else {
@@ -867,6 +971,401 @@ class Admin {
exit;
}
+ /**
+ * Lock or unlock annual statement changes for one year.
+ *
+ * @return void
+ */
+ private function set_statement_lock() {
+ $this->require_cap( 'manage_kleingarten' );
+ $year = absint( isset( $_POST['year'] ) ? $_POST['year'] : current_time( 'Y' ) );
+ $statement_type = isset( $_POST['statement_type'] ) ? sanitize_key( wp_unslash( $_POST['statement_type'] ) ) : 'parcel';
+ $subject_id = absint( isset( $_POST['subject_id'] ) ? $_POST['subject_id'] : 0 );
+ $mode = isset( $_POST['lock_mode'] ) ? sanitize_key( wp_unslash( $_POST['lock_mode'] ) ) : '';
+
+ check_admin_referer( 'kgvvm_set_statement_lock_' . $year );
+
+ if ( $year < 1 || ! in_array( $mode, array( 'lock', 'unlock' ), true ) ) {
+ $this->redirect_with_notice( 'kgvvm-costs', 'error', __( 'Ungültige Anfrage.', KGVVM_TEXT_DOMAIN ), array( 'view' => 'statement', 'statement_type' => $statement_type, 'subject_id' => $subject_id, 'year' => $year ) );
+ }
+
+ $is_locked = 'lock' === $mode;
+ $saved = $this->costs->set_statement_lock( $year, $is_locked, get_current_user_id() );
+
+ if ( ! $saved ) {
+ $this->redirect_with_notice( 'kgvvm-costs', 'error', __( 'Der Sperrstatus der Jahresabrechnung konnte nicht gespeichert werden.', KGVVM_TEXT_DOMAIN ), array( 'view' => 'statement', 'statement_type' => $statement_type, 'subject_id' => $subject_id, 'year' => $year ) );
+ }
+
+ $this->redirect_with_notice(
+ 'kgvvm-costs',
+ 'success',
+ $is_locked ? __( 'Jahresabrechnung wurde festgeschrieben.', KGVVM_TEXT_DOMAIN ) : __( 'Jahresabrechnung wurde erneut freigegeben.', KGVVM_TEXT_DOMAIN ),
+ array( 'view' => 'statement', 'statement_type' => $statement_type, 'subject_id' => $subject_id, 'year' => $year )
+ );
+ }
+
+ /**
+ * Save one inventory item.
+ *
+ * @return void
+ */
+ private function save_inventory_item() {
+ $this->require_cap( 'manage_kleingarten' );
+ check_admin_referer( 'kgvvm_save_inventory_item' );
+
+ $id = absint( isset( $_POST['id'] ) ? $_POST['id'] : 0 );
+ $data = $this->validator->sanitize_inventory_item( $_POST );
+ $errors = $this->validator->validate_inventory_item( $data );
+ $existing = $id > 0 ? $this->inventory->find( $id ) : null;
+
+ if ( $existing ) {
+ $borrowed_qty = $this->inventory->get_open_borrowed_quantity( $id );
+
+ if ( (int) $data['total_quantity'] < $borrowed_qty ) {
+ $errors->add( 'inventory_total_too_low', __( 'Die Gesamtmenge ist kleiner als aktuell ausgeliehen. Bitte zuerst Rückgaben erfassen.', KGVVM_TEXT_DOMAIN ) );
+ }
+ }
+
+ if ( $errors->has_errors() ) {
+ $this->redirect_with_notice( 'kgvvm-inventory', 'error', $errors->get_error_message(), array( 'id' => $id ) );
+ }
+
+ $saved = $this->inventory->save_item( $data, $id );
+
+ if ( ! $saved ) {
+ $this->redirect_with_notice( 'kgvvm-inventory', 'error', __( 'Der Inventargegenstand konnte nicht gespeichert werden.', KGVVM_TEXT_DOMAIN ), array( 'id' => $id ) );
+ }
+
+ $this->redirect_with_notice( 'kgvvm-inventory', 'success', __( 'Inventargegenstand wurde gespeichert.', KGVVM_TEXT_DOMAIN ) );
+ }
+
+ /**
+ * Borrow inventory item for one member.
+ *
+ * @return void
+ */
+ private function borrow_inventory_item() {
+ $this->require_cap( 'manage_kleingarten' );
+ check_admin_referer( 'kgvvm_borrow_inventory_item' );
+
+ $data = $this->validator->sanitize_inventory_loan( $_POST );
+ $errors = $this->validator->validate_inventory_loan( $data );
+
+ $item = $this->inventory->find( $data['item_id'] );
+
+ if ( ! $item ) {
+ $errors->add( 'inventory_item_missing', __( 'Der gewählte Inventargegenstand wurde nicht gefunden.', KGVVM_TEXT_DOMAIN ) );
+ } elseif ( ! (bool) $item->is_active ) {
+ $errors->add( 'inventory_item_inactive', __( 'Der gewählte Inventargegenstand ist inaktiv.', KGVVM_TEXT_DOMAIN ) );
+ } elseif ( (int) $data['quantity'] > (int) $item->available_quantity ) {
+ $errors->add( 'inventory_item_not_available', __( 'Die gewünschte Menge ist nicht verfügbar.', KGVVM_TEXT_DOMAIN ) );
+ }
+
+ if ( $errors->has_errors() ) {
+ $this->redirect_with_notice( 'kgvvm-inventory', 'error', $errors->get_error_message() );
+ }
+
+ $saved = $this->inventory->borrow_item( $data['item_id'], $data['user_id'], $data['quantity'], $data['due_date'], $data['note'] );
+
+ if ( ! $saved ) {
+ $this->redirect_with_notice( 'kgvvm-inventory', 'error', __( 'Die Ausleihe konnte nicht gespeichert werden.', KGVVM_TEXT_DOMAIN ) );
+ }
+
+ $this->redirect_with_notice( 'kgvvm-inventory', 'success', __( 'Ausleihe wurde erfasst.', KGVVM_TEXT_DOMAIN ) );
+ }
+
+ /**
+ * Return one inventory loan.
+ *
+ * @return void
+ */
+ private function return_inventory_loan() {
+ $this->require_cap( 'manage_kleingarten' );
+ check_admin_referer( 'kgvvm_return_inventory_loan' );
+
+ $loan_id = absint( isset( $_POST['loan_id'] ) ? $_POST['loan_id'] : 0 );
+ $return_note = sanitize_textarea_field( wp_unslash( isset( $_POST['return_note'] ) ? $_POST['return_note'] : '' ) );
+
+ if ( $loan_id < 1 ) {
+ $this->redirect_with_notice( 'kgvvm-inventory', 'error', __( 'Ungültige Anfrage.', KGVVM_TEXT_DOMAIN ) );
+ }
+
+ $saved = $this->inventory->return_loan( $loan_id, $return_note );
+
+ if ( ! $saved ) {
+ $this->redirect_with_notice( 'kgvvm-inventory', 'error', __( 'Die Rückgabe konnte nicht gespeichert werden.', KGVVM_TEXT_DOMAIN ) );
+ }
+
+ $this->redirect_with_notice( 'kgvvm-inventory', 'success', __( 'Rückgabe wurde erfasst.', KGVVM_TEXT_DOMAIN ) );
+ }
+
+ /**
+ * Render inventory management page.
+ *
+ * @return void
+ */
+ public function render_inventory_page() {
+ $this->require_cap( 'manage_kleingarten' );
+
+ $search = isset( $_GET['s'] ) ? sanitize_text_field( wp_unslash( $_GET['s'] ) ) : '';
+ $edit_id = absint( isset( $_GET['id'] ) ? $_GET['id'] : 0 );
+ $item = $edit_id > 0 ? $this->inventory->find( $edit_id ) : null;
+
+ $items = $this->inventory->search_items( array( 's' => $search, 'orderby' => isset( $_GET['orderby'] ) ? sanitize_key( wp_unslash( $_GET['orderby'] ) ) : 'name', 'order' => isset( $_GET['order'] ) ? sanitize_key( wp_unslash( $_GET['order'] ) ) : 'ASC' ) );
+ $open_loans = $this->inventory->get_open_loans();
+ $recent_loans = $this->inventory->get_recent_loans( 20 );
+
+ $member_query = new \WP_User_Query(
+ array(
+ 'role' => Roles::MEMBER_ROLE,
+ 'fields' => array( 'ID', 'display_name', 'user_email' ),
+ 'orderby' => 'display_name',
+ 'order' => 'ASC',
+ 'number' => 2000,
+ )
+ );
+
+ $members = (array) $member_query->get_results();
+
+ if ( empty( $members ) ) {
+ $members = (array) $this->assignments->get_member_users();
+ }
+
+ $summary_total_items = count( $items );
+ $summary_available_total = 0;
+ $summary_open_total = count( $open_loans );
+
+ foreach ( $items as $row ) {
+ $summary_available_total += max( 0, (int) $row->available_quantity );
+ }
+ ?>
+
+
+
+
' class='page-title-action'>
+
+ render_notice(); ?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ |
+ |
+ |
+ |
+ |
+
+
+
+
+ |
+
+
+
+ | borrowed_at ) ? wp_date( 'd.m.Y H:i', strtotime( $row->borrowed_at ) ) : '—' ); ?> |
+ item_name ? $row->item_name : '—' ); ?> |
+ borrower_name ? $row->borrower_name : '—' ); ?> |
+ borrowed_quantity, 0 ) ); ?> |
+ status ? __( 'Offen', KGVVM_TEXT_DOMAIN ) : __( 'Zurückgegeben', KGVVM_TEXT_DOMAIN ) ); ?> |
+
+
+
+
+
+
+
+ require_cap( 'manage_kleingarten' );
- $section_id = isset( $_GET['section_id'] ) ? absint( $_GET['section_id'] ) : 0;
- $date_from = isset( $_GET['date_from'] ) ? sanitize_text_field( wp_unslash( $_GET['date_from'] ) ) : '';
- $date_to = isset( $_GET['date_to'] ) ? sanitize_text_field( wp_unslash( $_GET['date_to'] ) ) : '';
- $order = isset( $_GET['order'] ) ? strtoupper( sanitize_key( wp_unslash( $_GET['order'] ) ) ) : 'DESC';
- $order = 'ASC' === $order ? 'ASC' : 'DESC';
- $sections = $this->sections->all_for_options();
+ $section_id = isset( $_GET['section_id'] ) ? absint( $_GET['section_id'] ) : 0;
+ $date_from = isset( $_GET['date_from'] ) ? sanitize_text_field( wp_unslash( $_GET['date_from'] ) ) : '';
+ $date_to = isset( $_GET['date_to'] ) ? sanitize_text_field( wp_unslash( $_GET['date_to'] ) ) : '';
+ $order = isset( $_GET['order'] ) ? strtoupper( sanitize_key( wp_unslash( $_GET['order'] ) ) ) : 'DESC';
+ $order = 'ASC' === $order ? 'ASC' : 'DESC';
+ $edit_reading_id = isset( $_GET['edit_reading'] ) ? absint( $_GET['edit_reading'] ) : 0;
+ $edit_reading = $edit_reading_id ? $this->readings->find( $edit_reading_id ) : null;
+ $sections = $this->sections->all_for_options();
if ( $date_from && $date_to && strtotime( $date_from ) > strtotime( $date_to ) ) {
$tmp = $date_from;
@@ -1051,6 +1552,42 @@ class Admin {
render_notice(); ?>
+
+
+
+