Completed
Push — custom_model_handle ( 581061 )
by
unknown
12:49
created

ModelMapper::export()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 14
ccs 9
cts 9
cp 1
rs 9.7998
c 0
b 0
f 0
cc 3
nc 3
nop 1
crap 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 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 12
    public function import(array $definitions, array $records, array $defaultAttributes = [], $persist = true): array
54
    {
55 12
        $imported = [];
56 12
        $recordsByHandle = [];
57 12
        foreach ($definitions as $handle => $definition) {
58 4
            $modelClass = $definition['class'];
59 4
            $converter = Craft::$app->controller->module->getConverter($modelClass);
60 4
            if ($converter) {
61 4
                if (!count($recordsByHandle)) {
62 4
                    $recordsByHandle = ArrayHelper::index($records, $converter->handle);
63
                }
64 4
                $record = $this->findOrNewRecord($recordsByHandle, $definition, $handle);
65
66 4
                if ($converter->getRecordDefinition($record) === $definition) {
67 4
                    Schematic::info('- Skipping '.get_class($record).' '.$handle);
68
                } else {
69 4
                    $converter->setRecordAttributes($record, $definition, $defaultAttributes);
70 4
                    if ($persist) {
71 4
                        Schematic::info('- Saving '.get_class($record).' '.$handle);
72 4
                        if (!$converter->saveRecord($record, $definition)) {
73 2
                            Schematic::importError($record, $handle);
74
                        }
75
                    }
76
                }
77
78 4
                $imported[] = $record;
79
            }
80 4
            unset($recordsByHandle[$handle]);
81
        }
82
83 12
        if (Schematic::$force && $persist) {
84
            // Delete records not in definitions
85 6
            foreach ($recordsByHandle as $handle => $record) {
86 2
                $modelClass = get_class($record);
87 2
                Schematic::info('- Deleting '.get_class($record).' '.$handle);
88 2
                $converter = Craft::$app->controller->module->getConverter($modelClass);
89
                $converter->deleteRecord($record);
90
            }
91
        }
92
93 10
        return $imported;
94
    }
95
96
    /**
97
     * Find record from records by handle or new record.
98
     *
99
     * @param Model[] $recordsByHandle
100
     * @param array   $definition
101
     * @param string  $handle
102
     *
103
     * @return Model
104
     */
105 4
    private function findOrNewRecord(array $recordsByHandle, array $definition, string $handle): Model
106
    {
107 4
        $record = new $definition['class']();
108 4
        if (array_key_exists($handle, $recordsByHandle)) {
109 4
            $existing = $recordsByHandle[$handle];
110 4
            if (get_class($record) == get_class($existing)) {
111 4
                $record = $existing;
112
            } else {
113
                $record->id = $existing->id;
114
                $record->setAttributes($existing->getAttributes());
115
            }
116
        }
117
118 4
        return $record;
119
    }
120
}
121