db = $db; } /** * Get a query builder instance for the model's table * * @return mixed */ public function query() { return $this->db->table( $this->table ); } /** * Apply conditions to a query builder instance * * @param mixed $query * @param array $conditions * * @return mixed */ protected function apply_conditions( $query, array $conditions = array() ) { foreach ( $conditions as $field => $value ) { if ( is_array( $value ) ) { if ( strtolower( $value[0] ) === 'in' && is_array( $value[1] ) ) { $query->where_in( $field, $value[1] ); } else { $query->where( $field, $value[0] ?? '=', $value[1] ); } } else { $query->where( $field, '=', $value ); } } return $query; } /** * Get total number of records based on conditions * * @param array $conditions * * @return int */ public function count( array $conditions = array() ) { $query = $this->apply_conditions( $this->db->table( $this->table ), $conditions ); return $query->count(); } /** * Get sum of a field based on conditions * * @param string $field * @param array $conditions * * @return float */ public function sum( string $field, array $conditions = array() ) { $query = $this->apply_conditions( $this->db->table( $this->table ), $conditions ); return (float) $query->sum( $field ); } /** * Create a new record in the database * * @param array $data * * @return mixed|false */ public function create( array $data ) { $filtered = array_intersect_key( $data, array_flip( $this->fillable ) ); $result = $this->db->table( $this->table )->insert( $filtered ); return $result > 0 ? $this->find( array( 'id' => $result ) ) : false; } /** * Update an existing record in the database * * @param int $id * @param array $data * * @return mixed */ public function update( int $id, array $data ) { $filtered = array_intersect_key( $data, array_flip( $this->fillable ) ); return $this->db->table( $this->table )->where( 'id', '=', $id )->update( $filtered ); } /** * Delete a record from the database * * @param int $id * * @return mixed */ public function delete( int $id ) { return $this->db->table( $this->table )->where( 'id', '=', $id )->delete(); } /** * Get multiple records from the database with pagination * * @param array $conditions * @param int $page Current page number * @param int $per_page Items per page * @param array $order_by * * @return array */ public function get( array $conditions = array(), int $page = 1, int $per_page = 10, $order_by = array() ) { $query = $this->apply_conditions( $this->db->table( $this->table ), $conditions ); $total = $query->count(); $offset = ( $page - 1 ) * $per_page; $data = $query->limit( $per_page )->offset( $offset ) ->order_by( $order_by )->get(); foreach ( $data as &$row ) { $row = $this->with_virtual_attributes( $row ); } return array( 'items' => $data, 'current_page' => $page, 'per_page' => $per_page, 'total' => $total, 'total_pages' => ceil( $total / $per_page ), ); } /** * Find a single record from the database * * @param array $conditions * * @return mixed */ public function find( array $conditions = array() ) { $query = $this->apply_conditions( $this->db->table( $this->table ), $conditions ); $row = $query->first(); if ( is_wp_error( $row ) || $row === null ) { return $row; } return $this->with_virtual_attributes( $row ); } /** * Get the table name for the model * * @return string */ public function get_table_name() { return $this->table; } /** * Get the virtual attributes for the model * * @param object $row * * @return object */ public function with_virtual_attributes( $row ) { if ( method_exists( $this, 'get_virtual_attributes' ) && $row ) { foreach ( $this->get_virtual_attributes( $row ) as $key => $value ) { $row->$key = $value; } } return $row; } }