Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
97.78% covered (success)
97.78%
44 / 45
50.00% covered (danger)
50.00%
1 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
PolymorphicObjectInteractor
97.78% covered (success)
97.78%
44 / 45
50.00% covered (danger)
50.00%
1 / 2
6
0.00% covered (danger)
0.00%
0 / 1
 supports
75.00% covered (warning)
75.00%
3 / 4
0.00% covered (danger)
0.00%
0 / 1
3.14
 interactWith
100.00% covered (success)
100.00%
41 / 41
100.00% covered (success)
100.00%
1 / 1
3
1<?php
2namespace Apie\Console\Helpers;
3
4use Apie\Console\ApieInputHelper;
5use Apie\Core\Context\ApieContext;
6use Apie\Core\Context\MetadataFieldHashmap;
7use Apie\Core\Metadata\CompositeMetadata;
8use Apie\Core\Metadata\Fields\DiscriminatorColumn;
9use Apie\Core\Metadata\Fields\FieldInterface;
10use Apie\Core\Metadata\Fields\StaticDiscriminatorColumn;
11use Apie\Core\Metadata\MetadataFactory;
12use Apie\Core\Metadata\MetadataInterface;
13use Apie\Core\Utils\ConverterUtils;
14use Apie\Core\Utils\EntityUtils;
15use Symfony\Component\Console\Helper\HelperSet;
16use Symfony\Component\Console\Helper\QuestionHelper;
17use Symfony\Component\Console\Input\InputInterface;
18use Symfony\Component\Console\Output\OutputInterface;
19use Symfony\Component\Console\Question\ChoiceQuestion;
20
21class PolymorphicObjectInteractor extends DefaultObjectInteractor implements InputInteractorInterface
22{
23    public function supports(MetadataInterface $metadata): bool
24    {
25        if ($metadata instanceof CompositeMetadata) {
26            $class = $metadata->toClass();
27            return $class !== null && EntityUtils::isPolymorphicEntity($class);
28        }
29
30        return false;
31    }
32
33    public function interactWith(
34        MetadataInterface $metadata,
35        HelperSet $helperSet,
36        InputInterface $input,
37        OutputInterface $output,
38        ApieContext $context
39    ): mixed {
40        $apieInputHelper = $helperSet->get('apie');
41        assert($apieInputHelper instanceof ApieInputHelper);
42        assert($metadata instanceof CompositeMetadata);
43        $class = $metadata->toClass();
44        assert($class !== null);
45        $helper = $helperSet->get('question');
46        assert($helper instanceof QuestionHelper);
47
48        $list = EntityUtils::getDiscriminatorClasses($class)->toStringArray();
49        $question = new ChoiceQuestion('Pick a value: ', array_combine($list, $list));
50        $result = ConverterUtils::toReflectionClass($helper->ask($input, $output, $question));
51        $output->writeln('');
52
53        $childMetadata = MetadataFactory::getCreationMetadata(
54            $result,
55            $context
56        );
57        assert($childMetadata instanceof CompositeMetadata);
58        $columns = [];
59        $filteredMap = array_filter(
60            $childMetadata->getHashmap()->toArray(),
61            function (FieldInterface $field, string $propertyName) use (&$columns, $result) {
62                if ($field instanceof DiscriminatorColumn || $field instanceof StaticDiscriminatorColumn) {
63                    $columns[$propertyName] = $field->getValueForClass($result);
64                    return false;
65                }
66
67                return true;
68            },
69            ARRAY_FILTER_USE_BOTH
70        );
71        $childMetadata = new CompositeMetadata(
72            new MetadataFieldHashmap($filteredMap),
73            $childMetadata->toClass()
74        );
75
76        return array_merge(
77            $columns,
78            parent::interactWith(
79                $childMetadata,
80                $helperSet,
81                $input,
82                $output,
83                $context
84            )
85        );
86    }
87}