Completed
Pull Request — master (#152)
by
unknown
06:11 queued 52s
created

ModelMapper::import()   B

Complexity

Conditions 10
Paths 20

Size

Total Lines 42

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 25
CRAP Score 10.0056

Importance

Changes 0
Metric Value
dl 0
loc 42
ccs 25
cts 26
cp 0.9615
rs 7.6666
c 0
b 0
f 0
cc 10
nc 20
nop 4
crap 10.0056

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace NerdsAndCompany\Schematic\Mappers;
4
5
use Craft;
6
use craft\base\Model;
7
use craft\helpers\ArrayHelper;
8
use yii\base\Component as BaseComponent;
9
use NerdsAndCompany\Schematic\Schematic;
10
use NerdsAndCompany\Schematic\Interfaces\MapperInterface;
11
12
/**
13
 * Schematic Model Mapper.
14
 *
15
 * Sync Craft Setups.
16
 *
17
 * @author    Nerds & Company
18
 * @copyright Copyright (c) 2015-2018, Nerds & Company
19
 * @license   MIT
20
 *
21
 * @see      http://www.nerds.company
22
 */
23
class ModelMapper extends BaseComponent implements MapperInterface
24
{
25
    /**
26
     * {@inheritdoc}
27
     */
28 3
    public function export(array $records): array
29
    {
30 3
        $result = [];
31 3
        foreach ($records as $record) {
32 2
            $modelClass = get_class($record);
33 2
            $converter = Craft::$app->controller->module->getConverter($modelClass);
34 2
            if ($converter) {
35 2
                $handle = $converter->handle;
36 2
                $result[$record->$handle] = $converter->getRecordDefinition($record);
37
            }
38
        }
39
40 3
        return $result;
41
    }
42
43
    /**
44
     * Import records.
45
     *
46
     * @param array $definitions
47
     * @param Model $records           The existing records
48
     * @param array $defaultAttributes Default attributes to use for each record
49
     * @param bool  $persist           Whether to persist the parsed records
50
     *
51
     * @return array
52
     *
53
     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
54
     */
55 12
    public function import(array $definitions, array $records, array $defaultAttributes = [], $persist = true): array
56
    {
57 12
        $imported = [];
58 12
        $recordsByHandle = [];
59 12
        foreach ($definitions as $handle => $definition) {
60 4
            $modelClass = $definition['class'];
61 4
            $converter = Craft::$app->controller->module->getConverter($modelClass);
62 4
            if ($converter) {
63 4
                if (!count($recordsByHandle)) {
64 4
                    $recordsByHandle = ArrayHelper::index($records, $converter->handle);
65
                }
66 4
                $record = $this->findOrNewRecord($recordsByHandle, $definition, $handle);
67
68 4
                if ($converter->getRecordDefinition($record) === $definition) {
69 4
                    Schematic::info('- Skipping '.get_class($record).' '.$handle);
70
                } else {
71 4
                    $converter->setRecordAttributes($record, $definition, $defaultAttributes);
72 4
                    if ($persist) {
73 4
                        Schematic::info('- Saving '.get_class($record).' '.$handle);
74 4
                        if (!$converter->saveRecord($record, $definition)) {
75 2
                            Schematic::importError($record, $handle);
76
                        }
77
                    }
78
                }
79
80 4
                $imported[] = $record;
81
            }
82 4
            unset($recordsByHandle[$handle]);
83
        }
84
85 12
        if (Schematic::$force && $persist) {
86
            // Delete records not in definitions
87 6
            foreach ($recordsByHandle as $handle => $record) {
88 2
                $modelClass = get_class($record);
89 2
                Schematic::info('- Deleting '.get_class($record).' '.$handle);
90 2
                $converter = Craft::$app->controller->module->getConverter($modelClass);
91
                $converter->deleteRecord($record);
92
            }
93
        }
94
95 10
        return $imported;
96
    }
97
98
    /**
99
     * Find record from records by handle or new record.
100
     *
101
     * @param Model[] $recordsByHandle
102
     * @param array   $definition
103
     * @param string  $handle
104
     *
105
     * @return Model
106
     */
107 4
    private function findOrNewRecord(array $recordsByHandle, array $definition, string $handle): Model
108
    {
109 4
        $record = new $definition['class']();
110 4
        if (array_key_exists($handle, $recordsByHandle)) {
111 4
            $existing = $recordsByHandle[$handle];
112 4
            if (get_class($record) == get_class($existing)) {
113 4
                $record = $existing;
114
            } else {
115
                $record->id = $existing->id;
116
                $record->setAttributes($existing->getAttributes());
117
            }
118
        }
119
120 4
        return $record;
121
    }
122
}
123