Adding join table selects (MySQL-only so far), findBy/findAllBy magic method enhancements (Ticket #412)

git-svn-id: https://svn.cakephp.org/repo/branches/1.2.x.x@3200 3807eeeb-6ff5-0310-8944-8be069107fe0
This commit is contained in:
nate 2006-07-04 01:29:48 +00:00
parent 4f425785d0
commit 86fc29facb
5 changed files with 135 additions and 41 deletions

View file

@ -449,6 +449,48 @@
}
}
}
/**
* Normalizes a string or array list
*
* @param mixed $list
* @param boolean $assoc If true, $list will be converted to an associative array
* @param string $sep If $list is a string, it will be split into an array with $sep
* @param boolean $trim If true, separated strings will be trimmed
* @return array
*/
function normalizeList($list, $assoc = true, $sep = ',', $trim = true) {
if (is_string($list)) {
$list = explode($sep, $list);
if ($trim) {
$list = array_map('trim', $list);
}
return normalizeList($list);
} elseif (is_array($list)) {
$keys = array_keys($list);
$count = count($keys);
$numeric = true;
if (!$assoc) {
for ($i = 0; $i < $count; $i++) {
if (!is_int($keys[$i])) {
$numeric = false;
break;
}
}
}
if (!$numeric || $assoc) {
for ($i = 0; $i < $count; $i++) {
if (is_int($keys[$i])) {
$newList[$list[$keys[$i]]] = null;
} else {
$newList[$keys[$i]] = $list[$keys[$i]];
}
}
$list = $newList;
}
}
return $list;
}
/**
* Prints out debug information about given variable.
*
@ -798,6 +840,11 @@
* @return mixed The contents of the temporary file.
*/
function cache($path, $data = null, $expires = '+1 day', $target = 'cache') {
if (defined('DISABLE_CACHE')) {
return null;
}
if (!is_numeric($expires)) {
$expires = strtotime($expires);
}

View file

@ -167,46 +167,66 @@ class DboSource extends DataSource {
$limit = null;
$page = null;
$recursive = null;
if (count($args) == 1) {
return $this->fetchAll($args[0]);
} elseif (count($args) > 1 && (strpos(low($args[0]), 'findby') === 0 || strpos(low($args[0]), 'findallby') === 0)) {
if (isset($args[1][1])) {
$fields = $args[1][1];
}
if (isset($args[1][2])) {
$order = $args[1][2];
}
$params = $args[1];
if (strpos(strtolower($args[0]), 'findby') === 0) {
$all = false;
$field = Inflector::underscore(preg_replace('/findBy/i', '', $args[0]));
if (isset($args[1][3])) {
$recursive = $args[1][3];
}
} else {
$all = true;
$field = Inflector::underscore(preg_replace('/findAllBy/i', '', $args[0]));
if (isset($args[1][3])) {
$limit = $args[1][3];
}
if (isset($args[1][4])) {
$page = $args[1][4];
}
if (isset($args[1][5])) {
$recursive = $args[1][5];
}
}
$query = array($args[2]->name . '.' . $field => $args[1][0]);
$or = (strpos($field, '_or_') !== false);
if ($or) {
$field = explode('_or_', $field);
} else {
$field = explode('_and_', $field);
}
$off = count($field) - 1;
if (isset($params[1 + $off])) {
$fields = $params[1 + $off];
}
if (isset($params[2 + $off])) {
$order = $params[2 + $off];
}
$c = 0;
$query = array();
foreach ($field as $f) {
$query[$args[2]->name . '.' . $f] = $params[$c++];
}
if ($or) {
$query = array('OR' => $query);
}
if ($all) {
if (isset($params[3 + $off])) {
$limit = $params[3 + $off];
}
if (isset($params[4 + $off])) {
$page = $params[4 + $off];
}
if (isset($params[5 + $off])) {
$recursive = $params[5 + $off];
}
return $args[2]->findAll($query, $fields, $order, $limit, $page, $recursive);
} else {
if (isset($params[3 + $off])) {
$recursive = $params[3 + $off];
}
return $args[2]->find($query, $fields, $order, $recursive);
}
} else {
@ -1012,11 +1032,31 @@ class DboSource extends DataSource {
$sql .= $limit;
}
$sql .= ' ' . join(', ', $this->fields($linkModel, $alias, $assocData['fields']));
$joinFields = array();
if (isset($assocData['with'])) {
$joinName = array_keys($assocData['with']);
$joinFields = $assocData['with'][$joinName[0]];
if (is_array($joinFields) && !empty($joinFields)) {
$joinFields = $this->fields($linkModel, $joinName[0], $joinFields);
} else {
$joinFields = array($this->name($joinName[0]) . '.*');
}
}
$sql .= ' ' . join(', ', am($this->fields($linkModel, $alias, $assocData['fields']), $joinFields));
$sql .= ' FROM ' . $this->fullTableName($linkModel) . ' ' . $this->alias . $this->name($alias);
$sql .= ' JOIN ' . $joinTbl . ' ON ' . $joinTbl;
$sql .= ' JOIN ' . $joinTbl;
$joinAssoc = $joinTbl;
if (isset($assocData['with'])) {
$joinAssoc = $joinName[0];
$sql .= $this->alias . $this->name($joinAssoc);
}
$sql .= ' ON ' . $this->name($joinAssoc);
$sql .= '.' . $this->name($assocData['foreignKey']) . ' = {$__cakeID__$}';
$sql .= ' AND ' . $joinTbl . '.' . $this->name($assocData['associationForeignKey']);
$sql .= ' AND ' . $this->name($joinAssoc) . '.' . $this->name($assocData['associationForeignKey']);
$sql .= ' = ' . $this->name($alias) . '.' . $this->name($linkModel->primaryKey);
$sql .= $this->conditions($assocData['conditions']);

View file

@ -458,13 +458,13 @@ class Model extends Object{
* @param string $type Type of assocation
* @access private
*/
function __constructLinkedModel($assoc, $className) {
function __constructLinkedModel($assoc, $className, $id = false, $table = null, $ds = null) {
$colKey = Inflector::underscore($className);
if (ClassRegistry::isKeySet($colKey)) {
$this->{$className} =& ClassRegistry::getObject($colKey);
} else {
$this->{$className} =& new $className();
$this->{$className} =& new $className($id, $table, $ds);
}
$this->alias[$assoc] = $this->{$className}->table;
@ -478,7 +478,7 @@ class Model extends Object{
* @access private
*/
function __generateAssociation($type) {
foreach($this->{$type}as $assocKey => $assocData) {
foreach($this->{$type} as $assocKey => $assocData) {
$class = $assocKey;
if (isset($this->{$type}[$assocKey]['className']) && $this->{$type}[$assocKey]['className'] !== null) {
@ -515,6 +515,8 @@ class Model extends Object{
case 'className':
$data = $class;
break;
} elseif ($key == 'with') {
$this->{$type}[$assocKey][$key] = normalizeList($this->{$type}[$assocKey][$key]);
}
$this->{$type}[$assocKey][$key] = $data;

View file

@ -45,7 +45,7 @@ uses('class_registry', 'validators');
* @package cake
* @subpackage cake.cake.libs.model
*/
class Model extends Object{
class Model extends Object {
/**
* The name of the DataSource connection that this Model uses
@ -253,11 +253,11 @@ class Model extends Object{
* @var array
*/
var $__associationKeys = array(
'belongsTo' => array('className', 'conditions', 'order', 'foreignKey', 'counterCache'),
'hasOne' => array('className', 'conditions', 'order', 'foreignKey', 'dependent'),
'hasMany' => array('className', 'conditions', 'order', 'foreignKey', 'fields', 'dependent', 'exclusive', 'finderQuery', 'counterQuery'),
'hasAndBelongsToMany' => array('className', 'joinTable', 'fields', 'foreignKey', 'associationForeignKey', 'conditions', 'order', 'uniq', 'finderQuery', 'deleteQuery', 'insertQuery')
);
'belongsTo' => array('className', 'conditions', 'order', 'foreignKey', 'counterCache'),
'hasOne' => array('className', 'conditions', 'order', 'foreignKey', 'dependent'),
'hasMany' => array('className', 'conditions', 'order', 'foreignKey', 'fields', 'dependent', 'exclusive', 'finderQuery', 'counterQuery'),
'hasAndBelongsToMany' => array('className', 'joinTable', 'fields', 'foreignKey', 'associationForeignKey', 'conditions', 'order', 'uniq', 'finderQuery', 'deleteQuery', 'insertQuery', 'with')
);
/**
* Holds provided/generated association key names and other data for all associations
@ -301,11 +301,11 @@ class Model extends Object{
parent::__construct();
if ($this->name === null) {
$this->name = get_class($this);
$this->name = get_class($this);
}
if ($this->primaryKey === null) {
$this->primaryKey = 'id';
$this->primaryKey = 'id';
}
$this->currentModel = Inflector::underscore($this->name);
@ -450,15 +450,18 @@ class Model extends Object{
* @param string $assoc
* @param string $className Class name
* @param string $type Type of assocation
* @param mixed $id Primary key ID of linked model
* @param string $table Database table associated with linked model
* @param string $ds Name of DataSource the model should be bound to
* @access private
*/
function __constructLinkedModel($assoc, $className) {
function __constructLinkedModel($assoc, $className, $id = false, $table = null, $ds = null) {
$colKey = Inflector::underscore($className);
if (ClassRegistry::isKeySet($colKey)) {
$this->{$className} = ClassRegistry::getObject($colKey);
} else {
$this->{$className} = new $className();
$this->{$className} = new $className($id, $table, $ds);
}
$this->alias[$assoc] = $this->{$className}->table;
@ -472,7 +475,7 @@ class Model extends Object{
* @access private
*/
function __generateAssociation($type) {
foreach($this->{$type}as $assocKey => $assocData) {
foreach($this->{$type} as $assocKey => $assocData) {
$class = $assocKey;
if (isset($this->{$type}[$assocKey]['className']) && $this->{$type}[$assocKey]['className'] !== null) {
@ -512,6 +515,8 @@ class Model extends Object{
}
$this->{$type}[$assocKey][$key] = $data;
} elseif ($key == 'with') {
$this->{$type}[$assocKey][$key] = normalizeList($this->{$type}[$assocKey][$key]);
}
if ($key == 'foreignKey' && !isset($this->keyToTable[$this->{$type}[$assocKey][$key]])) {

View file

@ -813,7 +813,7 @@ class AjaxHelper extends Helper {
$data[] = $key . ':"' . rawurlencode($val) . '"';
}
}
$out = 'var __ajaxUpdater__ = {' . join(', ', $data) . '};' . "\n";
$out = 'var __ajaxUpdater__ = {' . join(", \n", $data) . '};' . "\n";
$out .= 'for (n in __ajaxUpdater__) { if (typeof __ajaxUpdater__[n] == "string" && $(n)) Element.update($(n), unescape(__ajaxUpdater__[n])); }';
@ob_end_clean();