BG MVC Model View Controller eğitim serisi yayında...

Ana sayfa > Programlama > Bgmvc > Model sınıfı

Model sınıfı

Controller.php içindeki Controller sınıfından türetilen herhangi bir denetleyici sınıfı içindeki bir hareket fonksiyonundan, veritabanı işlemlerini gerçekleştirmek için oluşturulan DB.php dosyasında tanımlı DB sınıfına erişim sağlayarak bu sınıfın fonksiyonlarını kullanmak için, Model.php dosyasında tanımlı Model sınıfı oluşturulur.

app/controllers dizininde tanımlı bir denetleyici hareket fonksiyonu içinden, kullanılacak veritabanı tablosu için Model sınıfından türetilerek oluşturulmuş olan bir sınıf arayüzü üzerinden Model sınıfı fonksiyonları doğrudan çağrılarak DB sınıfı fonksiyonlarına erişim sağlanır.


<?php 
namespace Core;
use \PDO;
use Core\{DB, Router};

class Model {
    protected static $table = "";
    protected static $columns = false;
    protected $_validation_passed = true, $_errors = [], $_skip_update = [];

    protected static function get_db($set_fetch_class = false) {
        $db = DB::get_instance();
        if($set_fetch_class) {
            $db->set_class(get_called_class());
            $db->set_fetch_type(PDO::FETCH_CLASS);
        }
        return $db;
    }

    public static function insert($values) {
        $db = static::get_db();
        return $db->insert(static::$table, $values);
    }

    public static function update($values, $conditions) {
        $db = static::get_db();
        return $db->update(static::$table, $values, $conditions);
    }

    public function delete() {
        $db = static::get_db();
        $table = static::$table;
        $params = [
            'conditions' => "id = :id",
            'bind' => ['id' => $this->id]
        ];
        list('sql' => $conds, 'bind' => $bind) = self::query_param_builder($params);
        $sql = "DELETE FROM {$table} {$conds}";
        return $db->execute($sql, $bind);
    }

    public static function find($params = []) {
        $db = static::get_db(true);
        list('sql' => $sql, 'bind' => $bind) = self::select_builder($params);
		
        return $db->query($sql, $bind)->results();
    }

    public static function find_first($params = []) {
        $db = static::get_db(true);
        list('sql' => $sql, 'bind' => $bind) = self::select_builder($params);
        
		$results = $db->query($sql, $bind)->results();
        return isset($results[0])? $results[0] : false;
    }

    public static function find_by_id($id) {
        return static::find_first([
            'conditions' => "id = :id", 
            'bind' => ['id' => $id]
        ]);
    }

    public static function find_total($params = []) {
        unset($params['limit']);
        unset($params['offset']);
        $table = static::$table;
        $sql = "SELECT COUNT(*) AS total FROM {$table}";
        list('sql' => $conds, 'bind' => $bind) = self::query_param_builder($params);
        $sql .= $conds;
        $db = static::get_db();
        $results = $db->query($sql, $bind);
        $total = sizeof($results->results()) > 0 ? $results->results()[0]->total : 0;
        return $total;
    }

    public function save() {
        $save = false;
		$this->before_save();
		
		if($this->_validation_passed) {
            $db = static::get_db();
            $values = $this->get_values_for_save();
            if($this->is_new(()) {
                $save = $db->insert(static::$table, $values);
                if($save) {
                    $this->id = $db->last_insert_id();
                }
            } else {
                $save = $db->update(static::$table,$values, ['id' => $this->id]);
            }
        }
		
        return $save;
    }

    public function is_new(() {
        return empty($this->id);
    }

    public static function select_builder($params = []) {
        $columns = array_key_exists('columns', $params)? $params['columns'] : "*";
        $table = static::$table;
        $sql = "SELECT {$columns} FROM {$table}";
        list('sql' => $conds, 'bind' => $bind) = self::query_param_builder($params);
        $sql .= $conds;
        return ['sql' => $sql, 'bind' => $bind];
    }

    public static function query_param_builder($params = []) {
        $sql = "";
        $bind = array_key_exists('bind', $params)? $params['bind'] : [];
        // joins
        // [['table2', 'table1.id = table2.key', 'tableAlias', 'LEFT' ]]
        if(array_key_exists('joins', $params)) {
            $joins = $params['joins'];
            foreach($joins as $join) {
                $join_table = $join[0];
                $join_on = $join[1];
                $join_alias = isset($join[2])? $join[2] : "";
                $join_type = isset($join[3])? "{$join[3]} JOIN" : "JOIN";
                $sql .= " {$join_type} {$join_table} {$join_alias} ON {$join_on}";
            }
        }

        // where 
        if(array_key_exists('conditions', $params)) {
            $conds = $params['conditions'];
            $sql .= " WHERE {$conds}";
        }

        // group 
        if(array_key_exists('group', $params)) {
            $group = $params['group'];
            $sql .= " GROUP BY {$group}";
        }

        // order
        if(array_key_exists('order', $params)) {
            $order = $params['order'];
            $sql .= " ORDER BY {$order}";
        } 

        // limit
        if(array_key_exists('limit', $params)) {
            $limit = $params['limit'];
            $sql .= " LIMIT {$limit}";
        }

        // offset
        if(array_key_exists('offset', $params)) {
            $offset = $params['offset'];
            $sql .= " OFFSET {$offset}";
        }
        return ['sql' => $sql, 'bind' => $bind];
    }

    public function get_values_for_save() {
        $columns = static::get_columns();
        $values = [];
        foreach($columns as $column) {
            if(!in_array($column, $this->_skip_update)) {
               $values[$column] = $this->{$column};
            }
        }
        return $values;
    }

    public static function get_columns() {
        if(!static::$columns) {
           $db = static::get_db();
           $table = static::$table;
           $sql = "SHOW COLUMNS FROM {$table}";
           $results = $db->query($sql)->results();
           $columns = [];
           foreach($results as $column) {
               $columns[] = $column->Field;
           }
           static::$columns = $columns;
        }
        return static::$columns;
    }

    public function run_validation($validator) {
		$validates = $validator->run_validation();
        if(!$validates) {
           $this->_validation_passed = false;
           $this->_errors[$validator->field] = $validator->msg;
        }
    }

    public function get_errors() {
        return $this->_errors;
    }

    public function set_error($name, $value) {
        $this->_errors[$name] = $value;
        $this->_validation_passed = false;
    }

    public function time_stamps() {
        $dt = new \DateTime("now", new \DateTimeZone("UTC"));
        $now = $dt->format('Y-m-d H:i:s');
        $this->updated_at = $now;
        if($this->is_new(()) {
           $this->created_at = $now;
        }
    }

    public static function merge_with_pagination($params, $pageno, $total) {
		if(isset($_POST['records_limit'])) { 
		   $_SESSION['records_limit'] = $_POST['records_limit'];
	    }
	    $limit = isset($_SESSION['records_limit']) ? $_SESSION['records_limit'] : (int) Config::get('record_limit');
		if((int)$pageno>ceil($total/$limit)) {
		   Router::redirect('exceptions/index/nopage');	
		}		
	    $page = $pageno!='' ? $pageno : 1;
	    $pagination_start = ($page - 1) * $limit;
	    $params['limit'] = $limit;
	    $params['offset'] = $pagination_start;
		
		return [$params, $page];
    }	

    public function before_save(){}
}