Skip to content

Commit 6d8c361

Browse files
author
Pavel.Batanov
committed
Init
1 parent 1c1e4e2 commit 6d8c361

25 files changed

Lines changed: 891 additions & 1 deletion

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
composer.lock
2+
vendor/
3+
build/

.php_cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
$finder = PhpCsFixer\Finder::create()
4+
->exclude('vendor')
5+
->exclude('build')
6+
->in(__DIR__);
7+
8+
return PhpCsFixer\Config::create()
9+
->setRules([
10+
'@Symfony' => true,
11+
'concat_space' => ['spacing' => 'one'],
12+
'phpdoc_align' => false,
13+
'phpdoc_to_comment' => false,
14+
'header_comment' => false,
15+
])
16+
->setFinder($finder);

.scrutinizer.yml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
checks:
2+
php:
3+
code_rating: true
4+
duplication: true
5+
6+
build:
7+
nodes:
8+
analysis:
9+
tests:
10+
override:
11+
- php-scrutinizer-run
12+
tests:
13+
override:
14+
-
15+
command: vendor/bin/phpunit --coverage-clover=build/clover.xml
16+
coverage:
17+
file: build/clover.xml
18+
format: clover
19+
20+
filter:
21+
excluded_paths:
22+
- "./tests"

.travis.yml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
language: php
2+
3+
php:
4+
- 7.1
5+
- 7.2
6+
- nightly
7+
8+
sudo: false
9+
10+
matrix:
11+
fast_finish: true
12+
allow_failures:
13+
- php: nightly
14+
include:
15+
- php: 7.1
16+
env: PACKAGES='symfony/symfony=3.4.*'
17+
- php: 7.1
18+
env: PACKAGES='symfony/symfony=4.0.*'
19+
- php: 7.1
20+
env: PACKAGES='symfony/symfony=4.1.*'
21+
22+
before_install:
23+
- travis_retry composer self-update
24+
25+
install:
26+
- composer require --no-update ${PACKAGES}
27+
- composer --prefer-source install

README.md

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,45 @@
1-
# php-enum-bundle
1+
# Lamoda PHP Enum bundle
22
Utility wrapper for https://github.com/paillechat/php-enum
3+
4+
## Installation
5+
6+
Usage is as simple as
7+
8+
```bash
9+
composer require lamoda/enum-bundle:^1.0
10+
```
11+
12+
```php
13+
// Kernel
14+
15+
public function registerBundles()
16+
{
17+
// ...
18+
$bundles[] = new \Lamoda\EnumBundle\LamodaEnumBundle();
19+
// ...
20+
}
21+
```
22+
23+
```yaml
24+
# config.yml
25+
lamoda_enum:
26+
dbal_types:
27+
# short example
28+
my_domain_enum: My\Domain\Enum
29+
# full example
30+
my_domain_enum_2:
31+
class: My\Domain\Enum
32+
# identical strategy saves enum as its name as is, no conversion
33+
# lowercase strategy converts enum name to lowercase and vice versa on fetch
34+
strategy: identical
35+
```
36+
37+
```php
38+
class MyEntity
39+
{
40+
/** @ORM\Column(type="my_domain_enum") */
41+
private $value;
42+
}
43+
```
44+
45+
This will enable conversion of value field from your enum

composer.json

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
{
2+
"name": "lamoda/enum-bundle",
3+
"type": "symfony-bundle",
4+
"description": "Utility wrapper around PHP-enum",
5+
"license": "MIT",
6+
"authors": [
7+
{
8+
"name": "Pavel Batanov",
9+
"email": "pavel.batanov@lamoda.ru",
10+
"role": "Developer"
11+
}
12+
],
13+
"require": {
14+
"php": "^7.1",
15+
"paillechat/php-enum": "^1.2 || ^2.1",
16+
"symfony/http-kernel": "^3.4 || ^4.0",
17+
"symfony/dependency-injection": "^3.4 || ^4.0",
18+
"symfony/config": "^3.4 || ^4.0",
19+
"doctrine/dbal": "^2.4"
20+
},
21+
"require-dev": {
22+
"phpunit/phpunit": "^7.0",
23+
"symfony/yaml": "^4.0"
24+
},
25+
"autoload": {
26+
"psr-4": {
27+
"Lamoda\\EnumBundle\\": "src/"
28+
}
29+
},
30+
"autoload-dev": {
31+
"psr-4": {
32+
"Lamoda\\EnumBundle\\Tests\\": "tests/"
33+
}
34+
}
35+
}

phpunit.xml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
3+
<phpunit bootstrap="./vendor/autoload.php">
4+
5+
<php>
6+
<ini name="error_reporting" value="-1" />
7+
</php>
8+
<testsuites>
9+
<testsuite name="unit tests">
10+
<directory>./tests/Unit</directory>
11+
</testsuite>
12+
<testsuite name="functional tests">
13+
<directory>./tests/Functional</directory>
14+
</testsuite>
15+
</testsuites>
16+
17+
<filter>
18+
<whitelist>
19+
<directory>./src/</directory>
20+
<exclude>
21+
<directory>./build/</directory>
22+
<directory>./vendor/</directory>
23+
<directory>./tests/</directory>
24+
</exclude>
25+
</whitelist>
26+
</filter>
27+
</phpunit>

src/DBAL/EnumType.php

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
<?php
2+
3+
namespace Lamoda\EnumBundle\DBAL;
4+
5+
use Doctrine\DBAL\Platforms\AbstractPlatform;
6+
use Doctrine\DBAL\Types\ConversionException;
7+
use Doctrine\DBAL\Types\Type;
8+
use Lamoda\EnumBundle\Naming\IdenticalNamingStrategy;
9+
use Lamoda\EnumBundle\Naming\NamingStrategyInterface;
10+
use Paillechat\Enum\Enum;
11+
use Paillechat\Enum\Exception\EnumException;
12+
13+
final class EnumType extends Type
14+
{
15+
/** @var string */
16+
private $fqcn;
17+
/** @var string */
18+
private $name;
19+
/** @var NamingStrategyInterface */
20+
private $strategy;
21+
22+
public function setName(string $name): void
23+
{
24+
$this->name = $name;
25+
}
26+
27+
public function setFqcn(string $fqcn): void
28+
{
29+
$this->fqcn = $fqcn;
30+
}
31+
32+
public function setStrategy(NamingStrategyInterface $strategy): void
33+
{
34+
$this->strategy = $strategy;
35+
}
36+
37+
private function getStrategy(): NamingStrategyInterface
38+
{
39+
if (!$this->strategy) {
40+
$this->strategy = new IdenticalNamingStrategy();
41+
}
42+
43+
return $this->strategy;
44+
}
45+
46+
/**
47+
* {@inheritdoc}
48+
*/
49+
public function convertToPHPValue($value, AbstractPlatform $platform)
50+
{
51+
/** @var Enum $fqcn */
52+
$fqcn = $this->fqcn;
53+
54+
try {
55+
return $fqcn::createByName($this->getStrategy()->toEnumName($value));
56+
} catch (EnumException $e) {
57+
throw ConversionException::conversionFailed($value, $this->getName());
58+
}
59+
}
60+
61+
/**
62+
* {@inheritdoc}
63+
*/
64+
public function convertToDatabaseValue($value, AbstractPlatform $platform)
65+
{
66+
if (!is_a($value, $this->fqcn)) {
67+
throw ConversionException::conversionFailed($value, $this->getName());
68+
}
69+
70+
return $this->getStrategy()->fromEnumName((string) $value);
71+
}
72+
73+
/** {@inheritdoc} */
74+
public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform)
75+
{
76+
return $platform->getVarcharTypeDeclarationSQL($fieldDeclaration);
77+
}
78+
79+
/** {@inheritdoc} */
80+
public function getName(): string
81+
{
82+
return $this->name;
83+
}
84+
}

src/DBAL/EnumTypeInitializer.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
namespace Lamoda\EnumBundle\DBAL;
4+
5+
use Doctrine\DBAL\Types\Type;
6+
use Lamoda\EnumBundle\Naming\NamingStrategyInterface;
7+
8+
final class EnumTypeInitializer
9+
{
10+
/**
11+
* @param string $type
12+
* @param string $fqcn
13+
* @param NamingStrategyInterface|null $strategy
14+
*
15+
* @throws \Doctrine\DBAL\DBALException
16+
*/
17+
public function initialize(string $type, string $fqcn, NamingStrategyInterface $strategy = null): void
18+
{
19+
if (Type::hasType($type)) {
20+
return;
21+
}
22+
23+
Type::addType($type, EnumType::class);
24+
/** @var EnumType $typeInstance */
25+
$typeInstance = Type::getType($type);
26+
$typeInstance->setFqcn($fqcn);
27+
$typeInstance->setName($type);
28+
if ($strategy) {
29+
$typeInstance->setStrategy($strategy);
30+
}
31+
}
32+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<?php
2+
3+
namespace Lamoda\EnumBundle\DependencyInjection;
4+
5+
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
6+
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
7+
use Symfony\Component\Config\Definition\ConfigurationInterface;
8+
9+
final class Configuration implements ConfigurationInterface
10+
{
11+
/** {@inheritdoc} */
12+
public function getConfigTreeBuilder(): TreeBuilder
13+
{
14+
$builder = new TreeBuilder();
15+
16+
$root = $builder->root('lamoda_enum');
17+
18+
$this->configureEnumNodes($root);
19+
20+
return $builder;
21+
}
22+
23+
private function configureEnumNodes(ArrayNodeDefinition $parent): void
24+
{
25+
$types = $parent->children()->arrayNode('dbal_types');
26+
27+
$dbalTypeProto = $types->prototype('array');
28+
$dbalTypeProto->addDefaultsIfNotSet();
29+
$dbalTypeProto
30+
->beforeNormalization()
31+
->ifString()
32+
->then(
33+
function (string $v) {
34+
return ['class' => $v];
35+
}
36+
)
37+
->end();
38+
$dbalTypeProto
39+
->children()->scalarNode('class')
40+
->isRequired()
41+
->example('My\Enum');
42+
$dbalTypeProto
43+
->children()->enumNode('strategy')
44+
->values(
45+
[
46+
'lowercase',
47+
'identical'
48+
]
49+
)
50+
->defaultValue('identical')
51+
;
52+
}
53+
}

0 commit comments

Comments
 (0)