<?php
/**
 * Created by PhpStorm.
 * User: Игорь
 * Date: 24.01.2017
 * Time: 12:47
 */

namespace PFRM;



class Model {

  protected $_table_name;

  public $app;

  function __construct() {
    global $app;
    $this->app = $app;

    $this->_table_name = preg_replace( '/^.*\\\(.*)Model$/', "$1", get_called_class() );
  }


  /**
   * Сохраниние объекта
   */
  public function save() {
    $operation = "INSERT INTO ";
    $suffix = "";
    if ( isset( $this->table_id ) ) {
      $operation = "UPDATE ";
      $suffix = " WHERE id = :id";
    }
    $table_columns = NULL;
    $pseudo_columns = NULL;
    foreach ($this as $key => $value ) {
      if ( preg_match('/^table_(?<name>.*)/', $key, $matches) ) {
        if ( $matches['name'] != 'id' && isset( $this->$key ) ) {
          $table_columns[] = $matches['name'];
          $pseudo_columns[] = ':' . $matches['name'];
        }
      }
    }
    if ( is_array( $table_columns ) ) {
      $names = ' ( ' . implode( ',', $table_columns ) . ' ) ';
      $pseudo_names = ' ( ' . implode( ',', $pseudo_columns ) . ' ) ';
      $stmt = $this->app->dbh->prepare( $operation . $this->_table_name . $names . ' VALUES ' . $pseudo_names . $suffix );
      foreach ($table_columns as $value) {
        $tmp_str = 'table_' . $value;
        $stmt->bindParam( ':' . $value, $this->$tmp_str );
      }
      if ( isset( $this->table_id ) ) {
        $stmt->bindParam( ':id', $this->table_id );
      }
      $stmt->execute();
    }
  }

  /**
   * Поиск первого вхождения по условию
   *
   * @param string $condition SQL-строка, которая будет идти после WHERE
   *
   * @return bool|object false или объект
   */
  static public function findFirst( $condition ) {
    global $app;
    $child_model_name = get_called_class();
    $model = new $child_model_name;
    $stmt = $app->dbh->prepare( 'SELECT * FROM ' . $model->_table_name . ' WHERE ' . $condition);
    $stmt->execute();
    $data = $stmt->fetchAll(\PDO::FETCH_ASSOC);
    if (! empty($data) ) {
      foreach ($data[0] as $key => $value ) {
        $column_name = 'table_' . $key;
        $model->$column_name = $value;
      }
      return $model;
    }
    $model = null;
    return false;
  }

  /**
   * Поиск объектов по условию
   *
   * @param string $condition SQL-строка, которая будет идти после WHERE
   *
   * @return array|bool false или массив объектов
   */
  static public function find( $condition ) {
    global $app;
    $child_model_name = get_called_class();
    $model = new $child_model_name;
    $stmt = $app->dbh->prepare( 'SELECT * FROM ' . $model->_table_name . ' WHERE ' . $condition);
    $model = null;
    $stmt->execute();
    $data = $stmt->fetchAll(\PDO::FETCH_ASSOC);
    if (! empty($data) ) {
      $out = [];
      foreach ( $data as $data_single ) {
        $model = new $child_model_name;
        foreach ($data_single as $key => $value ) {
          $column_name = 'table_' . $key;
          $model->$column_name = $value;
        }
        $out[]=$model;
        $model = null;
      }
      return $out;
    }
    return false;
  }

  /**
   * Получение количества записей в таблице
   *
   * @return integer
   */
  public function count() {
    $child_model_name = get_called_class();
    $model = new $child_model_name;
    $stmt = $this->app->dbh->prepare( 'SELECT count(id) FROM ' . $model->_table_name );
    $model = null;
    $stmt->execute();
    return (int) $stmt->fetchColumn();
  }
}