Entities

Entities

Entities are to Articulate what Models are to Eloquent. They are simple objects that represent a particular row of data within your database or data-source, without knowing or caring where the data came from.

Creating an entity is a simple process. Create yourself a class and extend Sprocketbox\Articulate\Entities\Entity, like so;

namespace App\Entities;

use Sprocketbox\Articulate\Entities\Entity;

class User extends Entity
{
}

This is actually the minimum needed for an entity. There is however a bit more you can do to have better control and IDE completion.

Entity Attributes

There are three ways to interact with an entities attributes, through magic properties, getters & setters or the plain old methods.

Magic Properties

All attributes are available as magic properties making use of PHPs __get, __set and __isset magic methods. Because these properties are stored in a similar manner to Eloquents, defining the properties actually breaks the process.

There is nothing specific that needs to be done to make this work, it just will, but if you want to give your IDE a helping hand, you can define the properties in the class level docblock like so;

namespace App\Entities;

use Sprocketbox\Articulate\Entities\Entity;

/**
 * @property-read int       $id
 * @property  string        $name
 * @property  string        $email
 * @property  string        $password
 * @property  string        $rememberToken
 * @property  Carbon\Carbon $createdAt
 * @property  Carbon\Carbon $updatedAt
 */
class User extends Entity
{
}

Pick your case

The properties themselves are accessible as both camelCase and snake_case, so define your properties in whichever way matches your coding style/standards.

Getters & Setters

If you wish to have more control over the getting and setting of your entities attributes, you can create getters and setters in the format getAttributeName and setAttributeName.

If a getter or setting exists for a particular attribute, the magic properties will use it. This is particularly useful as it allows you to define dynamic attributes, such as full name, or human readable filesize.

Below is an example of our User entity with getters and setters.

namespace App\Entities;

use Sprocketbox\Articulate\Entities\Entity;

/**
 * @property-read int       $id
 * @property  string        $name
 * @property  string        $email
 * @property  string        $password
 * @property  string        $rememberToken
 * @property  Carbon\Carbon $createdAt
 * @property  Carbon\Carbon $updatedAt
 */
class User extends Entity
{
    public function getId(): int
    {
        return $this->getAttribute('id');
    }

    public function setName(string $name): self
    {
        $this->setAttribute('name', $name);
        return $this;
    }

    public function getName(): string
    {
        return $this->getAttribute('name');
    }
}

Beware, infinite loops live here

Your getters and setters should always use getAttribute and setAttribute to get and set your attributes.

The get and set methods will check for the presence of getters and/or setters, and call them if they exist. Using these inside your methods will create an infinite loop.

Plain Old Methods

There are four methods provided by the base entity class that can help you interact with attributes, and they are split into two groups.

Plain Attributes

The two plain attribute methods are getAttribute($name) and setAttribute($name, $value), and they speak directly to the attributes array, ignoring any getters & setters.

Magic Attributes

The two magic attribute methods are get($name) and set($name, $value), and they will attempt to use a getter/setter if one exists. Calling these in your getters and/or setters will create an infinite loop that will end all life as we know it.

Dynamic Attributes

Entities are dumb by design, so you can use any of the attribute methods to both set and get, completely dynamic properties, whether new values from elsewhere or formatted versions of attributes that already exist.

To avoid having your dynamic attributes persisted to the database, you can either not define them as an attribute in the mapper, or define them as a dynamic attribute.