Test Failed
Push — master ( d42710...4a514d )
by
unknown
03:09
created

GroupAttachmentWidget::identToClassname()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 36
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 36
rs 8.8571
c 0
b 0
f 0
cc 2
eloc 20
nc 2
nop 1

1 Method

Rating   Name   Duplication   Size   Complexity  
A GroupAttachmentWidget::controllerIdent() 0 4 1
1
<?php
2
3
namespace Charcoal\Admin\Widget;
4
5
// dependencies from `PHP`
6
use Charcoal\Model\MetadataInterface;
7
use InvalidArgumentException;
8
use RuntimeException;
9
10
// local dependencies
11
use Charcoal\Cms\TemplateableInterface;
12
13
// dependencies from `charcoal-model`
14
use Charcoal\Model\Service\MetadataLoader;
15
16
// dependencies from `charcoal-property`
17
use Charcoal\Property\Structure\StructureMetadata;
18
19
// dependencies from `charcoal-ui`
20
use Charcoal\Ui\Form\FormInterface;
21
use Charcoal\Ui\Form\FormTrait;
22
use Charcoal\Ui\Layout\LayoutAwareInterface;
23
use Charcoal\Ui\Layout\LayoutAwareTrait;
24
use Charcoal\Ui\PrioritizableInterface;
25
26
// dependencies from `pimple`
27
use Pimple\Container;
28
29
/**
30
 * Class TemplateAttachmentWidget
31
 */
32
class GroupAttachmentWidget extends AttachmentWidget implements
33
    FormInterface,
34
    LayoutAwareInterface
35
{
36
    use FormTrait;
37
    use LayoutAwareTrait;
38
39
    /**
40
     * The cache of snake-cased words.
41
     *
42
     * @var array
43
     */
44
    protected static $snakeCache = [];
45
46
    /**
47
     * The cache of camel-cased words.
48
     *
49
     * @var array
50
     */
51
    protected static $camelCache = [];
52
53
    /**
54
     * Store the metadata loader instance.
55
     *
56
     * @var MetadataLoader
57
     */
58
    private $metadataLoader;
59
60
    /**
61
     * @var boolean
62
     */
63
    protected $isAttachmentMetadataFinalized;
64
65
    /**
66
     * @var string
67
     */
68
    protected $controllerIdent;
69
70
    /**
71
     * Comparison function used by {@see uasort()}.
72
     *
73
     * @param  PrioritizableInterface $a Sortable entity A.
74
     * @param  PrioritizableInterface $b Sortable entity B.
75
     * @return integer Sorting value: -1 or 1.
76
     */
77
    protected function sortItemsByPriority(
78
        PrioritizableInterface $a,
79
        PrioritizableInterface $b
80
    ) {
81
        $priorityA = $a->priority();
82
        $priorityB = $b->priority();
83
84
        if ($priorityA === $priorityB) {
85
            return 0;
86
        }
87
88
        return ($priorityA < $priorityB) ? (-1) : 1;
89
    }
90
91
    /**
92
     * @param  Container $container The DI container.
93
     * @return void
94
     */
95
    protected function setDependencies(Container $container)
96
    {
97
        parent::setDependencies($container);
98
99
        $this->setWidgetFactory($container['widget/factory']);
100
101
        // Satisfies FormInterface
102
        $this->setFormGroupFactory($container['form/group/factory']);
103
        $this->setMetadataLoader($container['metadata/loader']);
104
    }
105
106
    /**
107
     * Set a metadata loader.
108
     *
109
     * @param  MetadataLoader $loader The loader instance, used to load metadata.
110
     * @return self
111
     */
112
    protected function setMetadataLoader(MetadataLoader $loader)
113
    {
114
        $this->metadataLoader = $loader;
115
116
        return $this;
117
    }
118
119
    /**
120
     * Retrieve the metadata loader.
121
     *
122
     * @throws RuntimeException If the metadata loader was not previously set.
123
     * @return MetadataLoader
124
     */
125
    protected function metadataLoader()
126
    {
127
        if ($this->metadataLoader === null) {
128
            throw new RuntimeException(sprintf(
129
                'Metadata Loader is not defined for "%s"',
130
                \get_class($this)
131
            ));
132
        }
133
134
        return $this->metadataLoader;
135
    }
136
137
    /**
138
     * Load a metadata file.
139
     *
140
     * @param  string $metadataIdent A metadata file path or namespace.
141
     * @return MetadataInterface
142
     */
143
    protected function loadMetadata($metadataIdent)
144
    {
145
        $metadataLoader = $this->metadataLoader();
146
        $metadata       = $metadataLoader->load($metadataIdent, $this->createMetadata());
147
148
        return $metadata;
149
    }
150
151
    /**
152
     * @throws InvalidArgumentException If structureMetadata $data is note defined.
153
     * @return MetadataInterface
154
     */
155
    protected function createMetadata()
156
    {
157
        return new StructureMetadata();
158
    }
159
160
    /**
161
     * @inheritDoc
162
     */
163
    public function setData(array $data)
164
    {
165
        parent::setData($data);
166
167
        $this->addAttachmentGroupFromMetadata();
168
    }
169
170
    /**
171
     * Load attachments group widget and them as form groups.
172
     *
173
     * @param boolean $reload Allows to reload the data.
174
     * @throws InvalidArgumentException If structureMetadata $data is note defined.
175
     * @throws RuntimeException If the metadataLoader is not defined.
176
     * @return void
177
     */
178
    protected function addAttachmentGroupFromMetadata($reload = false)
179
    {
180
        if ($this->obj() instanceof TemplateableInterface) {
181
            $this->setControllerIdent($this->obj()->templateIdentClass());
182
        }
183
184
        if ($reload || !$this->isAttachmentMetadataFinalized) {
185
            $obj                 = $this->obj();
186
            $controllerInterface = $this->controllerIdent();
187
188
            $interfaces = [];
189
            array_push($interfaces, $this->objType(), $controllerInterface);
190
191
            $structureMetadata = $this->createMetadata();
192
193
            if (count($interfaces)) {
194
                $controllerMetadataIdent = sprintf('widget/metadata/%s/%s', $obj->objType(), $obj->id());
195
                $structureMetadata       = $this->metadataLoader()->load(
196
                    $controllerMetadataIdent,
197
                    $structureMetadata,
198
                    $interfaces
199
                );
200
            }
201
202
            $attachmentWidgets = $structureMetadata->get('attachments.widgets');
203
            foreach ((array)$attachmentWidgets as $ident => $metadata) {
204
                $this->addGroup($ident, $metadata);
205
            }
206
207
            $this->isAttachmentMetadataFinalized = true;
208
        }
209
    }
210
211
    /**
212
     * Set the form object's template controller identifier.
213
     *
214
     * @param  mixed $ident The template controller identifier.
215
     * @return self
216
     */
217
    public function setControllerIdent($ident)
218
    {
219
        if (class_exists($ident)) {
220
            $this->controllerIdent = $ident;
221
222
            return $this;
223
        }
224
225
        if (substr($ident, -9) !== '-template') {
226
            $ident .= '-template';
227
        }
228
229
        $this->controllerIdent = $ident;
230
231
        return $this;
232
    }
233
234
    /**
235
     * Retrieve the form object's template controller identifier.
236
     *
237
     * @return mixed
238
     */
239
    public function controllerIdent()
240
    {
241
        return $this->controllerIdent;
242
    }
243
}
244