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']);
}
$iterations = Set::normalize($iterator);
/* pr(compact('iterations')); */
/* pr(array('checkpoint' => 'Iterations', compact('iterations'))); */
foreach ($iterations as $alias => $options) {
$efields = array();
if (is_null($options)) {
$options = array();
}
@@ -143,18 +142,24 @@ class LinkableBehavior extends ModelBehavior {
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;
} elseif (!empty($options['table']) && empty($options['class'])) {
$options['class'] = Inflector::classify($options['table']);
}
/* pr(compact('alias', 'options')); */
$_Model =& ClassRegistry::init($options['class']); // the incoming model to be linked in query
$Reference =& ClassRegistry::init($options['reference']['class']); // the already in query model that links to $_Model
/* pr("_Model: {$options['alias']} : {$options['class']}" . */
/* " ({$_Model->alias} : {$_Model->name})"); */
/* pr("Reference: {$options['reference']['alias']} : {$options['reference']['class']}" . */
/* " ({$Reference->alias} : {$Reference->name})"); */
/* pr(array('checkpoint' => 'Begin Model Work', compact('alias', 'options'))); */
$modelClass = $options['class'];
$modelAlias = $options['alias'];
$referenceClass = $options['reference']['class'];
$referenceAlias = $options['reference']['alias'];
$_Model =& ClassRegistry::init($modelClass); // the incoming model to be linked in query
$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();
$associatedThroughReference = 0;
@@ -185,39 +190,41 @@ class LinkableBehavior extends ModelBehavior {
$_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
if (($type === 'hasMany' || $type === 'hasOne') ^ $associatedThroughReference) {
$primaryAlias = $options['reference']['alias'];
$foreignAlias = $options['alias'];
$primaryAlias = $referenceAlias;
$foreignAlias = $modelAlias;
$primaryModel = $Reference;
$foreignModel = $_Model;
} else {
$primaryAlias = $options['alias'];
$foreignAlias = $options['reference']['alias'];
$primaryAlias = $modelAlias;
$foreignAlias = $referenceAlias;
$primaryModel = $_Model;
$foreignModel = $Reference;
}
/* pr("primaryModel: $primaryModel->name ($primaryModel->alias)"); */
/* pr("foreignModel: $foreignModel->name ($foreignModel->alias)"); */
/* pr($type); */
/* pr($association); */
if ($associatedThroughReference)
$associationAlias = $referenceAlias;
else
$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 ($type === 'hasAndBelongsToMany') {
if (isset($association['with']))
$Link =& $_Model->{$association['with']};
$linkClass = $association['with'];
else
$Link =& $_Model->{Inflector::classify($association['joinTable'])};
$linkClass = Inflector::classify($association['joinTable']);
$Link =& $_Model->{$linkClass};
if (isset($options['linkalias']))
$linkAlias = $options['linkalias'];
@@ -246,8 +253,8 @@ class LinkableBehavior extends ModelBehavior {
$referenceLink = $Link->escapeField(Inflector::underscore($Reference->alias) . '_id', $linkAlias);
// Get the primary key from the tables we're joining.
$referenceKey = $Reference->escapeField(null, $options['reference']['alias']);
$modelKey = $_Model->escapeField(null, $options['alias']);
$referenceKey = $Reference->escapeField(null, $referenceAlias);
$modelKey = $_Model->escapeField(null, $modelAlias);
// 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
@@ -257,19 +264,14 @@ class LinkableBehavior extends ModelBehavior {
// They control that with the 'type' parameter which will be at
// the top level join.
$options['joins'][] = array('type' => 'INNER',
'alias' => $options['alias'],
'conditions' => "{$modelKey} = {$modelLink}",
'table' => $db->fullTableName($_Model, true));
'alias' => $modelAlias,
'conditions' => "{$modelKey} = {$modelLink}",
'table' => $db->fullTableName($_Model, true));
// Now for the top level join. This will be added into the list
// of joins down below, outside of the HABTM specific code.
if (!isset($options['fields']) || !is_array($options['fields']))
$efields = $db->fields($_Model, $options['alias']);
elseif (!empty($options['fields']))
$efields = $db->fields($_Model, $options['alias'], $options['fields']);
$options['class'] = $linkClass;
$options['alias'] = $linkAlias;
$options['fields'] = array();
$options['table'] = $Link->getDataSource()->fullTableName($Link);
$options['conditions'][] = "{$referenceLink} = {$referenceKey}";
}
@@ -302,15 +304,15 @@ class LinkableBehavior extends ModelBehavior {
}
if (!isset($options['fields']) || !is_array($options['fields']))
$efields = $db->fields($_Model, $options['alias']);
$options['fields'] = $db->fields($_Model, $modelAlias);
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'])
? 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 = array_intersect_key($options, $optionsKeys);
@@ -319,8 +321,8 @@ class LinkableBehavior extends ModelBehavior {
array('defaults' =>
array_merge($defaults,
array('reference' =>
array('class' => $options['class'],
'alias' => $options['alias']))));
array('class' => $modelClass,
'alias' => $modelAlias))));
}
$query['joins'][] = array_intersect_key($options, array('type' => true, 'alias' => true, 'table' => true, 'joins' => true, 'conditions' => true));
}