Further tweaking to the linkable behavior, first by fixing the $efields addition from the last checkin of this file, and second by fixing a problem with linking onto a HABTM relationship, since the alias was coming out screwy (although this issue was hacked by using 'table' to determine the class and alias).

git-svn-id: file:///svn-source/pmgr/branches/ledger_transactions_20090605/site@151 97e9348a-65ac-dc4b-aefc-98561f571b83
This commit is contained in:
abijah
2009-06-16 21:39:27 +00:00
parent 212c982851
commit cb02b9e1e0

View File

@@ -132,9 +132,8 @@ class LinkableBehavior extends ModelBehavior {
unset($iterator['defaults']); unset($iterator['defaults']);
} }
$iterations = Set::normalize($iterator); $iterations = Set::normalize($iterator);
/* pr(compact('iterations')); */ /* pr(array('checkpoint' => 'Iterations', compact('iterations'))); */
foreach ($iterations as $alias => $options) { foreach ($iterations as $alias => $options) {
$efields = array();
if (is_null($options)) { if (is_null($options)) {
$options = array(); $options = array();
} }
@@ -143,18 +142,24 @@ class LinkableBehavior extends ModelBehavior {
throw new InvalidArgumentException(sprintf('%s::%s must receive aliased links', get_class($this), __FUNCTION__)); throw new InvalidArgumentException(sprintf('%s::%s must receive aliased links', get_class($this), __FUNCTION__));
} }
if (empty($options['table']) && empty($options['class'])) { if (empty($options['class']))
$options['class'] = $alias; $options['class'] = $alias;
} elseif (!empty($options['table']) && empty($options['class'])) {
$options['class'] = Inflector::classify($options['table']); /* pr(array('checkpoint' => 'Begin Model Work', compact('alias', 'options'))); */
}
/* pr(compact('alias', 'options')); */ $modelClass = $options['class'];
$_Model =& ClassRegistry::init($options['class']); // the incoming model to be linked in query $modelAlias = $options['alias'];
$Reference =& ClassRegistry::init($options['reference']['class']); // the already in query model that links to $_Model $referenceClass = $options['reference']['class'];
/* pr("_Model: {$options['alias']} : {$options['class']}" . */ $referenceAlias = $options['reference']['alias'];
/* " ({$_Model->alias} : {$_Model->name})"); */
/* pr("Reference: {$options['reference']['alias']} : {$options['reference']['class']}" . */ $_Model =& ClassRegistry::init($modelClass); // the incoming model to be linked in query
/* " ({$Reference->alias} : {$Reference->name})"); */ $Reference =& ClassRegistry::init($referenceClass); // the already in query model that links to $_Model
/* pr(array('checkpoint' => 'Aliases Established', */
/* 'Model' => ($modelAlias .' : '. $modelClass . */
/* ' ('. $_Model->alias .' : '. $_Model->name .')'), */
/* 'Reference' => ($referenceAlias .' : '. $referenceClass . */
/* ' ('. $Reference->alias .' : '. $Reference->name .')'))); */
$db =& $_Model->getDataSource(); $db =& $_Model->getDataSource();
$associatedThroughReference = 0; $associatedThroughReference = 0;
@@ -185,39 +190,41 @@ class LinkableBehavior extends ModelBehavior {
$_Model->unbindModel(array('belongsTo' => array($Reference->alias))); $_Model->unbindModel(array('belongsTo' => array($Reference->alias)));
} }
if ($associatedThroughReference)
$this->recursive_array_replace("%{MODEL_ALIAS}",
$options['reference']['alias'],
$association['conditions']);
else
$this->recursive_array_replace("%{MODEL_ALIAS}",
$options['alias'],
$association['conditions']);
// Determine which model holds the foreign key // Determine which model holds the foreign key
if (($type === 'hasMany' || $type === 'hasOne') ^ $associatedThroughReference) { if (($type === 'hasMany' || $type === 'hasOne') ^ $associatedThroughReference) {
$primaryAlias = $options['reference']['alias']; $primaryAlias = $referenceAlias;
$foreignAlias = $options['alias']; $foreignAlias = $modelAlias;
$primaryModel = $Reference; $primaryModel = $Reference;
$foreignModel = $_Model; $foreignModel = $_Model;
} else { } else {
$primaryAlias = $options['alias']; $primaryAlias = $modelAlias;
$foreignAlias = $options['reference']['alias']; $foreignAlias = $referenceAlias;
$primaryModel = $_Model; $primaryModel = $_Model;
$foreignModel = $Reference; $foreignModel = $Reference;
} }
/* pr("primaryModel: $primaryModel->name ($primaryModel->alias)"); */ if ($associatedThroughReference)
/* pr("foreignModel: $foreignModel->name ($foreignModel->alias)"); */ $associationAlias = $referenceAlias;
/* pr($type); */ else
/* pr($association); */ $associationAlias = $modelAlias;
$this->recursive_array_replace("%{MODEL_ALIAS}",
$associationAlias,
$association['conditions']);
/* pr(array('checkpoint' => 'Models Established - Check Associations', */
/* 'primaryModel' => $primaryAlias .' : '. $primaryModel->name, */
/* 'foreignModel' => $foreignAlias .' : '. $foreignModel->name, */
/* compact('type', 'association'))); */
if (empty($options['conditions'])) { if (empty($options['conditions'])) {
if ($type === 'hasAndBelongsToMany') { if ($type === 'hasAndBelongsToMany') {
if (isset($association['with'])) if (isset($association['with']))
$Link =& $_Model->{$association['with']}; $linkClass = $association['with'];
else else
$Link =& $_Model->{Inflector::classify($association['joinTable'])}; $linkClass = Inflector::classify($association['joinTable']);
$Link =& $_Model->{$linkClass};
if (isset($options['linkalias'])) if (isset($options['linkalias']))
$linkAlias = $options['linkalias']; $linkAlias = $options['linkalias'];
@@ -246,8 +253,8 @@ class LinkableBehavior extends ModelBehavior {
$referenceLink = $Link->escapeField(Inflector::underscore($Reference->alias) . '_id', $linkAlias); $referenceLink = $Link->escapeField(Inflector::underscore($Reference->alias) . '_id', $linkAlias);
// Get the primary key from the tables we're joining. // Get the primary key from the tables we're joining.
$referenceKey = $Reference->escapeField(null, $options['reference']['alias']); $referenceKey = $Reference->escapeField(null, $referenceAlias);
$modelKey = $_Model->escapeField(null, $options['alias']); $modelKey = $_Model->escapeField(null, $modelAlias);
// Join the linkage table to our model. We'll use an inner join, // Join the linkage table to our model. We'll use an inner join,
// as the whole purpose of the linkage table is to make this // as the whole purpose of the linkage table is to make this
@@ -257,19 +264,14 @@ class LinkableBehavior extends ModelBehavior {
// They control that with the 'type' parameter which will be at // They control that with the 'type' parameter which will be at
// the top level join. // the top level join.
$options['joins'][] = array('type' => 'INNER', $options['joins'][] = array('type' => 'INNER',
'alias' => $options['alias'], 'alias' => $modelAlias,
'conditions' => "{$modelKey} = {$modelLink}", 'conditions' => "{$modelKey} = {$modelLink}",
'table' => $db->fullTableName($_Model, true)); 'table' => $db->fullTableName($_Model, true));
// Now for the top level join. This will be added into the list // Now for the top level join. This will be added into the list
// of joins down below, outside of the HABTM specific code. // of joins down below, outside of the HABTM specific code.
if (!isset($options['fields']) || !is_array($options['fields'])) $options['class'] = $linkClass;
$efields = $db->fields($_Model, $options['alias']);
elseif (!empty($options['fields']))
$efields = $db->fields($_Model, $options['alias'], $options['fields']);
$options['alias'] = $linkAlias; $options['alias'] = $linkAlias;
$options['fields'] = array();
$options['table'] = $Link->getDataSource()->fullTableName($Link); $options['table'] = $Link->getDataSource()->fullTableName($Link);
$options['conditions'][] = "{$referenceLink} = {$referenceKey}"; $options['conditions'][] = "{$referenceLink} = {$referenceKey}";
} }
@@ -302,15 +304,15 @@ class LinkableBehavior extends ModelBehavior {
} }
if (!isset($options['fields']) || !is_array($options['fields'])) if (!isset($options['fields']) || !is_array($options['fields']))
$efields = $db->fields($_Model, $options['alias']); $options['fields'] = $db->fields($_Model, $modelAlias);
elseif (!empty($options['fields'])) elseif (!empty($options['fields']))
$efields = $db->fields($_Model, $options['alias'], $options['fields']); $options['fields'] = $db->fields($_Model, $modelAlias, $options['fields']);
$query['fields'] = array_merge($query['fields'], $efields, $query['fields'] = array_merge($query['fields'], $options['fields'],
(empty($association['fields']) (empty($association['fields'])
? array() : $db->fields($_Model, $options['alias'], $association['fields']))); ? array() : $db->fields($_Model, $modelAlias, $association['fields'])));
/* pr(array('checkpoint' => 'Model Work Complete', compact('options'))); */ /* pr(array('checkpoint' => 'Model Work Complete', compact('options', 'modelClass', 'modelAlias'))); */
$options[$this->_key] = am($options[$this->_key], array_diff_key($options, $optionsKeys)); $options[$this->_key] = am($options[$this->_key], array_diff_key($options, $optionsKeys));
$options = array_intersect_key($options, $optionsKeys); $options = array_intersect_key($options, $optionsKeys);
@@ -319,8 +321,8 @@ class LinkableBehavior extends ModelBehavior {
array('defaults' => array('defaults' =>
array_merge($defaults, array_merge($defaults,
array('reference' => array('reference' =>
array('class' => $options['class'], array('class' => $modelClass,
'alias' => $options['alias'])))); 'alias' => $modelAlias))));
} }
$query['joins'][] = array_intersect_key($options, array('type' => true, 'alias' => true, 'table' => true, 'joins' => true, 'conditions' => true)); $query['joins'][] = array_intersect_key($options, array('type' => true, 'alias' => true, 'table' => true, 'joins' => true, 'conditions' => true));
} }