Completed
Pull Request — master (#114)
by Bart
04:26
created

ModelMapper   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 95
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 5

Importance

Changes 0
Metric Value
wmc 15
lcom 0
cbo 5
dl 0
loc 95
rs 10
c 0
b 0
f 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
D import() 0 40 9
A findOrNewRecord() 0 15 3
A export() 0 13 3
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
    public function export(array $records): array
29
    {
30
        $result = [];
31
        foreach ($records as $record) {
32
            $modelClass = get_class($record);
33
            $converter = Craft::$app->controller->module->getConverter($modelClass);
34
            if ($converter) {
35
                $result[$record->handle] = $converter->getRecordDefinition($record);
36
            }
37
        }
38
39
        return $result;
40
    }
41
42
    /**
43
     * Import records.
44
     *
45
     * @param array $definitions
46
     * @param Model $records           The existing records
47
     * @param array $defaultAttributes Default attributes to use for each record
48
     * @param bool  $persist           Whether to persist the parsed records
49
     *
50
     * @return array
51
     */
52
    public function import(array $definitions, array $records, array $defaultAttributes = [], $persist = true): array
53
    {
54
        $imported = [];
55
        $recordsByHandle = ArrayHelper::index($records, 'handle');
56
        foreach ($definitions as $handle => $definition) {
57
            $modelClass = $definition['class'];
58
            $converter = Craft::$app->controller->module->getConverter($modelClass);
59
            if ($converter) {
60
                $record = $this->findOrNewRecord($recordsByHandle, $definition, $handle);
61
62
                if ($converter->getRecordDefinition($record) === $definition) {
63
                    Schematic::info('- Skipping '.get_class($record).' '.$handle);
64
                } else {
65
                    $converter->setRecordAttributes($record, $definition, $defaultAttributes);
66
                    if ($persist) {
67
                        Schematic::info('- Saving '.get_class($record).' '.$handle);
68
                        if ($converter->saveRecord($record, $definition)) {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
69
                        } else {
70
                            Schematic::importError($record, $handle);
71
                        }
72
                    }
73
                }
74
75
                $imported[] = $record;
76
            }
77
            unset($recordsByHandle[$handle]);
78
        }
79
80
        if (Schematic::$force && $persist) {
81
            // Delete records not in definitions
82
            foreach ($recordsByHandle as $handle => $record) {
83
                $modelClass = get_class($record);
84
                Schematic::info('- Deleting '.get_class($record).' '.$handle);
85
                $converter = Craft::$app->controller->module->getConverter($modelClass);
86
                $converter->deleteRecord($record);
87
            }
88
        }
89
90
        return $imported;
91
    }
92
93
    /**
94
     * Find record from records by handle or new record.
95
     *
96
     * @param Model[] $recordsByHandle
97
     * @param array   $definition
98
     * @param string  $handle
99
     *
100
     * @return Model
101
     */
102
    private function findOrNewRecord(array $recordsByHandle, array $definition, string $handle): Model
103
    {
104
        $record = new $definition['class']();
105
        if (array_key_exists($handle, $recordsByHandle)) {
106
            $existing = $recordsByHandle[$handle];
107
            if (get_class($record) == get_class($existing)) {
108
                $record = $existing;
109
            } else {
110
                $record->id = $existing->id;
111
                $record->setAttributes($existing->getAttributes());
112
            }
113
        }
114
115
        return $record;
116
    }
117
}
118