Eloquent Integration
Laravel eloquent explained
## Introduction
The Laravel Eloquent ORM comes default with ABC Manager. We will describe the
basic usage of Eloquent in ABC Manager. For more information, visit
the Eloquent docs.
### Usage
With Eloquent, each database table has a corresponding `Model` which is used to
interact with that table. Models allow you to query for data in your tables, as
well as insert, update & delete new records into the table.
You can define a model anywhere in your bundle, but as a convention we create
a `Model` directory which contains all models. All models must extend the ABC
BaseModel in order to use ABC scopes on deleted or unpublished items.
```php
### File: src/Demo/ContentBundle/Model/Article.php
<?php
namespace Demo\ContentBundle\Model;
use Abc\BaseBundle\ORM\Eloquent\BaseModel;
use Abc\BaseBundle\ORM\Eloquent\SoftDeletesInterface;
/**
* Model of an article
*/
final class Article extends BaseModel implements SoftDeletesInterface
{
// Traits
use \Abc\BaseBundle\ORM\Eloquent\Traits\SoftDeletesTrait;
use \Abc\BaseBundle\ORM\Eloquent\Traits\WorkflowTrait;
protected $table = 'articles';
}
```
To retrieve models in your application logic, make use of the static model
methods just as the Laravel docs describe. Take a loot at this controller action
which retrieves the 5 records of the Article Model.
```php
### File: src/Demo/PublicationBundle/Controller/Demo.php
/**
* Demo RTE Placeholders
*/
public function rtePlaceholdersAction(): Response
{
// Retrieve 5 articles
$articles = \Demo\ContentBundle\Model\Article::limit(5)->get();
// Render a demo template
return $this->renderDemo(
// Render template for the current demo
$this->renderBundleTemplate(
'DemoPublicationBundle:page/content/demos/eloquent.html.twig',
compact('articles')
),
// Sidebar
self::otherSidebar('eloquent')
);
}
```
### Scopes
ABC Manager provides some extra scopes for models that have soft-deletes,
scheduling or workflow. You can add these scopes to your models by using a
trait.
#### Soft deleting scope
Add the `\Abc\BaseBundle\ORM\Eloquent\Traits\SoftDeletesTrait` to enable soft
deletes filter on the given model. With this trait it won't show any soft
deleted items. To includes all deleted items call `withTrashed()` on the query
builder.
```php
$articles = Article::withTrashed()->get();
```
#### Workflow scope
The workflow scope filters out any unpublished records. To include all
unpublished records you can call `withAnyWorkflow()` on the query builder.
```php
$articles = Article::withAnyWorkflow()->get();
```
To includes items up to a specific workflow level, you can use
`withMaxWorkflow()`. For example, to query both published records and records in
review:
```php
use Abc\BaseBundle\Workflow;
$articles = Article::withMaxWorkflow(Workflow::WORKFLOW_REVIEW)->get();
```
The default maximum workflow level can also be configured for each model.
```php
use Abc\BaseBundle\Workflow;
class Article extends \Abc\BaseBundle\ORM\Eloquent\BaseModel
{
protected static $allowedWorkflowLevel = Workflow::WORKFLOW_REVIEW;
}
```
#### Scheduling scope
Add the `\Abc\BaseBundle\ORM\Eloquent\Traits\SchedulingTrait` to enable
scheduling on your model. This will only show records where the current time is
larger than online date and smaller than offline date. To include also offline
records you can call `withOffline()` on the query builder.
```php
$articles = Article::withOffline()->get();
```
To filter for a different time for a specific query, use the `withOnlineAt()` on
the query builder.
```php
$when = new DateTime;
$articles = Article::withOnlineAt($when)->get();
```
### Default fields
When the ABC BaseModel is extended in an eloquent model, it will also define the
default fields. These default fields are: `deleted`, `workflow`, `created`,
`created_by`, `changed` and `changed_by`. When you want to add your own default
fields you can't simply just define them in the model. You will then overwrite
the ABC default fields. Use the following constructor method in your model to
add defaults on top of the base default:
```php
public function __construct(array $attributes = [])
{
// Merge Article model defaults with defaults defined by the BaseModel
$this->attributes = array_merge(
$this->attributes,
['title' => 'Lorum ipsum']
);
parent::__construct($attributes);
}
```
### Connections
By default, an Eloquent model uses the database of the current application. It
is also possible to pin a model to a specific application database, which is
useful for using the model from within another application. To do so, override
`getDatabase()` of the model, possibly in a new base class if needed for several
models:
```php
class Article extends \Abc\BaseBundle\ORM\Eloquent\BaseModel
{
use \Abc\AbcBundle\DBAL\DatabaseManager\AccessTrait;
public function getConnection(): \Illuminate\Database\Connection
{
return self::getDatabaseManager('demo2')->connection();
}
}
```