Subversion-Projekte lars-tiefland.laravel_shop

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
148 lars 1
<?php
2
 
3
namespace Faker\ORM\Spot;
4
 
5
use Faker\Generator;
6
use Faker\Guesser\Name;
7
use Spot\Locator;
8
use Spot\Mapper;
9
use Spot\Relation\BelongsTo;
10
 
11
/**
12
 * Service class for populating a table through a Spot Entity class.
13
 */
14
class EntityPopulator
15
{
16
    /**
17
     * When fetching existing data - fetch only few first rows.
18
     */
19
    public const RELATED_FETCH_COUNT = 10;
20
 
21
    /**
22
     * @var Mapper
23
     */
24
    protected $mapper;
25
 
26
    /**
27
     * @var Locator
28
     */
29
    protected $locator;
30
 
31
    /**
32
     * @var array
33
     */
34
    protected $columnFormatters = [];
35
    /**
36
     * @var array
37
     */
38
    protected $modifiers = [];
39
 
40
    /**
41
     * @var bool
42
     */
43
    protected $useExistingData = false;
44
 
45
    /**
46
     * @param bool $useExistingData
47
     */
48
    public function __construct(Mapper $mapper, Locator $locator, $useExistingData = false)
49
    {
50
        $this->mapper = $mapper;
51
        $this->locator = $locator;
52
        $this->useExistingData = $useExistingData;
53
    }
54
 
55
    /**
56
     * @return string
57
     */
58
    public function getMapper()
59
    {
60
        return $this->mapper;
61
    }
62
 
63
    public function setColumnFormatters($columnFormatters)
64
    {
65
        $this->columnFormatters = $columnFormatters;
66
    }
67
 
68
    /**
69
     * @return array
70
     */
71
    public function getColumnFormatters()
72
    {
73
        return $this->columnFormatters;
74
    }
75
 
76
    public function mergeColumnFormattersWith($columnFormatters)
77
    {
78
        $this->columnFormatters = array_merge($this->columnFormatters, $columnFormatters);
79
    }
80
 
81
    public function setModifiers(array $modifiers)
82
    {
83
        $this->modifiers = $modifiers;
84
    }
85
 
86
    /**
87
     * @return array
88
     */
89
    public function getModifiers()
90
    {
91
        return $this->modifiers;
92
    }
93
 
94
    public function mergeModifiersWith(array $modifiers)
95
    {
96
        $this->modifiers = array_merge($this->modifiers, $modifiers);
97
    }
98
 
99
    /**
100
     * @return array
101
     */
102
    public function guessColumnFormatters(Generator $generator)
103
    {
104
        $formatters = [];
105
        $nameGuesser = new Name($generator);
106
        $columnTypeGuesser = new ColumnTypeGuesser($generator);
107
        $fields = $this->mapper->fields();
108
 
109
        foreach ($fields as $fieldName => $field) {
110
            if ($field['primary'] === true) {
111
                continue;
112
            }
113
 
114
            if ($formatter = $nameGuesser->guessFormat($fieldName)) {
115
                $formatters[$fieldName] = $formatter;
116
 
117
                continue;
118
            }
119
 
120
            if ($formatter = $columnTypeGuesser->guessFormat($field)) {
121
                $formatters[$fieldName] = $formatter;
122
 
123
                continue;
124
            }
125
        }
126
        $entityName = $this->mapper->entity();
127
        $entity = $this->mapper->build([]);
128
        $relations = $entityName::relations($this->mapper, $entity);
129
 
130
        foreach ($relations as $relation) {
131
            // We don't need any other relation here.
132
            if ($relation instanceof BelongsTo) {
133
                $fieldName = $relation->localKey();
134
                $entityName = $relation->entityName();
135
                $field = $fields[$fieldName];
136
                $required = $field['required'];
137
 
138
                $locator = $this->locator;
139
 
140
                $formatters[$fieldName] = function ($inserted) use ($required, $entityName, $locator, $generator) {
141
                    if (!empty($inserted[$entityName])) {
142
                        return $generator->randomElement($inserted[$entityName])->get('id');
143
                    }
144
 
145
                    if ($required && $this->useExistingData) {
146
                        // We did not add anything like this, but it's required,
147
                        // So let's find something existing in DB.
148
                        $mapper = $locator->mapper($entityName);
149
                        $records = $mapper->all()->limit(self::RELATED_FETCH_COUNT)->toArray();
150
 
151
                        if (empty($records)) {
152
                            return null;
153
                        }
154
 
155
                        return $generator->randomElement($records)['id'];
156
                    }
157
 
158
                    return null;
159
                };
160
            }
161
        }
162
 
163
        return $formatters;
164
    }
165
 
166
    /**
167
     * Insert one new record using the Entity class.
168
     *
169
     * @return string
170
     */
171
    public function execute($insertedEntities)
172
    {
173
        $obj = $this->mapper->build([]);
174
 
175
        $this->fillColumns($obj, $insertedEntities);
176
        $this->callMethods($obj, $insertedEntities);
177
 
178
        $this->mapper->insert($obj);
179
 
180
        return $obj;
181
    }
182
 
183
    private function fillColumns($obj, $insertedEntities): void
184
    {
185
        foreach ($this->columnFormatters as $field => $format) {
186
            if (null !== $format) {
187
                $value = is_callable($format) ? $format($insertedEntities, $obj) : $format;
188
                $obj->set($field, $value);
189
            }
190
        }
191
    }
192
 
193
    private function callMethods($obj, $insertedEntities): void
194
    {
195
        foreach ($this->getModifiers() as $modifier) {
196
            $modifier($obj, $insertedEntities);
197
        }
198
    }
199
}