Completed
Push — develop ( 3bef5f...80abfd )
by Nate
02:27
created

InputTrait::inputToIndexSources()   B

Complexity

Conditions 7
Paths 10

Size

Total Lines 32

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 56

Importance

Changes 0
Metric Value
dl 0
loc 32
ccs 0
cts 24
cp 0
rs 8.4746
c 0
b 0
f 0
cc 7
nc 10
nop 1
crap 56
1
<?php
2
3
/**
4
 * @copyright  Copyright (c) Flipbox Digital Limited
5
 * @license    https://github.com/flipboxfactory/craft-element-lists/LICENSE
6
 * @link       https://github.com/flipboxfactory/craft-element-lists/
7
 */
8
9
namespace flipbox\craft\element\lists\fields;
10
11
use Craft;
12
use craft\base\Element;
13
use craft\base\ElementInterface;
14
use craft\elements\db\ElementQueryInterface;
15
use craft\helpers\ArrayHelper;
16
use flipbox\craft\elements\nestedIndex\web\assets\index\NestedElementIndex;
17
use flipbox\craft\ember\helpers\SiteHelper;
18
19
/**
20
 * @author Flipbox Factory <[email protected]>
21
 * @since 2.0.0
22
 *
23
 * @property string $inputTemplate
24
 * @property string $inputJsClass
25
 * @property string $handle
26
 * @property int $id
27
 * @property string|null $viewMode
28
 * @property int|null $limit
29
 * @property string $selectionLabel
30
 */
31
trait InputTrait
32
{
33
    /**
34
     * Returns the element class associated with this field type.
35
     *
36
     * @return string The Element class name
37
     */
38
    abstract protected static function elementType(): string;
39
40
    /**
41
     * Returns an array of the source keys the field should be able to select elements from.
42
     *
43
     * @param ElementInterface|null $element
44
     * @return array|string
45
     */
46
    abstract protected function inputSources(ElementInterface $element = null);
47
48
    /**
49
     * @param null $value
50
     * @param ElementInterface|null $element
51
     * @return array
52
     * @throws \yii\base\InvalidConfigException
53
     */
54
    protected function inputTemplateVariables($value = null, ElementInterface $element = null): array
55
    {
56
        if ($value instanceof ElementQueryInterface) {
57
            $value = $value
58
                ->anyStatus()
59
                ->ids();
60
        } elseif (!is_array($value)) {
61
            $value = [];
62
        }
63
64
        Craft::$app->getView()->registerAssetBundle(NestedElementIndex::class);
65
66
        return [
67
            'sources' => $this->inputToIndexSources(
68
                $this->inputSources($element)
69
            ),
70
            'element' => $element,
71
            'container' => 'nested-index-' . $this->handle,
72
            'elementType' => static::elementType(),
73
            'inputJsClass' => $this->inputJsClass,
74
            'inputJs' => $this->getInputJs($value, $element),
75
            'indexJsClass' => 'Craft.NestedElementIndex',
76
            'indexJs' => $this->getIndexJs($element)
77
        ];
78
    }
79
80
    /**
81
     * Converts input sources to index sources (used to filter results).
82
     *
83
     * @param $sources
84
     * @return array
85
     */
86
    protected function inputToIndexSources($sources): array
87
    {
88
        $indexSources = Craft::$app->getElementIndexes()->getSources(static::elementType());
89
90
        if ($sources === '*') {
91
            // Remove any structure sources
92
            foreach ($indexSources as &$indexSource) {
93
                ArrayHelper::remove($indexSource, 'structureEditable');
94
                ArrayHelper::remove($indexSource, 'structureId');
95
            }
96
97
            return $indexSources;
98
        }
99
100
        if (!is_array($sources)) {
101
            $sources = [$sources];
102
        }
103
104
        // Only return the selected sources
105
        foreach($indexSources as $key => $indexSource) {
106
            if (!array_key_exists('key', $indexSource)) {
107
                unset($indexSources[$key]);
108
                continue;
109
            }
110
111
            if (!in_array($indexSource['key'], $sources)) {
112
                unset($indexSources[$key]);
113
            }
114
        }
115
116
        return $indexSources;
117
    }
118
119
    /*******************************************
120
     * JS CONFIGS
121
     *******************************************/
122
123
    /**
124
     * @param array $elementIds
125
     * @param ElementInterface $element
126
     * @return array
127
     */
128
    private function getInputJs(array $elementIds, ElementInterface $element = null): array
129
    {
130
        /** @var Element $element */
131
        $siteId = SiteHelper::ensureSiteId($element ? $element->siteId : null);
132
133
        $selectionCriteria = [
134
            'enabledForSite' => null,
135
            'siteId' => $siteId
136
        ];
137
138
        return [
139
            'elementType' => static::elementType(),
140
            'sources' => $this->inputSources($element),
141
            'criteria' => $selectionCriteria,
142
            'sourceElementId' => $element->getId() ?: null,
143
            'viewMode' => $this->viewMode,
144
            'limit' => $this->limit,
145
            'selectionLabel' => $this->selectionLabel,
146
            'storageKey' => 'nested.index.input.' . $this->handle,
147
            'elements' => $elementIds,
148
            'addAction' => 'element-lists/source/associate',
149
            'selectTargetAttribute' => 'target',
150
            'selectParams' => [
151
                'source' => $element->getId() ?: null,
152
                'field' => $this->id,
153
                'site' => $siteId,
154
            ]
155
        ];
156
    }
157
158
    /**
159
     * @param ElementInterface $element
160
     * @return array
161
     */
162
    private function getIndexJs(ElementInterface $element = null): array
163
    {
164
165
        /** @var Element $element */
166
        $elementId = ($element !== null && $element->getId() !== null) ? $element->getId() : false;
167
168
        $siteId = SiteHelper::ensureSiteId($element ? $element->siteId : null);
169
170
        return [
171
            'source' => 'nested',
172
            'context' => 'index',
173
            'viewMode' => $this->viewMode,
174
            'showStatusMenu' => true,
175
            'showSiteMenu' => true,
176
            'hideSidebar' => true,
177
            'toolbarFixed' => false,
178
            'storageKey' => 'nested.index.' . $this->handle,
179
            'updateElementsAction' => 'element-lists/element-indexes/get-elements',
180
            'submitActionsAction' => 'element-lists/element-indexes/perform-action',
181
            'loadMoreElementsAction' => 'element-lists/element-indexes/get-more-elements',
182
            'criteria' => [
183
                'enabledForSite' => null,
184
                'siteId' => $siteId,
185
                $this->handle => [
186
                    'source' => $elementId,
187
                    'sourceSiteId' => $siteId
188
                ]
189
            ],
190
            'viewParams' => [
191
                'sourceId' => $elementId,
192
                'fieldId' => $this->id
193
            ]
194
        ];
195
    }
196
}
197