Skip to content

Tutorial Models

yuri.blanc edited this page Jul 5, 2017 · 1 revision

Creating a Model

disclaimer

This section refers to HackORM models and pHackp current database implementation. it's possible that HackORM will be changed with another well-established orm.

Naming conventions and database creation conventions
  1. Class name = lowercase table name
  2. Class property = column name
  3. id = the primary key of any table, must be auto-increment and primary. (Mandatory)
  4. 1-1/1-N relationship = referencing column and property must be classname_id
  5. N-M relationship = table must be called as class1_class2 with a primary autoincrement key id and both relationship keys respectively classname_id

1. Create class

HackORM models must subclass \yuxblank\phackp\database\Model::class The class provides all the features required to interact with database directly by active record pattern.

Create a class following the subclass or implementation guide. (see above)

<?php
namespace model;
class User extends Model

2) Define object properties == table and columns

HackORM will match object public properties to column tables, and class name to table name.

It's straightforward for new projects, but quite limited for existing databases. So if you're planning to use an existing database, i suggest to use another ORM that handles this case or use directly Database class (that abstracts PDO).

Let's write a Model class:

<?php
namespace model;
class User extends Model {
  
  public $id; // mandatory
  public $name;
  public $surname;
  public $usergroup_id; // this references UserGroup::class model id.
}

Now we have to create our User table, so:

   CREATE TABLE user
   (
       id INT PRIMARY KEY AUTO_INCREMENT,
       name VARCHAR(50),
       surname VARCHAR(50),
       usergroup_id INT
   );
   

Since we are referencing the UserGroup table, we now create it's model

    <?php
    namespace model;
    class UserGroup extends Model {
      
      public $id; // mandatory
      public $name;
      public $level;
    }
   

Create the UserGroup table:

    CREATE TABLE usergroup
    (
        id INT PRIMARY KEY AUTO_INCREMENT,
        name VARCHAR(50),
        level INT(2)
    );

3) Using our model for CRUD operations

For referencing the model, we need an instance of it.

We can inject the model where needed or create a new instance.

An example of controller action creating an entity:
    public function getUser(ServerRequestInterface $serverRequest)
    {
       if ($serverRequest->getParsedBody()){
          $name = filter_var($serverRequest->getParsedBody()['form_name'], FILTER_SANITIZE_STRING);
          $surname = filter_var($serverRequest->getParsedBody()['form_surname'], FILTER_SANITIZE_STRING);
          $usergroup = filter_var($serverRequest->getParsedBody()['form_usergroup'], FILTER_SANITIZE_NUMBER_INT);
          // replace $user with a new instance of $user or null if doesn't exist.
          $user = new User();
          $user->name = $name;
          $user->surname = $surname;
          $user->usergroup_id = $usergroup;
          
          if ($user->save()){
             // flow after use save
          } else {
             // flow after use save fail
          }
       }
       
    } 
An example of controller action reading an entity:
    // $user is injected into the method. It's an empty instance (if injected by container)
    public function getUser(ServerRequestInterface $serverRequest, User $user)
    {
       if ($serverRequest->getQueryParams()['id']){
          $id = filter_var($serverRequest->getQueryParams()['id'], FILTER_SANITIZE_NUMBER_INT);
          // replace $user with a new instance of $user or null if doesn't exist.
          $user = $user->findById($id);
          // continue flow
       }
      
    } 
Update of an existing entity:
 $user->id = $id; // $id is the id of the updating entity.
 $user->name = "new name";
 $user->update();
Remove of an entity:
// now we use the Factory Model::Make() instead of "new" keyword.
 User::make()
 ->findById($id) // $id is the id of the updating entity.
 ->delete();

4) Object relationships

HackORM exposes useful methods to get related object instances. A common way to define an entity relation is done by defining a method to retrieve relationships.

has one

Our User Entity has a relationship 1-1 to UserGroup entity. So we create a method in the User class.

      <?php
      namespace model;
      class UserGroup extends Model {
        
        public $id; // mandatory
        public $name;
        public $level;
        
        public function userGroup(){
           return $this->hasOne(UserGroup::class);
        }
      }

Model::class will handle the relationship for us, given the relationship class. Simply calling :

$user->userGroup();

Will return the instance of UserGroup::class referred by usergroup_id property of User::class.