Advertisement
Guest User

Alexya's ORM Model class :D

a guest
Mar 22nd, 2016
108
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 9.64 KB | None | 0 0
  1. <?php
  2. namespace Alexya\Database\ORM;
  3.  
  4. use \Alexya\Database\QueryBuilder;
  5.  
  6. /**
  7.  * Model class
  8.  *
  9.  * This class represents a record from the database and contains methods for fetching,
  10.  * adding and deleting records from the table.
  11.  *
  12.  * To build your ORM classes they must extend this class and be located
  13.  * in the package `\Application\ORM`. In order to use ORM your database MUST
  14.  * follow the naming conventions located in `examples/Conventions/Database.md`,
  15.  * this way Alexya will find the table name based on the class name, if you don't
  16.  * want to follow this conventions you can set the table name in the property
  17.  * {@see \Alexya\Database\ORM::$_table}
  18.  *
  19.  * To retrieve a record from the table use the method {@see \Alexya\Database\ORM\Model::find}
  20.  * which accepts the value of {@see \Alexya\Database\ORM\Model::$_primaryKey} as parameter.
  21.  *
  22.  * To retrieve various records from the table use the method {@see \Alexya\Database\ORM\Model::get}
  23.  *
  24.  * To add a new record to the table use the method {@see \Alexya\Database\ORM\Model::create}
  25.  *
  26.  * When you want to update the values on the database simply call the method
  27.  * {@see \Alexya\Database\ORM::save}.
  28.  *
  29.  * To delete the record from the table use the method {@see \Alexya\Database\ORM::delete}
  30.  *
  31.  * Example:
  32.  *
  33.  *     namespace Application\ORM
  34.  *     {
  35.  *         class User extends \Alexya\Database\ORM\Model
  36.  *         {
  37.  *              protected static $_table      = "users";  //This can be omitted since class name is the same as table name
  38.  *              protected static $_primaryKey = "userID"; //If this is omitted Alexya assumes that primary key is always "id"
  39.  *         }
  40.  *     }
  41.  *
  42.  *     $user = \Application\ORM\User::find(1); //SELECT * FROM `users` WHERE `userID`=1
  43.  *    
  44.  *     $user->password = "[!52test]::";
  45.  *     $user->name = "Test name";
  46.  *
  47.  *     $user->save(); //UPDATE `users` SET `password`='[!52test]::', `name`='Test name' WHERE `userID`=1
  48.  *
  49.  *     $new_user =  \Application\ORM\Users::create();
  50.  *    
  51.  *     $new_user->userID   = 2;
  52.  *     $new_user->name     = "test2";
  53.  *     $new_user->password = "test2";
  54.  *     $new_user->email    = "test2@email.com";
  55.  *
  56.  *     $new_user->save(); //INSERT INTO `users` (`userID`, `name`, `password`, `email`) VALUES (2, 'test2', 'test2', 'test2@email.com')
  57.  *
  58.  * @author Manulaiko <manulaiko@gmail.com>
  59.  *
  60.  * @package \Alexya\Database\ORM
  61.  */
  62. class Model
  63. {
  64.     ///////////////////////////////////
  65.     // Static methods and properties //
  66.     ///////////////////////////////////
  67.     /**
  68.      * Table name
  69.      *
  70.      * If it's empty it will follow the conventions located in `examples/Conventions/Database.md`
  71.      *
  72.      * @var string
  73.      */
  74.     protected static $_table = "";
  75.    
  76.     /**
  77.      * Table primary key
  78.      *
  79.      * By default it's always `id`
  80.      *
  81.      * @var string
  82.      */
  83.     protected static $_primaryKey = "id";
  84.    
  85.     /**
  86.      * Builds and returns an array with specified amount of records
  87.      *
  88.      * The first parameter is an integer that represents the amount of elements
  89.      * the array should have.
  90.      *
  91.      * The second parameter is can be either a string, an object of type
  92.      * {@see \Alexya\Database\QueryBuilder} or an array. It contains the extra
  93.      * SQL to add to the query, if it's an array it represents the WHERE condition
  94.      * of the query.
  95.      *
  96.      * Each element from the array is an instance of the model class.
  97.      *
  98.      * Example:
  99.      *
  100.      *     $posts = \Application\ORM\Post::get(); // SELECT * FROM `posts`
  101.      *    
  102.      *     $posts = \Application\ORM\Post::get(5, [
  103.      *         "id[>=]" => 10
  104.      *     ]); // SELECT * FROM `posts` WHERE `id`>=10 LIMIT 5
  105.      *    
  106.      *     $query = new QueryBuilder();
  107.      *     $query->order("date");
  108.      *     $posts = \Application\ORM\Post::get(5, $query); // SELECT * FROM `posts` ORDER BY `date` DESC LIMIT 5
  109.      *    
  110.      *     $posts = \Application\ORM\Post::get(5, "WHERE (`title` REGEXP "^([A-Z].*)$")"); // SELECT * FROM `posts` WHERE (`title` REGEXP "^([A-Z].*)$") LIMIT 5
  111.      *
  112.      * @param int                       $length Array length, if -1 will return the whole table
  113.      * @param array|string|QueryBuilder $extra  Extra SQL to add to the query
  114.      *
  115.      * @return array Array containing records from table
  116.      */
  117.     public static function get(int $length = -1, $extra = "") : array
  118.     {
  119.         global $Database;
  120.        
  121.         $query = new QueryBuilder();
  122.        
  123.         if(is_array($extra)) {
  124.             $extra = $query->parseTags($extra);
  125.         } else if(is_object($extra) && ($extra instanceof QueryBuilder)) {
  126.             $extra = $extra->getQuery();
  127.         } else if(!is_string($extra)) {
  128.             $extra = "";
  129.         }
  130.        
  131.         $query->select()
  132.               ->from(static::_getTable())
  133.               ->sql($extra);
  134.         if($length > -1) {
  135.             $query->limit($length);
  136.         }
  137.        
  138.         $results = $Database->execute($query);
  139.         $return  = [];
  140.        
  141.         foreach($results as $result) {
  142.             $return[] = new static($result);
  143.         }
  144.        
  145.         return $return;
  146.     }
  147.    
  148.     /**
  149.      * Returns a record from the table
  150.      *
  151.      * Finds a record from the table based on the {@see \Alexya\Database\ORM\Model::$_primaryKey}
  152.      * of the table and returns an instance of the model class.
  153.      *
  154.      * @param mixed $primaryKey Table primary key value
  155.      *
  156.      * @return \Alexya\Database\ORM\Model Record model from database
  157.      */
  158.     public static function find($primaryKey) : Model
  159.     {
  160.         global $Database;
  161.        
  162.         $query = new QueryBuilder();
  163.         $query->select()
  164.               ->from(static::_getTable())
  165.               ->where([
  166.                     static::$_primaryKey => $primaryKey
  167.                 ]);
  168.                
  169.         $result = $Database->execute($query);
  170.        
  171.         return new static($result[0]);
  172.     }
  173.    
  174.     /**
  175.      * Creates a new record
  176.      *
  177.      * The parameter is an array that contains the initial columns of the record.
  178.      *
  179.      * Example:
  180.      *
  181.      *     $post = \Application\ORM\Post::create([
  182.      *         "id" => 1
  183.      *     ]);
  184.      *    
  185.      *     $post->title = "Test";
  186.      *     $post->text  = "Test 1";
  187.      *    
  188.      *     $post->save();
  189.      *     // INSERT INTO `posts` (`id`, `title`, `text`) VALUES (1, 'Test', 'Test 1')
  190.      *
  191.      * @param array $columns Initial record columns
  192.      *
  193.      * @return \Alexya\Database\ORM\Model Record model
  194.      */
  195.     public static function create(array $columns = []) : Model
  196.     {
  197.         $model = new static($columns);
  198.         $model->_isInsert = true;
  199.        
  200.         return $model;
  201.     }
  202.    
  203.     /**
  204.      * Returns table name
  205.      *
  206.      * @return string Table name
  207.      */
  208.     protected static function _getTable() : string
  209.     {
  210.         if(!empty(static::$_table)) {
  211.             return static::$_table;
  212.         }
  213.        
  214.         static::$_table = Inflector::pluralize(
  215.             strtolower(
  216.                 str_replace("\\", "_", str_replace("Application\\ORM\\", "", $class))
  217.             )
  218.         );
  219.        
  220.         return static::$_table;
  221.     }
  222.  
  223.     ///////////////////////////////////////
  224.     // Non static methods and properties //
  225.     ///////////////////////////////////////
  226.     /**
  227.      * Table columns
  228.      *
  229.      * @var array
  230.      */
  231.     protected $_columns = [];
  232.  
  233.     /**
  234.      * Whether this is a new record or not
  235.      */
  236.     protected $_isInsert = false;
  237.    
  238.     /**
  239.      * Constructor
  240.      *
  241.      * @param array $columns Table columns
  242.      */
  243.     protected function __construct(array $columns)
  244.     {
  245.         $this->_columns = $columns;
  246.        
  247.         $this->onInstance();
  248.     }
  249.    
  250.     /**
  251.      * On instance method
  252.      *
  253.      * This method will be called right after the constructor.
  254.      * You don't need to overwrite the constructor, just rewrite this method.
  255.      */
  256.     public function onInstance()
  257.     {
  258.        
  259.     }
  260.  
  261.     /**
  262.      * Builds and saves the changes to the table
  263.      */
  264.     public function save()
  265.     {
  266.         global $Database;
  267.        
  268.         $query   = new QueryBuilder();
  269.         $columns = [];
  270.        
  271.         if($this->_isInsert) {
  272.             $query->insert(static::_getTable())
  273.                   ->values($this->_columns);
  274.         } else {
  275.             $query->update(static::_getTable())
  276.                   ->set($this->_columns)
  277.                   ->where([
  278.                         static::$_primaryKey => $this->_columns[static::$_primaryKey]
  279.                     ]);
  280.         }
  281.        
  282.         $Database->execute($query);
  283.     }
  284.  
  285.     /**
  286.      * Deletes this record from table
  287.      */
  288.     public function delete()
  289.     {
  290.         global $Database;
  291.        
  292.         $query = new QueryBuilder();
  293.         $query->delete(static::_getTable())
  294.               ->where([
  295.                     static::$_primaryKey => $this->_columns[static::$_primaryKey]
  296.                 ]);
  297.                
  298.         $Database->execute($query);
  299.     }
  300.  
  301.     /**
  302.      * Magic method get
  303.      *
  304.      * @param string $key Name of the property
  305.      *
  306.      * @return mixed $key in $this->_columns
  307.      */
  308.     public function __get($key)
  309.     {
  310.         if(isset($this->_columns[$key])) {
  311.             return $this->_columns[$key];
  312.         }
  313.        
  314.         return null;
  315.     }
  316.  
  317.     /**
  318.      * Magic method set
  319.      *
  320.      * @param string $key   Name of the property
  321.      * @param mixed  $value Property value
  322.      */
  323.     public function __set($key, $value)
  324.     {
  325.         $this->_columns[$key] = $value;
  326.     }
  327. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement