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\CakePHP;
4
 
5
use Cake\ORM\TableRegistry;
6
 
7
class EntityPopulator
8
{
9
    protected $class;
10
    protected $connectionName;
11
    protected $columnFormatters = [];
12
    protected $modifiers = [];
13
 
14
    public function __construct($class)
15
    {
16
        $this->class = $class;
17
    }
18
 
19
    /**
20
     * @param string $name
21
     */
22
    public function __get($name)
23
    {
24
        return $this->{$name};
25
    }
26
 
27
    /**
28
     * @param string $name
29
     */
30
    public function __set($name, $value)
31
    {
32
        $this->{$name} = $value;
33
    }
34
 
35
    public function mergeColumnFormattersWith($columnFormatters)
36
    {
37
        $this->columnFormatters = array_merge($this->columnFormatters, $columnFormatters);
38
    }
39
 
40
    public function mergeModifiersWith($modifiers)
41
    {
42
        $this->modifiers = array_merge($this->modifiers, $modifiers);
43
    }
44
 
45
    /**
46
     * @return array
47
     */
48
    public function guessColumnFormatters($populator)
49
    {
50
        $formatters = [];
51
        $class = $this->class;
52
        $table = $this->getTable($class);
53
        $schema = $table->schema();
54
        $pk = $schema->primaryKey();
55
        $guessers = $populator->getGuessers() + ['ColumnTypeGuesser' => new ColumnTypeGuesser($populator->getGenerator())];
56
        $isForeignKey = static function ($column) use ($table) {
57
            foreach ($table->associations()->type('BelongsTo') as $assoc) {
58
                if ($column == $assoc->foreignKey()) {
59
                    return true;
60
                }
61
            }
62
 
63
            return false;
64
        };
65
 
66
        foreach ($schema->columns() as $column) {
67
            if ($column == $pk[0] || $isForeignKey($column)) {
68
                continue;
69
            }
70
 
71
            foreach ($guessers as $guesser) {
72
                if ($formatter = $guesser->guessFormat($column, $table)) {
73
                    $formatters[$column] = $formatter;
74
 
75
                    break;
76
                }
77
            }
78
        }
79
 
80
        return $formatters;
81
    }
82
 
83
    /**
84
     * @return array
85
     */
86
    public function guessModifiers()
87
    {
88
        $modifiers = [];
89
        $table = $this->getTable($this->class);
90
 
91
        $belongsTo = $table->associations()->type('BelongsTo');
92
 
93
        foreach ($belongsTo as $assoc) {
94
            $modifiers['belongsTo' . $assoc->name()] = function ($data, $insertedEntities) use ($assoc) {
95
                $table = $assoc->target();
96
                $foreignModel = $table->alias();
97
 
98
                $foreignKeys = [];
99
 
100
                if (!empty($insertedEntities[$foreignModel])) {
101
                    $foreignKeys = $insertedEntities[$foreignModel];
102
                } else {
103
                    $foreignKeys = $table->find('all')
104
                    ->select(['id'])
105
                    ->map(static function ($row) {
106
                        return $row->id;
107
                    })
108
                    ->toArray();
109
                }
110
 
111
                if (empty($foreignKeys)) {
112
                    throw new \Exception(sprintf('%s belongsTo %s, which seems empty at this point.', $this->getTable($this->class)->table(), $assoc->table()));
113
                }
114
 
115
                $foreignKey = $foreignKeys[array_rand($foreignKeys)];
116
                $data[$assoc->foreignKey()] = $foreignKey;
117
 
118
                return $data;
119
            };
120
        }
121
 
122
        // TODO check if TreeBehavior attached to modify lft/rgt cols
123
 
124
        return $modifiers;
125
    }
126
 
127
    /**
128
     * @param array $options
129
     */
130
    public function execute($class, $insertedEntities, $options = [])
131
    {
132
        $table = $this->getTable($class);
133
        $entity = $table->newEntity();
134
 
135
        foreach ($this->columnFormatters as $column => $format) {
136
            if (null !== $format) {
137
                $entity->{$column} = is_callable($format) ? $format($insertedEntities, $table) : $format;
138
            }
139
        }
140
 
141
        foreach ($this->modifiers as $modifier) {
142
            $entity = $modifier($entity, $insertedEntities);
143
        }
144
 
145
        if (!$entity = $table->save($entity, $options)) {
146
            throw new \RuntimeException("Failed saving $class record");
147
        }
148
 
149
        $pk = $table->primaryKey();
150
 
151
        if (is_string($pk)) {
152
            return $entity->{$pk};
153
        }
154
 
155
        return $entity->{$pk[0]};
156
    }
157
 
158
    public function setConnection($name)
159
    {
160
        $this->connectionName = $name;
161
    }
162
 
163
    protected function getTable($class)
164
    {
165
        $options = [];
166
 
167
        if (!empty($this->connectionName)) {
168
            $options['connection'] = $this->connectionName;
169
        }
170
 
171
        return TableRegistry::get($class, $options);
172
    }
173
}