Completed
Push — master ( f04a1d...4a48e8 )
by
unknown
10s
created

SourcesBehavior   A

Complexity

Total Complexity 40

Size/Duplication

Total Lines 146
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 3

Test Coverage

Coverage 79.75%

Importance

Changes 0
Metric Value
wmc 40
lcom 0
cbo 3
dl 0
loc 146
ccs 63
cts 79
cp 0.7975
rs 9.2
c 0
b 0
f 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
A findSources() 0 14 5
A getSources() 0 13 3
F getSource() 0 79 32

How to fix   Complexity   

Complex Class

Complex classes like SourcesBehavior often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use SourcesBehavior, and based on these observations, apply Extract Interface, too.

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 32
    public function findSources(string $fieldType, array $attributes, string $indexFrom, string $indexTo): array
35
    {
36 32
        foreach ($attributes as $key => $attribute) {
37 32
            if ($key === 'source') {
38 4
                $attributes[$key] = $this->getSource($fieldType, $attribute, $indexFrom, $indexTo);
39 32
            } elseif ($key === 'sources') {
40 4
                $attributes[$key] = $this->getSources($fieldType, $attribute, $indexFrom, $indexTo);
41 32
            } elseif (is_array($attribute)) {
42 32
                $attributes[$key] = $this->findSources($fieldType, $attribute, $indexFrom, $indexTo);
43
            }
44
        }
45
46 32
        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 9
    public function getSources(string $fieldType, $sources, string $indexFrom, string $indexTo)
60
    {
61 9
        $mappedSources = $sources;
62 9
        if (is_array($sources)) {
63 7
            $mappedSources = [];
64 7
            $sources = array_filter($sources);
65 7
            foreach ($sources as $source) {
66 7
                $mappedSources[] = $this->getSource($fieldType, $source, $indexFrom, $indexTo);
67
            }
68
        }
69
70 9
        return $mappedSources;
71
    }
72
73
    /**
74
     * Gets a source by the attribute indexFrom, and returns it with attribute $indexTo.
75
     *
76
     * @TODO Break up and simplify this method
77
     *
78
     * @param string $fieldType
79
     * @param string $source
80
     * @param string $indexFrom
81
     * @param string $indexTo
82
     *
83
     * @return string|null
84
     *
85
     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
86
     * @SuppressWarnings(PHPMD.NPathComplexity)
87
     */
88 9
    public function getSource(string $fieldType, string $source = null, string $indexFrom, string $indexTo)
89
    {
90 9
        if (false === strpos($source, ':')) {
91 7
            return $source;
92
        }
93
94
        /** @var Model $sourceObject */
95 9
        $sourceObject = null;
96
97 9
        list($sourceType, $sourceFrom) = explode(':', $source);
98
        switch ($sourceType) {
99 9
            case 'editSite':
100
                $service = Craft::$app->sites;
101
                $method = 'getSiteBy';
102
                break;
103 9
            case 'single':
104 9
            case 'section':
105 9
            case 'createEntries':
106 9
            case 'editPeerEntries':
107 9
            case 'deleteEntries':
108 9
            case 'deletePeerEntries':
109 9
            case 'deletePeerEntryDrafts':
110 9
            case 'editEntries':
111 9
            case 'editPeerEntryDrafts':
112 9
            case 'publishEntries':
113 9
            case 'publishPeerEntries':
114 9
            case 'publishPeerEntryDrafts':
115 5
                $service = Craft::$app->sections;
116 5
                $method = 'getSectionBy';
117 5
                break;
118 9
            case 'group':
119 7
            case 'editCategories':
120 5
                $service = 'Users' == $fieldType ? Craft::$app->userGroups : Craft::$app->categories;
121 5
                $method = 'getGroupBy';
122 5
                break;
123 7
            case 'folder':
124 5
            case 'createFoldersInVolume':
125 5
            case 'deleteFilesAndFoldersInVolume':
126 5
            case 'saveAssetInVolume':
127 5
            case 'viewVolume':
128 5
                $service = Craft::$app->volumes;
129 5
                $method = 'getVolumeBy';
130 5
                break;
131 2
            case 'taggroup':
132
                $service = Craft::$app->tags;
133
                $method = 'getTagGroupBy';
134
                break;
135 2
            case 'field':
136 2
                $service = Craft::$app->fields;
137 2
                $method = 'getFieldBy';
138 2
                break;
139
            case 'editGlobalSet':
140
                $service = Craft::$app->globals;
141
                $method = 'getSetBy';
142
                break;
143
            case 'utility':
144
                return $source;
145
        }
146
147 9
        if (isset($service) && isset($method) && isset($sourceFrom)) {
148 9
            $method = $method.ucfirst($indexFrom);
149
            try {
150 9
                $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 9
        if ($sourceObject) {
160 8
            return $sourceType.':'.$sourceObject->$indexTo;
161
        }
162
163 1
        Schematic::warning('No mapping found for source '.$source);
164
165 1
        return null;
166
    }
167
}
168