Moved entities mappings from annotations to external config files

This commit is contained in:
Alejandro Celaya 2018-12-16 12:08:03 +01:00
parent fb705b44a4
commit a28c1d17c5
13 changed files with 244 additions and 172 deletions

View file

@ -5,6 +5,7 @@ namespace Shlinkio\Shlink\Common\Factory;
use Doctrine\Common\Cache\ArrayCache; use Doctrine\Common\Cache\ArrayCache;
use Doctrine\Common\Cache\Cache; use Doctrine\Common\Cache\Cache;
use Doctrine\Common\Persistence\Mapping\Driver\PHPDriver;
use Doctrine\DBAL\DBALException; use Doctrine\DBAL\DBALException;
use Doctrine\DBAL\Types\Type; use Doctrine\DBAL\Types\Type;
use Doctrine\ORM\EntityManager; use Doctrine\ORM\EntityManager;
@ -37,12 +38,9 @@ class EntityManagerFactory implements FactoryInterface
Type::addType(ChronosDateTimeType::CHRONOS_DATETIME, ChronosDateTimeType::class); Type::addType(ChronosDateTimeType::CHRONOS_DATETIME, ChronosDateTimeType::class);
} }
return EntityManager::create($connectionConfig, Setup::createAnnotationMetadataConfiguration( $config = Setup::createConfiguration($isDevMode, $ormConfig['proxies_dir'] ?? null, $cache);
$ormConfig['entities_paths'] ?? [], $config->setMetadataDriverImpl(new PHPDriver($ormConfig['entities_mappings'] ?? []));
$isDevMode,
$ormConfig['proxies_dir'] ?? null, return EntityManager::create($connectionConfig, $config);
$cache,
false
));
} }
} }

View file

@ -0,0 +1,63 @@
<?php
declare(strict_types=1);
namespace Shlinkio\Shlink\Core;
use Doctrine\DBAL\Types\Type;
use Doctrine\ORM\Mapping\Builder\ClassMetadataBuilder;
use Doctrine\ORM\Mapping\ClassMetadata;
use Shlinkio\Shlink\Common\Type\ChronosDateTimeType;
/** @var $metadata ClassMetadata */
$builder = new ClassMetadataBuilder($metadata);
$builder->setTable('short_urls')
->setCustomRepositoryClass(Repository\ShortUrlRepository::class);
$builder->createField('id', Type::BIGINT)
->columnName('id')
->makePrimaryKey()
->generatedValue('IDENTITY')
->option('unsigned', true)
->build();
$builder->createField('longUrl', Type::STRING)
->columnName('original_url')
->length(1024)
->build();
$builder->createField('shortCode', Type::STRING)
->columnName('short_code')
->unique()
->length(255)
->build();
$builder->createField('dateCreated', ChronosDateTimeType::CHRONOS_DATETIME)
->columnName('date_created')
->build();
$builder->createField('validSince', ChronosDateTimeType::CHRONOS_DATETIME)
->columnName('valid_since')
->nullable()
->build();
$builder->createField('validUntil', ChronosDateTimeType::CHRONOS_DATETIME)
->columnName('valid_until')
->nullable()
->build();
$builder->createField('maxVisits', Type::INTEGER)
->columnName('max_visits')
->nullable()
->build();
$builder->createOneToMany('visits', Entity\Visit::class)
->mappedBy('shortUrl')
->fetchExtraLazy()
->build();
$builder->createManyToMany('tags', Entity\Tag::class)
->setJoinTable('short_urls_in_tags')
->addInverseJoinColumn('tag_id', 'id')
->addJoinColumn('short_url_id', 'id')
->build();

View file

@ -0,0 +1,25 @@
<?php
declare(strict_types=1);
namespace Shlinkio\Shlink\Core;
use Doctrine\DBAL\Types\Type;
use Doctrine\ORM\Mapping\Builder\ClassMetadataBuilder;
use Doctrine\ORM\Mapping\ClassMetadata;
/** @var $metadata ClassMetadata */
$builder = new ClassMetadataBuilder($metadata);
$builder->setTable('tags')
->setCustomRepositoryClass(Repository\TagRepository::class);
$builder->createField('id', Type::BIGINT)
->columnName('id')
->makePrimaryKey()
->generatedValue('IDENTITY')
->option('unsigned', true)
->build();
$builder->createField('name', Type::STRING)
->unique()
->build();

View file

@ -0,0 +1,52 @@
<?php
declare(strict_types=1);
namespace Shlinkio\Shlink\Core;
use Doctrine\DBAL\Types\Type;
use Doctrine\ORM\Mapping\Builder\ClassMetadataBuilder;
use Doctrine\ORM\Mapping\ClassMetadata;
use Shlinkio\Shlink\Common\Type\ChronosDateTimeType;
/** @var $metadata ClassMetadata */
$builder = new ClassMetadataBuilder($metadata);
$builder->setTable('visits')
->setCustomRepositoryClass(Repository\VisitRepository::class);
$builder->createField('id', Type::BIGINT)
->columnName('id')
->makePrimaryKey()
->generatedValue('IDENTITY')
->option('unsigned', true)
->build();
$builder->createField('referer', Type::STRING)
->nullable()
->length(256)
->build();
$builder->createField('date', ChronosDateTimeType::CHRONOS_DATETIME)
->columnName('`date`')
->build();
$builder->createField('remoteAddr', Type::STRING)
->columnName('remote_addr')
->length(256)
->nullable()
->build();
$builder->createField('userAgent', Type::STRING)
->columnName('user_agent')
->length(512)
->nullable()
->build();
$builder->createManyToOne('shortUrl', Entity\ShortUrl::class)
->addJoinColumn('short_url_id', 'id', false)
->build();
$builder->createManyToOne('visitLocation', Entity\VisitLocation::class)
->addJoinColumn('visit_location_id', 'id')
->cascadePersist()
->build();

View file

@ -0,0 +1,37 @@
<?php
declare(strict_types=1);
namespace Shlinkio\Shlink\Core;
use Doctrine\DBAL\Types\Type;
use Doctrine\ORM\Mapping\Builder\ClassMetadataBuilder;
use Doctrine\ORM\Mapping\ClassMetadata;
/** @var $metadata ClassMetadata */
$builder = new ClassMetadataBuilder($metadata);
$builder->setTable('visit_locations');
$builder->createField('id', Type::BIGINT)
->columnName('id')
->makePrimaryKey()
->generatedValue('IDENTITY')
->option('unsigned', true)
->build();
$columns = [
'country_code' => 'countryCode',
'country_name' => 'countryName',
'region_name' => 'regionName',
'city_name' => 'cityName',
'latitude' => 'latitude',
'longitude' => 'longitude',
'timezone' => 'timezone',
];
foreach ($columns as $columnName => $fieldName) {
$builder->createField($fieldName, Type::STRING)
->columnName($columnName)
->nullable()
->build();
}

View file

@ -5,8 +5,8 @@ return [
'entity_manager' => [ 'entity_manager' => [
'orm' => [ 'orm' => [
'entities_paths' => [ 'entities_mappings' => [
__DIR__ . '/../src/Entity', __DIR__ . '/../config/entities-mappings',
], ],
], ],
], ],

View file

@ -6,72 +6,27 @@ namespace Shlinkio\Shlink\Core\Entity;
use Cake\Chronos\Chronos; use Cake\Chronos\Chronos;
use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection; use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Shlinkio\Shlink\Common\Entity\AbstractEntity; use Shlinkio\Shlink\Common\Entity\AbstractEntity;
use Shlinkio\Shlink\Core\Model\ShortUrlMeta; use Shlinkio\Shlink\Core\Model\ShortUrlMeta;
use Shlinkio\Shlink\Core\Repository\ShortUrlRepository;
use function count; use function count;
/**
* Class ShortUrl
* @author
* @link
*
* @ORM\Entity(repositoryClass=ShortUrlRepository::class)
* @ORM\Table(name="short_urls")
*/
class ShortUrl extends AbstractEntity class ShortUrl extends AbstractEntity
{ {
/** /** @var string */
* @var string
* @ORM\Column(name="original_url", type="string", nullable=false, length=1024)
*/
private $longUrl; private $longUrl;
/** /** @var string */
* @var string
* @ORM\Column(
* name="short_code",
* type="string",
* nullable=false,
* length=255,
* unique=true
* )
*/
private $shortCode; private $shortCode;
/** /** @var Chronos */
* @var Chronos
* @ORM\Column(name="date_created", type="chronos_datetime")
*/
private $dateCreated; private $dateCreated;
/** /** @var Collection|Visit[] */
* @var Collection|Visit[]
* @ORM\OneToMany(targetEntity=Visit::class, mappedBy="shortUrl", fetch="EXTRA_LAZY")
*/
private $visits; private $visits;
/** /** @var Collection|Tag[] */
* @var Collection|Tag[]
* @ORM\ManyToMany(targetEntity=Tag::class, cascade={"persist"})
* @ORM\JoinTable(name="short_urls_in_tags", joinColumns={
* @ORM\JoinColumn(name="short_url_id", referencedColumnName="id")
* }, inverseJoinColumns={
* @ORM\JoinColumn(name="tag_id", referencedColumnName="id")
* })
*/
private $tags; private $tags;
/** /** @var Chronos|null */
* @var Chronos|null
* @ORM\Column(name="valid_since", type="chronos_datetime", nullable=true)
*/
private $validSince; private $validSince;
/** /** @var Chronos|null */
* @var Chronos|null
* @ORM\Column(name="valid_until", type="chronos_datetime", nullable=true)
*/
private $validUntil; private $validUntil;
/** /** @var integer|null */
* @var integer
* @ORM\Column(name="max_visits", type="integer", nullable=true)
*/
private $maxVisits; private $maxVisits;
public function __construct(string $longUrl, ShortUrlMeta $meta = null) public function __construct(string $longUrl, ShortUrlMeta $meta = null)

View file

@ -3,25 +3,12 @@ declare(strict_types=1);
namespace Shlinkio\Shlink\Core\Entity; namespace Shlinkio\Shlink\Core\Entity;
use Doctrine\ORM\Mapping as ORM;
use JsonSerializable; use JsonSerializable;
use Shlinkio\Shlink\Common\Entity\AbstractEntity; use Shlinkio\Shlink\Common\Entity\AbstractEntity;
use Shlinkio\Shlink\Core\Repository\TagRepository;
/**
* Class Tag
* @author
* @link
*
* @ORM\Entity(repositoryClass=TagRepository::class)
* @ORM\Table(name="tags")
*/
class Tag extends AbstractEntity implements JsonSerializable class Tag extends AbstractEntity implements JsonSerializable
{ {
/** /** @var string */
* @var string
* @ORM\Column(unique=true)
*/
private $name; private $name;
public function __construct(string $name) public function __construct(string $name)

View file

@ -4,57 +4,27 @@ declare(strict_types=1);
namespace Shlinkio\Shlink\Core\Entity; namespace Shlinkio\Shlink\Core\Entity;
use Cake\Chronos\Chronos; use Cake\Chronos\Chronos;
use Doctrine\ORM\Mapping as ORM;
use JsonSerializable; use JsonSerializable;
use Shlinkio\Shlink\Common\Entity\AbstractEntity; use Shlinkio\Shlink\Common\Entity\AbstractEntity;
use Shlinkio\Shlink\Common\Exception\WrongIpException; use Shlinkio\Shlink\Common\Exception\WrongIpException;
use Shlinkio\Shlink\Common\Util\IpAddress; use Shlinkio\Shlink\Common\Util\IpAddress;
use Shlinkio\Shlink\Core\Model\Visitor; use Shlinkio\Shlink\Core\Model\Visitor;
use Shlinkio\Shlink\Core\Repository\VisitRepository;
use Shlinkio\Shlink\Core\Visit\Model\UnknownVisitLocation; use Shlinkio\Shlink\Core\Visit\Model\UnknownVisitLocation;
use Shlinkio\Shlink\Core\Visit\Model\VisitLocationInterface; use Shlinkio\Shlink\Core\Visit\Model\VisitLocationInterface;
/**
* Class Visit
* @author
* @link
*
* @ORM\Entity(repositoryClass=VisitRepository::class)
* @ORM\Table(name="visits")
*/
class Visit extends AbstractEntity implements JsonSerializable class Visit extends AbstractEntity implements JsonSerializable
{ {
/** /** @var string */
* @var string
* @ORM\Column(type="string", length=256, nullable=true)
*/
private $referer; private $referer;
/** /** @var Chronos */
* @var Chronos
* @ORM\Column(type="chronos_datetime", nullable=false)
*/
private $date; private $date;
/** /** @var string|null */
* @var string|null
* @ORM\Column(type="string", length=256, name="remote_addr", nullable=true)
*/
private $remoteAddr; private $remoteAddr;
/** /** @var string */
* @var string
* @ORM\Column(type="string", length=512, name="user_agent", nullable=true)
*/
private $userAgent; private $userAgent;
/** /** @var ShortUrl */
* @var ShortUrl
* @ORM\ManyToOne(targetEntity=ShortUrl::class)
* @ORM\JoinColumn(name="short_url_id", referencedColumnName="id")
*/
private $shortUrl; private $shortUrl;
/** /** @var VisitLocation */
* @var VisitLocation
* @ORM\ManyToOne(targetEntity=VisitLocation::class, cascade={"persist"})
* @ORM\JoinColumn(name="visit_location_id", referencedColumnName="id", nullable=true)
*/
private $visitLocation; private $visitLocation;
public function __construct(ShortUrl $shortUrl, Visitor $visitor, ?Chronos $date = null) public function __construct(ShortUrl $shortUrl, Visitor $visitor, ?Chronos $date = null)

View file

@ -3,55 +3,25 @@ declare(strict_types=1);
namespace Shlinkio\Shlink\Core\Entity; namespace Shlinkio\Shlink\Core\Entity;
use Doctrine\ORM\Mapping as ORM;
use Shlinkio\Shlink\Common\Entity\AbstractEntity; use Shlinkio\Shlink\Common\Entity\AbstractEntity;
use Shlinkio\Shlink\Core\Visit\Model\VisitLocationInterface; use Shlinkio\Shlink\Core\Visit\Model\VisitLocationInterface;
use function array_key_exists; use function array_key_exists;
/**
* Class VisitLocation
* @author
* @link
*
* @ORM\Entity()
* @ORM\Table(name="visit_locations")
*/
class VisitLocation extends AbstractEntity implements VisitLocationInterface class VisitLocation extends AbstractEntity implements VisitLocationInterface
{ {
/** /** @var string */
* @var string
* @ORM\Column(nullable=true, name="country_code")
*/
private $countryCode; private $countryCode;
/** /** @var string */
* @var string
* @ORM\Column(nullable=true, name="country_name")
*/
private $countryName; private $countryName;
/** /** @var string */
* @var string
* @ORM\Column(nullable=true, name="region_name")
*/
private $regionName; private $regionName;
/** /** @var string */
* @var string
* @ORM\Column(nullable=true, name="city_name")
*/
private $cityName; private $cityName;
/** /** @var string */
* @var string
* @ORM\Column(nullable=true, name="latitude")
*/
private $latitude; private $latitude;
/** /** @var string */
* @var string
* @ORM\Column(nullable=true, name="longitude")
*/
private $longitude; private $longitude;
/** /** @var string */
* @var string
* @ORM\Column(nullable=true, name="timezone")
*/
private $timezone; private $timezone;
public function __construct(array $locationInfo) public function __construct(array $locationInfo)

View file

@ -0,0 +1,33 @@
<?php
declare(strict_types=1);
namespace Shlinkio\Shlink\Rest;
use Doctrine\DBAL\Types\Type;
use Doctrine\ORM\Mapping\Builder\ClassMetadataBuilder;
use Doctrine\ORM\Mapping\ClassMetadata;
use Shlinkio\Shlink\Common\Type\ChronosDateTimeType;
/** @var $metadata ClassMetadata */
$builder = new ClassMetadataBuilder($metadata);
$builder->setTable('api_keys');
$builder->createField('id', Type::BIGINT)
->makePrimaryKey()
->generatedValue('IDENTITY')
->option('unsigned', true)
->build();
$builder->createField('key', Type::STRING)
->columnName('`key`')
->unique()
->build();
$builder->createField('expirationDate', ChronosDateTimeType::CHRONOS_DATETIME)
->columnName('expiration_date')
->nullable()
->build();
$builder->createField('enabled', Type::BOOLEAN)
->build();

View file

@ -5,8 +5,8 @@ return [
'entity_manager' => [ 'entity_manager' => [
'orm' => [ 'orm' => [
'entities_paths' => [ 'entities_mappings' => [
__DIR__ . '/../src/Entity', __DIR__ . '/../config/entities-mappings',
], ],
], ],
], ],

View file

@ -4,36 +4,18 @@ declare(strict_types=1);
namespace Shlinkio\Shlink\Rest\Entity; namespace Shlinkio\Shlink\Rest\Entity;
use Cake\Chronos\Chronos; use Cake\Chronos\Chronos;
use Doctrine\ORM\Mapping as ORM;
use Shlinkio\Shlink\Common\Entity\AbstractEntity; use Shlinkio\Shlink\Common\Entity\AbstractEntity;
use Shlinkio\Shlink\Common\Util\StringUtilsTrait; use Shlinkio\Shlink\Common\Util\StringUtilsTrait;
/**
* Class ApiKey
* @author Shlink
* @link http://shlink.io
*
* @ORM\Entity()
* @ORM\Table(name="api_keys")
*/
class ApiKey extends AbstractEntity class ApiKey extends AbstractEntity
{ {
use StringUtilsTrait; use StringUtilsTrait;
/** /** @var string */
* @var string
* @ORM\Column(name="`key`", nullable=false, unique=true)
*/
private $key; private $key;
/** /** @var Chronos|null */
* @var Chronos|null
* @ORM\Column(name="expiration_date", nullable=true, type="chronos_datetime")
*/
private $expirationDate; private $expirationDate;
/** /** @var bool */
* @var bool
* @ORM\Column(type="boolean")
*/
private $enabled; private $enabled;
public function __construct(?Chronos $expirationDate = null) public function __construct(?Chronos $expirationDate = null)