Skip to content

Commit 7359bb6

Browse files
committed
Skeleton code for the data merging routine to be used in edit actions
1 parent 4d96262 commit 7359bb6

File tree

1 file changed

+64
-1
lines changed

1 file changed

+64
-1
lines changed

src/ORM/Marshaller.php

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,10 @@
1414
*/
1515
namespace Cake\ORM;
1616

17+
use Cake\Collection\Collection;
1718
use Cake\Database\Expression\TupleComparison;
1819
use Cake\Database\Type;
20+
use Cake\Datasource\EntityInterface;
1921
use Cake\ORM\Association;
2022
use Cake\ORM\Table;
2123

@@ -47,7 +49,7 @@ class Marshaller {
4749
* Constructor.
4850
*
4951
* @param \Cake\ORM\Table $table
50-
* @param boolean Whether or not this masrhaller is in safe mode
52+
* @param boolean Whether or not this marshaller is in safe mode
5153
*/
5254
public function __construct(Table $table, $safe = false) {
5355
$this->_table = $table;
@@ -214,4 +216,65 @@ protected function _loadBelongsToMany($assoc, $ids) {
214216
return $assoc->find()->where($filter)->toArray();
215217
}
216218

219+
public function merge(EntityInterface $entity, array $data, $include = []) {
220+
$propertyMap = $this->_buildPropertyMap($include);
221+
$tableName = $this->_table->alias();
222+
223+
if (isset($data[$tableName])) {
224+
$data = $data[$tableName];
225+
}
226+
227+
$properties = [];
228+
foreach ($data as $key => $value) {
229+
$original = $entity->get($key);
230+
if (isset($propertyMap[$key])) {
231+
$assoc = $propertyMap[$key]['association'];
232+
$nested = $propertyMap[$key]['nested'];
233+
$value = $this->_mergeAssociation($original, $assoc, $value, $nested);
234+
} elseif ($original == $value) {
235+
continue;
236+
}
237+
$properties[$key] = $value;
238+
}
239+
240+
$entity->set($properties);
241+
return $entity;
242+
}
243+
244+
public function mergeMany($entities, array $data, $include = []) {
245+
$primary = (array)$this->_table->primaryKey();
246+
$indexed = (new Collection($data))->indexBy($primary[0]);
247+
$output = [];
248+
249+
foreach ($entities as $entity) {
250+
$key = $entity->get($primary[0]);
251+
if ($key === null || !isset($indexed[$key])) {
252+
continue;
253+
}
254+
$output[] = $this->merge($entity, $indexed[$key], $include);
255+
unset($indexed[$key]);
256+
}
257+
258+
foreach ($indexed as $record) {
259+
$output[] = $this->one($record, $include);
260+
}
261+
return $output;
262+
}
263+
264+
protected function _mergeAssociation($original, $assoc, $value, $include) {
265+
if (!$original) {
266+
return $this->_marshalAssociation($assoc, $value, $include);
267+
}
268+
269+
$targetTable = $assoc->target();
270+
$marshaller = $targetTable->marshaller();
271+
if ($assoc->type() === Association::ONE_TO_ONE) {
272+
return $marshaller->merge($original, $value, (array)$include);
273+
}
274+
if ($assoc->type() === Association::MANY_TO_MANY) {
275+
return $marshaller->_belongsToMany($assoc, $value, (array)$include);
276+
}
277+
return $marshaller->mergeMany($original, $value, (array)$include);
278+
}
279+
217280
}

0 commit comments

Comments
 (0)