%PDF- %PDF-
Direktori : /home/komfo908/.trash/wp-content.1/plugins/supportcandy/includes/models/ |
Current File : /home/komfo908/.trash/wp-content.1/plugins/supportcandy/includes/models/class-wpsc-customer.php |
<?php if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly! } if ( ! class_exists( 'WPSC_Customer' ) ) : final class WPSC_Customer { /** * Object data in key => val pair. * * @var array */ private $data = array(); /** * Set whether or not current object properties modified * * @var boolean */ private $is_modified = false; /** * Schema for this model * * @var array */ public static $schema = array(); /** * Prevent fields to modify * * @var array */ public static $prevent_modify = array(); /** * DB object caching * * @var array */ private static $cache = array(); /** * Initialize this class * * @return void */ public static function init() { // Apply schema for this model. add_action( 'init', array( __CLASS__, 'apply_schema' ), 2 ); // Get object of this class. add_filter( 'wpsc_load_ref_classes', array( __CLASS__, 'load_ref_class' ) ); // after customer profile update. add_action( 'profile_update', array( __CLASS__, 'customer_profile_update' ), 10, 2 ); // after user registration. add_action( 'user_register', array( __CLASS__, 'register_customer' ), 10, 2 ); } /** * Apply schema for this model * * @return void */ public static function apply_schema() { $schema = array( 'id' => array( 'has_ref' => false, 'ref_class' => '', 'has_multiple_val' => false, ), 'user' => array( 'has_ref' => true, 'ref_class' => 'wp_user', 'has_multiple_val' => false, ), 'ticket_count' => array( 'has_ref' => false, 'ref_class' => '', 'has_multiple_val' => false, ), ); foreach ( WPSC_Custom_Field::$custom_fields as $cf ) { if ( $cf->field == 'customer' ) { $schema[ $cf->slug ] = array( 'has_ref' => $cf->type::$has_ref, 'ref_class' => $cf->type::$ref_class, 'has_multiple_val' => $cf->type::$has_multiple_val, ); } } self::$schema = apply_filters( 'wpsc_customer_schema', $schema ); // Prevent modify. $prevent_modify = array( 'id' ); self::$prevent_modify = apply_filters( 'wpsc_customer_prevent_modify', $prevent_modify ); } /** * Model constructor * * @param int $id - Optional. Data record id to retrive object for. */ public function __construct( $id = 0 ) { global $wpdb; $id = intval( $id ); if ( isset( self::$cache[ $id ] ) ) { $this->data = self::$cache[ $id ]->data; return; } if ( $id > 0 ) { $customer = $wpdb->get_row( "SELECT * FROM {$wpdb->prefix}psmsc_customers WHERE id = " . $id, ARRAY_A ); if ( ! is_array( $customer ) ) { return; } foreach ( $customer as $key => $val ) { $this->data[ $key ] = $val !== null ? $val : ''; } self::$cache[ $id ] = $this; } } /** * Convert object into an array * * @return array */ public function to_array() { return $this->data; } /** * Magic get function to use with object arrow function * * @param string $var_name - variable name. * @return mixed */ public function __get( $var_name ) { if ( ! isset( $this->data[ $var_name ] ) || $this->data[ $var_name ] == null || $this->data[ $var_name ] == '' ) { return self::$schema[ $var_name ]['has_multiple_val'] ? array() : ''; } if ( self::$schema[ $var_name ]['has_multiple_val'] ) { $response = array(); $values = $this->data[ $var_name ] ? explode( '|', $this->data[ $var_name ] ) : array(); foreach ( $values as $val ) { $response[] = self::$schema[ $var_name ]['has_ref'] ? WPSC_Functions::get_object( self::$schema[ $var_name ]['ref_class'], $val ) : $val; } return $response; } else { return self::$schema[ $var_name ]['has_ref'] && $this->data[ $var_name ] ? WPSC_Functions::get_object( self::$schema[ $var_name ]['ref_class'], $this->data[ $var_name ] ) : $this->data[ $var_name ]; } } /** * Magic function to use setting object field with arrow function * * @param string $var_name - (Required) property slug. * @param mixed $value - (Required) value to set for a property. * @return void */ public function __set( $var_name, $value ) { if ( ! isset( $this->data[ $var_name ] ) || in_array( $var_name, self::$prevent_modify ) ) { return; } $data_val = ''; if ( self::$schema[ $var_name ]['has_multiple_val'] ) { $data_vals = array_map( fn( $val ) => is_object( $val ) ? WPSC_Functions::set_object( self::$schema[ $var_name ]['ref_class'], $val ) : $val, $value ); $data_val = $data_vals ? implode( '|', $data_vals ) : ''; } else { $data_val = is_object( $value ) ? WPSC_Functions::set_object( self::$schema[ $var_name ]['ref_class'], $value ) : $value; } if ( $this->data[ $var_name ] == $data_val ) { return; } $this->data[ $var_name ] = $data_val; $this->is_modified = true; } /** * Save changes made * * @return boolean */ public function save() { global $wpdb; if ( ! $this->is_modified ) { return true; } $data = $this->data; $success = true; if ( ! isset( $data['id'] ) ) { $cr = self::insert( $data ); if ( $cr ) { $this->data = $cr->data; $success = true; } else { $success = false; } } else { unset( $data['id'] ); $success = $wpdb->update( $wpdb->prefix . 'psmsc_customers', $data, array( 'id' => $this->data['id'] ) ); } $this->is_modified = false; self::$cache[ $this->id ] = $this; return $success ? true : false; } /** * Insert new record * * @param array $data - insert data. * @return WPSC_Customer */ public static function insert( $data ) { global $wpdb; $user = self::get_by_email( $data['email'] ); if ( $user->id ) { return $user; } $success = $wpdb->insert( $wpdb->prefix . 'psmsc_customers', $data ); if ( ! $success ) { return false; } $customer = new WPSC_Customer( $wpdb->insert_id ); return $customer; } /** * Delete record of given ID * * @param WPSC_Customer $customer - customer object. * @return boolean */ public static function destroy( $customer ) { global $wpdb; // Delete attachments of the customer. $success = $wpdb->update( $wpdb->prefix . 'psmsc_attachments', array( 'is_active' => '0' ), array( 'customer_id' => $customer->id ) ); $success = $wpdb->delete( $wpdb->prefix . 'psmsc_customers', array( 'id' => $customer->id ) ); if ( ! $success ) { return false; } unset( self::$cache[ $customer->id ] ); return true; } /** * Set data to create new object using direct data. Used in find method * * @param array $data - data to set for object. * @return void */ private function set_data( $data ) { foreach ( $data as $var_name => $val ) { $this->data[ $var_name ] = $val !== null ? $val : ''; } } /** * Find records based on given filters * * @param array $filter - array containing array items like search, where, orderby, order, page_no, items_per_page, etc. * @param boolean $is_object - return data as array or object. Default object. * @return mixed */ public static function find( $filter = array(), $is_object = true ) { global $wpdb; $filter['items_per_page'] = isset( $filter['items_per_page'] ) ? $filter['items_per_page'] : 20; $filter['page_no'] = isset( $filter['page_no'] ) ? $filter['page_no'] : 1; $filter['orderby'] = isset( $filter['orderby'] ) ? $filter['orderby'] : 'name'; $filter['order'] = isset( $filter['order'] ) ? $filter['order'] : 'ASC'; $sql = 'SELECT c.* FROM ' . $wpdb->prefix . 'psmsc_customers c '; $join = self::get_joins( $filter ); $where = self::get_where( $filter ); // Add table alice to orderby. $filter['orderby'] = 'c.' . $filter['orderby']; $order = WPSC_Functions::parse_order( $filter ); $limit = WPSC_Functions::parse_limit( $filter ); $group_by = 'GROUP BY c.id '; $sql = $sql . $join . $where . $group_by . $order . $limit; $results = $wpdb->get_results( $sql, ARRAY_A ); // total results. $sql = 'SELECT count(DISTINCT c.id) FROM ' . $wpdb->prefix . 'psmsc_customers c '; $total_items = $wpdb->get_var( $sql . $join . $where ); $response = WPSC_Functions::parse_response( $results, $total_items, $filter ); // Return array. if ( ! $is_object ) { return $response; } // create and return array of objects. $temp_results = array(); foreach ( $response['results'] as $customer ) { $ob = new WPSC_Customer(); $data = array(); foreach ( $customer as $key => $val ) { $data[ $key ] = $val; } $ob->set_data( $data ); $temp_results[] = $ob; } $response['results'] = $temp_results; return $response; } /** * Apply joins to the query if search is needed * * @param array $filter - user filter. * @return array */ private static function get_joins( $filter ) { global $wpdb; $joins = array(); $search = WPSC_Functions::get_filter_search_str( $filter ); if ( $search ) { $joins = array( 'LEFT JOIN ' . $wpdb->users . ' u ON c.user = u.ID' ); } return $joins ? implode( ' ', $joins ) . ' ' : ''; } /** * Get where for find method * * @param array $filter - user filter. * @return array */ private static function get_where( $filter ) { $where = array( '1=1' ); // Load meta filters. $meta_query = isset( $filter['meta_query'] ) ? $filter['meta_query'] : array(); if ( $meta_query ) { $where[] = self::parse_filters( $meta_query ); } $search = WPSC_Functions::get_filter_search_str( $filter ); if ( $search ) { $search_query = array(); // Customers table cols. foreach ( self::$schema as $slug => $schema ) { if ( ! $schema['has_ref'] && $slug != 'id' ) { $search_query[] = 'CONVERT(c.' . $slug . ' USING utf8) LIKE \'%' . $search . '%\''; } } // Users table cols. $users_search = array( 'CONVERT(u.user_login USING utf8) LIKE \'%' . $search . '%\'', 'CONVERT(u.user_nicename USING utf8) LIKE \'%' . $search . '%\'', 'CONVERT(u.user_email USING utf8) LIKE \'%' . $search . '%\'', 'CONVERT(u.display_name USING utf8) LIKE \'%' . $search . '%\'', ); $search_query = array_merge( $search_query, $users_search ); $where[] = implode( ' OR ', $search_query ); } return 'WHERE (' . implode( ') AND (', $where ) . ') '; } /** * Parse user filters for this model * * @param array $filters - user filters. * @return string */ private static function parse_filters( $filters ) { // Invalid filter. if ( ! isset( $filters['relation'] ) || count( $filters ) < 2 ) { return '1=1'; } $relation = $filters['relation']; $filter_str = array(); foreach ( $filters as $key => $filter ) { // Skip if current element is relation indicator. if ( $key === 'relation' ) { continue; } // Invalid filter if it is not an array. if ( ! is_array( $filter ) ) { return '1=1'; } // Call recursively if there is multi-layer filter detected. if ( isset( $filter['relation'] ) ) { $filter_str[] = self::parse_user_filters( $filter ); continue; } // Invalid filter if it does not contain slug, compare and val indexes. $slug = isset( $filter['slug'] ) ? WPSC_Functions::sanitize_sql_key( $filter['slug'] ) : false; $compare = isset( $filter['compare'] ) ? $filter['compare'] : false; $val = isset( $filter['val'] ) ? $filter['val'] : false; if ( ! $slug || ! $compare || $val === false ) { return '1=1'; } // custom filter. if ( $slug === 'custom_query' ) { $filter_str[] = $val; } else { switch ( $compare ) { case '<': case '=': case '>': case '<=': case '>=': if ( self::$schema[ $slug ]['has_multiple_val'] ) { $filter_str[] = '1=1'; break; } $filter_str[] = 'c.' . $slug . ' ' . $compare . ' \'' . esc_sql( $val ) . '\''; break; case 'BETWEEN': $filter_str[] = 'c.' . $slug . ' BETWEEN \'' . esc_sql( $val[0] ) . '\' AND \'' . esc_sql( $val[1] ) . '\''; break; case 'IN': if ( self::$schema[ $slug ]['has_multiple_val'] ) { $filter_str[] = 'c.' . $slug . ' RLIKE \'(^|[|])(' . implode( '|', esc_sql( $val ) ) . ')($|[|])\''; } else { $filter_str[] = 'c.' . $slug . ' IN ( \'' . implode( '\', \'', esc_sql( $val ) ) . '\' )'; } break; case 'NOT IN': if ( self::$schema[ $slug ]['has_multiple_val'] ) { $filter_str[] = 'c.' . $slug . ' NOT RLIKE \'(^|[|])(' . implode( '|', esc_sql( $val ) ) . ')($|[|])\''; } else { $filter_str[] = 'c.' . $slug . ' NOT IN ( \'' . implode( '\', \'', esc_sql( $val ) ) . '\' )'; } break; } } } return count( $filter_str ) > 1 ? '( ' . implode( ' ' . $relation . ' ', $filter_str ) . ' )' : $filter_str[0]; } /** * Load current class to reference classes * * @param array $classes - Associative array of class names indexed by its slug. * @return array */ public static function load_ref_class( $classes ) { $classes['wpsc_customer'] = array( 'class' => __CLASS__, 'save-key' => 'id', ); return $classes; } /** * Customer autocomplete callback * * @param string $term - search term. * @return array */ public static function customer_autocomplete( $term ) { return array_map( fn( $customer )=>array( 'id' => $customer->id, 'title' => sprintf( /* translators: %1$s: Name, %2$s: Email Address */ esc_attr__( '%1$s (%2$s)', 'supportcandy' ), $customer->name, $customer->email ), ), self::customer_search( $term ) ); } /** * Search customer and return array of customer objects. * * @param string $term - search string. * @return array */ public static function customer_search( $term ) { // search in wp user table. $users = ( new WP_User_Query( array( 'search' => '*' . esc_attr( $term ) . '*', 'search_columns' => array( 'user_login', 'user_nicename', 'user_email', 'display_name', ), 'number' => 10, ) ) )->get_results(); // import into customer table if not already exists. foreach ( $users as $user ) { self::get_by_user_id( $user->ID ); } // finally search customer table. $customers = self::find( array( 'search' => $term, 'items_per_page' => 10, ) )['results']; // return results. return array_filter( $customers, function ( $customer ) { return $customer->email !== 'anonymous@anonymous.anonymous'; } ); } /** * Return customer by an email address * * @param string $email - email address. * @return WPSC_Customer */ public static function get_by_email( $email ) { if ( ! $email ) { return new WPSC_Customer(); } $response = self::find( array( 'meta_query' => array( 'relation' => 'AND', array( 'slug' => 'email', 'compare' => '=', 'val' => $email, ), ), ) ); return $response['results'] ? $response['results'][0] : new WPSC_Customer(); } /** * Return customer object by wp user id * * @param int $id - wp user id. * @return boolean */ public static function get_by_user_id( $id ) { if ( ! $id ) { return new WPSC_Customer(); } $response = self::find( array( 'meta_query' => array( 'relation' => 'AND', array( 'slug' => 'user', 'compare' => '=', 'val' => $id, ), ), ) ); if ( $response['results'] ) { return $response['results'][0]; } else { $user = get_user_by( 'id', $id ); if ( ! $user ) { return new WPSC_Customer(); } return self::insert( array( 'user' => $user->ID, 'name' => $user->display_name, 'email' => $user->user_email, ) ); } } /** * Update customer record such as name, email address, user type, etc. when wp user record is updated. * * @param int $user_id - wp user id. * @param WP_User $old_user_data - user object before change. * @return void */ public static function customer_profile_update( $user_id, $old_user_data ) { global $wpdb; $user = get_userdata( $user_id ); $customer = self::get_by_user_id( $user_id ); if ( $customer ) { $customer->name = $user->display_name; // update user_type from "guest" to "registered" as well as customer id for tickets which was created as guest with email address that is now updated. if ( $customer->email != $user->user_email ) { // get the guest customer object of newly added email. Update tickets (if any). $guest_customer = self::get_by_email( $user->user_email ); if ( $guest_customer->id ) { $wpdb->update( $wpdb->prefix . 'psmsc_tickets', array( 'customer' => $customer->id, 'user_type' => 'registered', ), array( 'customer' => $guest_customer->id, ) ); // destroy guest customer. self::destroy( $guest_customer ); } // update customer email. $customer->email = $user->user_email; } $customer->save(); } } /** * Add/update customer record after wp user registration * * @param int $user_id - wp user id. * @param array $user_data - registered user data. * @return void */ public static function register_customer( $user_id, $user_data ) { $user = get_user_by( 'ID', $user_id ); $name = isset( $user->display_name ) ? $user->display_name : $user_data['user_login']; $customer = self::get_by_email( $user_data['user_email'] ); if ( ! $customer->id ) { // Create customer record. $new_customer = array( 'user' => $user_id, 'name' => $name, 'email' => $user_data['user_email'], ); $customer = self::insert( $new_customer ); } else { // update customer record. $customer->user = $user_id; $customer->name = $name; $customer->save(); } } /** * Get object for anonymous customer * * @return WPSC_Customer */ public static function get_anonymous_customer() { $data = array( 'id' => '0', 'name' => 'Anonymous', 'email' => 'anonymous@anonymous.anonymous', ); $object = new WPSC_Customer(); $object->set_data( $data ); return $object; } /** * Update total ticket count for the customer in database * * @return void */ public function update_ticket_count() { global $wpdb; $count = $wpdb->get_var( "SELECT count(id) from {$wpdb->prefix}psmsc_tickets WHERE is_active=1 AND customer=" . $this->id ); $this->ticket_count = $count; $this->save(); } /** * Check whether customer is an agent or not * * @return boolean */ public function is_agent() { $agent = WPSC_Agent::get_by_customer( $this ); return $agent->id ? true : false; } } endif; WPSC_Customer::init();