Skip to content

Commit 03cc80d

Browse files
committed
Refactor unit handling and introduce time unit classes
1 parent 1979bdd commit 03cc80d

73 files changed

Lines changed: 1091 additions & 1084 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,8 @@
11
<?php
22

3-
use SoureCode\Bundle\Unit\Model\Metric\Length\Centimeter;
4-
use SoureCode\Bundle\Unit\Model\Metric\Length\Decameter;
5-
use SoureCode\Bundle\Unit\Model\Metric\Length\Decimeter;
6-
use SoureCode\Bundle\Unit\Model\Metric\Length\Hectometer;
7-
use SoureCode\Bundle\Unit\Model\Metric\Length\Kilometer;
8-
use SoureCode\Bundle\Unit\Model\Metric\Length\Meter;
9-
use SoureCode\Bundle\Unit\Model\Metric\Length\Micrometer;
10-
use SoureCode\Bundle\Unit\Model\Metric\Length\Millimeter;
11-
use SoureCode\Bundle\Unit\Model\Metric\Length\Nanometer;
12-
use SoureCode\Bundle\Unit\Model\Metric\Length\Picometer;
13-
use SoureCode\Bundle\Unit\Model\Metric\Prefix;
143
use Symfony\Component\DependencyInjection\ContainerBuilder;
154

165
return static function (ContainerBuilder $containerBuilder) {
176
$containerBuilder->prependExtensionConfig('soure_code_unit', [
18-
'units' => [
19-
'length' => [
20-
'mapping' => [
21-
Prefix::KILO->value => Kilometer::class,
22-
Prefix::HECTO->value => Hectometer::class,
23-
Prefix::DECA->value => Decameter::class,
24-
Prefix::BASE->value => Meter::class,
25-
Prefix::DECI->value => Decimeter::class,
26-
Prefix::CENTI->value => Centimeter::class,
27-
Prefix::MILLI->value => Millimeter::class,
28-
Prefix::MICRO->value => Micrometer::class,
29-
Prefix::NANO->value => Nanometer::class,
30-
Prefix::PICO->value => Picometer::class,
31-
],
32-
],
33-
],
347
]);
358
};

src/Doctrine/DBAL/Types/LengthType.php

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,9 @@
55
use Doctrine\DBAL\Platforms\AbstractPlatform;
66
use Doctrine\DBAL\Types\ConversionException;
77
use Doctrine\DBAL\Types\FloatType;
8-
use SoureCode\Bundle\Unit\Model\Metric\ConverterInterface;
9-
use SoureCode\Bundle\Unit\Model\Metric\FactoryInterface;
10-
use SoureCode\Bundle\Unit\Model\Metric\Length\LengthUnitInterface;
11-
use SoureCode\Bundle\Unit\Model\Metric\Length\Picometer;
12-
use SoureCode\Bundle\Unit\Model\Metric\NormalizerInterface;
13-
use SoureCode\Bundle\Unit\Model\Metric\UnitInterface;
8+
use SoureCode\Bundle\Unit\Model\Length\LengthUnitInterface;
9+
use SoureCode\Bundle\Unit\Model\Length\Picometer;
10+
use SoureCode\Bundle\Unit\Model\UnitInterface;
1411

1512
class LengthType extends FloatType
1613
{
@@ -21,10 +18,6 @@ class LengthType extends FloatType
2118
*/
2219
public static string $databaseUnitClass = Picometer::class;
2320

24-
public static ConverterInterface $converter;
25-
public static FactoryInterface $factory;
26-
public static NormalizerInterface $normalizer;
27-
2821
public function convertToPHPValue($value, AbstractPlatform $platform): ?UnitInterface
2922
{
3023
$value = parent::convertToPHPValue($value, $platform);
@@ -33,9 +26,12 @@ public function convertToPHPValue($value, AbstractPlatform $platform): ?UnitInte
3326
return null;
3427
}
3528

36-
$databaseUnit = self::$factory->create($value, self::$databaseUnitClass::getPrefix());
29+
/**
30+
* @var UnitInterface $databaseUnit
31+
*/
32+
$databaseUnit = new self::$databaseUnitClass($value);
3733

38-
return self::$normalizer->normalize($databaseUnit);
34+
return $databaseUnit->normalize();
3935
}
4036

4137
public function convertToDatabaseValue($value, AbstractPlatform $platform): ?string
@@ -48,7 +44,7 @@ public function convertToDatabaseValue($value, AbstractPlatform $platform): ?str
4844
throw ConversionException::conversionFailedInvalidType($value, $this->getName(), [UnitInterface::class]);
4945
}
5046

51-
$databaseUnit = self::$converter->convert($value, self::$databaseUnitClass::getPrefix());
47+
$databaseUnit = $value->convert(self::$databaseUnitClass);
5248

5349
return parent::convertToDatabaseValue((string) $databaseUnit->getValue(), $platform);
5450
}

src/Form/LengthType.php

Lines changed: 0 additions & 106 deletions
This file was deleted.

src/Form/PrefixType.php

Lines changed: 0 additions & 55 deletions
This file was deleted.

src/Form/UnitType.php

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
<?php
2+
3+
namespace SoureCode\Bundle\Unit\Form;
4+
5+
use SoureCode\Bundle\Unit\Model\Length\AbstractLengthUnit;
6+
use SoureCode\Bundle\Unit\Model\UnitInterface;
7+
use Symfony\Component\Form\AbstractType;
8+
use Symfony\Component\Form\CallbackTransformer;
9+
use Symfony\Component\Form\FormBuilderInterface;
10+
use Symfony\Component\OptionsResolver\OptionsResolver;
11+
12+
/**
13+
* @template-extends AbstractType<UnitInterface>
14+
*/
15+
class UnitType extends AbstractType
16+
{
17+
public function __construct()
18+
{
19+
}
20+
21+
public function buildForm(FormBuilderInterface $builder, array $options): void
22+
{
23+
$builder
24+
->add('value', ValueType::class, [
25+
'error_bubbling' => true,
26+
])
27+
->add('unit_type', UnitTypeType::class, [
28+
'error_bubbling' => true,
29+
'default_unit_type' => $options['default_unit_type'],
30+
'unit_class' => $options['unit_class'],
31+
'choice_filter' => function ($choiceValue) use ($options) {
32+
return isset($options['unit_class']::getMapping()[$choiceValue]);
33+
},
34+
]);
35+
36+
$builder->addModelTransformer(new CallbackTransformer(
37+
function (?UnitInterface $data): ?array {
38+
if (null === $data) {
39+
return null;
40+
}
41+
42+
return [
43+
'value' => (string) $data->getValue(),
44+
'unit_type' => $data::getUnitType(),
45+
];
46+
},
47+
function (?array $data) use ($options): ?UnitInterface {
48+
if (null === $data) {
49+
return null;
50+
}
51+
52+
$unitType = $data['unit_type'];
53+
$value = $data['value'];
54+
55+
if (null === $unitType || null === $value) {
56+
return null;
57+
}
58+
59+
/**
60+
* @var class-string<UnitInterface> $unitClass
61+
*/
62+
$unitClass = $options['unit_class'];
63+
64+
$unit = $unitClass::create($value, $unitType);
65+
66+
/**
67+
* @var class-string<UnitInterface> $targetUnitClass
68+
*/
69+
$targetUnitClass = $options['target_unit_class'];
70+
71+
if (null !== $targetUnitClass) {
72+
$unit = $unit->convert($targetUnitClass);
73+
}
74+
75+
return $unit;
76+
}
77+
));
78+
}
79+
80+
public function configureOptions(OptionsResolver $resolver): void
81+
{
82+
$resolver->setDefaults([
83+
'data_class' => null,
84+
'compound' => true,
85+
'empty_data' => [],
86+
'by_reference' => false,
87+
'error_bubbling' => false,
88+
89+
'unit_class' => AbstractLengthUnit::class,
90+
'default_unit_type' => null,
91+
'target_unit_class' => null,
92+
]);
93+
94+
$resolver->setAllowedValues('unit_class', function (?string $value): bool {
95+
if (null === $value) {
96+
return false;
97+
}
98+
99+
return is_subclass_of($value, UnitInterface::class);
100+
});
101+
102+
$resolver->setAllowedValues('default_unit_type', function (?string $value): bool {
103+
return is_subclass_of($value, UnitInterface::class) || null === $value;
104+
});
105+
106+
$resolver->setAllowedValues('target_unit_class', function (?string $value): bool {
107+
return is_subclass_of($value, UnitInterface::class) || null === $value;
108+
});
109+
}
110+
111+
public function getBlockPrefix(): string
112+
{
113+
return 'sourecode_unit_length';
114+
}
115+
}

0 commit comments

Comments
 (0)