Traits
The idea behind this is to re-use common logic between models. There's not much magic behind this, it's just traits.
The ones included in Flex are:
- Timestampable: Adds created and update date to models.
- Sluggable: Adds a slug field, which is created based on a mix of other fields.
- Versionable: Adds versioning to a model, so the model using this behavior stores a copy of itself along with a version number. A model can switch to any version with a single command.
- Geopositioned: Adds latitude and longitude to a model, and also an utility distance calculator function.
- Translatable: Adds translation records for the selected fields.
The source can be checked in src/Traits.
There is no magic behind these traits, you have to add the required method calls in the expected hooks to make them work.
Timestampable
Add it to a model
use Makiavelo\Flex\Traits\Timestampable;
class User extends Flex
{
use Timestampable;
public $id;
public $name;
public $last_name;
public function __construct()
{
parent::__construct();
$this->meta()->add('table', 'user');
}
public function preSave()
{
// The trait hook is directly called, no magic.
$this->_timestampablePreSave();
return true;
}
}
Usage
$repo = FlexRepository::get();
$model = new User();
$model->setName('John');
$model->setLastName('Doe');
$repo->save($model);
echo $model->getCreatedAt();
echo $model->getUpdatedAt();
Sluggable
use Makiavelo\Flex\Traits\Sluggable;
class User extends Flex
{
use Sluggable;
public $id;
public $name;
public $last_name;
public function __construct()
{
parent::__construct();
$this->meta()->add('table', 'user');
// Calling in the constructor the required method
$this->_sluggableInit([
'fields' => ['name', 'last_name'],
'update' => true
]);
}
public function preSave()
{
// The trait hook is directly called, no magic.
$this->_sluggablePreSave();
return true;
}
}
Usage:
$repo = FlexRepository::get();
$model = new User();
$model->setName('John');
$model->setLastName('Doe');
$repo->save($model);
echo $model->getSlug(); // john-doe
Versionable
use Makiavelo\Flex\Traits\Versionable;
class User extends Flex
{
use Versionable;
public $id;
public $name;
public $last_name;
public $description;
public function __construct()
{
parent::__construct();
$this->meta()->add('table', 'user');
}
public function preSave()
{
// The trait hook is directly called, no magic.
$this->_versionablePreSave();
return true;
}
}
Usage:
$repo = FlexRepository::get();
$model = new User();
$model->setName('John');
$model->setLastName('Doe');
$model->setDescription('Some description');
$repo->save($model); // Version 1 created
$model->setName('Jack');
$repo->save($model); // Version 2 created
$model->changeVersion(1);
$repo->save($model); // Version 3 created, equal to version 1
echo $model->getVersion(); // 3
Geopositioned
This one only adds fields and functionality, so no hooks required to make it work.
use Makiavelo\Flex\Traits\Geopositioned;
class User extends Flex
{
use Geopositioned;
public $id;
public $name;
public function __construct()
{
parent::__construct();
$this->meta()->add('table', 'user');
}
}
Usage:
$repo = FlexRepository::get();
$model = new User();
$model->setName('John');
// Florence
$model->setLat('42.8201432');
$model->setLng('10.7506802');
// Rome
$distance = $model->distanceTo('41.9097306', '12.2558141');
echo $distance; // Distance in meters
echo round($distance/1000); // Distance in kilometers
Translatable
Add trait to a model:
class Post extends Flex
{
use Translatable;
public $id;
public $title;
public $body;
public $description;
public function __construct()
{
parent::__construct();
$this->meta()->add('table', 'post');
// Calling in the constructor the required method
$this->_translatableInit();
}
}
Usage:
$model = new Post();
$model->setTitle('A post title');
$model->setBody('Some long body in default lang');
$model->setDescription('Some cool description');
$model->translations()->add(
$model->translation('es', [
'title' => 'Titulo de post',
'description' => 'Un cuerpo largo en espanol',
'short_description' => 'Descripcion corta'
])
);
$model->translations()->add(
$model->translation('fr', [
'description' => 'I have to learn french...',
'short_description' => 'Maybe...'
])
);
FlexRepository::get()->save($model);
The behavior will add a relation to the model called 'Translations' and add a table called 'post_translation' ({table}_translation). To handle the translations table, a simple Flex object is used, so you can treat the translations as another 'Has' relation. A convenience method is added to the model called 'translation' which basically creates that flex model and adds it to the translations list.