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)) { |
|
|
|
|
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
|
|
|
|
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 theelse
branch, consider inverting the condition.could be turned into
This is much more concise to read.