ACC SHELL

Path : /srv/www/vhosts/agroing/web/models/
File Upload :
Current File : /srv/www/vhosts/agroing/web/models/base_model.php

<?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 = '&lt;';
	public static $p_next_link = '&gt;';
	public static $p_first_link = '&lt;&lt;&lt;';
	public static $p_last_link = '&gt;&gt;&gt;';

	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