Renderable_relationship::viewable()   A
last analyzed

Complexity

Conditions 5
Paths 4

Size

Total Lines 45
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 2 Features 0
Metric Value
cc 5
eloc 23
c 3
b 2
f 0
nc 4
nop 3
dl 0
loc 45
rs 9.2408
1
<?php declare(strict_types=1);
2
3
namespace Modelarium\Frontend\Vue\Renderable;
4
5
use Doctrine\Inflector\InflectorFactory;
6
use Illuminate\Support\Str;
7
use Formularium\Exception\ClassNotFoundException;
8
use Formularium\Field;
9
use Formularium\Renderable;
10
use Formularium\HTMLNode;
11
use Formularium\Frontend\Vue\RenderableVueTrait;
12
use Formularium\Frontend\Vue\Framework as VueFramework;
13
use Modelarium\Datatype\Datatype_relationship;
14
use Modelarium\Datatype\RelationshipFactory;
15
16
class Renderable_relationship extends Renderable
17
{
18
    use RenderableVueTrait {
19
        RenderableVueTrait::viewable as _viewable;
20
        RenderableVueTrait::editable as _editable;
21
    }
22
23
    /**
24
     * Subcall of wrapper editable()
25
     *
26
     * @param mixed $value
27
     * @param Field $field
28
     * @param HTMLNode $previous
29
     * @return HTMLNode
30
     */
31
    public function viewable($value, Field $field, HTMLNode $previous): HTMLNode
32
    {
33
        /**
34
         * @var VueFramework $vue
35
         */
36
        $vue = $this->framework;
37
        /**
38
         * @var Datatype_relationship $datatype
39
         */
40
        $datatype = $field->getDatatype();
41
42
        $relationship = $datatype->getRelationship();
43
        if ($relationship === RelationshipFactory::RELATIONSHIP_ONE_TO_ONE ||
44
            (
45
                $relationship === RelationshipFactory::RELATIONSHIP_ONE_TO_MANY && !$datatype->getIsInverse()
46
            )
47
        ) {
48
            $isMultiple = true;
49
        } else {
50
            $isMultiple = false; // TODO
51
        }
52
53
        if ($isMultiple) {
54
            $previous = new HtmlNode(
55
                'div' // TODO: list?
56
            );
57
            $p = new HtmlNode(
58
                $datatype->getTarget() . 'Card',
59
                [
60
                    'v-for' => 'item in ' . $vue->getVueCode()->getFieldModelVariable() . $datatype->getTargetTable(),
61
                    'v-bind' => 'item',
62
                    ':key' => 'item.id'
63
                ]
64
            );
65
            $previous->appendContent($p);
66
        } else {
67
            $previous = new HtmlNode(
68
                $datatype->getTarget() . 'Card',
69
                [
70
                    'v-bind' => $vue->getVueCode()->getFieldModelVariable() . $datatype->getTarget(),
71
                    'v-if' => $vue->getVueCode()->getFieldModelVariable() . $datatype->getTarget()
72
                ]
73
            );
74
        }
75
        return $previous;
76
    }
77
78
    /**
79
     * Subcall of wrapper editable()
80
     *
81
     * @param mixed $value
82
     * @param Field $field
83
     * @param HTMLNode $previous
84
     * @return HTMLNode
85
     */
86
    public function editable($value, Field $field, HTMLNode $previous): HTMLNode
87
    {
88
        $previous = $this->_editable($value, $field, $previous);
89
90
        /*
91
         * init variables
92
         */
93
        $inflector = InflectorFactory::create()->build();
0 ignored issues
show
Unused Code introduced by
The assignment to $inflector is dead and can be removed.
Loading history...
94
        /**
95
         * @var VueFramework $vue
96
         */
97
        $vue = $this->framework;
98
        $vueCode = $vue->getVueCode();
99
        $mvar = $vueCode->getFieldModelVariable();
100
        /**
101
         * @var Datatype_relationship $datatype
102
         */
103
        $datatype = $field->getDatatype();
104
105
        if ($datatype->isMorph()) {
106
            // TODO
107
            return $previous;
108
        }
109
110
        // @phpstan-ignore-next-line
111
        $targetModel = call_user_func($datatype->getTargetClass() . '::getFormularium');
112
        if ($targetModel === false) {
113
            throw new ClassNotFoundException("Cannot find model " . $datatype->getTarget());
114
        }
115
        /**
116
         * @var \Formularium\Model $targetModel
117
         */
118
119
        // get the title field
120
        $titleField = $targetModel->firstField(
121
            function (Field $field) {
122
                return $field->getRenderable('title', false);
123
            }
124
        );
125
        // get the title field
126
        $queryField = $titleField;
127
128
        // import graphql query
129
        $query = 'relationList' . $targetModel->getName() . 'Query';
130
        $targetStudly = Str::studly($datatype->getTarget());
131
        $vueCode->appendImport($query, "raw-loader!../" . $targetStudly . "/queryList.graphql");
132
        $vueCode->appendExtraData($query, $query);
133
134
        $relationship = $datatype->getRelationship();
135
        if ($relationship === RelationshipFactory::RELATIONSHIP_MANY_TO_MANY ||
136
            $relationship === RelationshipFactory::MORPH_MANY_TO_MANY
137
            // TODO: inverses 1:n?
138
        ) {
139
            $component = 'RelationshipMultiple';
140
        } elseif ($field->getRenderable('relationshipSelect', false)) { // TODO: document
141
            $component = 'RelationshipSelect';
142
        } else {
143
            $component = 'RelationshipAutocomplete';
144
        }
145
146
        // replace the <select> with our component
147
        foreach (array_merge($previous->get('select'), $previous->get('input')) as $input) {
148
            $classes = $input->getAttribute('class');
149
            $input->setTag($component)
150
                ->setAttributes(
151
                    [
152
                        'name' => $field->getName(),
153
                        'htmlClass' => $classes,
154
                        'class' => '',
155
                        'titleField' => ($titleField ? $titleField->getName() : 'id'),
156
                        'queryField' => ($queryField ? $queryField->getName() : 'id'),
157
                        ':query' => $query,
158
                        'targetType' => $datatype->getTarget(),
159
                        'targetTypePlural' => $datatype->getTargetPlural(),
160
                        'v-model' => $mvar . $field->getName()
161
                    ]
162
                );
163
        }
164
165
        return $previous;
166
    }
167
}
168