Completed
Pull Request — master (#114)
by Bart
02:11
created

ModelMapper::findOrNewRecord()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 15
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 15
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 10
nc 3
nop 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
     * Get all record definitions.
27
     *
28
     * @return array
29
     */
30
    public function export(array $records): array
31
    {
32
        $result = [];
33
        foreach ($records as $record) {
34
            $modelClass = get_class($record);
35
            $converter = Craft::$app->controller->module->getConverter($modelClass);
36
            if ($converter) {
37
                $result[$record->handle] = $converter->getRecordDefinition($record);
38
            }
39
        }
40
41
        return $result;
42
    }
43
44
    /**
45
     * Import records.
46
     *
47
     * @param array $definitions
48
     * @param Model $records           The existing records
49
     * @param array $defaultAttributes Default attributes to use for each record
50
     * @param bool  $persist           Whether to persist the parsed records
51
     *
52
     * @return array
53
     */
54
    public function import(array $definitions, array $records, array $defaultAttributes = [], $persist = true): array
55
    {
56
        $imported = [];
57
        $recordsByHandle = ArrayHelper::index($records, 'handle');
58
        foreach ($definitions as $handle => $definition) {
59
            $modelClass = $definition['class'];
60
            $converter = Craft::$app->controller->module->getConverter($modelClass);
61
            if ($converter) {
62
                $record = $this->findOrNewRecord($recordsByHandle, $definition, $handle);
63
64
                if ($converter->getRecordDefinition($record) === $definition) {
65
                    Schematic::info('- Skipping '.get_class($record).' '.$handle);
66
                } else {
67
                    $converter->setRecordAttributes($record, $definition, $defaultAttributes);
68
                    if ($persist) {
69
                        Schematic::info('- Saving '.get_class($record).' '.$handle);
70
                        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...
71
                        } else {
72
                            Schematic::importError($record, $handle);
73
                        }
74
                    }
75
                }
76
77
                $imported[] = $record;
78
            }
79
            unset($recordsByHandle[$handle]);
80
        }
81
82
        if (Schematic::$force && $persist) {
83
            // Delete records not in definitions
84
            foreach ($recordsByHandle as $handle => $record) {
85
                $modelClass = get_class($record);
86
                Schematic::info('- Deleting '.get_class($record).' '.$handle);
87
                $converter = Craft::$app->controller->module->getConverter($modelClass);
88
                $converter->deleteRecord($record);
89
            }
90
        }
91
92
        return $imported;
93
    }
94
95
    /**
96
     * Find record from records by handle or new record.
97
     *
98
     * @param Model[] $recordsByHandle
99
     * @param array   $definition
100
     * @param string  $handle
101
     *
102
     * @return Model
103
     */
104
    private function findOrNewRecord(array $recordsByHandle, array $definition, string $handle): Model
105
    {
106
        $record = new $definition['class']();
107
        if (array_key_exists($handle, $recordsByHandle)) {
108
            $existing = $recordsByHandle[$handle];
109
            if (get_class($record) == get_class($existing)) {
110
                $record = $existing;
111
            } else {
112
                $record->id = $existing->id;
113
                $record->setAttributes($existing->getAttributes());
114
            }
115
        }
116
117
        return $record;
118
    }
119
}
120