Generator::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 5
c 2
b 0
f 0
dl 0
loc 12
rs 10
cc 1
nc 1
nop 4
1
<?php
2
3
/*
4
 * This file is part of the SexyField package.
5
 *
6
 * (c) Dion Snoeijen <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
declare (strict_types = 1);
13
14
namespace Tardigrades\SectionField\Generator;
15
16
use Assert\Assertion;
17
use Psr\Container\ContainerInterface;
18
use Tardigrades\Entity\Field as FieldEntity;
19
use Tardigrades\Entity\FieldInterface;
20
use Tardigrades\Entity\SectionInterface;
21
use Tardigrades\FieldType\FieldTypeInterface;
22
use Tardigrades\SectionField\Generator\Writer\Writable;
23
use Tardigrades\SectionField\Service\FieldManagerInterface;
24
use Tardigrades\SectionField\Service\FieldTypeManagerInterface;
25
use Tardigrades\SectionField\Service\SectionManagerInterface;
26
27
abstract class Generator implements GeneratorInterface
28
{
29
    /** @var FieldManagerInterface */
30
    protected $fieldManager;
31
32
    /** @var FieldTypeManagerInterface */
33
    protected $fieldTypeManager;
34
35
    /** @var SectionManagerInterface */
36
    protected $sectionManager;
37
38
    /** @var array */
39
    protected $relationships;
40
41
    /** @var array */
42
    protected $buildMessages = [];
43
44
    /** @var ContainerInterface */
45
    protected $container;
46
47
    public function __construct(
48
        FieldManagerInterface $fieldManager,
49
        FieldTypeManagerInterface $fieldTypeManager,
50
        SectionManagerInterface $sectionManager,
51
        ContainerInterface $container
52
    ) {
53
        $this->fieldManager = $fieldManager;
54
        $this->fieldTypeManager = $fieldTypeManager;
55
        $this->sectionManager = $sectionManager;
56
        $this->container = $container;
57
58
        $this->relationships = [];
59
    }
60
61
    protected function addOpposingRelationships(SectionInterface $section, array $fields): array
62
    {
63
        $this->relationships = $this->sectionManager->getRelationshipsOfAll();
64
        foreach ($this->relationships[(string) $section->getHandle()] as $fieldHandle => $relationship) {
65
            if (false !== strpos($fieldHandle, '-opposite')) {
66
                $fieldHandle = str_replace('-opposite', '', $fieldHandle);
67
68
                $oppositeRelationshipField = new FieldEntity();
69
                $config = [
70
                    'field' => [
71
                        'name' => $fieldHandle,
72
                        'handle' => $fieldHandle,
73
                        'kind' => $relationship['kind'],
74
                        'to' => $relationship['to']
75
                    ]
76
                ];
77
78
                $oppositeRelationshipField->setName($fieldHandle);
79
                $oppositeRelationshipField->setHandle($fieldHandle);
80
81
                if (!empty($relationship['relationship-type'])) {
82
                    $config['field']['relationship-type'] = $relationship['relationship-type'];
83
                }
84
                $oppositeRelationshipField->setConfig($config);
85
                $oppositeRelationshipFieldType = $this->fieldTypeManager
86
                    ->readByFullyQualifiedClassName(
87
                        $relationship['fullyQualifiedClassName']
88
                    );
89
                $oppositeRelationshipField->setFieldType($oppositeRelationshipFieldType);
90
                $fields[] = $oppositeRelationshipField;
91
            }
92
        }
93
94
        return $fields;
95
    }
96
97
    /**
98
     * There are scenario's in which a field should be ignored by a generator
99
     *
100
     * @param FieldInterface $field
101
     * @return bool
102
     */
103
    protected function shouldIgnore(FieldInterface $field): bool
104
    {
105
        $fieldType = $this->container->get(
106
            (string) $field->getFieldType()->getFullyQualifiedClassName()
107
        );
108
        // The field type generator config refers to how the field type itself is defined
109
        // as a service. You can see that in the services.yml
110
        $fieldTypeGeneratorConfig = $fieldType->getFieldTypeGeneratorConfig()->toArray();
111
        if (!key_exists(static::GENERATE_FOR, $fieldTypeGeneratorConfig)) {
0 ignored issues
show
Bug introduced by
The constant Tardigrades\SectionField...Generator::GENERATE_FOR was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
112
            return true;
113
        }
114
115
        // See if this field is to be ignored by this generator because it's explicitly
116
        // set to ignore === true
117
        try {
118
            // The field generator config refers to how the field instructs the generator
119
            // You see that in the field configuration yml
120
            $fieldGeneratorConfig = $field->getConfig()->getGeneratorConfig()->toArray();
121
            if (!empty($fieldGeneratorConfig[static::GENERATE_FOR]['ignore']) &&
122
                $fieldGeneratorConfig[static::GENERATE_FOR]['ignore']
123
            ) {
124
                return true;
125
            }
126
        } catch (\Exception $exception) {}
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
127
128
        return false;
129
    }
130
131
    protected function getFieldTypeGeneratorConfig(FieldInterface $field, string $generateFor): array
132
    {
133
        $fieldType = $this->container->get((string) $field->getFieldType()->getFullyQualifiedClassName());
134
        $fieldTypeGeneratorConfig = $fieldType->getFieldTypeGeneratorConfig()->toArray();
135
136
        $messageWhenEmpty = 'No generator defined for '
137
            . $field->getName()
138
            . ' type: '
139
            . $field->getFieldType()->getType();
140
141
        $messageWhenNoKey = 'Nothing to do for this generator: ' . $generateFor;
142
143
        try {
144
            Assertion::notEmpty($fieldTypeGeneratorConfig, $messageWhenEmpty);
145
            Assertion::keyExists($fieldTypeGeneratorConfig, $generateFor, $messageWhenNoKey);
146
        } catch (\Exception $exception) {
147
            $this->buildMessages[] = $exception->getMessage();
148
        }
149
150
        return $fieldTypeGeneratorConfig;
151
    }
152
153
    /**
154
     * The field type generator templates are to be defined in the packages
155
     * that provide the specific support for what is to be generated
156
     *
157
     * The field's field type, is in a base package, the default package is: 'sexy-field-field-types-base'
158
     * The supporting directory, is where the generator is to find it's templates
159
     * For example: 'sexy-field-entity' or 'sexy-field-doctrine'
160
     *
161
     * @param FieldInterface $field
162
     * @param string $supportingDirectory
163
     * @return mixed
164
     */
165
    protected function getFieldTypeTemplateDirectory(
166
        FieldInterface $field,
167
        string $supportingDirectory
168
    ) {
169
        /** @var FieldTypeInterface $fieldType */
170
        $fieldType = $this->container->get((string) $field->getFieldType()->getFullyQualifiedClassName());
171
172
        $fieldTypeDirectory = explode('/', $fieldType->directory());
173
        foreach ($fieldTypeDirectory as $key => $segment) {
174
            if ($segment === 'vendor') {
175
                $selector = $key + 2;
176
                $fieldTypeDirectory[$selector] = $supportingDirectory;
177
                break;
178
            }
179
        }
180
181
        return implode('/', $fieldTypeDirectory);
182
    }
183
184
    public function getBuildMessages(): array
185
    {
186
        return $this->buildMessages;
187
    }
188
189
    abstract public function generateBySection(SectionInterface $section): Writable;
190
}
191