390 lines
14 KiB
PHP
390 lines
14 KiB
PHP
<?php
|
|
/**
|
|
* Sanitizing and validation helpers.
|
|
*
|
|
* @package KGV\VereinManager
|
|
*/
|
|
|
|
namespace KGV\VereinManager;
|
|
|
|
if ( ! defined( 'ABSPATH' ) ) {
|
|
exit;
|
|
}
|
|
|
|
class Validator {
|
|
|
|
/**
|
|
* Sanitize section input.
|
|
*
|
|
* @param array $data Raw request data.
|
|
* @return array
|
|
*/
|
|
public function sanitize_section( $data ) {
|
|
return array(
|
|
'name' => sanitize_text_field( wp_unslash( isset( $data['name'] ) ? $data['name'] : '' ) ),
|
|
'description' => sanitize_textarea_field( wp_unslash( isset( $data['description'] ) ? $data['description'] : '' ) ),
|
|
'status' => sanitize_key( wp_unslash( isset( $data['status'] ) ? $data['status'] : 'active' ) ),
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Validate section.
|
|
*
|
|
* @param array $data Sanitized data.
|
|
* @return \WP_Error
|
|
*/
|
|
public function validate_section( $data ) {
|
|
$errors = new \WP_Error();
|
|
|
|
if ( '' === $data['name'] ) {
|
|
$errors->add( 'name_required', __( 'Bitte einen Namen für die Sparte eingeben.', KGVVM_TEXT_DOMAIN ) );
|
|
}
|
|
|
|
if ( ! in_array( $data['status'], array( 'active', 'inactive' ), true ) ) {
|
|
$errors->add( 'invalid_status', __( 'Der Status der Sparte ist ungültig.', KGVVM_TEXT_DOMAIN ) );
|
|
}
|
|
|
|
return $errors;
|
|
}
|
|
|
|
/**
|
|
* Sanitize parcel input.
|
|
*
|
|
* @param array $data Raw request data.
|
|
* @return array
|
|
*/
|
|
public function sanitize_parcel( $data ) {
|
|
$area = isset( $data['area'] ) ? str_replace( ',', '.', wp_unslash( $data['area'] ) ) : '';
|
|
$annual_rent = isset( $data['annual_rent'] ) ? str_replace( ',', '.', wp_unslash( $data['annual_rent'] ) ) : '';
|
|
$area = '' === trim( (string) $area ) ? null : (float) $area;
|
|
$annual_rent = '' === trim( (string) $annual_rent ) ? null : (float) $annual_rent;
|
|
|
|
return array(
|
|
'label' => sanitize_text_field( wp_unslash( isset( $data['label'] ) ? $data['label'] : '' ) ),
|
|
'section_id' => absint( isset( $data['section_id'] ) ? $data['section_id'] : 0 ),
|
|
'area' => $area,
|
|
'annual_rent' => $annual_rent,
|
|
'status' => sanitize_key( wp_unslash( isset( $data['status'] ) ? $data['status'] : 'free' ) ),
|
|
'note' => sanitize_textarea_field( wp_unslash( isset( $data['note'] ) ? $data['note'] : '' ) ),
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Validate parcel.
|
|
*
|
|
* @param array $data Sanitized data.
|
|
* @return \WP_Error
|
|
*/
|
|
public function validate_parcel( $data ) {
|
|
$errors = new \WP_Error();
|
|
|
|
if ( '' === $data['label'] ) {
|
|
$errors->add( 'label_required', __( 'Bitte eine Parzellennummer oder Bezeichnung eingeben.', KGVVM_TEXT_DOMAIN ) );
|
|
}
|
|
|
|
if ( $data['section_id'] < 1 ) {
|
|
$errors->add( 'section_required', __( 'Bitte eine Sparte auswählen.', KGVVM_TEXT_DOMAIN ) );
|
|
}
|
|
|
|
if ( ! in_array( $data['status'], array( 'free', 'assigned', 'reserved', 'inactive' ), true ) ) {
|
|
$errors->add( 'invalid_status', __( 'Der Parzellenstatus ist ungültig.', KGVVM_TEXT_DOMAIN ) );
|
|
}
|
|
|
|
if ( null !== $data['area'] && $data['area'] < 0 ) {
|
|
$errors->add( 'invalid_area', __( 'Die Fläche darf nicht negativ sein.', KGVVM_TEXT_DOMAIN ) );
|
|
}
|
|
|
|
if ( null !== $data['annual_rent'] && $data['annual_rent'] < 0 ) {
|
|
$errors->add( 'invalid_annual_rent', __( 'Die Pacht darf nicht negativ sein.', KGVVM_TEXT_DOMAIN ) );
|
|
}
|
|
|
|
return $errors;
|
|
}
|
|
|
|
/**
|
|
* Sanitize meter input.
|
|
*
|
|
* @param array $data Raw request data.
|
|
* @return array
|
|
*/
|
|
public function sanitize_meter( $data ) {
|
|
$calibration_year = isset( $data['calibration_year'] ) ? absint( $data['calibration_year'] ) : 0;
|
|
|
|
return array(
|
|
'type' => sanitize_key( wp_unslash( isset( $data['type'] ) ? $data['type'] : '' ) ),
|
|
'meter_number' => sanitize_text_field( wp_unslash( isset( $data['meter_number'] ) ? $data['meter_number'] : '' ) ),
|
|
'section_id' => absint( isset( $data['section_id'] ) ? $data['section_id'] : 0 ),
|
|
'installed_at' => $this->normalize_date( isset( $data['installed_at'] ) ? $data['installed_at'] : '' ),
|
|
'calibration_year' => $calibration_year > 0 ? $calibration_year : null,
|
|
'is_active' => ! empty( $data['is_active'] ) ? 1 : 0,
|
|
'note' => sanitize_textarea_field( wp_unslash( isset( $data['note'] ) ? $data['note'] : '' ) ),
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Validate meter data.
|
|
*
|
|
* @param array $data Sanitized data.
|
|
* @return \WP_Error
|
|
*/
|
|
public function validate_meter( $data ) {
|
|
$errors = new \WP_Error();
|
|
|
|
if ( ! in_array( $data['type'], array( 'water', 'power' ), true ) ) {
|
|
$errors->add( 'invalid_type', __( 'Bitte einen gültigen Zählertyp auswählen.', KGVVM_TEXT_DOMAIN ) );
|
|
}
|
|
|
|
if ( '' === $data['meter_number'] ) {
|
|
$errors->add( 'meter_number_required', __( 'Bitte eine Zählernummer eingeben.', KGVVM_TEXT_DOMAIN ) );
|
|
}
|
|
|
|
if ( $data['section_id'] < 1 ) {
|
|
$errors->add( 'section_required', __( 'Bitte eine Sparte für den Zähler auswählen.', KGVVM_TEXT_DOMAIN ) );
|
|
}
|
|
|
|
if ( null !== $data['calibration_year'] ) {
|
|
$current_year = (int) gmdate( 'Y' ) + 20;
|
|
|
|
if ( $data['calibration_year'] < 2000 || $data['calibration_year'] > $current_year ) {
|
|
$errors->add( 'invalid_calibration_year', __( 'Bitte ein gültiges Eichjahr angeben.', KGVVM_TEXT_DOMAIN ) );
|
|
}
|
|
}
|
|
|
|
return $errors;
|
|
}
|
|
|
|
/**
|
|
* Sanitize tenant input.
|
|
*
|
|
* @param array $data Raw request data.
|
|
* @return array
|
|
*/
|
|
public function sanitize_tenant( $data ) {
|
|
return array(
|
|
'first_name' => sanitize_text_field( wp_unslash( isset( $data['first_name'] ) ? $data['first_name'] : '' ) ),
|
|
'last_name' => sanitize_text_field( wp_unslash( isset( $data['last_name'] ) ? $data['last_name'] : '' ) ),
|
|
'address' => sanitize_textarea_field( wp_unslash( isset( $data['address'] ) ? $data['address'] : '' ) ),
|
|
'phone' => sanitize_text_field( wp_unslash( isset( $data['phone'] ) ? $data['phone'] : '' ) ),
|
|
'email' => sanitize_email( wp_unslash( isset( $data['email'] ) ? $data['email'] : '' ) ),
|
|
'contract_start' => $this->normalize_date( isset( $data['contract_start'] ) ? $data['contract_start'] : '' ),
|
|
'contract_end' => $this->normalize_date( isset( $data['contract_end'] ) ? $data['contract_end'] : '' ),
|
|
'is_active' => ! empty( $data['is_active'] ) ? 1 : 0,
|
|
'note' => sanitize_textarea_field( wp_unslash( isset( $data['note'] ) ? $data['note'] : '' ) ),
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Validate tenant.
|
|
*
|
|
* @param array $data Sanitized data.
|
|
* @return \WP_Error
|
|
*/
|
|
public function validate_tenant( $data ) {
|
|
$errors = new \WP_Error();
|
|
|
|
if ( '' === $data['first_name'] || '' === $data['last_name'] ) {
|
|
$errors->add( 'name_required', __( 'Bitte Vor- und Nachnamen des Pächters angeben.', KGVVM_TEXT_DOMAIN ) );
|
|
}
|
|
|
|
if ( '' === $data['contract_start'] ) {
|
|
$errors->add( 'contract_start_required', __( 'Bitte einen Vertragsbeginn angeben.', KGVVM_TEXT_DOMAIN ) );
|
|
}
|
|
|
|
if ( $data['email'] && ! is_email( $data['email'] ) ) {
|
|
$errors->add( 'invalid_email', __( 'Die angegebene E-Mail-Adresse ist ungültig.', KGVVM_TEXT_DOMAIN ) );
|
|
}
|
|
|
|
if ( $data['contract_start'] && $data['contract_end'] && strtotime( $data['contract_end'] ) < strtotime( $data['contract_start'] ) ) {
|
|
$errors->add( 'invalid_contract_range', __( 'Das Vertragsende darf nicht vor dem Vertragsbeginn liegen.', KGVVM_TEXT_DOMAIN ) );
|
|
}
|
|
|
|
return $errors;
|
|
}
|
|
|
|
/**
|
|
* Sanitize meter reading input.
|
|
*
|
|
* @param array $data Raw request data.
|
|
* @return array
|
|
*/
|
|
public function sanitize_meter_reading( $data ) {
|
|
$reading_value = isset( $data['reading_value'] ) ? str_replace( ',', '.', wp_unslash( $data['reading_value'] ) ) : '';
|
|
|
|
return array(
|
|
'parcel_id' => absint( isset( $data['parcel_id'] ) ? $data['parcel_id'] : 0 ),
|
|
'meter_id' => absint( isset( $data['meter_id'] ) ? $data['meter_id'] : 0 ),
|
|
'reading_value' => '' === trim( (string) $reading_value ) ? '' : (float) $reading_value,
|
|
'reading_date' => $this->normalize_date( isset( $data['reading_date'] ) ? $data['reading_date'] : '' ),
|
|
'note' => sanitize_textarea_field( wp_unslash( isset( $data['note'] ) ? $data['note'] : '' ) ),
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Validate one meter reading.
|
|
*
|
|
* @param array $data Sanitized data.
|
|
* @return \WP_Error
|
|
*/
|
|
public function validate_meter_reading( $data ) {
|
|
$errors = new \WP_Error();
|
|
|
|
if ( $data['parcel_id'] < 0 ) {
|
|
$errors->add( 'parcel_required', __( 'Die Parzelle für die Ablesung ist ungültig.', KGVVM_TEXT_DOMAIN ) );
|
|
}
|
|
|
|
if ( $data['meter_id'] < 1 ) {
|
|
$errors->add( 'meter_required', __( 'Der ausgewählte Zähler ist ungültig.', KGVVM_TEXT_DOMAIN ) );
|
|
}
|
|
|
|
if ( '' === $data['reading_date'] ) {
|
|
$errors->add( 'reading_date_required', __( 'Bitte ein Ablesedatum angeben.', KGVVM_TEXT_DOMAIN ) );
|
|
}
|
|
|
|
if ( '' === $data['reading_value'] || ! is_numeric( $data['reading_value'] ) ) {
|
|
$errors->add( 'reading_value_required', __( 'Bitte einen gültigen Zählerstand eingeben.', KGVVM_TEXT_DOMAIN ) );
|
|
} elseif ( (float) $data['reading_value'] < 0 ) {
|
|
$errors->add( 'reading_value_negative', __( 'Der Zählerstand darf nicht negativ sein.', KGVVM_TEXT_DOMAIN ) );
|
|
}
|
|
|
|
return $errors;
|
|
}
|
|
|
|
/**
|
|
* Sanitize one cost entry.
|
|
*
|
|
* @param array $data Raw request data.
|
|
* @return array
|
|
*/
|
|
public function sanitize_cost_entry( $data ) {
|
|
$unit_amount = isset( $data['unit_amount'] ) ? str_replace( ',', '.', wp_unslash( $data['unit_amount'] ) ) : '';
|
|
$entry_year = $this->sanitize_cost_year( $data );
|
|
$distribution_type = sanitize_key( wp_unslash( isset( $data['distribution_type'] ) ? $data['distribution_type'] : 'parcel' ) );
|
|
|
|
return array(
|
|
'entry_year' => $entry_year,
|
|
'name' => sanitize_text_field( wp_unslash( isset( $data['name'] ) ? $data['name'] : '' ) ),
|
|
'distribution_type' => $distribution_type,
|
|
'unit_amount' => '' === trim( (string) $unit_amount ) ? '' : (float) $unit_amount,
|
|
'total_cost' => 0.0,
|
|
'note' => sanitize_textarea_field( wp_unslash( isset( $data['note'] ) ? $data['note'] : '' ) ),
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Validate one cost entry.
|
|
*
|
|
* @param array $data Sanitized data.
|
|
* @return \WP_Error
|
|
*/
|
|
public function validate_cost_entry( $data ) {
|
|
$errors = $this->validate_cost_year( $data['entry_year'] );
|
|
|
|
if ( '' === $data['name'] ) {
|
|
$errors->add( 'cost_name_required', __( 'Bitte einen Namen für den Kostenposten eingeben.', KGVVM_TEXT_DOMAIN ) );
|
|
}
|
|
|
|
if ( ! in_array( $data['distribution_type'], array( 'parcel', 'member' ), true ) ) {
|
|
$errors->add( 'cost_distribution_required', __( 'Bitte auswählen, ob der Betrag pro Parzelle oder pro Mitglied gilt.', KGVVM_TEXT_DOMAIN ) );
|
|
}
|
|
|
|
if ( '' === $data['unit_amount'] || ! is_numeric( $data['unit_amount'] ) ) {
|
|
$errors->add( 'cost_unit_amount_required', __( 'Bitte einen gültigen Betrag eingeben.', KGVVM_TEXT_DOMAIN ) );
|
|
} elseif ( (float) $data['unit_amount'] < 0 ) {
|
|
$errors->add( 'cost_unit_amount_negative', __( 'Der Betrag darf nicht negativ sein.', KGVVM_TEXT_DOMAIN ) );
|
|
}
|
|
|
|
return $errors;
|
|
}
|
|
|
|
/**
|
|
* Sanitize the selected cost year.
|
|
*
|
|
* @param array $data Raw request data.
|
|
* @return int
|
|
*/
|
|
public function sanitize_cost_year( $data ) {
|
|
return isset( $data['entry_year'] ) ? absint( $data['entry_year'] ) : 0;
|
|
}
|
|
|
|
/**
|
|
* Sanitize yearly water and electricity prices.
|
|
*
|
|
* @param array $data Raw request data.
|
|
* @return array
|
|
*/
|
|
public function sanitize_cost_year_settings( $data ) {
|
|
$power_price = isset( $data['power_price_per_kwh'] ) ? str_replace( ',', '.', wp_unslash( $data['power_price_per_kwh'] ) ) : '';
|
|
$water_price = isset( $data['water_price_per_m3'] ) ? str_replace( ',', '.', wp_unslash( $data['water_price_per_m3'] ) ) : '';
|
|
|
|
return array(
|
|
'entry_year' => $this->sanitize_cost_year( $data ),
|
|
'section_id' => absint( isset( $data['section_id'] ) ? $data['section_id'] : 0 ),
|
|
'power_price_per_kwh' => '' === trim( (string) $power_price ) ? null : (float) $power_price,
|
|
'water_price_per_m3' => '' === trim( (string) $water_price ) ? null : (float) $water_price,
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Validate the selected cost year.
|
|
*
|
|
* @param int $entry_year Year value.
|
|
* @return \WP_Error
|
|
*/
|
|
public function validate_cost_year( $entry_year ) {
|
|
$errors = new \WP_Error();
|
|
$current_year = (int) gmdate( 'Y' ) + 10;
|
|
|
|
if ( $entry_year < 2000 || $entry_year > $current_year ) {
|
|
$errors->add( 'invalid_entry_year', __( 'Bitte ein gültiges Jahr für den Kostenposten auswählen.', KGVVM_TEXT_DOMAIN ) );
|
|
}
|
|
|
|
return $errors;
|
|
}
|
|
|
|
/**
|
|
* Validate yearly price settings.
|
|
*
|
|
* @param array $data Sanitized year settings.
|
|
* @return \WP_Error
|
|
*/
|
|
public function validate_cost_year_settings( $data ) {
|
|
$errors = $this->validate_cost_year( $data['entry_year'] );
|
|
|
|
if ( $data['section_id'] < 1 ) {
|
|
$errors->add( 'invalid_section', __( 'Bitte eine Sparte auswählen.', KGVVM_TEXT_DOMAIN ) );
|
|
}
|
|
|
|
if ( null !== $data['power_price_per_kwh'] && ( ! is_numeric( $data['power_price_per_kwh'] ) || (float) $data['power_price_per_kwh'] < 0 ) ) {
|
|
$errors->add( 'invalid_power_price', __( 'Bitte einen gültigen Preis pro kWh eingeben.', KGVVM_TEXT_DOMAIN ) );
|
|
}
|
|
|
|
if ( null !== $data['water_price_per_m3'] && ( ! is_numeric( $data['water_price_per_m3'] ) || (float) $data['water_price_per_m3'] < 0 ) ) {
|
|
$errors->add( 'invalid_water_price', __( 'Bitte einen gültigen Preis pro m³ eingeben.', KGVVM_TEXT_DOMAIN ) );
|
|
}
|
|
|
|
return $errors;
|
|
}
|
|
|
|
/**
|
|
* Normalize optional date fields to Y-m-d.
|
|
*
|
|
* @param string $value Raw value.
|
|
* @return string|null
|
|
*/
|
|
private function normalize_date( $value ) {
|
|
$value = trim( (string) wp_unslash( $value ) );
|
|
|
|
if ( '' === $value ) {
|
|
return '';
|
|
}
|
|
|
|
$timestamp = strtotime( $value );
|
|
|
|
if ( false === $timestamp ) {
|
|
return '';
|
|
}
|
|
|
|
return date( 'Y-m-d', $timestamp );
|
|
}
|
|
}
|