[Back] <?php
/**
* @property string $full_name
*/
class OsCustomerModel extends OsModel {
var $id,
$uuid,
$first_name,
$last_name,
$password,
$email,
$phone,
$account_nonse,
$status,
$activation_key,
$google_user_id,
$facebook_user_id,
$avatar_image_id,
$is_guest,
$notes,
$admin_notes,
$wordpress_user_id,
$meta_class = 'OsCustomerMetaModel',
$updated_at,
$created_at;
function __construct( $id = false ) {
$this->table_name = LATEPOINT_TABLE_CUSTOMERS;
$this->nice_names = array(
'first_name' => __( 'Customer First Name', 'latepoint' ),
'email' => __( 'Email Address', 'latepoint' ),
'phone' => __( 'Phone Number', 'latepoint' ),
'last_name' => __( 'Customer Last Name', 'latepoint' )
);
parent::__construct( $id );
}
public function generate_data_vars(): array {
return [
'id' => $this->id,
'first_name' => $this->first_name,
'last_name' => $this->last_name,
'full_name' => $this->full_name,
'email' => $this->email,
'phone' => $this->phone
];
}
public function get_meta_by_key( $meta_key, $default = false ) {
if ( $this->is_new_record() ) {
return $default;
}
$meta = new OsCustomerMetaModel();
return $meta->get_by_key( $meta_key, $this->id, $default );
}
/**
* @param int $limit
* @param bool $filter_allowed_records
*
* @return OsOrderModel[]
*/
public function get_orders( int $limit = 0, bool $filter_allowed_records = false ): array {
$orders = new OsOrderModel();
if ( $limit ) {
$orders = $orders->set_limit( $limit );
}
if ( $filter_allowed_records ) {
$orders->filter_allowed_records();
}
return $orders->where( [ 'customer_id' => $this->id ] )->order_by( 'created_at desc' )->get_results_as_models();
}
public function get_initials() {
return mb_substr( $this->first_name, 0, 1 ) . mb_substr( $this->last_name, 0, 1 );
}
public function delete_meta_by_key( $meta_key ) {
if ( $this->is_new_record() ) {
return true;
}
$meta = new OsCustomerMetaModel();
return $meta->delete_by_key( $meta_key, $this->id );
}
public function save_meta_by_key( $meta_key, $meta_value ) {
if ( $this->is_new_record() ) {
return false;
}
$meta = new OsCustomerMetaModel();
return $meta->save_by_key( $meta_key, $meta_value, $this->id );
}
public function set_timezone_name( $timezone_name = false ) {
if ( ! $timezone_name ) {
$timezone_name = OsTimeHelper::get_timezone_name_from_session();
}
$this->save_meta_by_key( 'timezone_name', $timezone_name );
}
public function get_selected_timezone_name() {
if(OsSettingsHelper::is_on('steps_show_timezone_selector')){
return $this->get_meta_by_key( 'timezone_name', OsTimeHelper::get_timezone_name_from_session() );
}else{
return OsTimeHelper::get_wp_timezone_name();
}
}
public function get_selected_timezone_obj() {
$timezone_obj = new DateTimeZone( $this->get_selected_timezone_name() );
return $timezone_obj;
}
public function delete( $id = false ) {
if ( ! $id && isset( $this->id ) ) {
$id = $this->id;
}
$bookings = new OsBookingModel();
$bookings_to_delete = $bookings->where( [ 'customer_id' => $id ] )->get_results_as_models();
if ( $bookings_to_delete ) {
foreach ( $bookings_to_delete as $booking ) {
$booking->delete();
}
}
$orders = new OsOrderModel();
$orders_to_delete = $orders->where( [ 'customer_id' => $id ] )->get_results_as_models();
if ( $orders_to_delete ) {
foreach ( $orders_to_delete as $order ) {
$order->delete();
}
}
$transactions = new OsTransactionModel();
$transactions_to_delete = $transactions->where( [ 'customer_id' => $id ] )->get_results_as_models();
if ( $transactions_to_delete ) {
foreach ( $transactions_to_delete as $transaction ) {
$transaction->delete();
}
}
$customer_metas = new OsCustomerMetaModel();
$customer_metas_to_delete = $customer_metas->where( [ 'object_id' => $id ] )->get_results_as_models();
if ( $customer_metas_to_delete ) {
foreach ( $customer_metas_to_delete as $customer_meta ) {
$customer_meta->delete();
}
}
return parent::delete( $id );
}
public function get_bookings( $limit = false, $filter_allowed_records = false ) {
$bookings = new OsBookingModel();
if ( $limit ) {
$bookings = $bookings->set_limit( $limit );
}
if ( $filter_allowed_records ) {
$bookings->filter_allowed_records();
}
return $bookings->where( [ 'customer_id' => $this->id ] )->get_results_as_models();
}
public function get_past_bookings( $limit = false, $filter_allowed_records = false ) {
$bookings = new OsBookingModel();
if ( $limit ) {
$bookings = $bookings->set_limit( $limit );
}
if ( $filter_allowed_records ) {
$bookings->filter_allowed_records();
}
return $bookings->should_not_be_cancelled()->where( array(
'customer_id' => $this->id,
'OR' => array(
'start_date <' => OsTimeHelper::today_date( 'Y-m-d' ),
'AND' => array(
'start_date' => OsTimeHelper::today_date( 'Y-m-d' ),
'start_time <' => OsTimeHelper::get_current_minutes()
)
)
) )->get_results_as_models();
}
/**
* @return OsBundleModel[]
*/
public function get_not_scheduled_bundles(): array {
$non_scheduled_bundles = [];
$orders = new OsOrderModel();
$orders = $orders->where( [ 'customer_id' => $this->id ] )->get_results_as_models();
if ( $orders ) {
foreach ( $orders as $order ) {
$bundles = $order->get_bundles_from_order_items();
if ( $bundles ) {
foreach ( $bundles as $order_item_id => $bundle ) {
$bundle_services = $bundle->get_services();
foreach ( $bundle_services as $bundle_service ) {
$bookings = new OsBookingModel();
$total_scheduled_bookings = $bookings->where( [ 'order_item_id' => $order_item_id, 'service_id' => $bundle_service->id ] )->should_not_be_cancelled()->count();
if ( $total_scheduled_bookings < $bundle_service->join_attributes['quantity'] ) {
$non_scheduled_bundles[ $order_item_id ] = $bundle;
break;
}
}
}
}
}
}
return $non_scheduled_bundles;
}
public function get_cancelled_bookings( $limit = false, $filter_allowed_records = false ) {
$bookings = new OsBookingModel();
if ( $limit ) {
$bookings = $bookings->set_limit( $limit );
}
if ( $filter_allowed_records ) {
$bookings->filter_allowed_records();
}
return $bookings->should_be_cancelled()->order_by( 'start_date, start_time asc' )->where( [ 'customer_id' => $this->id ] )->get_results_as_models();
}
public function get_future_bookings( $limit = false, $filter_allowed_records = false ) {
$bookings = new OsBookingModel();
if ( $limit ) {
$bookings = $bookings->set_limit( $limit );
}
if ( $filter_allowed_records ) {
$bookings->filter_allowed_records();
}
return $bookings->should_not_be_cancelled()->order_by( 'start_date, start_time asc' )->where( [ 'customer_id' => $this->id ] )->should_be_in_future()->get_results_as_models();
}
public function get_future_bookings_count( $filter_allowed_records = false ) {
$bookings = new OsBookingModel();
if ( $filter_allowed_records ) {
$bookings->filter_allowed_records();
}
return $bookings->should_not_be_cancelled()->where( array(
'customer_id' => $this->id,
'OR' => array(
'start_date >' => OsTimeHelper::today_date( 'Y-m-d' ),
'AND' => array(
'start_date' => OsTimeHelper::today_date( 'Y-m-d' ),
'start_time >' => OsTimeHelper::get_current_minutes()
)
)
) )->count();
}
public function get_total_bookings_count( $filter_allowed_records = false ) {
$bookings = new OsBookingModel();
if ( $filter_allowed_records ) {
$bookings->filter_allowed_records();
}
return $bookings->select( 'count(id) as total_bookings' )->where( array( 'customer_id' => $this->id ) )->count();
}
public function filter_allowed_records(): OsModel {
if ( ! OsRolesHelper::are_all_records_allowed() ) {
$this->select( LATEPOINT_TABLE_CUSTOMERS . '.*' )->join( LATEPOINT_TABLE_BOOKINGS, [ 'customer_id' => LATEPOINT_TABLE_CUSTOMERS . '.id' ] )->group_by( LATEPOINT_TABLE_CUSTOMERS . '.id' );
if ( ! OsRolesHelper::are_all_records_allowed( 'agent' ) ) {
$this->filter_where_conditions( [ LATEPOINT_TABLE_BOOKINGS . '.agent_id' => OsRolesHelper::get_allowed_records( 'agent' ) ] );
}
if ( ! OsRolesHelper::are_all_records_allowed( 'location' ) ) {
$this->filter_where_conditions( [ LATEPOINT_TABLE_BOOKINGS . '.location_id' => OsRolesHelper::get_allowed_records( 'location' ) ] );
}
if ( ! OsRolesHelper::are_all_records_allowed( 'service' ) ) {
$this->filter_where_conditions( [ LATEPOINT_TABLE_BOOKINGS . '.service_id' => OsRolesHelper::get_allowed_records( 'service' ) ] );
}
}
return $this;
}
public function primary_contact_type(){
$contact_type = OsAuthHelper::get_selected_customer_authentication_field_type();
switch($contact_type){
case 'phone':
return $this->phone;
break;
default:
return $this->email;
break;
}
}
public function update_password( $password ) {
// update connected wp user password
if ( OsAuthHelper::can_wp_users_login_as_customers() && $this->wordpress_user_id ) {
$is_logged_in = OsWpUserHelper::get_current_user_id() == $this->wordpress_user_id;
$logged_in_wp_user = $is_logged_in ? OsWpUserHelper::get_current_user() : false;
// user is getting logged out after changing a password - we need to check if the user that we are changing password for is currently logged in, if it is - make sure to log them back in after password change
wp_set_password($password, $this->wordpress_user_id);
if($is_logged_in && $logged_in_wp_user) OsAuthHelper::login_wp_user($logged_in_wp_user);
}
return $this->update_attributes( [ 'password' => wp_hash_password($password), 'is_guest' => false ] );
}
protected function get_full_name() {
return trim( join( ' ', array( $this->first_name, $this->last_name ) ) );
}
protected function get_default_status() {
return 'pending_verification';
}
protected function before_create() {
if ( ! isset( $this->is_guest ) ) {
$this->is_guest = true;
}
if ( empty( $this->status ) ) {
$this->status = $this->get_default_status();
}
if ( empty( $this->password ) ) {
$this->password = wp_hash_password( bin2hex( openssl_random_pseudo_bytes( 8 ) ) );
}
if ( empty( $this->activation_key ) ) {
$this->activation_key = sha1( wp_rand( 10000, 99999 ) . time() . $this->email );
}
if ( empty( $this->account_nonse ) ) {
$this->account_nonse = sha1( wp_rand( 10000, 99999 ) . time() . $this->activation_key );
}
}
public function get_avatar_url() {
return OsCustomerHelper::get_avatar_url( $this );
}
public function get_avatar_image() {
return OsCustomerHelper::get_avatar_image( $this );
}
// if this was a guest account without a set password and social login was not used, you can login just by email
public function can_login_without_password() {
return ( $this->is_guest && empty( $this->google_user_id ) && empty( $this->facebook_user_id ) );
}
public function prepare_data_before_it_is_set( $data ) {
if ( isset( $data['phone'] ) ) {
$data['phone'] = OsUtilHelper::sanitize_phone_number( $data['phone'] );
}
return $data;
}
protected function before_save() {
if ( empty( $this->uuid ) ) {
$this->uuid = OsUtilHelper::generate_uuid();
}
}
public function get_uuid() : string{
if ( !$this->is_new_record() && empty( $this->uuid ) ) {
$this->update_attributes(['uuid' => OsUtilHelper::generate_uuid()]);
}
return $this->uuid ?? '';
}
protected function allowed_params( $role = 'admin' ) {
switch ( $role ) {
case 'admin':
$allowed_params = [
'id',
'uuid',
'first_name',
'last_name',
'email',
'phone',
'avatar_image_id',
'is_guest',
'notes',
'admin_notes',
'wordpress_user_id',
'password'
];
break;
case 'customer':
case 'public':
$allowed_params = [
'first_name',
'last_name',
'email',
'phone',
'avatar_image_id',
'notes',
'password'
];
break;
}
return $allowed_params;
}
protected function params_to_save( $role = 'admin' ) {
$params_to_save = array(
'id',
'uuid',
'first_name',
'last_name',
'email',
'phone',
'password',
'activation_key',
'account_nonse',
'avatar_image_id',
'status',
'is_guest',
'notes',
'admin_notes',
'wordpress_user_id',
'google_user_id',
'facebook_user_id'
);
return $params_to_save;
}
protected function properties_to_validate( $alternative_validation = false ) {
// if alternative validation is enabled - use a different scope of rules (useful when you don't need to run all validations for example on social login)
if ( $alternative_validation ) {
$validations = array(
'email' => array( 'presence', 'email', 'uniqueness' ),
);
} else {
$validations = array(
'first_name' => array( 'presence' ),
'last_name' => array( 'presence' ),
'email' => array( 'presence', 'email', 'uniqueness' ),
);
$default_fields = OsSettingsHelper::get_default_fields_for_customer();
foreach ( $default_fields as $name => $field ) {
if ( $field['required'] && $field['active'] ) {
$validations[ $name ][] = 'presence';
$validations[ $name ] = array_unique( $validations[ $name ] );
} else {
if ( isset( $validations[ $name ] ) ) {
$validations[ $name ] = array_diff( $validations[ $name ], [ 'presence' ] );
}
}
}
$validations = apply_filters( 'latepoint_customer_model_validations', $validations );
}
return $validations;
}
}