<?php
/**
 * Its used for Base model.
 *
 * @since: 21/09/2021
 * @author: Sarwar Hasan
 * @version 1.0.0
 * @package Appsbd\V1\Core
 */

namespace Appsbd_Lite\V4\Core;

use Appsbd_Lite\V4\libs\AppInput;

if ( ! class_exists( __NAMESPACE__ . '\BaseModel' ) ) {


	/**
	 * Class BaseModel
	 *
	 * @package Appsbd\V1\Core
	 */
	abstract class BaseModel {
		/**
		 * Its property validations
		 *
		 * @var array
		 */
		protected $validations;
		/**
		 * Its property set_properties
		 *
		 * @var array
		 */
		protected $set_properties;
		/**
		 * Its property likes_fields
		 *
		 * @var array
		 */
		protected $likes_fields;

		/**
		 * Its property order_by_fields
		 *
		 * @var array
		 */
		protected $order_by_fields = array();
		/**
		 * Its property set_option
		 *
		 * @var array
		 */
		protected $set_option;
		/**
		 * Its property set option type AND or OR
		 *
		 * @var array
		 */
		protected $set_option_type = array();
		/**
		 * Its property update_where_extra_field
		 *
		 * @var array
		 */
		protected $update_where_extra_field;
		/**
		 * Its property update_where_extra_field_option
		 *
		 * @var array
		 */
		protected $update_where_extra_field_option = array();
		/**
		 * Its property table_name
		 *
		 * @var string
		 */
		protected $table_name;
		/**
		 * Its property table_short_form
		 *
		 * @var string
		 */
		protected $table_short_form = '';
		/**
		 * Its property primary_key
		 *
		 * @var int
		 */
		protected $primary_key;
		/**
		 * Its property unique_key
		 *
		 * @var array
		 */
		protected $unique_key;
		/**
		 * Its property multi_key
		 *
		 * @var array
		 */
		protected $multi_key;
		/**
		 * Its property auto_inc_field
		 *
		 * @var array
		 */
		protected $auto_inc_field;
		/**
		 * Its property my_sql_error
		 *
		 * @var string
		 */
		protected $my_sql_error;
		/**
		 * Its property setted_propertyfor_log
		 *
		 * @var string
		 */
		public $setted_propertyfor_log = '';
		/**
		 * Its property html_input_field
		 *
		 * @var array
		 */
		protected $html_input_field = array();
		/**
		 * Its property is_where_set
		 *
		 * @var bool
		 */
		protected $is_where_set = false;
		/**
		 * Its property is_validation_rule
		 *
		 * @var bool
		 */
		protected $is_validation_rule = false;
		/**
		 * Its property quries
		 *
		 * @var array
		 */
		private static $quries = array();
		/**
		 * Its property group_by
		 *
		 * @var null
		 */
		private $group_by = null;
		/**
		 * Its property avoid_custom_check
		 *
		 * @var bool
		 */
		private $avoid_custom_check = false;
		/**
		 * Its property check_cache
		 *
		 * @var bool
		 */
		protected $check_cache = false;
		/**
		 * Its property cache_time
		 *
		 * @var int
		 */
		protected $cache_time = 300; 
		/**
		 * Its property kernel_object
		 *
		 * @var null
		 */
		protected $kernel_object = null;
		/**
		 * Its property app_base_name
		 *
		 * @var string
		 */
		protected $app_base_name = '';
		/**
		 * Its property join_objects
		 *
		 * @var array
		 */
		protected $join_objects = array();
		/**
		 * Its property db
		 *
		 * @var string
		 */
		protected $db;
		/**
		 * Its property query_builder
		 *
		 * @var QueryBuilder
		 */
		private $query_builder;

		/**
		 * Its property date_fields
		 *
		 * @var array
		 */
		protected $date_fields = array();

		/**
		 * BaseModel constructor.
		 */
		public function __construct() {
			global $wpdb;
			$this->db =& $wpdb;

			$this->query_builder                   = new QueryBuilder();
			$this->table_short_form                = '';
			$this->set_properties                  = array();
			$this->set_option                      = array();
			$this->update_where_extra_field        = array();
			$this->update_where_extra_field_option = array();
			$this->unique_key                      = array();
			$this->multi_key                       = array();
			$this->auto_inc_field                  = array();
			$this->likes_fields                    = array();
		}

		/**
		 * The get db object is generated by appsbd
		 *
		 * @return \wpdb
		 */
		public static function &get_db_object() {
			global $wpdb;
			return $wpdb;
		}
		/**
		 * The _e is generated by appsbd
		 *
		 * @param any  $string Its string param.
		 * @param null $parameter Its parameter param.
		 * @param null $_ Its _ param.
		 */
		public function esc_attr_e( $string, $parameter = null, $_ = null ) {
			$args = func_get_args();
			echo esc_attr( call_user_func_array( array( $this, '__' ), $args ) );
		}


		/**
		 * The settedPropertyforLog is generated by appsbd
		 *
		 * @return string
		 */
		public function setted_propertyfor_log() {
			return $this->setted_propertyfor_log;
		}


		/**
		 * The _ee is generated by appsbd
		 *
		 * @param any  $string Its string param.
		 * @param null $parameter Its parameter param.
		 * @param null $_ Its _ param.
		 */
		public function _ee( $string, $parameter = null, $_ = null ) {
			$args = func_get_args();
			foreach ( $args as &$arg ) {
				if ( is_string( $arg ) ) {
					$arg = $this->__( $arg );
				}
			}
			echo esc_attr( call_user_func_array( array( $this, '__' ), $args ) );
		}


		/**
		 * The ___ is generated by appsbd
		 *
		 * @param any  $string Its string param.
		 * @param null $parameter Its parameter param.
		 * @param null $_ Its _ param.
		 *
		 * @return mixed
		 */
		public function ___( $string, $parameter = null, $_ = null ) {
			$args = func_get_args();
			foreach ( $args as &$arg ) {
				if ( is_string( $arg ) ) {
					$arg = $this->__( $arg );
				}
			}

			return call_user_func_array( array( $this, '__' ), $args );
		}


		/**
		 * The __ is generated by appsbd
		 *
		 * @param any  $string Its string param.
		 * @param null $parameter Its parameter param.
		 * @param null $_ Its _ param.
		 *
		 * @return mixed
		 */
		public function __( $string, $parameter = null, $_ = null ) {
			$args    = func_get_args();
			$msg = call_user_func_array( '__', array( $args[0], $this->app_base_name ) );
			$args[0] = $msg;
			if ( count( $args ) > 1 ) {
				$msg = call_user_func_array( 'sprintf', $args );
			} else {
				$msg = $args[0];
			}

			return $msg;
		}


		/**
		 * The CheckCache is generated by appsbd
		 *
		 * @param bool $set_value Its set_value param.
		 * @param int  $cache_time Its cache_time param.
		 */
		public function check_cache( $set_value = true, $cache_time = 0 ) {

		}


		/**
		 * The getTextByKey is generated by appsbd
		 *
		 * @param any  $property Its property param.
		 * @param bool $is_tag Its is_tag param.
		 * @param null $key Its key param.
		 *
		 * @return mixed|string|null
		 */
		public function get_text_by_key( $property, $is_tag = true, $key = null ) {
			if ( $is_tag ) {
				$data = $this->get_property_options_tag( $property );
			} else {
				$data = $this->get_property_options( $property );
			}
			if ( ! empty( $key ) || property_exists( $this, $property ) ) {
				if ( empty( $key ) ) {
					$key = $this->$property;
				}

				return ! empty( $data[ $key ] ) ? $data[ $key ] : $key;
			} else {
				return 'Undefined Property';
			}
		}


		/**
		 * The AddWarning is generated by appsbd
		 *
		 * @param any  $message Its message param.
		 * @param null $parameter Its parameter param.
		 * @param null $_ Its _ param.
		 */
		public function add_warning( $message, $parameter = null, $_ = null ) {
			$args   = func_get_args();
			$message = call_user_func_array( array( $this, '___' ), $args );
			\Appsbd_Lite\V4\Core\Kernel_Lite::add_warning( $message );
		}


		/**
		 * The AddError is generated by appsbd
		 *
		 * @param any  $message Its message param.
		 * @param null $parameter Its parameter param.
		 * @param null $_ Its _ param.
		 */
		public function add_error( $message, $parameter = null, $_ = null ) {
			$args    = func_get_args();
			$message = call_user_func_array( array( $this, '___' ), $args );
			\Appsbd_Lite\V4\Core\Kernel_Lite::add_error( $message );
		}


		/**
		 * The AddInfo is generated by appsbd
		 *
		 * @param any  $message Its message param.
		 * @param null $parameter Its parameter param.
		 * @param null $_ Its _ param.
		 */
		public function add_info( $message, $parameter = null, $_ = null ) {
			$args    = func_get_args();
			$message = call_user_func_array( array( $this, '__' ), $args );
			\Appsbd_Lite\V4\Core\Kernel_Lite::add_info( $message );
		}


		/**
		 * The GetTotalQueriesForLog is generated by appsbd
		 *
		 * @return string
		 */
		public static function get_total_queries_for_log() {
			$response = '';
			if ( ! empty( self::$quries ) ) {
				foreach ( self::$quries as $qur ) {
					$qur       = str_replace( "\n", '', $qur );
					$response .= ( $qur ) . ";\n";
				}
			}

			return $response;
		}


		/**
		 * The GetTotalQueriesCountStr is generated by appsbd
		 *
		 * @return string
		 */
		public static function get_total_queries_count_str() {
			$total = count( self::$quries );

			return "Total quries(s) = $total";
		}


		/**
		 * The setTableShortName is generated by appsbd.
		 *
		 * @param any $name Its name param.
		 */
		public function set_table_short_name( $name ) {
			$this->table_short_form = $name;
		}

		/**
		 * The create db table is generated by appsbd.
		 */
		public static function create_db_table() {
			return;
		}

		/**
		 * The drop db table is generated by appsbd.
		 */
		public function drop_db_table() {
			if ( ! empty( $this->table_name ) ) {
				$table_name = self::get_db_object()->prefix . $this->table_name;
				$sql        = "DROP TABLE IF EXISTS $table_name;";
				self::get_db_object()->query( $sql );
			}
		}


		/**
		 * The CheckBasicCheck is generated by appsbd
		 *
		 * @return bool
		 */
		protected function check_basic_check() {
			if ( empty( $this->table_name ) ) {
				appsbd_add_model_errors_code_v1( 'E002' );

				return false;
			}

			return true;
		}


		/**
		 * The doFieldValueFilter is generated by appsbd
		 *
		 * @param any $name Its name param.
		 * @param any $post_value Its post_value param.
		 * @param any $is_xs_clean Its is_xs_clean param.
		 */
		protected function do_field_value_filter( $name, &$post_value, $is_xs_clean ) {
		}


		/**
		 * The GetPostValue is generated by appsbd
		 *
		 * @param any    $name Its name param.
		 * @param string $default Its default param.
		 * @param bool   $is_xs_clean Its is_xs_clean param.
		 *
		 * @return mixed|string
		 */
		public function get_post_value( $name, $default = '', $is_xs_clean = true ) {
			$obj_data = $this->$name;
			if ( ! empty( $this->$name ) || ( '0_-A' === is_string( $obj_data ) && $obj_data . '_-A' ) ) {
				$default = $this->$name;
			}
			$post_value = ! empty( $this->get_post_value( $name ) ) ? $this->get_post_value( $name ) : $default;
			$this->do_field_value_filter( $name, $post_value, $is_xs_clean );

			return ! empty( $post_value ) ? $post_value : $default;
		}


		/**
		 * The insert_id is generated by appsbd
		 *
		 * @return mixed
		 */
		public function insert_id() {
			return $this->db->insert_id;
		}


		/**
		 * The getDBError is generated by appsbd
		 *
		 * @return mixed
		 */
		public function get_db_error() {
			return $this->db->last_error;
		}

		/**
		 * The set custom model where properties is generated by appsbd
		 */
		protected function set_custom_model_where_properties() {
			return;
		}


		/**
		 * The AddGroupBy is generated by appsbd
		 *
		 * @param any $key Its key param.
		 */
		public function add_group_by( $key ) {
			$this->group_by = $key;
		}


		/**
		 * The AddLike is generated by appsbd
		 *
		 * @param any    $like_fld Its like_fld param.
		 * @param any    $like_value Its like_value param.
		 * @param string $like_side Its like_side param.
		 * @param string $condition_type Its condition type AND or OR.
		 * @param bool   $escape Its for escape enable or not.
		 */
		public function add_like( $like_fld, $like_value, $like_side = 'both', $condition_type = 'AND', $escape = true ) {
			if ( property_exists( $this, $like_fld ) ) {
				$std                  = new \stdClass();
				$std->field           = $like_fld;
				$std->value           = $like_value;
				$std->likeside        = $like_side;
				$std->condition_type  = $condition_type;
				$std->is_not_like     = false;
				$std->escape          = $escape;
				$this->likes_fields[] = $std;
			}
		}

		/**
		 * The add order by is generated by appsbd
		 *
		 * @param mixed $prop Its prop param.
		 * @param mixed $order Its order param.
		 */
		public function add_order_by( $prop, $order ) {
			$std                     = new \stdClass();
			$std->field              = $prop;
			$std->ord                = $order;
			$this->order_by_fields[] = $std;
		}
		/**
		 * The AddLike is generated by appsbd
		 *
		 * @param any    $like_fld Its like_fld param.
		 * @param any    $like_value Its like_value param.
		 * @param string $like_side Its like_side param.
		 * @param string $condition_type Its condition type AND or OR.
		 * @param bool   $escape Its for escape enable or not.
		 */
		public function add_not_like( $like_fld, $like_value, $like_side = 'both', $condition_type = 'AND', $escape = true ) {
			if ( property_exists( $this, $like_fld ) ) {
				$std                  = new \stdClass();
				$std->field           = $like_fld;
				$std->value           = $like_value;
				$std->likeside        = $like_side;
				$std->condition_type  = $condition_type;
				$std->is_not_like     = true;
				$std->escape          = $escape;
				$this->likes_fields[] = $std;
			}
		}


		/**
		 * The AvoidCustomModelWhereProperties is generated by appsbd
		 *
		 * @param bool $is_avoid Its is_avoid param.
		 */
		public function avoid_custom_model_where_properties( $is_avoid = true ) {
			$this->avoid_custom_check = $is_avoid;
		}


		/**
		 * The GetPropertyRawOptions is generated by appsbd
		 *
		 * @param any   $property Its property param.
		 * @param false $is_withselect Its is_with_select param.
		 *
		 * @return array|string[]
		 */
		public function get_property_raw_options( $property, $is_withselect = false ) {
			if ( $is_withselect ) {
				return array( '' => 'Select' );
			}

			return array();
		}


		/**
		 * The GetPropertyOptions is generated by appsbd
		 *
		 * @param any   $property Its property param.
		 * @param false $is_with_select Its is_with_select param.
		 *
		 * @return array|string[]
		 */
		public function get_property_options( $property, $is_with_select = false ) {
			$return_obj = $this->get_property_raw_options( $property, $is_with_select );
			foreach ( $return_obj as &$v ) {
				$v = $this->__( $v );
			}

			return $return_obj;
		}


		/**
		 * The GetPropertyOptionsIcon is generated by appsbd
		 *
		 * @param any $property Its property param.
		 *
		 * @return array
		 */
		public function get_property_options_icon( $property ) {
			return array();
		}


		/**
		 * The GetPropertyOptionsColor is generated by appsbd
		 *
		 * @param any $property Its property param.
		 *
		 * @return array
		 */
		public function get_property_options_color( $property ) {
			return array();
		}


		/**
		 * The GetPropertyOptionsTag is generated by appsbd
		 *
		 * @param any    $property Its property param.
		 * @param string $tag Its tag param.
		 * @param string $class_prefix Its class_prefix param.
		 * @param string $class_postfix Its class_postfix param.
		 * @param string $default Its default param.
		 *
		 * @return array|string[]
		 */
		public function get_property_options_tag( $property, $tag = 'span', $class_prefix = 'text-', $class_postfix = '', $default = '' ) {
			$properties = $this->get_property_options( $property );
			if ( count( $properties ) > 0 ) {
				$colors = $this->get_property_options_color( $property );
				$icons  = $this->get_property_options_icon( $property );
				foreach ( $properties as $key => &$value ) {
					$color = ! empty( $colors[ $key ] ) ? $colors[ $key ] : $default;
					$icon  = ! empty( $icons[ $key ] ) ? '<i class="' . $icons[ $key ] . '"></i>' : '';
					$value = "<{$tag} class=\"{$class_prefix}{$color}{$class_postfix}\">{$icon} {$value}</{$tag}>";
				}
			}

			return $properties;
		}


		/**
		 * The SetDBJoinWhereCondition is generated by appsbd
		 *
		 * @param any  $db Its db param.
		 * @param bool $clear_properties Its clear_properties param.
		 * @param bool $is_select_db Its is_select_db param.
		 */
		public function set_db_join_where_condition( $db, $clear_properties = true, $is_select_db = true ) {
			$this->set_db_select_where_properties( array(), $clear_properties, $is_select_db, $db );
		}


		/**
		 * The SetDBSelectWhereProperties is generated by appsbd
		 *
		 * @param array $extra_param Its extra_param param.
		 * @param bool  $clear_properties Its clear_properties param.
		 * @param bool  $is_select_db Its is_select_db param.
		 * @param null  $db Its db param.
		 *
		 * @return bool
		 */
		protected function set_db_select_where_properties( $extra_param = array(), $clear_properties = true, $is_select_db = true, $db = null ) {
			if ( ! $this->avoid_custom_check ) {
				$this->set_custom_model_where_properties();
			}
			$alreadyadded = array();
			$tbname       = $this->get_table_name() . '.';
			$this->set_custom_param_data();
			if ( empty( $db ) ) {
				if ( $is_select_db ) {
					$db = $this->get_select_db();
				} else {
					$db = $this->get_update_db();
				}
			}
			if ( empty( $this->table_name ) ) {
				return false;
			}

			
			$primary_key = $this->primary_key;
			if ( ! empty( $primary_key ) && isset( $this->set_properties[ $primary_key ] ) ) {
				$type = isset( $this->set_option_type[ $primary_key ] ) ? $this->set_option_type[ $primary_key ] : 'AND';
				if ( ! empty( $this->set_option [ $primary_key ] ) ) {
					$db->where( '(' . $tbname . $primary_key . ' ' . $this->$primary_key . ')', '', false, $type );
				} else {
					$db->where( $tbname . $primary_key, $this->$primary_key, true, $type );
				}
				$alreadyadded[]     = $primary_key;
				$this->is_where_set = true;
			}
			$general_keys = array();
			
			if ( count( $this->unique_key ) > 0 ) {
				if ( is_array( $this->unique_key[0] ) ) {
					$selected_key = '';
					foreach ( $this->unique_key as $pos => $uk ) {
						$general_keys = array_merge( $general_keys, $uk );
						$is_ok        = true;
						foreach ( $uk as $fld ) {
							if ( ! isset( $this->set_properties[ $fld ] ) ) {
								$is_ok = false;
								break;
							}
						}
						if ( $is_ok ) {
							$selected_key = $pos;
						}
					}
					if ( '' != $selected_key ) {
						foreach ( $this->unique_key[ $selected_key ] as $uk ) {
							if ( ! in_array( $uk, $alreadyadded ) && isset( $this->set_properties[ $uk ] ) ) {
								$type = isset( $this->set_option_type[ $uk ] ) ? $this->set_option_type[ $uk ] : 'AND';
								if ( ! empty( $this->set_option [ $uk ] ) ) {
									$db->where( '(' . $tbname . $uk . ' ' . $this->$uk . ')', '', false, $type );
								} else {
									$db->where( $tbname . $uk, $this->$uk, true, $type );
								}
								$alreadyadded[]     = $uk;
								$this->is_where_set = true;
							}
						}
					}
				} else {
					
					foreach ( $this->unique_key as $uk ) {
						if ( ! in_array( $uk, $alreadyadded ) && isset( $this->set_properties[ $uk ] ) ) {
							$type = isset( $this->set_option_type[ $uk ] ) ? $this->set_option_type[ $uk ] : 'AND';
							if ( ! empty( $this->set_option [ $uk ] ) ) {
								$db->where( '(' . $tbname . $uk . ' ' . $this->$uk . ')', '', false, $type );
							} else {
								$db->where( $tbname . $uk, $this->$uk, true, $type );
							}
							$alreadyadded[]     = $uk;
							$this->is_where_set = true;
						}
					}
				}
			}

			
			if ( count( $this->multi_key ) > 0 ) {
				if ( is_array( $this->multi_key[0] ) ) {
					$selected_key = '';
					foreach ( $this->multi_key as $pos => $uk ) {
						$general_keys = array_merge( $general_keys, $uk );
						$is_ok        = true;
						foreach ( $uk as $fld ) {
							if ( ! isset( $this->set_properties[ $fld ] ) ) {
								$is_ok = false;
								break;
							}
						}
						if ( $is_ok ) {
							$selected_key = $pos;
						}
					}
					if ( '' != $selected_key ) {
						foreach ( $this->multi_key[ $selected_key ] as $uk ) {
							if ( ! in_array( $uk, $alreadyadded ) && isset( $this->set_properties[ $uk ] ) ) {
								$type = isset( $this->set_option_type[ $uk ] ) ? $this->set_option_type[ $uk ] : 'AND';
								if ( ! empty( $this->set_option [ $uk ] ) ) {
									$db->where( '(' . $tbname . $uk . $this->set_properties[ $uk ] . ')', '', false, $type );
								} else {
									$db->where( $tbname . $uk, $this->set_properties[ $uk ], true, $type );
								}
								$alreadyadded[]     = $uk;
								$this->is_where_set = true;
							}
						}
					}
				} else {
					
					foreach ( $this->multi_key as $uk ) {
						if ( ! in_array( $uk, $alreadyadded ) && isset( $this->set_properties[ $uk ] ) ) {
							$type = isset( $this->set_option_type[ $uk ] ) ? $this->set_option_type[ $uk ] : 'AND';
							if ( ! empty( $this->set_option [ $uk ] ) ) {
								$db->where( '(' . $tbname . $uk . $this->set_properties[ $uk ] . ')', '', false, $type );
							} else {
								$db->where( $tbname . $uk, $this->set_properties[ $uk ], true, $type );
							}
							$alreadyadded[]     = $uk;
							$this->is_where_set = true;
						}
					}
				}
			}

			
			foreach ( $general_keys as $uk ) {
				if ( ! in_array( $uk, $alreadyadded ) ) {
					if ( isset( $this->set_properties[ $uk ] ) ) {
						$type = isset( $this->set_option_type[ $uk ] ) ? $this->set_option_type[ $uk ] : 'AND';
						if ( ! empty( $this->set_option [ $uk ] ) ) {
							$db->where( '(' . $tbname . $uk . ' ' . $this->$uk . ')', '', false, $type );
						} else {
							$db->where( $tbname . $uk, $this->$uk, true, $type );
						}
						$alreadyadded[]     = $uk;
						$this->is_where_set = true;
					}
				}
			}

			foreach ( $this->set_properties as $key => $value ) {
				if ( property_exists( $this, $key ) && ! in_array( $key, $alreadyadded ) ) {
					$type = isset( $this->set_option_type[ $key ] ) ? $this->set_option_type[ $key ] : 'AND';
					if ( ! empty( $this->set_option [ $key ] ) ) {
						$db->where( '(' . $tbname . $key . ' ' . $this->$key . ')', '', false, $type );
					} else {
						$db->where( $tbname . $key, $this->$key, true, $type );
					}
					$alreadyadded[] = $key;
				}
			}
			if ( is_array( $extra_param ) ) {
				foreach ( $extra_param as $key => $value ) {
					if ( property_exists( $this, $key ) && ! in_array( $key, $alreadyadded ) ) {
						if ( ! empty( $this->set_option [ $key ] ) ) {
							$db->where( '(' . $tbname . $key . ' ' . $value . ')', '', false, $type );
						} else {
							$db->where( $tbname . $key, $value, true, $type );
						}
						$alreadyadded[] = $key;
					}
				}
			}
			
			if ( count( $this->likes_fields ) > 0 ) {
				foreach ( $this->likes_fields as $like_fld ) {
					$db->like( $like_fld->field, $like_fld->value, $like_fld->likeside, $like_fld->escape, $like_fld->condition_type, $like_fld->is_not_like );
				}
			}
			if ( ! empty( $this->group_by ) ) {
				$db->group_by( $this->group_by );
			}
			if ( $clear_properties ) {
				$this->reset_set_for_inset_update();
			}

			return true;
		}


		/**
		 * The SetDBSelectJoinProperties is generated by appsbd
		 *
		 * @param any   $db Its db param.
		 * @param array $extra_param Its extra_param param.
		 * @param bool  $clear_properties Its clear_properties param.
		 *
		 * @return bool
		 */
		public function set_db_select_join_properties( $db, $extra_param = array(), $clear_properties = true ) {
			$alreadyadded = array();
			$tbname       = $this->get_table_name() . '.';

			if ( empty( $this->table_name ) ) {
				return false;
			}

			
			$primary_key = $this->primary_key;
			if ( ! empty( $primary_key ) && isset( $this->set_properties[ $primary_key ] ) ) {
				if ( ! empty( $this->set_option [ $primary_key ] ) ) {
					$db->where( $tbname . $primary_key . $this->$primary_key, '', false );
				} else {
					$db->where( $tbname . $primary_key, $this->$primary_key );
				}
				$alreadyadded[]     = $primary_key;
				$this->is_where_set = true;
			}

			
			foreach ( $this->unique_key as $fk ) {
				foreach ( $fk as $uk ) {
					if ( isset( $this->set_properties[ $uk ] ) ) {
						if ( ! empty( $this->set_option [ $uk ] ) ) {
							$db->where( $tbname . $uk . $this->$uk, '', false );
						} else {
							$db->where( $tbname . $uk, $this->$uk );
						}
						$alreadyadded[]     = $uk;
						$this->is_where_set = true;
					}
				}
			}
			
			foreach ( $this->multi_key as $uk ) {
				if ( isset( $this->set_properties[ $uk ] ) ) {
					if ( ! empty( $this->set_option [ $uk ] ) ) {
						$db->where( $tbname . $uk . $this->set_properties[ $uk ], '', false );
					} else {
						$db->where( $tbname . $uk, $this->set_properties[ $uk ] );
					}
					$alreadyadded[]     = $uk;
					$this->is_where_set = true;
				}
			}
			foreach ( $this->set_properties as $key => $value ) {
				if ( property_exists( $this, $key ) && ! in_array( $key, $alreadyadded ) ) {
					if ( ! empty( $this->set_option [ $key ] ) ) {
						$db->where( $tbname . $key . $this->$key, '', false );
					} else {
						$db->where( $tbname . $key, $this->$key );
					}
					$alreadyadded[] = $key;
				}
			}
			foreach ( $extra_param as $key => $value ) {
				if ( property_exists( $this, $key ) && ! in_array( $key, $alreadyadded ) ) {
					if ( ! empty( $this->set_option [ $key ] ) ) {
						$db->where( $tbname . $key . $value, '', false );
					} else {
						$db->where( $tbname . $key, $value );
					}
					$alreadyadded[] = $key;
				}
			}
			if ( $clear_properties ) {
				$this->set_properties = array();
				$this->set_option     = array();
			}

			return true;
		}


		/**
		 * The Join is generated by appsbd
		 *
		 * @param BaseModel $join_obj Its join_obj param.
		 * @param any       $join_obj_property Its join_obj_property param.
		 * @param any       $main_obj_property Its main_obj_property param.
		 * @param string    $type Its type param.
		 * @param string    $as Its as param.
		 */
		public function join( $join_obj, $join_obj_property, $main_obj_property, $type = '', $as = '' ) {
			if ( ! empty( $as ) ) {
				$join_obj->set_table_short_name( $as );
			}
			$joinobj                    = new ObjectJoin();
			$joinobj->join_obj          = $join_obj;
			$joinobj->join_obj_property = $join_obj_property;
			$joinobj->main_obj_property = $main_obj_property;
			$joinobj->type              = $type;
			$this->join_objects[]       = $joinobj;
		}


		/**
		 * The SetJoinProperties is generated by appsbd
		 *
		 * @param bool $clear_properties Its clear_properties param.
		 */
		protected function set_join_properties( $clear_properties = true ) {
			if ( count( $this->join_objects ) > 0 ) {
				foreach ( $this->join_objects as $jn ) {
					
					$thistblstrproperty = $this->get_table_name_for_join_property( $jn->main_obj_property );
					if ( property_exists( $jn->join_obj, $jn->join_obj_property ) && ! empty( $thistblstrproperty ) ) {
						$tablestr = $jn->join_obj->get_table_name( false );
						$shorttbl = $jn->join_obj->get_table_name();
						$this->get_select_db()->join( $tablestr, " $shorttbl.$jn->join_obj_property=$thistblstrproperty", $jn->type );
						$jn->join_obj->set_db_select_join_properties( $this->get_select_db(), array(), $clear_properties );
					}
				}
			}
		}


		/**
		 * The SetJoinWhereConditions is generated by appsbd
		 *
		 * @param bool $clear_properties Its clear_properties param.
		 * @param bool $is_select_db Its is_select_db param.
		 */
		protected function set_join_where_conditions( $clear_properties = true, $is_select_db = true ) {
			if ( count( $this->join_objects ) > 0 ) {
				foreach ( $this->join_objects as $jn ) {
					
					
					$jn->join_obj->set_db_join_where_condition( $this->get_select_db(), $clear_properties, $is_select_db );
				}
			}
		}


		/**
		 * The getTableNameForJoinProperty is generated by appsbd
		 *
		 * @param any $property_name Its property_name param.
		 *
		 * @return string
		 */
		private function get_table_name_for_join_property( $property_name ) {
			if ( strpos( $property_name, '.' ) !== false ) {
				return $property_name;
			}
			if ( property_exists( $this, $property_name ) ) {
				return $this->get_table_name() . ".$property_name";
			} else {
				if ( count( $this->join_objects ) > 0 ) {
					foreach ( $this->join_objects as $jn ) {
						if ( property_exists( $jn->join_obj, $property_name ) ) {
							return $jn->join_obj->get_table_name() . ".$property_name";
						}
					}
				}
			}

			return '';
		}


		/**
		 * The SetDBUpdateWhereProperties is generated by appsbd
		 *
		 * @param array $extra_param Its extra_param param.
		 * @param bool  $is_check_where_propetry_set_or_not Its is_check_where_propetry_set_or_not param.
		 * @param false $clear_properties Its clear_properties param.
		 *
		 * @return bool
		 */
		protected function set_db_update_where_properties( $extra_param = array(), $is_check_where_propetry_set_or_not = true, $clear_properties = false ) {
			if ( ! $this->check_basic_check() ) {
				return false;
			}
			if ( count( $this->update_where_extra_field ) == 0 ) {
				return false;
			}
			$alreadyadded = array();
			
			$primary_key = $this->primary_key;
			if ( ! empty( $primary_key ) && isset( $this->update_where_extra_field[ $primary_key ] ) ) {
				if ( in_array( $primary_key, $this->update_where_extra_field_option ) ) {
					$this->get_update_db()->where( '(' . $primary_key . $this->update_where_extra_field[ $primary_key ] . ')', '', false );
				} else {
					$this->get_update_db()->where( $primary_key, $this->update_where_extra_field[ $primary_key ] );
				}
				$alreadyadded[] = $primary_key;
			}

			$general_keys = array();
			
			if ( count( $this->unique_key ) > 0 ) {
				if ( is_array( $this->unique_key[0] ) ) {
					$selected_key = '';
					foreach ( $this->unique_key as $pos => $uk ) {
						$general_keys = array_merge( $general_keys, $uk );
						$is_ok        = true;
						foreach ( $uk as $fld ) {
							if ( ! isset( $this->update_where_extra_field[ $fld ] ) ) {
								$is_ok = false;
								break;
							}
						}
						if ( $is_ok ) {
							$selected_key = $pos;
						}
					}
					if ( '' != $selected_key ) {
						foreach ( $this->unique_key[ $selected_key ] as $uk ) {
							if ( isset( $this->update_where_extra_field[ $uk ] ) && ! in_array( $uk, $alreadyadded ) ) {
								if ( in_array( $uk, $this->update_where_extra_field_option ) ) {
									$this->get_update_db()->where( '(' . $uk . $this->update_where_extra_field[ $uk ] . ')', '', false );
								} else {
									$this->get_update_db()->where( $uk, $this->update_where_extra_field[ $uk ] );
								}
								$alreadyadded[] = $uk;
							}
						}
					}
				} else {
					
					
					foreach ( $this->unique_key as $uk ) {
						if ( isset( $this->update_where_extra_field[ $uk ] ) && ! in_array( $uk, $alreadyadded ) ) {
							if ( in_array( $uk, $this->update_where_extra_field_option ) ) {
								$this->get_update_db()->where( '(' . $uk . $this->update_where_extra_field[ $uk ] . ')', '', false );
							} else {
								$this->get_update_db()->where( $uk, $this->update_where_extra_field[ $uk ] );
							}
							$alreadyadded[] = $uk;
						}
					}
				}
			}

			
			if ( count( $this->multi_key ) > 0 ) {
				if ( is_array( $this->multi_key[0] ) ) {
					$selected_key = '';
					foreach ( $this->multi_key as $pos => $uk ) {
						$general_keys = array_merge( $general_keys, $uk );
						$is_ok        = true;
						foreach ( $uk as $fld ) {
							if ( ! isset( $this->update_where_extra_field[ $fld ] ) ) {
								$is_ok = false;
								break;
							}
						}
						if ( $is_ok ) {
							$selected_key = $pos;
						}
					}
					if ( '' != $selected_key ) {
						foreach ( $this->multi_key[ $selected_key ] as $uk ) {
							if ( isset( $this->update_where_extra_field[ $uk ] ) && ! in_array( $uk, $alreadyadded ) ) {
								if ( in_array( $uk, $this->update_where_extra_field_option ) ) {
									$this->get_update_db()->where( '(' . $uk . $this->update_where_extra_field[ $uk ] . ')', '', false );
								} else {
									$this->get_update_db()->where( $uk, $this->update_where_extra_field[ $uk ] );
								}
								$alreadyadded[] = $uk;
							}
						}
					}
				} else {
					
					foreach ( $this->multi_key as $uk ) {
						if ( isset( $this->update_where_extra_field[ $uk ] ) && ! in_array( $uk, $alreadyadded ) ) {
							if ( in_array( $uk, $this->update_where_extra_field_option ) ) {
								$this->get_update_db()->where( '(' . $uk . $this->update_where_extra_field[ $uk ] . ')', '', false );
							} else {
								$this->get_update_db()->where( $uk, $this->update_where_extra_field[ $uk ] );
							}
							$alreadyadded[] = $uk;
						}
					}
				}
			}

			foreach ( $general_keys as $uk ) {
				if ( ! in_array( $uk, $alreadyadded ) ) {
					if ( isset( $this->update_where_extra_field[ $uk ] ) ) {
						if ( in_array( $uk, $this->update_where_extra_field_option ) ) {
							$this->get_update_db()->where( '(' . $uk . $this->update_where_extra_field[ $uk ] . ')', '', false );
						} else {
							$this->get_update_db()->where( $uk, $this->update_where_extra_field[ $uk ] );
						}
						$alreadyadded[]     = $uk;
						$this->is_where_set = true;
					}
				}
			}

			foreach ( $this->update_where_extra_field as $key => $value ) {
				if ( property_exists( $this, $key ) && ! in_array( $key, $alreadyadded ) ) {
					if ( in_array( $key, $this->update_where_extra_field_option ) ) {
						$this->get_update_db()->where( '(' . $key . $this->update_where_extra_field[ $key ] . ')', '', false );
					} else {
						$this->get_update_db()->where( $key, $this->update_where_extra_field[ $key ] );
					}
					$alreadyadded[] = $key;
				}
			}

			foreach ( $extra_param as $key => $value ) {
				if ( property_exists( $this, $key ) && ! in_array( $key, $alreadyadded ) ) {
					$this->get_update_db()->where( $key, $value );
					$alreadyadded[] = $key;
				}
			}
			if ( $is_check_where_propetry_set_or_not ) {
				if ( count( $alreadyadded ) == 0 ) {
					appsbd_add_model_errors_code_v1( 'E004' );

					return false;
				}
			}
			if ( $clear_properties ) {
				$this->update_where_extra_field        = array();
				$this->update_where_extra_field_option = array();
			}

			return true;
		}


		/**
		 * The UnsetAllExcepts is generated by appsbd
		 *
		 * @param String $properties Its properties param.
		 *
		 * @return bool
		 */
		public function unset_all_excepts( string $properties ) {
			$properties = explode( ',', $properties );
			$properties = array_map( 'trim', $properties );
			foreach ( $this->set_properties as $key => $value ) {
				if ( ! in_array( $key, $properties ) ) {
					$this->unset_prperty( $key );
				}
			}

			return count( $this->set_properties ) > 0;
		}

		/**
		 * The unset all update property is generated by appsbd
		 */
		public function unset_all_update_property() {
			$this->update_where_extra_field       = array();
			$this->update_where_extra_field_option = array();
		}


		/**
		 * The SetDBPropertyForInsertOrUpdate is generated by appsbd
		 *
		 * @param false $is_for_update Its is_for_update param.
		 *
		 * @return bool
		 */
		public function set_db_property_for_insert_or_update( $is_for_update = false ) {
			if ( ! $this->check_basic_check() ) {
				return false;
			}
			if ( ! $is_for_update ) {
				$primary_key = $this->primary_key;
				if ( ! empty( $primary_key ) && ! isset( $this->set_properties[ $primary_key ] ) && ! in_array( $primary_key, $this->auto_inc_field ) ) {
					appsbd_add_model_errors_code_v1( 'E002' );

					return false;
				}
			}
			$primary_key = $this->primary_key;
			foreach ( $this->set_properties as $key => $value ) {
				if ( $is_for_update && $primary_key == $key ) {
					continue;
				}
				if ( ! empty( $this->set_option [ $key ] ) ) {
					$this->get_update_db()->set( $key, $this->$key, false );
				} else {
					$this->get_update_db()->set( $key, $this->$key );
				}
			}
			$this->reset_set_for_inset_update( true );

			return true;
		}


		/**
		 * The SetDBLike is generated by appsbd
		 *
		 * @param any    $like_fld Its like_fld param.
		 * @param any    $like_value Its like_value param.
		 * @param string $like_side Its like_side param.
		 * @param bool   $is_select_db Its is_select_db param.
		 */
		public function set_db_like( $like_fld, $like_value, $like_side = 'after', $is_select_db = true ) {
			$db = $is_select_db ? $this->get_select_db() : $this->get_update_db();

			if ( ! empty( $like_fld ) ) {
				if ( property_exists( $this, $like_fld ) ) {
					$db->like( $like_fld, $like_value, $like_side );
				} else {
					if ( count( $this->join_objects ) > 0 ) {
						foreach ( $this->join_objects as $jn ) {
							
							$thistblstrproperty = $this->get_table_name_for_join_property( $like_fld );
							if ( property_exists( $jn->join_obj, $like_fld ) && ! empty( $thistblstrproperty ) ) {
								$like_fld = $thistblstrproperty;
								$db->like( $like_fld, $like_value, $like_side );
								break;
							}
						}
					}
				}
			}
		}


		/**
		 * The SetDBOrder is generated by appsbd
		 *
		 * @param any    $order_by Its order_by param.
		 * @param string $order Its order param.
		 * @param bool   $is_select_db Its is_select_db param.
		 */
		public function set_db_order( $order_by, $order = '', $is_select_db = true ) {
			$db = $is_select_db ? $this->get_select_db() : $this->get_update_db();

			if ( ! empty( $order_by ) && is_string( $order_by ) && property_exists( $this, $order_by ) ) {
				$db->order_by( $order_by, $order );
			} elseif ( ! empty( $order_by ) && is_string( $order_by ) && property_exists(
					$this,
					$order_by
				) && empty( $order ) ) {
				$db->order_by( $order_by );
			} elseif ( is_array( $order_by ) ) {
				$forder = '';
				foreach ( $order_by as $op => $ov ) {
					$forder .= "$op $ov ,";
				}
				$forder = rtrim( $forder, ',' );
				$db->order_by( $forder );
			} else {
				if ( ! empty( $this->order_by_fields ) && is_array( $this->order_by_fields ) ) {
					$forder = '';
					foreach ( $this->order_by_fields as $order_by_field ) {
						$forder .= "{$order_by_field->field} {$order_by_field->ord} ,";
					}
					$forder = @rtrim( $forder, ',' );
					if ( ! empty( $forder ) ) {
						$db->order_by( $forder );
					}
				}
			}
		}


		/**
		 * The SetDBLimit is generated by appsbd
		 *
		 * @param any  $limit Its limit param.
		 * @param int  $limit_start Its limit_start param.
		 * @param bool $is_select_db Its is_select_db param.
		 */
		public function set_db_limit( $limit, $limit_start = 0, $is_select_db = true ) {
			$db = $is_select_db ? $this->get_select_db() : $this->get_update_db();
			$db->limit( $limit, $limit_start );
		}


		/**
		 * The SetDBSelect is generated by appsbd
		 *
		 * @param string $select Its select param.
		 * @param bool   $is_select_db Its is_select_db param.
		 */
		public function set_db_select( $select = '', $is_select_db = true ) {
			$db     = $is_select_db ? $this->get_select_db() : $this->get_update_db();
			$dbname = $this->get_table_name();
			if ( empty( $select ) ) {
				$select = $dbname . '.* ';
			} else {
				$select = explode( ',', $select );
				foreach ( $select as $key => &$se ) {
					$se = trim( $se );
					if ( strpos( $se, '.' ) !== false ) {
						continue;
					}
					if ( '*' == $se ) {
						$se = $dbname . '.* ';
					} elseif ( property_exists( $this, $se ) ) {
						$se = "$dbname.$se ";
					} else {
						if ( count( $this->join_objects ) > 0 ) {
							foreach ( $this->join_objects as $jn ) {
								if ( property_exists( $jn->join_obj, $se ) ) {
									$se = $jn->join_obj->get_table_name() . ".$se";
								}
							}
						} else {
							unset( $select[ $key ] );
						}
					}
				}
				$select = implode( ', ', $select );
			}
			$db->select( $select );
		}


		/**
		 * The GetTableName is generated by appsbd
		 *
		 * @param bool $is_only_table_name Its is_only_table_name param.
		 *
		 * @return string
		 */
		public function get_table_name( $is_only_table_name = true ) {
			if ( ! empty( $this->table_short_form ) ) {
				if ( $is_only_table_name ) {
					return $this->table_short_form;
				} else {
					return $this->db->prefix . $this->table_name . ' as ' . $this->table_short_form;
				}
			}

			return $this->db->prefix . $this->table_name;
		}


		/**
		 * The BindObject is generated by appsbd
		 *
		 * @param any $obj Its obj param.
		 */
		protected function bind_object( $obj ) {
			if ( ! empty( $obj ) && ( is_object( $obj ) || is_array( $obj ) ) ) {
				foreach ( $obj as $key => $value ) {
					if ( in_array( $key, $this->html_input_field ) ) {
						$value = stripcslashes( $value );
					}
					$this->$key = $value;
				}
			}
		}

		/**
		 * The set validation is generated by appsbd
		 */
		public function set_validation() {
			$this->validations = array();
		}


		/**
		 * The IsValidForm is generated by appsbd
		 *
		 * @param bool $is_new Its is_new param.
		 * @param bool $add_error Its add_error param.
		 *
		 * @return bool
		 */
		public function is_valid_form( $is_new = true, $add_error = true ) {
			$is_ok    = true;
			$required = array();
			if ( empty( $this->validations ) ) {
				$this->set_validation();
			}
			foreach ( $this->validations as $key => $value ) {
				if ( $is_new || ( isset( $this->set_properties [ $key ] ) && empty( $this->set_option [ $key ] ) ) ) {
					if ( ! isset( $value['Rule'] ) ) {
						continue;
					}
					$rules         = explode( '|', $value['Rule'] );
					$bracket_value = array();
					if ( is_array( $rules ) ) {
						foreach ( $rules as &$rule ) {
							$rule     = trim( $rule );
							$rule     = strtolower( $rule );
							$rulename = preg_replace( '/[^a-z_]/', '', $rule );
							$lg       = (int) preg_replace( '/[^0-9]/', '', $rule );
							if ( ! empty( $rulename ) && $lg > 0 ) {
								$bracket_value[ $rulename ] = $lg;
							}
							$rule = $rulename;

						}

						if ( isset( $this->set_properties [ $key ] ) && in_array( 'xss_clean', $rules ) ) {
							$this->$key( wp_strip_all_tags( $this->$key ) );
						}

						if ( in_array( 'required', $rules ) ) {
							if ( empty( $this->$key ) && trim( $this->$key ) . '_-_' === '_-_' ) {
								$is_ok = false;
								array_push( $required, $value['Text'] );
								continue;
							}
						}

						if ( in_array( 'lowercase', $rules ) ) {
							$this->$key( wp_strip_all_tags( strtolower( $this->$key ) ) );

						}
						if ( ! empty( $this->$key ) && in_array( 'digit', $rules ) ) {
							if ( ! ctype_digit( $this->$key ) ) {
								$is_ok = false;
								if ( $add_error ) {
									$this->add_error( '%s should be digit', $value['Text'] );
								}
							}
						}
						if ( ! empty( $this->$key ) && in_array( 'numeric', $rules ) ) {
							if ( ! is_numeric( $this->$key ) ) {
								$is_ok = false;
								if ( $add_error ) {
									$this->add_error( '%s should be numeric', $value['Text'] );
								}
							}
						}
						if ( ! empty( $this->$key ) && in_array( 'max_length', $rules ) && isset( $bracket_value['max_length'] ) ) {
							if ( strlen( $this->$key ) > (int) $bracket_value['max_length'] ) {
								$is_ok = false;
								$bv    = (int) $bracket_value['max_length'];
								if ( $add_error ) {
									$this->add_error( ' %s should be less than %s', $value['Text'], $bv );
								}
							}
						}

						if ( ! empty( $this->$key ) && in_array( 'resize_length', $rules ) && isset( $bracket_value['resize_length'] ) ) {
							$resize_length = (int) $bracket_value['resize_length'];
							if ( strlen( $this->$key ) < $resize_length ) {
								$this->$key( substr( $this->$key, $resize_length ) );
							}
						}

						if ( in_array( 'email', $rules ) ) {
							if ( ! empty( $this->$key ) && ! preg_match( '/^[A-Z0-9._]+@[A-Z0-9.-]+\.[A-Z]{2,6}$/i', $this->$key ) ) {
								$is_ok = false;
								if ( $add_error ) {
									$this->add_error( '%s should be a valid email address', $value['Text'] );
								}
							}
						}
						if ( ! empty( $this->$key ) && in_array( 'hexcode', $rules ) ) {
							if ( ! ctype_xdigit( $this->$key ) ) {
								$is_ok = false;
								if ( $add_error ) {
									$this->add_error( $value['Text'] . ' should be hexadecimal' );
								}
							}
						}
					}
				}
			}

			if ( count( $required ) > 0 ) {
				if ( count( $required ) > 1 ) {
					if ( $add_error ) {
						$this->add_error( ' %s are required', implode( ', ', $required ) );
					}
				} else {
					if ( $add_error ) {
						$this->add_error( ' %s is required', implode( ', ', $required ) );
					}
				}
			}

			return $is_ok;
		}


		/**
		 * The Save is generated by appsbd
		 *
		 * @return bool
		 */
		public function save() {
			if ( ! $this->is_valid_form( true ) ) {
				return false;
			}
			if ( ! $this->set_db_property_for_insert_or_update() ) {
				return false;
			}
			$insert_array = $this->get_update_db()->get_setted_properties();
			if ( $this->db->insert( $this->db->prefix . $this->table_name, $insert_array ) !== false ) {
				$auto_inserted  = $this->db->insert_id;
				self::$quries[] = $this->db->last_query;
				if ( is_array( $this->auto_inc_field ) && count( $this->auto_inc_field ) > 0 ) {
					foreach ( $this->auto_inc_field as $fld ) {
						if ( property_exists( $this, $fld ) ) {
							$this->$fld = $auto_inserted;
						}
					}
				}
				$this->reset_set_for_inset_update();

				return true;
			} else {
				

				self::$quries[] = $this->db->last_query;
				/**
				 * Its for check query db
				 *
				 * @since 1.0
				 */
				do_action( 'apbd-db-query-error', get_class( $this ), $this->db->last_error, $this->app_base_name );
				appsbd_add_query_error_v1( $this->db->last_query );
				if ( ! empty( $this->db->last_error ) ) {
					appsbd_add_query_error_v1( $this->db->last_error );
				}
			}

			return false;
		}

		/**
		 * The get properties api response is generated by appsbd
		 *
		 * @param string $props Its props param.
		 *
		 * @return \stdClass
		 */
		public function get_properties_api_response( $props = '' ) {
			if ( is_string( $props ) ) {
				$props = explode( ',', $props );
			}
			$response = new \stdClass();
			if ( is_array( $props ) ) {
				foreach ( $props as $prop ) {
					$prop = trim( $prop );
					if ( property_exists( $this, $prop ) ) {
						$response->{$prop} = $this->{$prop};
					}
				}
			}
			return $response;
		}

		/**
		 * The Select is generated by appsbd
		 *
		 * @param string $select Its select param.
		 * @param false  $add_field_error Its add_field_error param.
		 *
		 * @return bool
		 */
		public function select( $select = '', $add_field_error = false ) {
			if ( ! $this->check_basic_check() ) {
				return false;
			}
			if ( ! $this->is_valid_form( false, $add_field_error ) ) {
				return false;
			}
			if ( ! $this->set_db_select_where_properties( array(), true, true ) ) {
				return false;
			}
			$this->set_db_select( $select, true );
			$this->set_join_properties();
			$query          = $this->query_builder->get_select_query( $this->get_table_name( false ) );
			self::$quries[] = $query;
			$result         = $this->db->get_row( $query );
			if ( $result ) {
				$this->bind_object( $result );
				$this->set_properties = array();
				$this->set_option     = array();

				return true;
			} else {
				return false;
			}
		}


		/**
		 * The SelectAll is generated by appsbd
		 *
		 * @param string $select Its select param.
		 * @param string $order_by Its order_by param.
		 * @param string $order Its order param.
		 * @param string $limit Its limit param.
		 * @param string $limit_start Its limit_start param.
		 * @param string $like_fld Its like_fld param.
		 * @param string $like_value Its like_value param.
		 * @param array  $extra_param Its extra_param param.
		 * @param string $like_side Its like_side param.
		 * @param bool   $is_escap Its is_escap param.
		 * @param false  $is_data_only Its is_data_only param.
		 *
		 * @return array|false
		 */
		public function select_all( $select = '', $order_by = '', $order = '', $limit = '', $limit_start = '', $like_fld = '', $like_value = '', $extra_param = array(), $like_side = 'after', $is_escap = true, $is_data_only = false ) {
			if ( ! $this->check_basic_check() ) {
				return false;
			}
			if ( ! $this->is_valid_form( false, false ) ) {
				return false;
			}
			if ( ! $this->set_db_select_where_properties( $extra_param, true, true ) ) {
				return false;
			}

			$this->set_db_like( $like_fld, $like_value, $like_side, true );

			$this->set_db_order( $order_by, $order, true );
			$this->set_db_limit( $limit, $limit_start );
			$this->set_db_select( $select, true );
			$this->set_join_properties();
			$this->set_join_where_conditions( false, true );
			$query          = $this->query_builder->get_select_query( $this->get_table_name( false ) );
			self::$quries[] = $query;
			$result         = $this->db->get_results( $query );
			if ( $result ) {
				if ( $is_data_only ) {
					return $result;
				} else {
					return array_map( array( $this, 'select_all_array_filter' ), $result );
				}
			} else {
				return array();
			}
		}


		/**
		 * The select_all_array_filter is generated by appsbd
		 *
		 * @param any $vl Its vl param.
		 *
		 * @return $this
		 */
		protected function select_all_array_filter( $vl ) {
			$n = new static();
			$n->bind_object( $vl );
			return $n;
		}


		/**
		 * The SelectAllGridData is generated by appsbd
		 *
		 * @param string $select Its select param.
		 * @param string $order_by Its order_by param.
		 * @param string $order Its order param.
		 * @param string $limit Its limit param.
		 * @param string $limit_start Its limit_start param.
		 * @param string $like_fld Its like_fld param.
		 * @param string $like_value Its like_value param.
		 * @param array  $extra_param Its extra_param param.
		 * @param string $like_side Its like_side param.
		 * @param bool   $is_escap Its is_escap param.
		 *
		 * @return static[]|false
		 */
		public function select_all_grid_data( $select = '', $order_by = '', $order = '', $limit = '', $limit_start = '', $like_fld = '', $like_value = '', $extra_param = array(), $like_side = 'after', $is_escap = true ) {
			return $this->select_all( $select, $order_by, $order, $limit, $limit_start, $like_fld, $like_value, $extra_param, $like_side, $is_escap, true );
		}


		/**
		 * The SelectAllWithIdentity is generated by appsbd
		 *
		 * @param any    $unique_field Its unique_field param.
		 * @param string $select Its select param.
		 * @param string $order_by Its order_by param.
		 * @param string $order Its order param.
		 * @param string $limit Its limit param.
		 * @param string $limit_start Its limit_start param.
		 * @param string $like_fld Its like_fld param.
		 * @param string $like_value Its like_value param.
		 * @param array  $extra_param Its extra_param param.
		 * @param string $like_side Its like_side param.
		 * @param bool   $is_escap Its is_escap param.
		 *
		 * @return array|false
		 */
		public function select_all_with_identity( $unique_field, $select = '', $order_by = '', $order = '', $limit = '', $limit_start = '', $like_fld = '', $like_value = '', $extra_param = array(), $like_side = 'after', $is_escap = true ) {
			$result = $this->select_all( $select, $order_by, $order, $limit, $limit_start, $like_fld, $like_value, $extra_param, $like_side, $is_escap );
			if ( count( $result ) > 0 ) {
				$newrsult = array();
				foreach ( $result as $obj ) {
					if ( ! empty( $obj->$unique_field ) ) {
						$newrsult[ $obj->$unique_field ] = $obj;
					}
				}

				return $newrsult;
			}

			return $result;
		}


		/**
		 * The SelectAllWithKeyValueWithStar is generated by appsbd
		 *
		 * @param any    $key Its key param.
		 * @param any    $value Its value param.
		 * @param bool   $is_star_add Its is_star_add param.
		 * @param string $order_by Its order_by param.
		 * @param string $order Its order param.
		 * @param string $limit Its limit param.
		 * @param string $limit_start Its limit_start param.
		 * @param string $like_fld Its like_fld param.
		 * @param string $like_value Its like_value param.
		 * @param array  $extra_param Its extra_param param.
		 * @param string $like_side Its like_side param.
		 * @param bool   $is_escap Its is_escap param.
		 *
		 * @return array
		 */
		public function select_all_with_key_value_with_star( $key, $value, $is_star_add = true, $order_by = '', $order = '', $limit = '', $limit_start = '', $like_fld = '', $like_value = '', $extra_param = array(), $like_side = 'after', $is_escap = true ) {
			$results    = $this->select_all( $key . ',' . $value, $order_by, $order, $limit, $limit_start, $like_fld, $like_value, $extra_param, $like_side, $is_escap );
			$return_data = array();
			if ( $is_star_add ) {
				$return_data['*'] = 'All';
			}
			foreach ( $results as $data ) {
				if ( ! empty( $data->$key ) ) {
					$return_data[ $data->$key ] = $data->$value;
				}
			}

			return $return_data;
		}


		/**
		 * The SelectAllWithKeyValue is generated by appsbd
		 *
		 * @param any    $key Its key param.
		 * @param any    $value Its value param.
		 * @param string $order_by Its order_by param.
		 * @param string $order Its order param.
		 * @param string $limit Its limit param.
		 * @param string $limit_start Its limit_start param.
		 * @param string $like_fld Its like_fld param.
		 * @param string $like_value Its like_value param.
		 * @param array  $extra_param Its extra_param param.
		 * @param string $like_side Its like_side param.
		 * @param bool   $is_escap Its is_escap param.
		 *
		 * @return array
		 */
		public function select_all_with_key_value( $key, $value, $order_by = '', $order = '', $limit = '', $limit_start = '', $like_fld = '', $like_value = '', $extra_param = array(), $like_side = 'after', $is_escap = true ) {
			return $this->select_all_with_key_value_with_star( $key, $value, false, $order_by, $order, $limit, $limit_start, $like_fld, $like_value, $extra_param, $like_side, $is_escap );
		}


		/**
		 * The SelectAllWithArrayKeys is generated by appsbd
		 *
		 * @param any    $key Its key param.
		 * @param string $order_by Its order_by param.
		 * @param string $order Its order param.
		 * @param string $limit Its limit param.
		 * @param string $limit_start Its limit_start param.
		 * @param string $like_fld Its like_fld param.
		 * @param string $like_value Its like_value param.
		 * @param array  $extra_param Its extra_param param.
		 * @param string $like_side Its like_side param.
		 * @param bool   $is_escap Its is_escap param.
		 *
		 * @return array
		 */
		public function select_all_with_array_keys( $key, $order_by = '', $order = '', $limit = '', $limit_start = '', $like_fld = '', $like_value = '', $extra_param = array(), $like_side = 'after', $is_escap = true ) {
			$results     = $this->select_all( $key, $order_by, $order, $limit, $limit_start, $like_fld, $like_value, $extra_param, $like_side, $is_escap );
			$return_data = array();
			foreach ( $results as $data ) {
				if ( ! empty( $data->$key ) ) {
					$return_data[] = $data->$key;
				}
			}

			return $return_data;
		}


		/**
		 * The FindAllBy is generated by appsbd
		 *
		 * @param any    $property Its property param.
		 * @param any    $value Its value param.
		 * @param array  $extra_param Its extra_param param.
		 * @param string $order_by Its order_by param.
		 * @param string $order Its order param.
		 * @param string $limit Its limit param.
		 * @param string $limit_start Its limit_start param.
		 * @param false  $is_cache Its is_cache param.
		 * @param int    $cache_time Its cache_time param.
		 *
		 * @return array|false
		 */
		public static function find_all_by( $property, $value, $extra_param = array(), $order_by = '', $order = 'ASC', $limit = '', $limit_start = '', $is_cache = false, $cache_time = 0 ) {
			$n = new static();
			$n->check_cache( $is_cache, $cache_time );
			if ( property_exists( $n, $property ) ) {
				$n->$property( $value );
				if ( is_array( $extra_param ) ) {
					foreach ( $extra_param as $key => $value ) {
						if ( property_exists( $n, $key ) ) {
							$n->$key( $value );
						}
					}
				}

				return $n->select_all( '', $order_by, $order, $limit, $limit_start );
			}

			return array();
		}


		/**
		 * The FindAllByKeyValue is generated by appsbd
		 *
		 * @param any   $find_by_property Its find_by_property param.
		 * @param any   $find_by_value Its find_by_value param.
		 * @param any   $key Its key param.
		 * @param any   $value Its value param.
		 * @param array $extra_param Its extra_param param.
		 * @param false $is_cache Its is_cache param.
		 * @param int   $cache_time Its cache_time param.
		 *
		 * @return array
		 */
		public static function find_all_by_key_value( $find_by_property, $find_by_value, $key, $value, $extra_param = array(), $is_cache = false, $cache_time = 0 ) {
			$n = new static();
			$n->check_cache( $is_cache, $cache_time );
			if ( property_exists( $n, $find_by_property ) ) {
				$n->$find_by_property( $find_by_value );

				return $n->select_all_with_key_value( $key, $value, '', '', '', '', '', '', $extra_param );
			}

			return array();
		}


		/**
		 * The FindAllByIdentiry is generated by appsbd
		 *
		 * @param any   $find_by_property Its find_by_property param.
		 * @param any   $find_by_value Its find_by_value param.
		 * @param any   $identity_fld Its identity_fld param.
		 * @param array $extra_param Its extra_param param.
		 * @param false $is_cache Its is_cache param.
		 * @param int   $cache_time Its cache_time param.
		 *
		 * @return array|false
		 */
		public static function find_all_by_identiry( $find_by_property, $find_by_value, $identity_fld, $extra_param = array(), $is_cache = false, $cache_time = 0 ) {
			$n = new static();
			$n->check_cache( $is_cache, $cache_time );
			if ( property_exists( $n, $find_by_property ) ) {
				$n->$find_by_property( $find_by_value );

				return $n->select_all_with_identity( $identity_fld, '', '', '', '', '', '', $extra_param );
			}

			return array();
		}


		/**
		 * The getPropertiesArray is generated by appsbd
		 *
		 * @param string $skipped Its skipped param.
		 *
		 * @return array
		 */
		public function get_properties_array( $skipped = '' ) {
			$skipped    = explode( ',', $skipped );
			$return     = array();
			$reflection = new ReflectionObject( $this );
			$properties = $reflection->get_properties( ReflectionProperty::IS_PUBLIC );
			$skipped[]  = 'settedPropertyforLog';
			foreach ( $properties as $property ) {
				if ( in_array( $property->get_name(), $skipped ) ) {
					continue;
				}
				$return[ $property->get_name() ] = $property->get_value( $this );
			}

			return $return;
		}


		/**
		 * The FetchCountAll is generated by appsbd
		 *
		 * @param string $like_fld Its like_fld param.
		 * @param string $like_value Its like_value param.
		 * @param array  $extra_param Its extra_param param.
		 * @param string $like_side Its like_side param.
		 * @param false  $is_cache Its is_cache param.
		 * @param int    $cache_time Its cache_time param.
		 *
		 * @return false|int
		 */
		public static function fetch_count_all( $like_fld = '', $like_value = '', $extra_param = array(), $like_side = 'after', $is_cache = false, $cache_time = 0 ) {
			$s = new static();
			$s->check_cache( $is_cache, $cache_time );

			return $s->count_all( $like_fld, $like_value, $extra_param, $like_side );
		}


		/**
		 * The FetchAllKeyValue is generated by appsbd
		 *
		 * @param any    $key Its key param.
		 * @param any    $value Its value param.
		 * @param false  $is_star_add Its is_star_add param.
		 * @param string $order_by Its order_by param.
		 * @param string $order Its order param.
		 * @param string $limit Its limit param.
		 * @param string $limit_start Its limit_start param.
		 * @param string $like_fld Its like_fld param.
		 * @param string $like_value Its like_value param.
		 * @param array  $extra_param Its extra_param param.
		 * @param string $like_side Its like_side param.
		 * @param bool   $is_escap Its is_escap param.
		 * @param false  $is_cache Its is_cache param.
		 * @param int    $cache_time Its cache_time param.
		 *
		 * @return array
		 */
		public static function fetch_all_key_value( $key, $value, $is_star_add = false, $order_by = '', $order = '', $limit = '', $limit_start = '', $like_fld = '', $like_value = '', $extra_param = array(), $like_side = 'after', $is_escap = true, $is_cache = false, $cache_time = 0 ) {
			$s = new static();
			$s->check_cache( $is_cache, $cache_time );
			$results     = $s->select_all( $key . ',' . $value, $order_by, $order, $limit, $limit_start, $like_fld, $like_value, $extra_param, $like_side, $is_escap );
			$return_data = array();
			if ( $is_star_add ) {
				$return_data['*'] = 'All';
			}
			foreach ( $results as $data ) {
				if ( ! empty( $data->$key ) ) {
					$return_data[ $data->$key ] = ! empty( $data->$value ) ? $data->$value : "Undefined $value";
				}
			}

			return $return_data;
		}


		/**
		 * The SelectAllWithIdentityWithSelectPropertyOnly is generated by appsbd
		 *
		 * @param any    $unique_field Its unique_field param.
		 * @param string $select Its select param.
		 * @param string $order_by Its order_by param.
		 * @param string $order Its order param.
		 * @param string $limit Its limit param.
		 * @param string $limit_start Its limit_start param.
		 * @param string $like_fld Its like_fld param.
		 * @param string $like_value Its like_value param.
		 * @param array  $extra_param Its extra_param param.
		 * @param string $like_side Its like_side param.
		 * @param bool   $is_escap Its is_escap param.
		 *
		 * @return array|false
		 */
		public function select_all_with_identity_with_select_property_only( $unique_field, $select = '', $order_by = '', $order = '', $limit = '', $limit_start = '', $like_fld = '', $like_value = '', $extra_param = array(), $like_side = 'after', $is_escap = true ) {
			$result = $this->select_all( $select, $order_by, $order, $limit, $limit_start, $like_fld, $like_value, $extra_param, $like_side, $is_escap, true );
			if ( count( $result ) > 0 ) {
				$new_rsult = array();
				foreach ( $result as $obj ) {
					if ( ! empty( $obj->$unique_field ) ) {
						$new_rsult[ $obj->$unique_field ] = $obj;
					}
				}

				return $new_rsult;
			}

			return $result;
		}


		/**
		 * The GetNewIncId is generated by appsbd
		 *
		 * @param any $field_name Its field_name param.
		 * @param any $default Its default param.
		 *
		 * @return int|string
		 */
		public function get_new_inc_id( $field_name, $default ) {
			$query  = "SELECT max($field_name) as last_s from " . $this->db->prefix . $this->table_name;
			$result = $this->db->get_row( $query );
			if ( $result ) {
				if ( ! empty( $result->last_s ) ) {
					$a = $result->last_s;
					$a++;

					return $a;
				}
			}

			return "$default";
		}


		/**
		 * The SelectQuery is generated by appsbd
		 *
		 * @param any   $sql Its sql param.
		 * @param false $is_array Its is_array param.
		 *
		 * @return array
		 */
		public function select_query( $sql, $is_array = false ) {
			if ( $is_array ) {
				$output = ARRAY_A;
			} else {
				$output = OBJECT;
			}
			self::$quries[] = $sql;
			$result         = $this->db->get_results( $sql, $output );
			if ( $result ) {
				return $result;
			} else {
				return array();
			}
		}


		/**
		 * The IsExists is generated by appsbd
		 *
		 * @param any   $property Its property param.
		 * @param any   $value Its value param.
		 * @param array $other_param Its other_param param.
		 *
		 * @return bool
		 */
		public function is_exists( $property, $value, $other_param = array() ) {
			if ( property_exists( $this, $property ) ) {
				$this->get_select_db()->where( $property, $value );
				foreach ( $other_param as $key => $pvalue ) {
					$this->get_select_db()->where( $key, $pvalue );
				}
				$this->get_select_db()->select( 'COUNT(*) AS total' );
				$query  = $this->query_builder->get_select_query( $this->get_table_name( false ) );
				$result = $this->db->get_row( $query );

				if ( ! empty( $result->total ) ) {
					return $result->total > 0;
				}
			}

			return false;
		}


		/**
		 * The GetSelectDB is generated by appsbd
		 *
		 * @return QueryBuilder
		 */
		public function get_select_db() {
			return $this->query_builder;
		}


		/**
		 * The GetUpdateDB is generated by appsbd
		 *
		 * @return QueryBuilder
		 */
		public function get_update_db() {
			return $this->query_builder;
		}

		/**
		 * The string trim is generated by appsbd
		 *
		 * @param mixed  $str Its str param.
		 * @param string $charlist Its charlist param.
		 *
		 * @return string
		 */
		public function string_trim( $str, $charlist = " \t\n\r\0\x0B" ) {
			if ( empty( $str ) || ! is_string( $str ) ) {
				return $str;
			}
			return trim( $str, $charlist );
		}

		/**
		 * The __call is generated by appsbd
		 *
		 * @param any $func Its func param.
		 * @param any $args Its args param.
		 */
		public function __call( $func, $args ) {
			if ( isset( $args [0] ) ) {
				$value = $this->$func;

				if ( $args [0] != $value || ( '' == $args [0] && null == $value ) ) {

					if ( property_exists( $this, $func ) ) {
						if ( isset( $args [1] ) ) {
							$this->set_option [ $func ] = $args [1];
						}
						if ( ! empty( $args [2] ) ) {
							$this->set_option_type[ $func ] = $args [2];
						}
						$this->set_properties [ $func ] = $args [0];
					}
					if ( ! empty( $args [1] ) ) {
						$this->$func = $args [0];
					} else {
						$this->$func = $this->string_trim( $args [0] );
					}
				}
			}
		}


		/**
		 * The __callStatic is generated by appsbd
		 *
		 * @param any $func Its func param.
		 * @param any $args Its args param.
		 *
		 * @return static|null
		 */
		public static function __callStatic( $func, $args ) {
			if ( static::starts_with( $func, 'FindBy' ) ) {
				$funcl    = strtolower( $func );
				$property = str_replace( 'findby', '', $funcl );

				return static::find_by( $property, $args[0] );
			}

		}

		/**
		 * The starts with is generated by appsbd
		 *
		 * @param string $haystack The string to search in .
		 * @param mixed  $needle . If <b>needle</b> is not a string, it is converted to an integer and applied as the ordinal value of a character.
		 *
		 * @return bool
		 */
		public static function starts_with( $haystack, $needle ) {
			$length = strlen( $needle );
			return ( substr( $haystack, 0, $length ) === $needle );
		}

		/**
		 * The FetchAll is generated by appsbd
		 *
		 * @param string $select Its select param.
		 * @param string $order_by Its order_by param.
		 * @param string $order Its order param.
		 * @param string $limit Its limit param.
		 * @param string $limit_start Its limit_start param.
		 * @param string $like_fld Its like_fld param.
		 * @param string $like_value Its like_value param.
		 * @param array  $extra_param Its extra_param param.
		 * @param string $like_side Its like_side param.
		 * @param bool   $is_escap Its is_escap param.
		 *
		 * @return array|false
		 */
		public static function fetch_all( $select = '', $order_by = '', $order = '', $limit = '', $limit_start = '', $like_fld = '', $like_value = '', $extra_param = array(), $like_side = 'after', $is_escap = true ) {
			$s = new static();

			return $s->select_all( $select, $order_by, $order, $limit, $limit_start, $like_fld, $like_value, $extra_param, $like_side, $is_escap );
		}


		/**
		 * The PostValue is generated by appsbd
		 *
		 * @param any  $index Its index param.
		 * @param null $default Its default param.
		 *
		 * @return mixed
		 */
		public function post_value( $index, $default = null ) {
			return AppInput::post_value( $index, $default );
		}


		/**
		 * The GetValue is generated by appsbd
		 *
		 * @param any  $index Its index param.
		 * @param null $default Its default param.
		 *
		 * @return mixed
		 */
		public function get_value( $index, $default = null ) {
			return AppInput::get_value( $index, $default );
		}


		/**
		 * The find_by is generated by appsbd
		 *
		 * @param any   $property Its property param.
		 * @param any   $value Its value param.
		 * @param array $extra_param Its extra_param param.
		 *
		 * @return static|null
		 */
		public static function find_by( $property, $value, $extra_param = array() ) {
			$n = new static();
			if ( property_exists( $n, $property ) ) {
				$n->$property( $value );
				if ( is_array( $extra_param ) ) {
					foreach ( $extra_param as $key => $value ) {
						if ( property_exists( $n, $key ) ) {
							$n->$key( $value );
						}
					}
				}
				if ( $n->select() ) {
					return $n;
				}
			}

			return null;
		}


		/**
		 * The CountALL is generated by appsbd
		 *
		 * @param string $like_fld Its like_fld param.
		 * @param string $like_value Its like_value param.
		 * @param array  $extra_param Its extra_param param.
		 * @param string $like_side Its like_side param.
		 *
		 * @return false|int
		 */
		public function count_all( $like_fld = '', $like_value = '', $extra_param = array(), $like_side = 'after' ) {
			if ( empty( $this->table_name ) ) {
				return false;
			}
			$this->get_select_db()->select( 'count(*) as total', false );
			if ( ! $this->set_db_select_where_properties( $extra_param, false, true ) ) {
				return false;
			}

			$this->set_db_like( $like_fld, $like_value, $like_side, true );

			$this->set_join_properties( false );
			$this->set_join_where_conditions( false, true );
			$query  = $this->query_builder->get_select_query( $this->get_table_name( false ) );
			$result = $this->db->get_row( $query );
			if ( $result && ! empty( $result->total ) ) {
				return $result->total;
			}

			return 0;

		}


		/**
		 * The ResetSetForInsetUpdate is generated by appsbd
		 *
		 * @param false $is_witout_log Its is_witout_log param.
		 */
		public function reset_set_for_inset_update( $is_witout_log = false ) {
			if ( $is_witout_log ) {
				$this->setted_propertyfor_log = '';
				foreach ( $this->set_properties as $key => $value ) {
					if ( isset( $this->html_input_field [ $key ] ) ) {
						continue;
					}
					if ( ! empty( $this->setted_propertyfor_log ) ) {
						$this->setted_propertyfor_log .= ', ';
					}
					$this->setted_propertyfor_log .= $key . '=' . $value;
				}
			}
			$this->set_properties = array();
			$this->set_option     = array();
		}


		/**
		 * The SetFromArray is generated by appsbd
		 *
		 * @param mixed $data_array Its data_array param.
		 * @param false $is_new Its is_new param.
		 * @param bool  $add_error Its add_error param.
		 *
		 * @return bool
		 */
		public function set_from_array( $data_array, $is_new = false, $add_error = true ) {
			foreach ( $data_array as $key => $value ) {
				if ( property_exists( $this, $key ) ) {
					if ( $this->check_before_set_data( $key, $value ) ) {
						$this->$key( $value );
					}
				}
			}
			return $this->is_valid_form( $is_new, $add_error );
		}

		/**
		 * The check before set data is generated by appsbd
		 *
		 * @param mixed $key Its the property.
		 * @param mixed $value Its the value.
		 *
		 * @return bool
		 */
		public function check_before_set_data( $key, &$value ) {
			return true;
		}

		/**
		 * The SetFromPostData is generated by appsbd
		 *
		 * @param false $is_new Its is_new param.
		 *
		 * @return bool
		 */
		public function set_from_post_data( $is_new = false ) {
			return $this->set_from_array( AppInput::get_posted_data(), $is_new );
		}


		/**
		 * The SetWhereUpdate is generated by appsbd
		 *
		 * @param any   $property Its property param.
		 * @param any   $value Its value param.
		 * @param false $is_not_xss_clean Its is_not_xss_clean param.
		 */
		public function set_where_update( $property, $value, $is_not_xss_clean = false ) {
			$this->update_where_extra_field [ $property ] = $value;
			if ( $is_not_xss_clean ) {
				$this->update_where_extra_field_option[] = $property;
			}
		}


		/**
		 * The IsSetDataForSaveUpdate is generated by appsbd
		 *
		 * @param false $is_show_msg Its is_show_msg param.
		 *
		 * @return bool
		 */
		public function is_set_data_for_save_update( $is_show_msg = false ) {
			$re = count( $this->set_properties ) > 0;
			if ( ! $re && $is_show_msg ) {
				appsbd_add_warning_v1_lite( 'No change for update' );
			}

			return $re;
		}


		/**
		 * The IsSetPrperty is generated by appsbd
		 *
		 * @param any $property Its property param.
		 *
		 * @return bool
		 */
		public function is_set_prperty( $property ) {
			return isset( $this->set_properties [ $property ] );
		}


		/**
		 * The UnsetPrperty is generated by appsbd
		 *
		 * @param any $property Its property param.
		 */
		public function unset_prperty( $property ) {
			if ( isset( $this->set_properties [ $property ] ) ) {
				unset( $this->set_properties [ $property ] );
			}
			if ( isset( $this->set_option [ $property ] ) ) {
				unset( $this->set_option [ $property ] );
			}
		}


		/**
		 * The IsHTMLProperty is generated by appsbd
		 *
		 * @param string $property Its property param.
		 *
		 * @return bool
		 */
		public function is_hrml_property( $property = '' ) {
			if ( in_array( $property, $this->html_input_field ) ) {
				return true;
			}

			return false;
		}


		/**
		 * The Update is generated by appsbd
		 *
		 * @param false $not_limit Its not_limit param.
		 * @param bool  $is_show_msg Its is_show_msg param.
		 * @param bool  $dont_process_id_where_not_set Its dont_process_id_where_not_set param.
		 *
		 * @return bool
		 */
		public function update( $not_limit = false, $is_show_msg = true, $dont_process_id_where_not_set = true ) {
			if ( $this->is_set_data_for_save_update() && count( $this->update_where_extra_field ) > 0 ) {
				if ( ! $this->is_valid_form( false ) ) {
					return false;
				}
				
				if ( ! $this->set_db_property_for_insert_or_update( true ) ) {
					return false;
				}

				
				if ( ! $this->set_db_update_where_properties( array(), $dont_process_id_where_not_set ) ) {
					return false;
				}
				$query          = $this->get_update_db()->get_update_query( $this->db->prefix . $this->table_name, $not_limit );
				self::$quries[] = $query;
				$uresult        = $this->db->query( $query );
				if ( false !== $uresult && $uresult > 0 ) {
					$this->reset_set_for_inset_update();
					$this->unset_all_update_property();

					return true;
				} elseif ( false === $uresult ) {
					/**
					 * Its for check query db
					 *
					 * @since 1.0
					 */
					do_action( 'apbd-db-query-error', get_class( $this ), $this->db->last_error, $this->app_base_name );
					appsbd_add_query_error_v1( $query );
				}
			} else {
				if ( $is_show_msg && ! $this->is_set_data_for_save_update() ) {
					$this->add_warning( 'No data found for update' );
				} elseif ( count( $this->update_where_extra_field ) == 0 ) {
					$this->add_error( 'E004' );
				}
			}

			

			return false;
		}


		/**
		 * The Delete is generated by appsbd
		 *
		 * @param false $not_limit Its not_limit param.
		 * @param bool  $is_show_msg Its is_show_msg param.
		 * @param bool  $dont_process_id_where_not_set Its dont_process_id_where_not_set param.
		 *
		 * @return bool
		 */
		public function delete( $not_limit = false, $is_show_msg = true, $dont_process_id_where_not_set = true ) {
			if ( count( $this->update_where_extra_field ) > 0 ) {
				if ( ! $this->is_valid_form( false ) ) {
					return false;
				}
				
				if ( ! $this->set_db_property_for_insert_or_update( true ) ) {
					return false;
				}

				
				if ( ! $this->set_db_update_where_properties( array(), $dont_process_id_where_not_set ) ) {
					return false;
				}
				$query          = $this->get_update_db()->get_delete_query( $this->db->prefix . $this->table_name, $not_limit );
				self::$quries[] = $query;
				$uresult        = $this->db->query( $query );
				if ( false !== $uresult && $uresult > 0 ) {
					$this->reset_set_for_inset_update();
					$this->unset_all_update_property();

					return true;
				} elseif ( false !== $uresult ) {
					appsbd_add_query_error_v1( $this->db->last_error );
				}
			} else {
				if ( $is_show_msg && ! $this->is_set_data_for_save_update() ) {
					appsbd_add_warning_v1_lite( 'No data found for update' );
				} elseif ( count( $this->update_where_extra_field ) == 0 ) {
					appsbd_add_model_errors_code_v1( 'E004' );
				}
			}

			return false;
		}


		/**
		 * The DeleteByKeyValue is generated by appsbd
		 *
		 * @param any   $key Its key param.
		 * @param any   $value Its value param.
		 * @param false $no_limit Its no_limit param.
		 * @param array $extra_param Its extra_param param.
		 *
		 * @return bool
		 */
		protected static function delete_by_key_value( $key, $value, $no_limit = false, $extra_param = array() ) {
			$this_obj = new static();
			if ( ! property_exists( $this_obj, $key ) ) {
				return false;
			}
			$this_obj->set_where_update( $key, $value );
			if ( is_array( $extra_param ) && count( $extra_param ) > 0 ) {
				foreach ( $extra_param as $ekey => $item ) {
					if ( property_exists( $this_obj, $ekey ) ) {
						$this_obj->set_where_update( $ekey, $item );
					}
				}
			}

			return $this_obj->delete( $no_limit );
		}


		/**
		 * The GetAffectedRows is generated by appsbd
		 *
		 * @param false $is_select_db Its is_select_db param.
		 *
		 * @return mixed
		 */
		public function get_affected_rows( $is_select_db = false ) {
			return $this->db->rows_affected;
		}


		/**
		 * The force_set_pk_for_update is generated by appsbd
		 *
		 * @param bool $is_clean Its is_clean param.
		 */
		public function force_set_pk_for_update( $is_clean = true ) {
			$pk = $this->primary_key;
			if ( ! empty( $this->$pk ) ) {
				if ( ! $is_clean ) {
					$this->get_update_db()->set( $pk . $this->$pk, false );
				} else {
					$this->get_update_db()->set( $pk, $this->$pk );
				}
			}
		}


		/**
		 * The GetTotalQueries is generated by appsbd
		 *
		 * @return false|string
		 */
		public static function get_total_queries() {
			ob_start();
			?>
            <div class="row">
                <div class="panel panel-info">
                    <div class="panel-heading">Queries</div>
                    <div class="panel-body">
									<pre>
										<?php

										foreach ( self::$quries as $qur ) {
											$qur = str_replace( "\n", '', $qur );
											print_r( $qur );
										}

										?>
									</pre>
                    </div>
                </div>
            </div>
			<?php
			return ob_get_clean();
		}


		/**
		 * The GetDBFields is generated by appsbd
		 *
		 * @return array
		 */
		public static function get_db_fields() {
			$this_obj     = new static();
			$table_name   = $this_obj->db->prefix . $this_obj->table_name;
			$fields       = $this_obj->db->get_results( "SHOW COLUMNS FROM {$table_name}" );
			$return_field = array();
			foreach ( $fields as $fld ) {
				if ( property_exists( $fld, 'Field' ) ) {
					// phpcs:ignore
					$return_field[ $fld->Field ] = $fld;
				} else {
					$return_field[ $fld->field ] = $fld;
				}
			}

			return $return_field;
		}


		/**
		 * The DBColumnAddOrModify is generated by appsbd
		 *
		 * @param any    $column_name Its column_name param.
		 * @param any    $type Its type param.
		 * @param any    $length Its length param.
		 * @param string $default Its default param.
		 * @param string $null_status Its null_status param.
		 * @param string $after Its after param.
		 * @param string $comment Its comment param.
		 * @param string $char_set Its char_set param.
		 */
		public static function db_column_add_or_modify( $column_name, $type, $length, $default = '', $null_status = 'NOT NULL', $after = '', $comment = '', $char_set = '' ) {
			$this_obj   = new static();
			$table_name = $this_obj->db->prefix . $this_obj->table_name;
			if ( empty( $table_name ) ) {
				return;
			}
			if ( '' == $default ) {
				$default = "''";
			}
			if ( ! empty( $char_set ) ) {
				$char_set = " CHARACTER SET {$char_set}";
			}
			if ( ! empty( $after ) ) {
				$after = " AFTER {$after}";
			}
			$fields = static::get_db_fields();
			if ( isset( $fields[ $column_name ] ) ) {
				$query_type = 'MODIFY';
			} else {
				$query_type = 'ADD';
			}
			if ( strtolower( $type ) == 'text' ) {
				$query = "ALTER TABLE `{$table_name}` {$query_type} COLUMN `{$column_name}`  {$type} $char_set {$null_status}  COMMENT '{$comment}' $after";

			} elseif ( strtolower( $type ) == 'timestamp' ) {
				if ( "''" == $default ) {
					$default = "'0000-00-00 00:00:00'";
				}
				$query = "ALTER TABLE `{$table_name}` {$query_type} COLUMN `{$column_name}`  {$type} {$null_status} DEFAULT $default $after";

			} else {
				$query = "ALTER TABLE `{$table_name}` {$query_type} COLUMN `{$column_name}`  {$type}({$length}) $char_set {$null_status} DEFAULT {$default} COMMENT '{$comment}' $after";
			}

			$this_obj->db->query( $query );
		}


		/**
		 * The DBDirectAlterQuery is generated by appsbd
		 *
		 * @param any $query Its query param.
		 *
		 * @return mixed
		 */
		public static function db_direct_alter_query( $query ) {
			$this_obj = new static();

			return $this_obj->db->query( $query );
		}

		/**
		 * The set date filter is generated by appsbd
		 *
		 * @param object $src_param Its search parm object.
		 *
		 * @return mixed
		 */
		public function set_date_filter( $src_param ) {

			if ( 'bt' == $src_param->opr ) {
				$src_param->val = (object) $src_param->val;
				if ( ! empty( $src_param->val->start ) ) {
					if ( empty( $src_param->val->end ) ) {
						$src_param->val->end = $src_param->val->start;
					}
					$src_param->val->start = appsbd_gm_date( $src_param->val->start, 'Y-m-d 00:00:00' );
					$src_param->val->end = appsbd_gm_date( $src_param->val->end, 'Y-m-d 23:59:59' );
					;
				}
			} elseif ( 'eq' == $src_param->opr ) {
				$src_param->opr        = 'bt';
				$start                 = appsbd_gm_date( $src_param->val, 'Y-m-d 00:00:00' );
				$end                   = appsbd_gm_date( $src_param->val, 'Y-m-d 23:59:59' );
				$src_param->val        = new \stdClass();
				$src_param->val->start = $start;
				$src_param->val->end   = $end;
			} elseif ( in_array( $src_param->opr, array( 'ge', 'lt' ) ) ) {
				$src_param->val = appsbd_gm_date( $src_param->val, 'Y-m-d 00:00:00' );
			} elseif ( in_array( $src_param->opr, array( 'gt', 'le' ) ) ) {
				$src_param->val = appsbd_gm_date( $src_param->val, 'Y-m-d 23:59:59' );
			} else {
				$src_param->val = appsbd_gm_date( $src_param->val, 'Y-m-d H:i:s' );
			}
			return $src_param;
		}
		/**
		 * The filter search param is generated by appsbd
		 *
		 * @param object $src_param Its search parm object.
		 *
		 * @return object
		 */
		public function filter_search_param( $src_param ) {
			if ( !empty($src_param->prop) && in_array( $src_param->prop, $this->date_fields ) ) {
				return $this->set_date_filter( $src_param );
			}
			return $src_param;
		}
		/**
		 * The set from search param is generated by appsbd
		 *
		 * @param array  $src_props Its src_props param.
		 * @param string $all_props Its all_props param.
		 * @param array  $allowed_list Its allowed_list param.
		 */
		public function set_search_by_param( $src_props = array(), $all_props = '', $allowed_list = array() ) {

			if ( is_string( $all_props ) ) {
				$all_props = explode( ',', $all_props );
			}

			foreach ( $src_props as $src_prop ) {
				$src_prop = (object) $src_prop;
				$src_prop = $this->filter_search_param( $src_prop );
				if ( isset( $src_prop->val ) ) {
					$src_prop->val = $this->string_trim( $src_prop->val );
					if ( '*' == $src_prop->prop ) {
						foreach ( $all_props as $all_prop ) {
							if ( is_string( $all_prop ) ) {
								$all_prop = trim( $all_prop );
								if ( property_exists( $this, $all_prop ) ) {
									$this->add_like( $all_prop, $src_prop->val, 'both', 'OR' );
								}
							}
						}
					} elseif ( property_exists( $this, $src_prop->prop ) ) {
						if ( 'like' == $src_prop->opr ) {
							$this->add_like( $src_prop->prop, $src_prop->val, 'both' );
						} elseif ( 'eq' == $src_prop->opr ) {
							$this->{$src_prop->prop}( $src_prop->val );
						} elseif ( 'lt' == $src_prop->opr ) {
							$this->{$src_prop->prop}( "< {$src_prop->val}", true );
						} elseif ( 'gt' == $src_prop->opr ) {
							$this->{$src_prop->prop}( "> {$src_prop->val}", true );
						} elseif ( 'le' == $src_prop->opr ) {
							$this->{$src_prop->prop}( "<= {$src_prop->val}", true );
						} elseif ( 'ge' == $src_prop->opr ) {
							$this->{$src_prop->prop}( ">= {$src_prop->val}", true );
						} elseif ( 'dt' == $src_prop->opr ) {
							$src_prop->val;
							if ( ! empty( $src_prop->val ) ) {
								$start_date = appsbd_gm_date(
									$src_prop->val,
									'Y-m-d 00:00:00'
								);
								$enddate    = appsbd_gm_date(
									$src_prop->val,
									'Y-m-d 23:59:59'
								);
								if ( ! empty( $start_date ) && ! empty( $enddate ) ) {
									$this->{$src_prop->prop}( "between '$start_date' and '$enddate'", true );
								}
							}
						} elseif ( 'dr' == $src_prop->opr ) {
							$prop = (object) $src_prop->val;
							if ( ! empty( $prop->start ) ) {
								if ( empty( $prop->end ) ) {
									$prop->end = $prop->start;
								}
								$start_date = appsbd_gm_date(
									$prop->start,
									'Y-m-d 00:00:00'
								);
								$enddate    = appsbd_gm_date(
									$prop->end,
									'Y-m-d 23:59:59'
								);
								if ( ! empty( $start_date ) && ! empty( $enddate ) ) {
									$this->{$src_prop->prop}( "between '$start_date' and '$enddate'", true );
								}
							}
						} elseif ( 'bt' == $src_prop->opr ) {
							$prop = (object) $src_prop->val;
							if ( ! empty( $prop->start ) ) {
								if ( empty( $prop->end ) ) {
									$prop->end = $prop->start;
								}
								$prop->start = sanitize_text_field( $prop->start );
								$prop->end   = sanitize_text_field( $prop->end );
								if ( ! empty( $prop->start ) && ! empty( $prop->end ) ) {
									$this->{$src_prop->prop}( "between '$prop->start' and '$prop->end'", true );
								}
							}
						}
					}
				}
			}
		}

		/**
		 * The set sort by param is generated by appsbd
		 *
		 * @param array $props Its searching property.
		 * @param array $allowed_list Its allow property list.
		 */
		public function set_sort_by_param( $props = array(), $allowed_list = array() ) {
			if ( is_string( $allowed_list ) ) {
				$allowed_list = explode( ',', $allowed_list );
			}
			foreach ( $props as $prop ) {
				$prop = (object) $prop;
				if ( ! empty( $prop->prop ) ) {
					$prop->prop = strtolower( $this->string_trim( $prop->prop ) );
					$prop->ord  = strtolower( $this->string_trim( $prop->ord ) );
					if ( in_array( $prop->ord, array( 'asc', 'desc' ) ) ) {
						if ( property_exists( $this, $prop->prop ) || in_array( $prop->prop, $allowed_list ) ) {
							$this->add_order_by( $prop->prop, $prop->ord );
						}
					}
				}
			}
		}
	}
}
