wpdb = $wpdb; $this->member_table = Schema::table( 'parcel_members' ); $this->tenant_table = Schema::table( 'parcel_tenants' ); } /** * Get WordPress users with the role "Mitglied". * * @return array */ public function get_member_users() { $query = new \WP_User_Query( array( 'role' => Roles::MEMBER_ROLE, 'orderby' => 'display_name', 'order' => 'ASC', 'number' => 500, ) ); return $query->get_results(); } /** * Get assigned member IDs for a parcel. * * @param int $parcel_id Parcel ID. * @return array */ public function get_member_ids_for_parcel( $parcel_id ) { $ids = $this->wpdb->get_col( $this->wpdb->prepare( "SELECT user_id FROM {$this->member_table} WHERE parcel_id = %d", $parcel_id ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared return array_map( 'absint', $ids ); } /** * Get all members assigned to one parcel. * * @param int $parcel_id Parcel ID. * @return array */ public function get_members_for_parcel( $parcel_id ) { $users = $this->wpdb->users; $sql = "SELECT u.ID, u.display_name, u.user_email FROM {$this->member_table} pm INNER JOIN {$users} u ON u.ID = pm.user_id WHERE pm.parcel_id = %d ORDER BY u.display_name ASC"; return $this->wpdb->get_results( $this->wpdb->prepare( $sql, $parcel_id ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared } /** * Get all parcels assigned to a specific user. * * @param int $user_id User ID. * @return array */ public function get_parcels_for_user( $user_id ) { $parcels = Schema::table( 'parcels' ); $sections = Schema::table( 'sections' ); $meters = Schema::table( 'meters' ); $sql = "SELECT p.*, s.name AS section_name, (SELECT meter_number FROM {$meters} wm WHERE wm.parcel_id = p.id AND wm.type = 'water' LIMIT 1) AS water_meter_number, (SELECT meter_number FROM {$meters} em WHERE em.parcel_id = p.id AND em.type = 'power' LIMIT 1) AS power_meter_number FROM {$this->member_table} pm INNER JOIN {$parcels} p ON p.id = pm.parcel_id LEFT JOIN {$sections} s ON s.id = p.section_id WHERE pm.user_id = %d ORDER BY s.name ASC, p.label ASC"; return $this->wpdb->get_results( $this->wpdb->prepare( $sql, $user_id ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared } /** * Check whether a parcel belongs to a given user. * * @param int $user_id User ID. * @param int $parcel_id Parcel ID. * @return bool */ public function user_has_parcel( $user_id, $parcel_id ) { $sql = "SELECT COUNT(*) FROM {$this->member_table} WHERE user_id = %d AND parcel_id = %d"; return (int) $this->wpdb->get_var( $this->wpdb->prepare( $sql, $user_id, $parcel_id ) ) > 0; // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared } /** * Get assigned tenant IDs for a parcel. * * @param int $parcel_id Parcel ID. * @return array */ public function get_tenant_ids_for_parcel( $parcel_id ) { $ids = $this->wpdb->get_col( $this->wpdb->prepare( "SELECT tenant_id FROM {$this->tenant_table} WHERE parcel_id = %d", $parcel_id ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared return array_map( 'absint', $ids ); } /** * Get all members linked to a tenant via assigned parcels. * * @param int $tenant_id Tenant ID. * @return array */ public function get_members_for_tenant( $tenant_id ) { $parcels = Schema::table( 'parcels' ); $users = $this->wpdb->users; $sql = "SELECT DISTINCT u.ID, u.display_name, u.user_email, p.label AS parcel_label FROM {$this->tenant_table} pt INNER JOIN {$parcels} p ON p.id = pt.parcel_id INNER JOIN {$this->member_table} pm ON pm.parcel_id = pt.parcel_id INNER JOIN {$users} u ON u.ID = pm.user_id WHERE pt.tenant_id = %d ORDER BY p.label ASC, u.display_name ASC"; return $this->wpdb->get_results( $this->wpdb->prepare( $sql, $tenant_id ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared } /** * Get all tenants assigned to one parcel. * * @param int $parcel_id Parcel ID. * @return array */ public function get_tenants_for_parcel( $parcel_id ) { $tenants = Schema::table( 'tenants' ); $sql = "SELECT t.* FROM {$this->tenant_table} pt INNER JOIN {$tenants} t ON t.id = pt.tenant_id WHERE pt.parcel_id = %d ORDER BY t.last_name ASC, t.first_name ASC"; return $this->wpdb->get_results( $this->wpdb->prepare( $sql, $parcel_id ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared } /** * Get all parcels assigned to one tenant. * * @param int $tenant_id Tenant ID. * @return array */ public function get_parcels_for_tenant( $tenant_id ) { $parcels = Schema::table( 'parcels' ); $sections = Schema::table( 'sections' ); $sql = "SELECT p.*, s.name AS section_name FROM {$this->tenant_table} pt INNER JOIN {$parcels} p ON p.id = pt.parcel_id LEFT JOIN {$sections} s ON s.id = p.section_id WHERE pt.tenant_id = %d ORDER BY s.name ASC, p.label ASC"; return $this->wpdb->get_results( $this->wpdb->prepare( $sql, $tenant_id ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared } /** * Synchronize member assignments. * * @param int $parcel_id Parcel ID. * @param array $user_ids User IDs. * @return void */ public function sync_member_ids( $parcel_id, $user_ids ) { $user_ids = array_values( array_unique( array_filter( array_map( 'absint', (array) $user_ids ) ) ) ); $this->wpdb->delete( $this->member_table, array( 'parcel_id' => $parcel_id ), array( '%d' ) ); foreach ( $user_ids as $user_id ) { $this->wpdb->insert( $this->member_table, array( 'parcel_id' => $parcel_id, 'user_id' => $user_id, 'created_at' => current_time( 'mysql' ), ), array( '%d', '%d', '%s' ) ); } } /** * Synchronize tenant assignments. * * @param int $parcel_id Parcel ID. * @param array $tenant_ids Tenant IDs. * @return void */ public function sync_tenant_ids( $parcel_id, $tenant_ids ) { $tenant_ids = array_values( array_unique( array_filter( array_map( 'absint', (array) $tenant_ids ) ) ) ); $this->wpdb->delete( $this->tenant_table, array( 'parcel_id' => $parcel_id ), array( '%d' ) ); foreach ( $tenant_ids as $tenant_id ) { $this->wpdb->insert( $this->tenant_table, array( 'parcel_id' => $parcel_id, 'tenant_id' => $tenant_id, 'created_at' => current_time( 'mysql' ), ), array( '%d', '%d', '%s' ) ); } } /** * Check whether a member is assigned to a different parcel. * * @param int $user_id User ID. * @param int $parcel_id Current parcel ID. * @return bool */ public function member_has_other_parcels( $user_id, $parcel_id ) { $sql = "SELECT COUNT(*) FROM {$this->member_table} WHERE user_id = %d AND parcel_id != %d"; return (int) $this->wpdb->get_var( $this->wpdb->prepare( $sql, $user_id, $parcel_id ) ) > 0; // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared } /** * Remove all assignments for a parcel. * * @param int $parcel_id Parcel ID. * @return void */ public function purge_parcel( $parcel_id ) { $this->wpdb->delete( $this->member_table, array( 'parcel_id' => $parcel_id ), array( '%d' ) ); $this->wpdb->delete( $this->tenant_table, array( 'parcel_id' => $parcel_id ), array( '%d' ) ); } /** * Remove all tenant relations before deleting the tenant. * * @param int $tenant_id Tenant ID. * @return void */ public function purge_tenant( $tenant_id ) { $this->wpdb->delete( $this->tenant_table, array( 'tenant_id' => $tenant_id ), array( '%d' ) ); } }