Skip to content

Instantly share code, notes, and snippets.

@funyx
Last active December 18, 2018 07:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save funyx/814b081c21431ed02e7c6990b50aa21a to your computer and use it in GitHub Desktop.
Save funyx/814b081c21431ed02e7c6990b50aa21a to your computer and use it in GitHub Desktop.
Implementation of ContainsOne (merging models)

#Notes

  • uses array spawn to access protected properties - their_field, our_field
  • reference::model type Closure not implemented
// load the model
$m = new \test\ModelOne($this->app->db);
$m->containsOne('ModelTwo','mt_');
$this->setModel($m, []);
// ModelTwo fields and references are accessible via
// prefix.field_name => mt_field
<?php
namespace test;
class Model extends \atk4\data\Model
{
public function getPrefix($caption)
{
$caption = str_replace([' ','-'], '_', $caption);
return strtolower($caption.'_');
}
public function containsOne($refLink, $prefix = null)
{
$oneModel = $this->refModel($refLink, ['persistence' => $this->persistence]);
$oneModelRefs = $oneModel->getRefs();
$oneModelEls = $oneModel->elements;
$oneModelMap = [];
$prefix = $prefix ?: $this->getPrefix($oneModel->getModelCaption());
$oneModelMap['refs'] = [];
$rf = (Array)$this->getRef($refLink);
// add all fields
$oneModelMap['fields'] = [];
foreach ($oneModelEls as $fieldName => $field) {
// add fields (not controllers and not foreign key)
if (strpos($fieldName, '#ref_')===false &&
$fieldName != 'controller' &&
$fieldName != $rf["\0*\0".'their_field']
) {
$fname = $prefix.$fieldName;
$field->never_persist = true;
$this->add($field, $fname);
$oneModelMap['fields'][$fieldName] = $fname;
}
}
// add all refs
foreach ($oneModelRefs as $refName => $ref) {
// add reference
$rName = '#ref_'.$prefix.$refName;
if (!($ref->model instanceof \Closure) && $refName != $rf["\0*\0".'their_field']) {
$rM = (Array)$ref;
$oneModelMap['refs'][$rName] = $this->add(
$this->factory('\\'.get_class($ref), [
$prefix.$refName,
'model'=>$rM['model'],
'our_field'=>$prefix.$rM["\0*\0".'our_field']
])
);
}
}
$this->addHook('afterLoad', function ($m) use ($refLink, $oneModelMap) {
$r = $m->ref($refLink);
$rf = (Array)$m->getRef($refLink);
$r->tryLoadBy($rf["\0*\0".'their_field'], $m[$rf["\0*\0".'our_field']]);
foreach ($oneModelMap['fields'] as $theirs => $ours) {
try {
if($theirs != 'id') {
$m[$ours] = $r[$theirs];
}
} catch (\atk4\data\Exception $e) {
}
}
}, null, 1);
$this->addHook('beforeSave', function ($m) use ($refLink, $oneModelMap) {
$r = $m->ref($refLink);
foreach ($oneModelMap['fields'] as $theirs => $ours) {
try {
if($theirs != $r->id_field){
$r[$theirs] = $m[$ours];
}
} catch (\atk4\data\Exception $e) {
}
}
$m->addHook('afterSave',function($m2) use ($r, $refLink){
$rf = (Array)$m2->getRef($refLink);
$r->addCondition($rf["\0*\0".'their_field'], $m2[$rf["\0*\0".'our_field']]);
$r->save();
});
});
return $this;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment