ACC SHELL
<?php
/**
* highest model with main functions
*
* @author Melounek
*/
class Base_model extends CI_Model {
public $a = array();
public $id;
public $table;
protected $useful_columns = array();
//////// Variables for get_all() /////////
public $order;
public $limit; // get_all() clear this after every call
public $where; // get_all() clear this after every call
public $joins;
public function set_limit($limit){ $this->limit = $limit; return $this; } // not compatible with pagination
public function set_order($order){ $this->order = $order; return $this; }
public function set_where($where){ $this->where = $where; return $this; }
public function set_joins($joins){ $this->joins .= " ".$joins; return $this; } // for clearing use variable directly
// pagination variables
public $p_per_page = false;
public $p_total_rows = false;
public static $p_prev_link = '<';
public static $p_next_link = '>';
public static $p_first_link = '<<<';
public static $p_last_link = '>>>';
public function __construct(){ }
// use update or insert depends on id. Returns affected id
public function save($data=array(),$id=NULL){
$this->load($data,$id);
if(!empty($this->a)){
if($this->id){
return $this->update();
}else{
return $this->insert();
}
}else{
Tools::flash("No data to save! [Base_model->save()]","critical");
return false;
}
}
public function load($data=array(),$id=NULL){
if(!empty($data)){
$this->a = $data;
if(!empty($this->a['id']) && is_numeric($this->a['id'])){
$this->id = $this->a['id']; // if id is in data, copy it to $this->id
}
}
if(is_numeric($id) && $id){
$this->id = $id;
}
//Tools::log("Base_model->load() id:'$id'; data: " . var_export($data,1)); // zahlcuje log
return $this;
}
/**
* vraci novou instanci dane tridy
* pretezuje se v relations_model
*
* @param type $data
* @param boolean $call_get_one
* @return object
*/
public function new_one($a=NULL,$call_get_one=false){
if(!$a) $a = $this->a;
$model_name = $this->table . "_model";
$result = new $model_name();
$result->load($a);
$result->useful_columns = $this->useful_columns;
$result->order = $this->order;
$result->limit = $this->limit;
$result->where = $this->where;
$result->joins = $this->joins;
if($call_get_one){
$result->get_one();
}
return $result;
}
public function new_ones($data,$call_get_one=false){
$return = array();
foreach($data as $d) $return[] = $this->new_one($d,$call_get_one);
return $return;
}
public function get_all($call_get_one=false,$log_msg=false){
if(!$log_msg) $log_msg = "with where='$this->where' order='$this->order' limit='$this->limit'";
$log_msg = str_replace("\n"," ","base_model::get_all() ".$log_msg); // create log message
Tools::log($log_msg);
$sql = " # ". $log_msg ."
select ". $this->useful_columns_sql() ." , ". $this->table .".id as id
from ". $this->table . $this->left_join() . // joins direct tables
" " . $this->joins . " " . // whatever you want
($this->where ? " where ".$this->where : "") .
($this->order ? " order by ".$this->order : "");
// count for pagination
if(!empty($this->p_per_page)){
$this->p_total_rows = $this->db->query($sql)->num_rows();
$limit = " limit " . (!empty($_GET['p'])?$_GET['p'].",":"") . $this->p_per_page; // set paginated limit
}else{
$limit = $this->limit ? " limit ".$this->limit : ""; // set simple limit
}
$data = $this->db->query($sql.$limit)->result_array();
$this->limit = "";
$this->where = "";
return $this->new_ones($data,$call_get_one);
}
public function get_pagination(){
$config['per_page'] = $this->p_per_page;
$config['total_rows'] = $this->p_total_rows;
//$config['num_links'] = null;
if(isset($_GET['p'])) $config['cur_page'] = $_GET['p'];
//$config['prev_tag_open'] = '<div class="none">'; $config['prev_tag_close'] = '</div>';
//$config['next_tag_open'] = '<div class="none">'; $config['next_tag_close'] = '</div>';
$config['prev_link'] = self::$p_prev_link;
$config['next_link'] = self::$p_next_link;
$config['first_link'] = self::$p_first_link;
$config['last_link'] = self::$p_last_link;
$config['base_url'] = "/";
foreach(explode("/",$_SERVER['PATH_INFO']) as $u){
if(strpos($u,"p:")===false) $config['base_url'] .= $u."/";
}
$this->pagination->initialize($config);
$html = '<div class="pagination">'.$this->pagination->create_links().'</div>';
return $html;
}
public function get_one($id=NULL){
$this->load(NULL,$id);
if($this->table=="def"){Tools::critical("table isn't set"); return false; }
if(empty($this->id)){ Tools::critical("called get_one() without id!"); return false; }
// it above is just necessary garbage
$sql = "select *,". $this->table .".id as id from ". $this->table . $this->left_join($this->table) ."
where ". $this->table .".id='". $this->id ."'";
$this->a = $this->db->query($sql)->row_array();
Tools::log("base_model::get_one() set data of id=".$this->id);
return $this;
}
public function pagination($per_page){
$this->load->library("pagination");
$this->p_per_page = $per_page;
return $this;
}
public function update($data=array(), $id=NULL, $table=NULL){
// var_dump($data);
if($table !== NULL) $this->table = $table;
$this->load($data,$id);
$columns = array();
$q = $this->db->query("show columns from " . $this->table);
$structure = $q->result_array($q);
foreach($structure as $column){
$columns[] = $column['Field'];
}
// var_dump($columns);
// var_dump($this->a);
// exit('<br>'.__FILE__.'; '.__LINE__);
$q = "update {$this->table} set ";
$c = 0;
foreach($this->a as $i=>$d){
if(!in_array($i, $columns)) continue;
if($this->id=="" && $i=="id"){$this->id = $d; continue;}
elseif($i=="id") continue;
if($c++) $q.=", ";
$q .= $i."='{$d}'";
}
if($c && $this->id){
$updated_row = $this->db->query("select id from ".$this->table." where id='".$this->id."' limit 1")->row_array();
if(empty($updated_row)){
Tools::critical("Tools::update() - unknow id ".$this->id);
return false;
}
$q .= " where id='{$this->id}'";
// var_dump($q);
// exit('<br>'.__FILE__.'; '.__LINE__);
$this->db->query($q);
Tools::log("Base_model->update() id: " . $this->id . " data: " . var_export($this->a,1));
return $this;
}
Tools::critical("Base_model->update() unknow error ... updated data: " . var_export($this->a,1));
return false;
}
public function insert($data=array(),$table=NULL){
if($table !== NULL) $this->table = $table;
$this->load($data);
$columns = array();
$q = $this->db->query("show columns from " . $this->table);
$structure = $q->result_array($q);
foreach($structure as $column){
$columns[] = $column['Field'];
}
$names = ""; $values = "";
$c = 0;
/// insert existing id
if(!empty($this->a['id'])){
$select_id = $this->db->query("select id from ".$this->table." where id='".$this->a['id']."'")->row_array();
}
if(isset($this->a['id']) && !empty($select_id)){
$saved_id = $this->a['id'];
unset($this->a['id']);
}
///
foreach($this->a as $i=>$d){
if(!in_array($i, $columns)) continue;
if($c++){ $names.=", "; $values.=", "; }
$names .= $i;
$values .= "'".$d."'";
}
if($names!=""){
$q = "insert into ".$this->table." ({$names}) values ({$values})";
if($this->db->query($q)){
$insert_id = $this->db->insert_id();
$this->a['id']=$insert_id;
Tools::log("Base_model->insert() id: " . $this->db->insert_id() . " data: " . var_export($this->a,1));
}
if(isset($saved_id) && $saved_id){
$this->del($saved_id,array('table'=>$this->table));
$this->db->query("update ".$this->table." set id=".$saved_id." where id=".$insert_id);
Tools::log("Base_model->insert() overwrites product id " . $saved_id);
}
$this->id = $insert_id;
return $this;
}
Tools::log("Base_model->insert() has get bad data for tableid: " . $saved_id);
return false;
}
public function del($id=NULL,$options=array()){
if(isset($options['table'])){
$table = $options['table'];
}else{
$table = $this->table;
}
$this->load(NULL,$id);
$q = "delete from ".$table." where id='{$this->id}'";
$this->db->query($q);
Tools::log("Base_model->del() did this: '$q'");
return $this->db->affected_rows();
}
public function left_join($table=false){
if(!$table) $table = $this->table; // don't set $this->table there... it's unexpected
$structure = $this->db->query(" # left_join()
select * from " . $table . " limit 1")->row_array();
$result = "";
if(!empty($structure)){
foreach($structure as $ind=>$col){
if(strpos($ind,"id_") !== false){
$sub_table = substr($ind,3);
$result .= "\n\tleft join {$sub_table} on {$table}.id_{$sub_table} = {$sub_table}.id";
}
}
}else{ // if table is empty, there is slower but useable variant with "SHOW COLUMNS"
$structure = $this->db->query(" # left_join() slower variant
show columns from " . $table)->result_array();
foreach($structure as $col){
if(strpos($col['Field'],"id_") !== false){
$sub_table = substr($col['Field'],3);
$result .= "\n\tleft join {$sub_table} on {$table}.id_{$sub_table} = {$sub_table}.id";
}
}
}
return $result;
}
/////////// LIBRARY /////////////////
public function set_useful_columns($columns){
if(isset($columns['id'])) unset($columns['id']); // id is included yet
$this->useful_columns = array_merge($this->useful_columns,$columns);
}
// returns columns for SELECT
protected function useful_columns_sql(){
if(!empty($this->useful_columns)){
return implode(',',$this->useful_columns);
}else{
return "0"; // to easyer writing sql wit comma
}
}
}
ACC SHELL 2018