> */ public function for_customer( int $customer_id ): array { $table = Tables::name( 'customer_contacts' ); $rows = $this->rows( "SELECT * FROM {$table} WHERE customer_id = %d ORDER BY is_primary DESC, id ASC", array( $customer_id ) ); return array_map( array( $this, 'hydrate' ), $rows ); } /** * Finds a contact. * * @since 0.1.0 * * @param int $id Contact id. * @return array|null */ public function find( int $id ): ?array { $table = Tables::name( 'customer_contacts' ); $row = $this->row( "SELECT * FROM {$table} WHERE id = %d", array( $id ) ); return null === $row ? null : $this->hydrate( $row ); } /** * Adds a contact. * * @since 0.1.0 * * @param int $customer_id Customer id. * @param array $data name, email, phone, job_role, is_primary. * @return int New id, or 0 on failure. */ public function insert( int $customer_id, array $data ): int { return $this->insert_row( Tables::name( 'customer_contacts' ), array( 'customer_id' => $customer_id, 'name' => (string) $data['name'], 'email' => (string) $data['email'], 'phone' => (string) $data['phone'], 'job_role' => (string) $data['job_role'], 'is_primary' => empty( $data['is_primary'] ) ? 0 : 1, 'created_at_gmt' => Date::now_gmt(), ), array( '%d', '%s', '%s', '%s', '%s', '%d', '%s' ) ); } /** * Updates a contact. * * @since 0.1.0 * * @param int $id Contact id. * @param array $data name, email, phone, job_role, is_primary. * @return bool */ public function update( int $id, array $data ): bool { return false !== $this->wpdb->update( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching Tables::name( 'customer_contacts' ), array( 'name' => (string) $data['name'], 'email' => (string) $data['email'], 'phone' => (string) $data['phone'], 'job_role' => (string) $data['job_role'], 'is_primary' => empty( $data['is_primary'] ) ? 0 : 1, ), array( 'id' => $id ), array( '%s', '%s', '%s', '%s', '%d' ), array( '%d' ) ); } /** * Clears the primary flag on every contact of a customer except one. * * @since 0.1.0 * * @param int $customer_id Customer id. * @param int $except_id Contact that keeps the flag. * @return void */ public function clear_primary_except( int $customer_id, int $except_id ): void { $table = Tables::name( 'customer_contacts' ); $this->wpdb->query( $this->prepare( "UPDATE {$table} SET is_primary = 0 WHERE customer_id = %d AND id <> %d", array( $customer_id, $except_id ) ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.PreparedSQL.NotPrepared,WordPress.DB.PreparedSQL.InterpolatedNotPrepared,PluginCheck.Security.DirectDB.UnescapedDBParameter -- Table name from the Tables whitelist; values prepared by prepare(). } /** * Deletes a contact. * * @since 0.1.0 * * @param int $id Contact id. * @return bool */ public function delete( int $id ): bool { return false !== $this->wpdb->delete( Tables::name( 'customer_contacts' ), array( 'id' => $id ), array( '%d' ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching } /** * Deletes all contacts of a customer. * * @since 0.1.0 * * @param int $customer_id Customer id. * @return void */ public function delete_for_customer( int $customer_id ): void { $this->wpdb->delete( Tables::name( 'customer_contacts' ), array( 'customer_id' => $customer_id ), array( '%d' ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching } /** * Casts a row. * * @param array $row Database row. * @return array */ private function hydrate( array $row ): array { $row['id'] = (int) $row['id']; $row['customer_id'] = (int) $row['customer_id']; $row['is_primary'] = (bool) $row['is_primary']; return $row; } }