Completed
Push — master ( 2bc8a1...07eadb )
by Bart
9s
created

Field::populate()   B

Complexity

Conditions 4
Paths 8

Size

Total Lines 26
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 3
Bugs 0 Features 0
Metric Value
c 3
b 0
f 0
dl 0
loc 26
ccs 0
cts 22
cp 0
rs 8.5806
cc 4
eloc 18
nc 8
nop 4
crap 20
1
<?php
2
3
namespace NerdsAndCompany\Schematic\Models;
4
5
use Craft\Craft;
6
use Craft\FieldModel;
7
use Craft\FieldGroupModel;
8
9
/**
10
 * Schematic Field Model.
11
 *
12
 * A schematic field model for mapping data
13
 *
14
 * @author    Nerds & Company
15
 * @copyright Copyright (c) 2015-2016, Nerds & Company
16
 * @license   MIT
17
 *
18
 * @link      http://www.nerds.company
19
 */
20
class Field
21
{
22
    /**
23
     * @return FieldFactory
24
     */
25
    protected function getFieldFactory()
26
    {
27
        return Craft::app()->schematic_fields->getFieldFactory();
28
    }
29
30
    /**
31
     * @return SectionsService
32
     */
33
    private function getSectionsService()
34
    {
35
        return Craft::app()->sections;
36
    }
37
38
    /**
39
     * @return UserGroupsService
40
     */
41
    private function getUserGroupsService()
42
    {
43
        return Craft::app()->userGroups;
44
    }
45
46
    /**
47
     * @return AssetSources
48
     */
49
    private function getAssetSourcesService()
50
    {
51
        return Craft::app()->schematic_assetSources;
52
    }
53
54
    /**
55
     * @return CategoriesService
56
     */
57
    private function getCategoriesService()
58
    {
59
        return Craft::app()->categories;
60
    }
61
62
    /**
63
     * @param FieldModel $field
64
     * @param $includeContext
65
     *
66
     * @return array
67
     */
68
    public function getDefinition(FieldModel $field, $includeContext)
69
    {
70
        $definition = [
71
            'name' => $field->name,
72
            'required' => $field->required,
73
            'instructions' => $field->instructions,
74
            'translatable' => $field->translatable,
75
            'type' => $field->type,
76
            'settings' => $field->settings,
77
        ];
78
79
        if ($includeContext) {
80
            $definition['context'] = $field->context;
81
        }
82
83
        if (isset($definition['settings']['sources'])) {
84
            $definition['settings']['sources'] = $this->getMappedSources($field->type, $definition['settings']['sources'], 'id', 'handle');
85
        }
86
87
        if (isset($definition['settings']['source'])) {
88
            $definition['settings']['source'] = $this->getSource($field->type, $definition['settings']['source'], 'id', 'handle');
89
        }
90
91
        return $definition;
92
    }
93
94
    /**
95
     * @param array                $fieldDefinition
96
     * @param FieldModel           $field
97
     * @param string               $fieldHandle
98
     * @param FieldGroupModel|null $group
99
     */
100
    public function populate(array $fieldDefinition, FieldModel $field, $fieldHandle, FieldGroupModel $group = null)
101
    {
102
        $field->name = $fieldDefinition['name'];
103
        $field->handle = $fieldHandle;
104
        $field->required = $fieldDefinition['required'];
105
        $field->translatable = $fieldDefinition['translatable'];
106
        $field->instructions = $fieldDefinition['instructions'];
107
        $field->type = $fieldDefinition['type'];
108
        $field->settings = $fieldDefinition['settings'];
109
110
        if ($group) {
111
            $field->groupId = $group->id;
112
        }
113
114
        if (isset($fieldDefinition['settings']['sources'])) {
115
            $settings = $fieldDefinition['settings'];
116
            $settings['sources'] = $this->getMappedSources($field->type, $settings['sources'], 'handle', 'id');
117
            $field->settings = $settings;
118
        }
119
120
        if (isset($fieldDefinition['settings']['source'])) {
121
            $settings = $fieldDefinition['settings'];
122
            $settings['source'] = $this->getSource($field->type, $settings['source'], 'handle', 'id');
123
            $field->settings = $settings;
124
        }
125
    }
126
127
    /**
128
     * Get sources based on the indexFrom attribute and return them with the indexTo attribute.
129
     *
130
     * @param string       $fieldType
131
     * @param string|array $sources
132
     * @param string       $indexFrom
133
     * @param string       $indexTo
134
     *
135
     * @return array|string
136
     */
137
    private function getMappedSources($fieldType, $sources, $indexFrom, $indexTo)
138
    {
139
        $mappedSources = $sources;
140
        if (is_array($sources)) {
141
            $mappedSources = [];
142
            foreach ($sources as $source) {
143
                $mappedSources[] = $this->getSource($fieldType, $source, $indexFrom, $indexTo);
144
            }
145
        }
146
147
        return $mappedSources;
148
    }
149
150
    /**
151
     * Gets a source by the attribute indexFrom, and returns it with attribute $indexTo.
152
     *
153
     * @TODO Break up and simplify this method
154
     *
155
     * @param string $fieldType
156
     * @param string $source
157
     * @param string $indexFrom
158
     * @param string $indexTo
159
     *
160
     * @return string
161
     */
162
    private function getSource($fieldType, $source, $indexFrom, $indexTo)
163
    {
164
        /** @var BaseElementModel $sourceObject */
165
        $sourceObject = null;
166
167
        if (strpos($source, ':') > -1) {
168
            list($sourceType, $sourceFrom) = explode(':', $source);
169
            switch ($sourceType) {
170
                case 'section':
171
                    $service = $this->getSectionsService();
172
                    $method = 'getSectionBy';
173
                    break;
174
                case 'group':
175
                    $service = $fieldType == 'Users' ? $this->getUserGroupsService() : $this->getCategoriesService();
176
                    $method = 'getGroupBy';
177
                    break;
178
                case 'folder':
179
                    $service = $this->getAssetSourcesService();
180
                    $method = 'getSourceTypeBy';
181
                    break;
182
            }
183
        } elseif ($source !== 'singles') {
184
            //Backwards compatibility
185
            $sourceType = 'section';
186
            $sourceFrom = $source;
187
            $service = $this->getSectionsService();
188
            $method = 'getSectionBy';
189
        }
190
191
        if (isset($service) && isset($method) && isset($sourceFrom)) {
192
            $method = $method.$indexFrom;
193
            $sourceObject = $service->$method($sourceFrom);
194
        }
195
196
        if ($sourceObject && isset($sourceType)) {
197
            $source = $sourceType.':'.$sourceObject->$indexTo;
198
        }
199
200
        return $source;
201
    }
202
}
203