Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <?php
- namespace Alexya\Database\ORM;
- use \Alexya\Database\QueryBuilder;
- /**
- * Model class
- *
- * This class represents a record from the database and contains methods for fetching,
- * adding and deleting records from the table.
- *
- * To build your ORM classes they must extend this class and be located
- * in the package `\Application\ORM`. In order to use ORM your database MUST
- * follow the naming conventions located in `examples/Conventions/Database.md`,
- * this way Alexya will find the table name based on the class name, if you don't
- * want to follow this conventions you can set the table name in the property
- * {@see \Alexya\Database\ORM::$_table}
- *
- * To retrieve a record from the table use the method {@see \Alexya\Database\ORM\Model::find}
- * which accepts the value of {@see \Alexya\Database\ORM\Model::$_primaryKey} as parameter.
- *
- * To retrieve various records from the table use the method {@see \Alexya\Database\ORM\Model::get}
- *
- * To add a new record to the table use the method {@see \Alexya\Database\ORM\Model::create}
- *
- * When you want to update the values on the database simply call the method
- * {@see \Alexya\Database\ORM::save}.
- *
- * To delete the record from the table use the method {@see \Alexya\Database\ORM::delete}
- *
- * Example:
- *
- * namespace Application\ORM
- * {
- * class User extends \Alexya\Database\ORM\Model
- * {
- * protected static $_table = "users"; //This can be omitted since class name is the same as table name
- * protected static $_primaryKey = "userID"; //If this is omitted Alexya assumes that primary key is always "id"
- * }
- * }
- *
- * $user = \Application\ORM\User::find(1); //SELECT * FROM `users` WHERE `userID`=1
- *
- * $user->password = "[!52test]::";
- * $user->name = "Test name";
- *
- * $user->save(); //UPDATE `users` SET `password`='[!52test]::', `name`='Test name' WHERE `userID`=1
- *
- * $new_user = \Application\ORM\Users::create();
- *
- * $new_user->userID = 2;
- * $new_user->name = "test2";
- * $new_user->password = "test2";
- * $new_user->email = "test2@email.com";
- *
- * $new_user->save(); //INSERT INTO `users` (`userID`, `name`, `password`, `email`) VALUES (2, 'test2', 'test2', 'test2@email.com')
- *
- * @author Manulaiko <manulaiko@gmail.com>
- *
- * @package \Alexya\Database\ORM
- */
- class Model
- {
- ///////////////////////////////////
- // Static methods and properties //
- ///////////////////////////////////
- /**
- * Table name
- *
- * If it's empty it will follow the conventions located in `examples/Conventions/Database.md`
- *
- * @var string
- */
- protected static $_table = "";
- /**
- * Table primary key
- *
- * By default it's always `id`
- *
- * @var string
- */
- protected static $_primaryKey = "id";
- /**
- * Builds and returns an array with specified amount of records
- *
- * The first parameter is an integer that represents the amount of elements
- * the array should have.
- *
- * The second parameter is can be either a string, an object of type
- * {@see \Alexya\Database\QueryBuilder} or an array. It contains the extra
- * SQL to add to the query, if it's an array it represents the WHERE condition
- * of the query.
- *
- * Each element from the array is an instance of the model class.
- *
- * Example:
- *
- * $posts = \Application\ORM\Post::get(); // SELECT * FROM `posts`
- *
- * $posts = \Application\ORM\Post::get(5, [
- * "id[>=]" => 10
- * ]); // SELECT * FROM `posts` WHERE `id`>=10 LIMIT 5
- *
- * $query = new QueryBuilder();
- * $query->order("date");
- * $posts = \Application\ORM\Post::get(5, $query); // SELECT * FROM `posts` ORDER BY `date` DESC LIMIT 5
- *
- * $posts = \Application\ORM\Post::get(5, "WHERE (`title` REGEXP "^([A-Z].*)$")"); // SELECT * FROM `posts` WHERE (`title` REGEXP "^([A-Z].*)$") LIMIT 5
- *
- * @param int $length Array length, if -1 will return the whole table
- * @param array|string|QueryBuilder $extra Extra SQL to add to the query
- *
- * @return array Array containing records from table
- */
- public static function get(int $length = -1, $extra = "") : array
- {
- global $Database;
- $query = new QueryBuilder();
- if(is_array($extra)) {
- $extra = $query->parseTags($extra);
- } else if(is_object($extra) && ($extra instanceof QueryBuilder)) {
- $extra = $extra->getQuery();
- } else if(!is_string($extra)) {
- $extra = "";
- }
- $query->select()
- ->from(static::_getTable())
- ->sql($extra);
- if($length > -1) {
- $query->limit($length);
- }
- $results = $Database->execute($query);
- $return = [];
- foreach($results as $result) {
- $return[] = new static($result);
- }
- return $return;
- }
- /**
- * Returns a record from the table
- *
- * Finds a record from the table based on the {@see \Alexya\Database\ORM\Model::$_primaryKey}
- * of the table and returns an instance of the model class.
- *
- * @param mixed $primaryKey Table primary key value
- *
- * @return \Alexya\Database\ORM\Model Record model from database
- */
- public static function find($primaryKey) : Model
- {
- global $Database;
- $query = new QueryBuilder();
- $query->select()
- ->from(static::_getTable())
- ->where([
- static::$_primaryKey => $primaryKey
- ]);
- $result = $Database->execute($query);
- return new static($result[0]);
- }
- /**
- * Creates a new record
- *
- * The parameter is an array that contains the initial columns of the record.
- *
- * Example:
- *
- * $post = \Application\ORM\Post::create([
- * "id" => 1
- * ]);
- *
- * $post->title = "Test";
- * $post->text = "Test 1";
- *
- * $post->save();
- * // INSERT INTO `posts` (`id`, `title`, `text`) VALUES (1, 'Test', 'Test 1')
- *
- * @param array $columns Initial record columns
- *
- * @return \Alexya\Database\ORM\Model Record model
- */
- public static function create(array $columns = []) : Model
- {
- $model = new static($columns);
- $model->_isInsert = true;
- return $model;
- }
- /**
- * Returns table name
- *
- * @return string Table name
- */
- protected static function _getTable() : string
- {
- if(!empty(static::$_table)) {
- return static::$_table;
- }
- static::$_table = Inflector::pluralize(
- strtolower(
- str_replace("\\", "_", str_replace("Application\\ORM\\", "", $class))
- )
- );
- return static::$_table;
- }
- ///////////////////////////////////////
- // Non static methods and properties //
- ///////////////////////////////////////
- /**
- * Table columns
- *
- * @var array
- */
- protected $_columns = [];
- /**
- * Whether this is a new record or not
- */
- protected $_isInsert = false;
- /**
- * Constructor
- *
- * @param array $columns Table columns
- */
- protected function __construct(array $columns)
- {
- $this->_columns = $columns;
- $this->onInstance();
- }
- /**
- * On instance method
- *
- * This method will be called right after the constructor.
- * You don't need to overwrite the constructor, just rewrite this method.
- */
- public function onInstance()
- {
- }
- /**
- * Builds and saves the changes to the table
- */
- public function save()
- {
- global $Database;
- $query = new QueryBuilder();
- $columns = [];
- if($this->_isInsert) {
- $query->insert(static::_getTable())
- ->values($this->_columns);
- } else {
- $query->update(static::_getTable())
- ->set($this->_columns)
- ->where([
- static::$_primaryKey => $this->_columns[static::$_primaryKey]
- ]);
- }
- $Database->execute($query);
- }
- /**
- * Deletes this record from table
- */
- public function delete()
- {
- global $Database;
- $query = new QueryBuilder();
- $query->delete(static::_getTable())
- ->where([
- static::$_primaryKey => $this->_columns[static::$_primaryKey]
- ]);
- $Database->execute($query);
- }
- /**
- * Magic method get
- *
- * @param string $key Name of the property
- *
- * @return mixed $key in $this->_columns
- */
- public function __get($key)
- {
- if(isset($this->_columns[$key])) {
- return $this->_columns[$key];
- }
- return null;
- }
- /**
- * Magic method set
- *
- * @param string $key Name of the property
- * @param mixed $value Property value
- */
- public function __set($key, $value)
- {
- $this->_columns[$key] = $value;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement