public function relationship($class, $type, $name, array $config = array())
{
$fieldName = $this->relationFieldName($type, $name);
$config += compact('name', 'type', 'key', 'fieldName');
$config['from'] = $class;
return $this->_instance('relationship', $config + array('strategy' => function ($rel) use($config, $class, $name, $type) {
if (isset($config['key'])) {
return array();
}
$link = null;
$hasLink = isset($config['link']);
$result = array();
$to = $rel->to();
$local = $class::key();
$className = $class::meta('name');
$keys = array(array($class, $name), array($class, Inflector::singularize($name)), array($to, Inflector::singularize($className)), array($to, $className));
foreach ($keys as $map) {
list($on, $key) = $map;
$key = lcfirst(Inflector::camelize($key));
if (!$on::hasField($key)) {
continue;
}
$join = $on === $class ? array($key => $on::key()) : array($local => $key);
$result['key'] = $join;
if (isset($config['link'])) {
return $result;
}
$fieldType = $on::schema()->type($key);
if ($fieldType === 'id' || $fieldType === 'MongoId') {
$isArray = $on::schema()->is('array', $key);
$link = $isArray ? $rel::LINK_KEY_LIST : $rel::LINK_KEY;
break;
}
}
if (!$link && !$hasLink) {
$link = $type === "belongsTo" ? $rel::LINK_CONTAINED : $rel::LINK_EMBEDDED;
}
return $result + ($hasLink ? array() : compact('link'));
}));
}