Completed
Push — after-import-callback ( 3a74b4...a80e19 )
by Bart
10:37 queued 10s
created

SourcesBehavior::findSources()   A

Complexity

Conditions 5
Paths 5

Size

Total Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 5

Importance

Changes 0
Metric Value
dl 0
loc 14
ccs 8
cts 8
cp 1
rs 9.4888
c 0
b 0
f 0
cc 5
nc 5
nop 4
crap 5
1
<?php
2
3
namespace NerdsAndCompany\Schematic\Behaviors;
4
5
use Craft;
6
use TypeError;
7
use yii\base\Behavior;
8
use craft\base\Model;
9
use NerdsAndCompany\Schematic\Schematic;
10
11
/**
12
 * Schematic Sources Behavior.
13
 *
14
 * Sync Craft Setups.
15
 *
16
 * @author    Nerds & Company
17
 * @copyright Copyright (c) 2015-2018, Nerds & Company
18
 * @license   MIT
19
 *
20
 * @see      http://www.nerds.company
21
 */
22
class SourcesBehavior extends Behavior
23
{
24
    /**
25
     * Recursively find sources in definition attributes.
26
     *
27
     * @param string $fieldType
28
     * @param array  $attributes
29
     * @param string $indexFrom
30
     * @param string $indexTo
31
     *
32
     * @return array
33
     */
34 9
    public function findSources(string $fieldType, array $attributes, string $indexFrom, string $indexTo): array
35
    {
36 9
        foreach ($attributes as $key => $attribute) {
37 9
            if ($key === 'source') {
38 7
                $attributes[$key] = $this->getSource($fieldType, $attribute, $indexFrom, $indexTo);
39 7
            } elseif ($key === 'sources') {
40 7
                $attributes[$key] = $this->getSources($fieldType, $attribute, $indexFrom, $indexTo);
41 7
            } elseif (is_array($attribute)) {
42
                $attributes[$key] = $this->findSources($fieldType, $attribute, $indexFrom, $indexTo);
43
            }
44
        }
45 9
46
        return $attributes;
47
    }
48
49
    /**
50
     * Get sources based on the indexFrom attribute and return them with the indexTo attribute.
51
     *
52
     * @param string       $fieldType
53
     * @param string|array $sources
54
     * @param string       $indexFrom
55
     * @param string       $indexTo
56
     *
57
     * @return array|string
58
     */
59
    public function getSources(string $fieldType, $sources, string $indexFrom, string $indexTo)
60
    {
61
        $mappedSources = $sources;
62
        if (is_array($sources)) {
63 9
            $mappedSources = [];
64
            $sources = array_filter($sources);
65 9
            foreach ($sources as $source) {
66 5
                $mappedSources[] = $this->getSource($fieldType, $source, $indexFrom, $indexTo);
67
            }
68
        }
69
70 9
        return $mappedSources;
71
    }
72 9
73
    /**
74 9
     * Gets a source by the attribute indexFrom, and returns it with attribute $indexTo.
75 9
     *
76 9
     * @TODO Break up and simplify this method
77 9
     *
78 9
     * @param string $fieldType
79 9
     * @param string $source
80 9
     * @param string $indexFrom
81 9
     * @param string $indexTo
82 9
     *
83 9
     * @return string|null
84 9
     *
85 9
     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
86 5
     * @SuppressWarnings(PHPMD.NPathComplexity)
87 5
     */
88 5
    public function getSource(string $fieldType, string $source = null, string $indexFrom, string $indexTo)
89 9
    {
90 7
        if (false === strpos($source, ':')) {
91 5
            return $source;
92 5
        }
93 5
94 7
        /** @var Model $sourceObject */
95 5
        $sourceObject = null;
96 5
97 5
        list($sourceType, $sourceFrom) = explode(':', $source);
98 5
        switch ($sourceType) {
99 5
            case 'editSite':
100 5
                $service = Craft::$app->sites;
101 5
                $method = 'getSiteBy';
102 2
                break;
103
            case 'single':
104
            case 'section':
105
            case 'createEntries':
106 2
            case 'editPeerEntries':
107 2
            case 'deleteEntries':
108 2
            case 'deletePeerEntries':
109 2
            case 'deletePeerEntryDrafts':
110
            case 'editEntries':
111
            case 'editPeerEntryDrafts':
112
            case 'publishEntries':
113
            case 'publishPeerEntries':
114
            case 'publishPeerEntryDrafts':
115
                $service = Craft::$app->sections;
116
                $method = 'getSectionBy';
117
                break;
118 9
            case 'group':
119 9
            case 'editCategories':
120
                $service = 'Users' == $fieldType ? Craft::$app->userGroups : Craft::$app->categories;
121 9
                $method = 'getGroupBy';
122
                break;
123
            case 'folder':
124
            case 'createFoldersInVolume':
125
            case 'deleteFilesAndFoldersInVolume':
126
            case 'saveAssetInVolume':
127
            case 'viewVolume':
128
                $service = Craft::$app->volumes;
129
                $method = 'getVolumeBy';
130 9
                break;
131 8
            case 'taggroup':
132
                $service = Craft::$app->tags;
133
                $method = 'getTagGroupBy';
134 1
                break;
135
            case 'field':
136 1
                $service = Craft::$app->fields;
137
                $method = 'getFieldBy';
138
                break;
139
            case 'editGlobalSet':
140
                $service = Craft::$app->globals;
141
                $method = 'getSetBy';
142
                break;
143
            case 'utility':
144
                return $source;
145
        }
146
147
        if (isset($service) && isset($method) && isset($sourceFrom)) {
148
            $method = $method.ucfirst($indexFrom);
149
            try {
150
                $sourceObject = $service->$method($sourceFrom);
151
            } catch (TypeError $e) {
152
                Schematic::error('An error occured mapping source '.$source.' from '.$indexFrom.' to '.$indexTo);
153
                Schematic::error($e->getMessage());
154
155
                return null;
156
            }
157
        }
158
159
        if ($sourceObject) {
160
            return $sourceType.':'.$sourceObject->$indexTo;
161
        }
162
163
        Schematic::warning('No mapping found for source '.$source);
164
165
        return null;
166
    }
167
}
168