Merge pull request #324 from acelaya/feature/entities-config

Moved entities mappings from annotations to external config files
This commit is contained in:
Alejandro Celaya 2018-12-16 13:18:19 +01:00 committed by GitHub
commit 7248ca2e9b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 245 additions and 172 deletions

View File

@ -14,6 +14,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
* [#312](https://github.com/shlinkio/shlink/issues/312) Now all config files both in `php` and `json` format are loaded from `config/params` folder, easing users to provided customizations to docker image.
* [#226](https://github.com/shlinkio/shlink/issues/226) Updated how table are rendered in CLI commands, making use of new features in Symfony 4.2.
* [#321](https://github.com/shlinkio/shlink/issues/321) Extracted entities mappings from entities to external config files.
#### Deprecated

View File

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

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' => [
'orm' => [
'entities_paths' => [
__DIR__ . '/../src/Entity',
'entities_mappings' => [
__DIR__ . '/../config/entities-mappings',
],
],
],

View File

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

View File

@ -3,25 +3,12 @@ declare(strict_types=1);
namespace Shlinkio\Shlink\Core\Entity;
use Doctrine\ORM\Mapping as ORM;
use JsonSerializable;
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
{
/**
* @var string
* @ORM\Column(unique=true)
*/
/** @var string */
private $name;
public function __construct(string $name)

View File

@ -4,57 +4,27 @@ declare(strict_types=1);
namespace Shlinkio\Shlink\Core\Entity;
use Cake\Chronos\Chronos;
use Doctrine\ORM\Mapping as ORM;
use JsonSerializable;
use Shlinkio\Shlink\Common\Entity\AbstractEntity;
use Shlinkio\Shlink\Common\Exception\WrongIpException;
use Shlinkio\Shlink\Common\Util\IpAddress;
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\VisitLocationInterface;
/**
* Class Visit
* @author
* @link
*
* @ORM\Entity(repositoryClass=VisitRepository::class)
* @ORM\Table(name="visits")
*/
class Visit extends AbstractEntity implements JsonSerializable
{
/**
* @var string
* @ORM\Column(type="string", length=256, nullable=true)
*/
/** @var string */
private $referer;
/**
* @var Chronos
* @ORM\Column(type="chronos_datetime", nullable=false)
*/
/** @var Chronos */
private $date;
/**
* @var string|null
* @ORM\Column(type="string", length=256, name="remote_addr", nullable=true)
*/
/** @var string|null */
private $remoteAddr;
/**
* @var string
* @ORM\Column(type="string", length=512, name="user_agent", nullable=true)
*/
/** @var string */
private $userAgent;
/**
* @var ShortUrl
* @ORM\ManyToOne(targetEntity=ShortUrl::class)
* @ORM\JoinColumn(name="short_url_id", referencedColumnName="id")
*/
/** @var ShortUrl */
private $shortUrl;
/**
* @var VisitLocation
* @ORM\ManyToOne(targetEntity=VisitLocation::class, cascade={"persist"})
* @ORM\JoinColumn(name="visit_location_id", referencedColumnName="id", nullable=true)
*/
/** @var VisitLocation */
private $visitLocation;
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;
use Doctrine\ORM\Mapping as ORM;
use Shlinkio\Shlink\Common\Entity\AbstractEntity;
use Shlinkio\Shlink\Core\Visit\Model\VisitLocationInterface;
use function array_key_exists;
/**
* Class VisitLocation
* @author
* @link
*
* @ORM\Entity()
* @ORM\Table(name="visit_locations")
*/
class VisitLocation extends AbstractEntity implements VisitLocationInterface
{
/**
* @var string
* @ORM\Column(nullable=true, name="country_code")
*/
/** @var string */
private $countryCode;
/**
* @var string
* @ORM\Column(nullable=true, name="country_name")
*/
/** @var string */
private $countryName;
/**
* @var string
* @ORM\Column(nullable=true, name="region_name")
*/
/** @var string */
private $regionName;
/**
* @var string
* @ORM\Column(nullable=true, name="city_name")
*/
/** @var string */
private $cityName;
/**
* @var string
* @ORM\Column(nullable=true, name="latitude")
*/
/** @var string */
private $latitude;
/**
* @var string
* @ORM\Column(nullable=true, name="longitude")
*/
/** @var string */
private $longitude;
/**
* @var string
* @ORM\Column(nullable=true, name="timezone")
*/
/** @var string */
private $timezone;
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' => [
'orm' => [
'entities_paths' => [
__DIR__ . '/../src/Entity',
'entities_mappings' => [
__DIR__ . '/../config/entities-mappings',
],
],
],

View File

@ -4,36 +4,18 @@ declare(strict_types=1);
namespace Shlinkio\Shlink\Rest\Entity;
use Cake\Chronos\Chronos;
use Doctrine\ORM\Mapping as ORM;
use Shlinkio\Shlink\Common\Entity\AbstractEntity;
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
{
use StringUtilsTrait;
/**
* @var string
* @ORM\Column(name="`key`", nullable=false, unique=true)
*/
/** @var string */
private $key;
/**
* @var Chronos|null
* @ORM\Column(name="expiration_date", nullable=true, type="chronos_datetime")
*/
/** @var Chronos|null */
private $expirationDate;
/**
* @var bool
* @ORM\Column(type="boolean")
*/
/** @var bool */
private $enabled;
public function __construct(?Chronos $expirationDate = null)