Completed
Push — master ( 00d60f...aabe5c )
by Dion
14s
created

Generator   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 129
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 11
dl 0
loc 129
rs 10
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A getFieldTypeTemplateDirectory() 0 17 3
A getBuildMessages() 0 3 1
A __construct() 0 12 1
A getFieldTypeGeneratorConfig() 0 20 2
A addOpposingRelationships() 0 34 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
    protected function getFieldTypeGeneratorConfig(FieldInterface $field, string $generateFor): array
98
    {
99
        $fieldType = $this->container->get((string) $field->getFieldType()->getFullyQualifiedClassName());
100
        $fieldTypeGeneratorConfig = $fieldType->getFieldTypeGeneratorConfig()->toArray();
101
102
        $messageWhenEmpty = 'No generator defined for '
103
            . $field->getName()
104
            . ' type: '
105
            . $field->getFieldType()->getType();
106
107
        $messageWhenNoKey = 'Nothing to do for this generator: ' . $generateFor;
108
109
        try {
110
            Assertion::notEmpty($fieldTypeGeneratorConfig, $messageWhenEmpty);
111
            Assertion::keyExists($fieldTypeGeneratorConfig, $generateFor, $messageWhenNoKey);
112
        } catch (\Exception $exception) {
113
            $this->buildMessages[] = $exception->getMessage();
114
        }
115
116
        return $fieldTypeGeneratorConfig;
117
    }
118
119
    /**
120
     * The field type generator templates are to be defined in the packages
121
     * that provide the specific support for what is to be generated
122
     *
123
     * The field's field type, is in a base package, the default package is: 'sexy-field-field-types-base'
124
     * The supporting directory, is where the generator is to find it's templates
125
     * For example: 'sexy-field-entity' or 'sexy-field-doctrine'
126
     *
127
     * @param FieldInterface $field
128
     * @param string $supportingDirectory
129
     * @return mixed
130
     */
131
    protected function getFieldTypeTemplateDirectory(
132
        FieldInterface $field,
133
        string $supportingDirectory
134
    ) {
135
        /** @var FieldTypeInterface $fieldType */
136
        $fieldType = $this->container->get((string) $field->getFieldType()->getFullyQualifiedClassName());
137
138
        $fieldTypeDirectory = explode('/', $fieldType->directory());
139
        foreach ($fieldTypeDirectory as $key => $segment) {
140
            if ($segment === 'vendor') {
141
                $selector = $key + 2;
142
                $fieldTypeDirectory[$selector] = $supportingDirectory;
143
                break;
144
            }
145
        }
146
147
        return implode('/', $fieldTypeDirectory);
148
    }
149
150
    public function getBuildMessages(): array
151
    {
152
        return $this->buildMessages;
153
    }
154
155
    abstract public function generateBySection(SectionInterface $section): Writable;
156
}
157