196 lines
6.1 KiB
PHP
196 lines
6.1 KiB
PHP
<?php
|
|
/**
|
|
* Parcel repository.
|
|
*
|
|
* @package KGV\VereinManager
|
|
*/
|
|
|
|
namespace KGV\VereinManager\Repositories;
|
|
|
|
use KGV\VereinManager\Schema;
|
|
|
|
if ( ! defined( 'ABSPATH' ) ) {
|
|
exit;
|
|
}
|
|
|
|
class ParcelRepository extends AbstractRepository {
|
|
|
|
/**
|
|
* Resolve table name.
|
|
*
|
|
* @return string
|
|
*/
|
|
protected function resolve_table() {
|
|
return Schema::table( 'parcels' );
|
|
}
|
|
|
|
/**
|
|
* Search parcels with relation information.
|
|
*
|
|
* @param array $args Query arguments.
|
|
* @return array
|
|
*/
|
|
public function search( $args = array() ) {
|
|
$search = isset( $args['s'] ) ? sanitize_text_field( wp_unslash( $args['s'] ) ) : '';
|
|
$status = isset( $args['status'] ) ? sanitize_key( wp_unslash( $args['status'] ) ) : '';
|
|
$section_id = isset( $args['section_id'] ) ? absint( $args['section_id'] ) : 0;
|
|
$orderby = $this->sanitize_orderby( isset( $args['orderby'] ) ? sanitize_key( wp_unslash( $args['orderby'] ) ) : 'label', array( 'label', 'status', 'area', 'annual_rent', 'created_at' ), 'label' );
|
|
$order = $this->sanitize_order( isset( $args['order'] ) ? sanitize_key( wp_unslash( $args['order'] ) ) : 'ASC' );
|
|
$limit = isset( $args['limit'] ) ? absint( $args['limit'] ) : 0;
|
|
$paged = isset( $args['paged'] ) ? max( 1, absint( $args['paged'] ) ) : 1;
|
|
$offset = $limit > 0 ? ( $paged - 1 ) * $limit : 0;
|
|
|
|
$meters = Schema::table( 'meters' );
|
|
$parcel_members = Schema::table( 'parcel_members' );
|
|
$parcel_tenants = Schema::table( 'parcel_tenants' );
|
|
$sections = Schema::table( 'sections' );
|
|
|
|
$sql = "SELECT p.*, s.name AS section_name,
|
|
MAX(CASE WHEN m.type = 'water' THEN m.meter_number ELSE NULL END) AS water_meter_number,
|
|
MAX(CASE WHEN m.type = 'power' THEN m.meter_number ELSE NULL END) AS power_meter_number,
|
|
COUNT(DISTINCT pm.user_id) AS member_count,
|
|
COUNT(DISTINCT pt.tenant_id) AS tenant_count
|
|
FROM {$this->table} p
|
|
LEFT JOIN {$sections} s ON s.id = p.section_id
|
|
LEFT JOIN {$meters} m ON m.parcel_id = p.id
|
|
LEFT JOIN {$parcel_members} pm ON pm.parcel_id = p.id
|
|
LEFT JOIN {$parcel_tenants} pt ON pt.parcel_id = p.id
|
|
WHERE 1=1";
|
|
|
|
$params = array();
|
|
|
|
if ( '' !== $search ) {
|
|
$like = '%' . $this->wpdb->esc_like( $search ) . '%';
|
|
$sql .= ' AND (p.label LIKE %s OR p.note LIKE %s)';
|
|
$params[] = $like;
|
|
$params[] = $like;
|
|
}
|
|
|
|
if ( in_array( $status, array( 'free', 'assigned', 'reserved', 'inactive' ), true ) ) {
|
|
$sql .= ' AND p.status = %s';
|
|
$params[] = $status;
|
|
}
|
|
|
|
if ( $section_id > 0 ) {
|
|
$sql .= ' AND p.section_id = %d';
|
|
$params[] = $section_id;
|
|
}
|
|
|
|
$sql .= " GROUP BY p.id ORDER BY p.{$orderby} {$order}, p.id DESC";
|
|
|
|
if ( $limit > 0 ) {
|
|
$sql .= ' LIMIT %d';
|
|
$params[] = $limit;
|
|
|
|
if ( $offset > 0 ) {
|
|
$sql .= ' OFFSET %d';
|
|
$params[] = $offset;
|
|
}
|
|
}
|
|
|
|
if ( ! empty( $params ) ) {
|
|
return $this->wpdb->get_results( $this->wpdb->prepare( $sql, $params ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
|
|
}
|
|
|
|
return $this->wpdb->get_results( $sql ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared,WordPress.DB.DirectDatabaseQuery.DirectQuery
|
|
}
|
|
|
|
/**
|
|
* Count parcels for the current filter set.
|
|
*
|
|
* @param array $args Query arguments.
|
|
* @return int
|
|
*/
|
|
public function count_filtered( $args = array() ) {
|
|
$search = isset( $args['s'] ) ? sanitize_text_field( wp_unslash( $args['s'] ) ) : '';
|
|
$status = isset( $args['status'] ) ? sanitize_key( wp_unslash( $args['status'] ) ) : '';
|
|
$section_id = isset( $args['section_id'] ) ? absint( $args['section_id'] ) : 0;
|
|
$sql = "SELECT COUNT(*) FROM {$this->table} p WHERE 1=1";
|
|
$params = array();
|
|
|
|
if ( '' !== $search ) {
|
|
$like = '%' . $this->wpdb->esc_like( $search ) . '%';
|
|
$sql .= ' AND (p.label LIKE %s OR p.note LIKE %s)';
|
|
$params[] = $like;
|
|
$params[] = $like;
|
|
}
|
|
|
|
if ( in_array( $status, array( 'free', 'assigned', 'reserved', 'inactive' ), true ) ) {
|
|
$sql .= ' AND p.status = %s';
|
|
$params[] = $status;
|
|
}
|
|
|
|
if ( $section_id > 0 ) {
|
|
$sql .= ' AND p.section_id = %d';
|
|
$params[] = $section_id;
|
|
}
|
|
|
|
if ( ! empty( $params ) ) {
|
|
return (int) $this->wpdb->get_var( $this->wpdb->prepare( $sql, $params ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
|
|
}
|
|
|
|
return (int) $this->wpdb->get_var( $sql ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared,WordPress.DB.DirectDatabaseQuery.DirectQuery
|
|
}
|
|
|
|
/**
|
|
* Save or update parcel.
|
|
*
|
|
* @param array $data Parcel data.
|
|
* @param int $id Optional parcel ID.
|
|
* @return int|false
|
|
*/
|
|
public function save( $data, $id = 0 ) {
|
|
$payload = array(
|
|
'label' => $data['label'],
|
|
'section_id' => $data['section_id'],
|
|
'area' => $data['area'],
|
|
'annual_rent' => $data['annual_rent'],
|
|
'status' => $data['status'],
|
|
'note' => $data['note'],
|
|
'updated_at' => $this->now(),
|
|
);
|
|
|
|
$formats = array( '%s', '%d', '%f', '%f', '%s', '%s', '%s' );
|
|
|
|
if ( null === $payload['area'] ) {
|
|
$payload['area'] = null;
|
|
$formats[2] = '%s';
|
|
}
|
|
|
|
if ( null === $payload['annual_rent'] ) {
|
|
$payload['annual_rent'] = null;
|
|
$formats[3] = '%s';
|
|
}
|
|
|
|
if ( $id > 0 ) {
|
|
$this->wpdb->update( $this->table, $payload, array( 'id' => $id ), $formats, array( '%d' ) );
|
|
return $id;
|
|
}
|
|
|
|
$payload['created_at'] = $this->now();
|
|
$this->wpdb->insert( $this->table, $payload, array( '%s', '%d', $formats[2], $formats[3], '%s', '%s', '%s', '%s' ) );
|
|
|
|
return $this->wpdb->insert_id;
|
|
}
|
|
|
|
/**
|
|
* Check whether a parcel label already exists in the same section.
|
|
*
|
|
* @param string $label Parcel label.
|
|
* @param int $section_id Section ID.
|
|
* @param int $exclude_id Optional parcel ID.
|
|
* @return bool
|
|
*/
|
|
public function label_exists( $label, $section_id, $exclude_id = 0 ) {
|
|
$sql = "SELECT COUNT(*) FROM {$this->table} WHERE label = %s AND section_id = %d";
|
|
$params = array( $label, $section_id );
|
|
|
|
if ( $exclude_id > 0 ) {
|
|
$sql .= ' AND id != %d';
|
|
$params[] = $exclude_id;
|
|
}
|
|
|
|
return (int) $this->wpdb->get_var( $this->wpdb->prepare( $sql, $params ) ) > 0; // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
|
|
}
|
|
}
|