# Models

A model is a concrete class representation a record of data (aka `entity`) which is persisted to the data storage layer of the application. Model classes are home to any business logic that is specific to a *single entity*. Operations in the model should not perform database queries or one-off business operations. Instead, they should be composed of helper functions to designed to simplify common operations (e.g formatting the entity's fields or building data structures from the entity).

### Doctrine ORM

The model layer of Siteadmin uses the [Doctrine 2 ORM](http://docs.doctrine-project.org/en/latest). All models use the same annotations and entity relationship methodologies as documented on Doctrine's website, and will not be discussed further here.

### Your First Model

A typical model will similar to the example below.

#### Annotations

* `@Entity()` - Identifies the class as a doctrine entity.
* `@InheritanceType("SINGLE_TABLE")` - Enable single table inheritance for the object. This allows child modules to easily extend this entity.
* `@Table(name="sa_users")` - Sets the name of the table where the will be stored. If the table does not already exist, it can be created by updating the doctrine schema. The table names of siteadmin modules should be prefixed with `sa_` as shown in the example. Custom modules should be prefixed with a project specific prefix of your choice. Try to keep it under 5 characters.
* `@HasLifecycleCallbacks` - Enables [doctrine lifecycle callbacks](http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/events.html#lifecycle-events).

#### Properties

By convention, properties should have a `protected` scope. Specific use cases may require `private` scope, but to enforce data integrity `public` scope is not acceptable under any condition.

All models must have a primary key defined (denoted by the `@Id` and `@GeneratedValue` annotations). An exception will be thrown if one is not defined.

#### Methods

As mentioned in the introduction, models should only contain getters/setters and helper methods. A `helper method` performs business logic that only affects the current entity (or associated entity). All database queries should be performed in a corresponding [repository](https://app.gitbook.com/s/-LB7PTje97ARlss-zn8u/developer-guide/models-and-doctrine-orm/repositories.md). In the context of the example below, the `User` entity may add/remove posts, format its own data, or prepare data structures from its own data. It should not affect the state of other entities.

```php
<?php
/**
 * @Entity()
 * @InheritanceType("SINGLE_TABLE")
 * @Table(name="sa_users")
 * @HasLifecycleCallbacks
 */
class User {
    /**
     * @Id
     * @Column(type="integer")
     * @GeneratedValue
     */
    protected $id;
    
    /**
     * @var Posts[]
     * @OneToMany(targetEntity="Post", mappedBy="user")
     */
    protected $posts;
    
    /**
     * @var string
     * @Column(type="string")
     */
    protected $firstName;
    
    /**
     * @var string
     * @Column(type="string")
     */
    protected $lastName;
    
    // <getters and setters>
    // ...
    
    // <helper functions>
    public function getFullName() {
        return sprintf('%s %s', $this->firstName, $this->lastName);
    }
}
```

## Create New Entity Instance

Entity instances should not be instantiated manually. Instead, use the [IOC manager](https://app.gitbook.com/s/-LB7PTje97ARlss-zn8u/developer-guide/models-and-doctrine-orm/ioc.md) to create instances.

## Do

```php
$user = ioc::resolve('User');
```

## Don't

```php
$user = new User();
```

## Save/Remove Model

View the [entity manager documentation](https://app.gitbook.com/s/-LB7PTje97ARlss-zn8u/developer-guide/models-and-doctrine-orm/entity_manager.md) for instructions on how to perform CRUD operations on a model.

## Advanced Queries

View the [repository documentation](https://app.gitbook.com/s/-LB7PTje97ARlss-zn8u/developer-guide/models-and-doctrine-orm/repositories.md) for instructions on how to create complex queries on one or more entities.
