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' ) ); $is_mandatory = isset( $data['is_mandatory'] ) && '1' === (string) wp_unslash( $data['is_mandatory'] ); 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, 'is_mandatory' => $is_mandatory, '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 ); } }