Entities and schema
Mautic uses Doctrine ORM to define the schema. Plugins define their schema using entity classes stored in its Entity directory. Define the schema for the entity through Doctrine’s PHP static function mapping or annotations.
Warning
You use the PHP mapping or annotations. You can’t use a mix of the two.
Entity PHP static function mapping
You can build the schema through Doctrine’s Doctrine\ORM\Mapping\Builder\ClassMetadataBuilder class. Refer to Doctrine ORM PHP mapping for methods available. Mautic also provides a decorated ClassMetadataBuilder class through Mautic\CoreBundle\Doctrine\Mapping\ClassMetadataBuilder described below.
<?php
declare(strict_types=1);
namespace MauticPlugin\HelloWorldBundle\Entity;
use Doctrine\DBAL\Types\Type;
use Doctrine\ORM\Mapping\ClassMetadata;
use Mautic\CoreBundle\Doctrine\Mapping\ClassMetadataBuilder;
class World
{
private ?int $id;
private ?string $world;
private ?int $isEnabled;
/**
* @param ClassMetadata<self> $metadata
*/
public static function loadMetadata(ClassMetadata $metadata): void
{
$builder = new ClassMetadataBuilder($metadata);
$builder
->setTable('hello_world')
->setCustomRepositoryClass(WorldRepository::class)
->addIndex(['is_enabled'], 'is_enabled');
$builder->addId();
$builder
->createField('world', Type::STRING)
->build();
$builder
->createField('isEnabled', Type::BOOLEAN)
->columnName('is_enabled')
->build();
}
public function getId(): int
{
return $this->id;
}
public function setId(int $id): void
{
$this->id = $id;
}
public function getWorld(): string
{
return $this->world;
}
public function setWorld(string $world): void
{
$this->world = $world;
}
public function isEnabled(): bool
{
return (bool) $this->isEnabled;
}
public function getIsEnabled(): int
{
return $this->isEnabled;
}
public function setIsEnabled(int $isEnabled): void
{
$this->isEnabled = $isEnabled;
}
}
- class Mautic\CoreBundle\Doctrine\Mapping\ClassMetadataBuilder
- addBigIntIdField([string $fieldName = 'id', string $columnName = 'id', bool $isPrimary = true, boolean $isNullable = false])
Adds autogenerated ID field type of BIGINT UNSIGNED
- Parameters:
$fieldName (
string) – Name of the ORM field.$columnName (
string) – Name of the column created in the database table.$isPrimary (
boolean) –TRUEto configure this field as a primary key for the table.$isNullable (
bool) –TRUEto allowNULLvalues.
- Returns:
$this- Return type:
\Mautic\CoreBundle\Doctrine\Mapping\ClassMetadataBuilder
- addCategory()
Creates a many to one relationship with MauticCategoryBundleEntityCategory. Defines a
categoryORM property mapped to acategory_idcolumn on the table with a foreign key tocategories.id.- Returns:
$this- Return type:
\Mautic\CoreBundle\Doctrine\Mapping\ClassMetadataBuilder
- addContact([bool $nullable = false, string $onDelete = 'CASCADE', bool $isPrimaryKey = false, ?string $inversedBy = null)
Creates a many to one relationship with MauticLeadBundleEntityLead. Defines a
contactORM property mapped to acontact_idcolumn on the table with a foreign key toleads.id.- Parameters:
$nullable (
bool) –TRUEto allowNULLvalues.$onDelete (
string) – Foreign key reference option such asCASCADEorSET NULL.$isPrimaryKey (
bool) –TRUEto configure this field as a primary key for the table.$inversedBy (
string|null) – Property on theMautic\LeadBundle\Entity\Leadentity this relates to. This is only used by Core.
- Returns:
$this- Return type:
\Mautic\CoreBundle\Doctrine\Mapping\ClassMetadataBuilder
- addDateAdded([bool $nullable = false])
Creates a mutable date/time field. Defines a
dateAddedORM property mapped to adate_addedcolumn on the table.- Parameters:
$nullable (
bool) –TRUEto allowNULLvalues.
- Returns:
$this- Return type:
\Mautic\CoreBundle\Doctrine\Mapping\ClassMetadataBuilder
- addField(string $name, string $type[, array $mapping = []])
Decorates
Doctrine\ORM\Mapping\Builder\ClassMetadataBuilder::addFieldthat sets the max length to 191 characters for string typed or indexed fields for compatibility with UTF8MB4 encoding.- Parameters:
$name (
string) – Name of the ORM field.$type (
string) – Doctrine field type. SeeDoctrine\DBAL\Types\Types.$mapping (
array) – Custom field definitions.
- Returns:
$this- Return type:
\Mautic\CoreBundle\Doctrine\Mapping\ClassMetadataBuilder
- addId()
- Returns:
$this- Return type:
\Mautic\CoreBundle\Doctrine\Mapping\ClassMetadataBuilder
- addIdColumns([string $nameColumn = 'name', string $descriptionColumn = 'description'])
Creates
id,name, anddescriptionORM fields.idis an auto-incremented unsigned integer set as a primary key.nameis created asvarchar(191)anddescriptionaslongtext. Customize the ORM names fornameanddescriptionthrough the optional parameters.- Parameters:
$nameColumn (
string) – Customize the name for thenamefield.$descriptionColumn (
string) – Customize the name for thedescriptionfield.
- Returns:
$this- Return type:
\Mautic\CoreBundle\Doctrine\Mapping\ClassMetadataBuilder
- addIpAddress([bool $nullable = false])
Creates a many to one relationship with MauticCoreBundleEntityIpAddress. Defines a
ipAddressORM property mapped to aip_idcolumn on the table with a foreign key toip_addresses.id.- Parameters:
$nullable (
bool) –TRUEto allowNULLvalues.
- Returns:
$this- Return type:
\Mautic\CoreBundle\Doctrine\Mapping\ClassMetadataBuilder
- addNamedField(string $name, string $type, string $columnName[, $nullable = false])
Creates a field with a custom column name.
- Parameters:
$name (
string) – Name of the ORM field.$type (
string) – Doctrine field type. SeeDoctrine\DBAL\Types\Types.$columnName (
string) – Name of the table’s column name.$nullable (
bool) –TRUEto allowNULLvalues.
- Returns:
$this- Return type:
\Mautic\CoreBundle\Doctrine\Mapping\ClassMetadataBuilder
- addNullableField(string $name[, string $type = Types::STRING, ?string $columnName = null])
Creates a field that allows a
NULLvalue.- Parameters:
$name (
string) – Name of the ORM field.$type (
string) – Doctrine field type. SeeDoctrine\DBAL\Types\Types.$columnName (
string) – Name of the table’s column name.
- Returns:
$this- Return type:
\Mautic\CoreBundle\Doctrine\Mapping\ClassMetadataBuilder
- addPublishDates()
Creates
publishUpandpublishDownnullable mutable date/time fields aspublish_upandpublish_downrespectively.- Returns:
$this- Return type:
\Mautic\CoreBundle\Doctrine\Mapping\ClassMetadataBuilder
- addUuid()
Creates a
idGUID field as a primary key. You should generate a UUID in the entity’s__constructor pass one into the__constructwhen creating a new entity. You can use$this->id = Ramsey\Uuid\Uuid::uuid4()->toString();.- Returns:
$this- Return type:
\Mautic\CoreBundle\Doctrine\Mapping\ClassMetadataBuilder
- createField(string $name, string $type)
Instantiates and returns a
Doctrine\ORM\Mapping\Builder\FieldBuilderobject.lengthis set if the field is a string type or indexed.- Returns:
\Doctrine\ORM\Mapping\Builder\FieldBuilder
- createManyToMany(string $name, string $targetEntity)
Creates a many to many field to the targeted entity. Instantiates and returns a
Mautic\CoreBundle\Doctrine\Mapping\ManyToManyAssociationBuilderobject that decoratesDoctrine\ORM\Mapping\Builder\ManyToManyAssociationBuilderwithorphanRemoval()support.- Parameters:
$name (
string) – Name of the ORM field.$targetEntity (
string) – Fully qualified classname for the targeted entity.
- Returns:
\Mautic\CoreBundle\Doctrine\Mapping\ManyToManyAssociationBuilder
- createManyToOne(string $name, string $targetEntity)
Creates a field with a many to one relationship to the targeted entity. Instantiates and returns a
Mautic\CoreBundle\Doctrine\Mapping\AssociationBuilderobject that decoratesDoctrine\ORM\Mapping\Builder\AssociationBuilderwithorphanRemoval()andisPrimaryKey()support.- Parameters:
$name (
string) – Name of the ORM field.$targetEntity (
string) – Fully qualified classname for the targeted entity.
- Returns:
\Mautic\CoreBundle\Doctrine\Mapping\AssociationBuilder
- createOneToMany(string $name, string $targetEntity)
Creates a field with a one to many relationship to the targeted entity. Instantiates and returns a
Mautic\CoreBundle\Doctrine\Mapping\OneToManyAssociationBuilderobject that decoratesDoctrine\ORM\Mapping\Builder\OneToManyAssociationBuilderwithorphanRemoval()support.- Parameters:
$name (
string) – Name of the ORM field.$targetEntity (
string) – Fully qualified classname for the targeted entity.
- Returns:
\Mautic\CoreBundle\Doctrine\Mapping\OneToManyAssociationBuilder
- createOneToOne(string $name, string $targetEntity)
Creates a field with a one to one relationship to the targeted entity. Instantiates and returns a
Mautic\CoreBundle\Doctrine\Mapping\AssociationBuilderobject that decoratesDoctrine\ORM\Mapping\Builder\AssociationBuilderwithorphanRemoval()andisPrimaryKey()support.- Parameters:
$name (
string) – Name of the ORM field.$targetEntity (
string) – Fully qualified classname for the targeted entity.
- Returns:
\Mautic\CoreBundle\Doctrine\Mapping\AssociationBuilder
- isIndexedVarchar(string $name, string $type)
Checks whether the field should have a max length of 191 configured for compatibility with UTF8MB4 encoded fields.
- Returns:
Returns
TRUEif the field is astringtype or is indexed.- Return type:
bool
Entity annotations
You can choose to use annotations instead of the PHP static method. Refer to Doctrine’s documentation on available annotations.
<?php
declare(strict_types=1);
namespace Mautic\UserBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Ramsey\Uuid\Uuid;
/**
* @ORM\Table (name="worlds")
*/
class World
{
/**
* @ORM\Column(type="guid")
* @ORM\Id
*/
private $id;
/**
* @ORM\Column(type="string", length=191)
*/
private $name;
public function __construct()
{
$this->id = Uuid::uuid4()->toString();
}
public function getId(): string
{
return $this->id;
}
public function getName(): string
{
return $this->name;
}
public function setName(string $name): void
{
$this->name = $name;
}
}
Plugin schema migrations
Mautic Core uses Doctrine migrations to manage schema changes. Plugins don’t have access to this as migration files are in Core’s migrations directory.
Mautic provides a way for Plugins to manage their schema changes through the Integration bundle’s \Mautic\IntegrationsBundle\Migration\Engine. Mautic automatically handles migrations if the Plugin’s bundle class extends Mautic\IntegrationsBundle\Bundle\AbstractPluginBundle.
<?php
declare(strict_types=1);
namespace MauticPlugin\HelloWorldBundle;
use Mautic\IntegrationsBundle\Bundle\AbstractPluginBundle;
class HelloWorldBundle extends AbstractPluginBundle
{
}
Define migrations in the Plugin’s Migrations directory. The file and class names can be anything but it’s recommended to match the version of the Plugin that introduces the change. For example, Version_1_0_1.php. Extend each migration class with \Mautic\IntegrationsBundle\Migration\AbstractMigration.
Warning
Mautic executes every migration file when it upgrades the Plugin. Therefore, you must define the isApplicable() method to let Mautic know to execute the migration’s SQL queries. Otherwise, Doctrine throws an exception if MySQL returns an error such as when an index or column already exists.
<?php
declare(strict_types=1);
namespace MauticPlugin\HelloWorldBundle\Migrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\DBAL\Schema\SchemaException;
use Mautic\IntegrationsBundle\Migration\AbstractMigration;
class Version_1_0_1 extends AbstractMigration
{
private $table = 'hello_world';
protected function isApplicable(Schema $schema): bool
{
try {
return !$schema->getTable($this->concatPrefix($this->table))->hasColumn('is_enabled');
} catch (SchemaException $e) {
return false;
}
}
protected function up(): void
{
$this->addSql("ALTER TABLE `{$this->concatPrefix($this->table)}` ADD `is_enabled` tinyint(1) 0");
$this->addSql("CREATE INDEX {$this->concatPrefix('is_enabled')} ON {$this->concatPrefix($this->table)}(is_enabled);");
}
}
- class Mautic\IntegrationsBundle\Migration\AbstractMigration
- protected property tablePrefix
Mautic’s configured database table prefix.
- protected abstract isApplicable(Schema $schema)
- Parameters:
$schema (
Doctrine\DBAL\Schema\Schema) – Use theSchemaobject to evaluate Mautic’s current schema.
- Returns:
Return
FALSEto skip this migration. Otherwise,TRUE.- Return type:
bool
- protected addSql(string $sql)
- Parameters:
$sql (
string) – SQL query to execute. Prefix table and index names withtablePrefixor useconcatPrefix.
- Return type:
void
- protected columnsToString(array $columns)
- Parameters:
$columns (
array) – Array of column names.
- Returns:
Returns a comma separated value list from the values given in the array. For example,
$this->columnsToString(['a', 'b', 'c'])will return'a,b,c'.- Return type:
string
- protected concatPrefix(string $name)
Prefixes the given name with the configured table prefix.
- Parameters:
$name (
string) – Name of column or index to prefix.
- Returns:
Prefixed name.
- Return type:
string
- protected generateAlterTableForeignKeyStatement(string $table, array $columns, string $referenceTable, array $referenceColumns[, string $suffix = ''])
Generates full SQL statement to add a new foreign key to a table.
- Parameters:
$table (
string) – Name of the current table without the table prefix.$columns (
array) – Array of columns for the current table.$referenceTable (
string) – Name of the referenced table without the table prefix.$referenceColumns (
array) – Array of columns for the referenced table.$suffix (
string) – String to append to the query such asON DELETE CASCADE.
- Returns:
SQL statement for adding a new foreign key.
- Return type:
string
- protected generateIndexStatement(string $table, array $columns)
Generates an
INDEXstatement to be used within aCREATE TABLEorALTER TABLEstatement to create an index.- Parameters:
$table (
string) – Name of the table where the index will be added.$columns (
array) – Array of columns to included in the index.
- Returns:
INDEX {tableName} ($columns...)statement- Return type:
string