2005-07-04 01:07:14 +00:00
|
|
|
<?php
|
2005-08-21 06:49:02 +00:00
|
|
|
/* SVN FILE: $Id$ */
|
2005-07-04 04:30:45 +00:00
|
|
|
/**
|
2005-09-17 02:22:07 +00:00
|
|
|
* Library of array functions for Cake.
|
2005-12-27 03:33:44 +00:00
|
|
|
*
|
2005-09-17 02:22:07 +00:00
|
|
|
* Internal use only.
|
I've merged in Olle's changes.
Larry, I've merged in _some_ of your changes, I'll merge in the scaffolding and joins code when you tell me it's ready. But I don't want to break how the Controller class works, can't we really do without the constructClasses() method call? Which reminds me, with your joins code, will we be able to use constructs like $user->post->findAll() and $user->post->save()?
Also, what are your changes to the DBO_MySQL class? I mean the mysqlResultSet(), and fetchResult() methods. I didn't see any MySQL-specific code inside them, perhaps they belong to the DBO class itself?
- I've changed the headers on user-editable files in /app and /config. I hope they will constitute a compromise between readability and legality. I've left file Id, copyright, and licence notices.
- /libs/basic.php::uses() function logs included files in global $loaded. Please, consider it a note to myself. Also, I've moved the NeatArray class out of the /libs/basics.php (into /libs/neat_array.php).
- Some cleanups in the Controller and Dispatcher classes.
- DBO::Prepare() accepts strings _and_ arrays now. It's a step towards a unified params theory.
- I think I've added some comments to DBO sub-classes, but it might have been Olle.
- A fix in Model class (findAll didn't work properly)
- Object's constructor sets $this->db to &DBO, which means all Object-descendand classes have default access to the database if it's connected. We need to clean up the code accordingly (some classes set their own $this->db references).
git-svn-id: https://svn.cakephp.org/repo/trunk/cake@236 3807eeeb-6ff5-0310-8944-8be069107fe0
2005-06-05 11:05:24 +00:00
|
|
|
*
|
2005-08-21 06:49:02 +00:00
|
|
|
* PHP versions 4 and 5
|
2005-07-04 04:30:45 +00:00
|
|
|
*
|
2005-08-21 06:49:02 +00:00
|
|
|
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
|
2006-05-26 05:29:17 +00:00
|
|
|
* Copyright (c) 2006, Cake Software Foundation, Inc.
|
|
|
|
* 1785 E. Sahara Avenue, Suite 490-204
|
|
|
|
* Las Vegas, Nevada 89104
|
2005-08-21 06:49:02 +00:00
|
|
|
*
|
2005-12-23 21:57:26 +00:00
|
|
|
* Licensed under The MIT License
|
|
|
|
* Redistributions of files must retain the above copyright notice.
|
2005-07-04 04:30:45 +00:00
|
|
|
*
|
2005-12-27 03:33:44 +00:00
|
|
|
* @filesource
|
2006-05-26 05:29:17 +00:00
|
|
|
* @copyright Copyright (c) 2006, Cake Software Foundation, Inc.
|
|
|
|
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
|
|
|
|
* @package cake
|
|
|
|
* @subpackage cake.cake.libs
|
|
|
|
* @since CakePHP v 0.2.9
|
|
|
|
* @version $Revision$
|
|
|
|
* @modifiedby $LastChangedBy$
|
|
|
|
* @lastmodified $Date$
|
|
|
|
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
|
2005-07-04 04:30:45 +00:00
|
|
|
*/
|
|
|
|
/**
|
2005-09-17 02:22:07 +00:00
|
|
|
* Class used for internal manipulation of multi-dimensional arrays (arrays of arrays).
|
2005-08-21 06:49:02 +00:00
|
|
|
*
|
|
|
|
* Long description for class
|
2005-07-04 04:30:45 +00:00
|
|
|
*
|
2006-05-26 05:29:17 +00:00
|
|
|
* @package cake
|
|
|
|
* @subpackage cake.cake.libs
|
2005-07-04 04:30:45 +00:00
|
|
|
*/
|
2006-05-26 05:29:17 +00:00
|
|
|
class NeatArray{
|
2005-12-27 03:33:44 +00:00
|
|
|
/**
|
|
|
|
* Value of NeatArray.
|
|
|
|
*
|
|
|
|
* @var array
|
|
|
|
* @access public
|
|
|
|
*/
|
2006-05-26 05:29:17 +00:00
|
|
|
var $value;
|
2005-12-27 03:33:44 +00:00
|
|
|
/**
|
|
|
|
* Constructor. Defaults to an empty array.
|
|
|
|
*
|
|
|
|
* @param array $value
|
|
|
|
* @access public
|
|
|
|
* @uses NeatArray::value
|
|
|
|
*/
|
2006-05-26 05:29:17 +00:00
|
|
|
function NeatArray($value = array()) {
|
|
|
|
$this->value = $value;
|
|
|
|
}
|
2005-12-27 03:33:44 +00:00
|
|
|
/**
|
|
|
|
* Finds and returns records with $fieldName equal to $value from this NeatArray.
|
|
|
|
*
|
|
|
|
* @param string $fieldName
|
|
|
|
* @param string $value
|
|
|
|
* @return mixed
|
|
|
|
* @access public
|
|
|
|
* @uses NeatArray::value
|
|
|
|
*/
|
2006-05-26 05:29:17 +00:00
|
|
|
function findIn($fieldName, $value) {
|
|
|
|
if (!is_array($this->value)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
$out = false;
|
|
|
|
$keys = array_keys($this->value);
|
|
|
|
$count = sizeof($keys);
|
|
|
|
|
|
|
|
for($i = 0; $i < $count; $i++) {
|
|
|
|
if (isset($this->value[$keys[$i]][$fieldName]) && ($this->value[$keys[$i]][$fieldName] == $value))
|
|
|
|
{
|
|
|
|
$out[$keys[$i]] = $this->value[$keys[$i]];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return $out;
|
|
|
|
}
|
2005-12-27 03:33:44 +00:00
|
|
|
/**
|
|
|
|
* Checks if $this->value is an array, and removes all empty elements.
|
|
|
|
*
|
|
|
|
* @access public
|
|
|
|
* @uses NeatArray::value
|
|
|
|
*/
|
2006-05-26 05:29:17 +00:00
|
|
|
function cleanup() {
|
|
|
|
$out = is_array($this->value) ? array(): null;
|
|
|
|
foreach($this->value as $k => $v) {
|
|
|
|
if ($v == "0") {
|
|
|
|
$out[$k] = $v;
|
|
|
|
} elseif ($v) {
|
|
|
|
$out[$k] = $v;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
$this->value=$out;
|
|
|
|
}
|
2005-12-27 03:33:44 +00:00
|
|
|
/**
|
|
|
|
* Adds elements from given array to itself.
|
|
|
|
*
|
|
|
|
* @param string $value
|
|
|
|
* @return bool
|
|
|
|
* @access public
|
|
|
|
* @uses NeatArray::value
|
|
|
|
*/
|
2006-05-26 05:29:17 +00:00
|
|
|
function add($value) {
|
|
|
|
return ($this->value = $this->plus($value)) ? true : false;
|
|
|
|
}
|
2005-12-27 03:33:44 +00:00
|
|
|
/**
|
|
|
|
* Returns itself merged with given array.
|
|
|
|
*
|
|
|
|
* @param array $value Array to add to NeatArray.
|
|
|
|
* @return array
|
|
|
|
* @access public
|
|
|
|
* @uses NeatArray::value
|
|
|
|
*/
|
2006-05-26 05:29:17 +00:00
|
|
|
function plus($value) {
|
|
|
|
$merge = array_merge($this->value, (is_array($value) ? $value : array($value)));
|
|
|
|
return $merge;
|
|
|
|
}
|
2005-12-27 03:33:44 +00:00
|
|
|
/**
|
|
|
|
* Counts repeating strings and returns an array of totals.
|
|
|
|
*
|
|
|
|
* @param int $sortedBy A value of 1 sorts by values, a value of 2 sorts by keys. Defaults to null (no sorting).
|
|
|
|
* @return array
|
|
|
|
* @access public
|
|
|
|
* @uses NeatArray::value
|
|
|
|
*/
|
2006-05-26 05:29:17 +00:00
|
|
|
function totals($sortedBy = 1, $reverse = true) {
|
|
|
|
$out = array();
|
|
|
|
foreach($this->value as $val) {
|
|
|
|
isset($out[$val]) ? $out[$val]++ : $out[$val] = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($sortedBy == 1) {
|
|
|
|
$reverse ? arsort($out, SORT_NUMERIC) : asort($out, SORT_NUMERIC);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($sortedBy == 2) {
|
|
|
|
$reverse ? krsort($out, SORT_STRING) : ksort($out, SORT_STRING);
|
|
|
|
}
|
|
|
|
return $out;
|
|
|
|
}
|
2005-12-27 03:33:44 +00:00
|
|
|
/**
|
|
|
|
* Performs an array_filter() on the contents of this NeatArray.
|
|
|
|
*
|
|
|
|
* @param string $with Name of callback function to perform on each element of this NeatArray.
|
|
|
|
* @return array
|
|
|
|
*/
|
2006-05-26 05:29:17 +00:00
|
|
|
function filter($with) {
|
|
|
|
return $this->value = array_filter($this->value, $with);
|
|
|
|
}
|
2005-12-27 03:33:44 +00:00
|
|
|
/**
|
|
|
|
* Passes each of its values through a specified function or method.
|
|
|
|
* Think of PHP's {@link http://php.net/array_walk array_walk()}.
|
|
|
|
*
|
|
|
|
* @param string $with Name of callback function
|
|
|
|
* @return array Returns value of NeatArray::value
|
|
|
|
* @access public
|
|
|
|
* @uses NeatArray::value
|
|
|
|
*/
|
2006-05-26 05:29:17 +00:00
|
|
|
function walk($with) {
|
|
|
|
array_walk($this->value, $with);
|
|
|
|
return $this->value;
|
|
|
|
}
|
2005-12-27 03:33:44 +00:00
|
|
|
/**
|
|
|
|
* Apply $template to all elements of this NeatArray, and return the array itself.
|
|
|
|
*
|
|
|
|
* @param string $template {@link http://php.net/sprintf sprintf()}-compatible string to be applied to all values of this NeatArray.
|
|
|
|
* @return array
|
|
|
|
*/
|
2006-05-26 05:29:17 +00:00
|
|
|
function sprintf($template) {
|
|
|
|
$count = count($this->value);
|
|
|
|
for($ii = 0; $ii < $count; $ii++) {
|
|
|
|
$this->value[$ii] = sprintf($template, $this->value[$ii]);
|
|
|
|
}
|
|
|
|
return $this->value;
|
|
|
|
}
|
2005-12-27 03:33:44 +00:00
|
|
|
/**
|
|
|
|
* Extracts a value from all array items.
|
|
|
|
*
|
|
|
|
* @return array
|
|
|
|
* @access public
|
|
|
|
* @uses NeatArray::value
|
|
|
|
*/
|
2006-05-26 05:29:17 +00:00
|
|
|
function extract($name) {
|
|
|
|
$out = array();
|
|
|
|
foreach($this->value as $val) {
|
|
|
|
if (isset($val[$name]))
|
|
|
|
$out[]=$val[$name];
|
|
|
|
}
|
|
|
|
return $out;
|
|
|
|
}
|
2005-12-27 03:33:44 +00:00
|
|
|
/**
|
|
|
|
* Returns a list of unique elements.
|
|
|
|
*
|
|
|
|
* @return array
|
|
|
|
*/
|
2006-05-26 05:29:17 +00:00
|
|
|
function unique() {
|
|
|
|
$unique = array_unique($this->value);
|
|
|
|
return $unique;
|
|
|
|
}
|
2005-12-27 03:33:44 +00:00
|
|
|
/**
|
|
|
|
* Removes duplicate elements from the value and returns it.
|
|
|
|
*
|
|
|
|
* @return array
|
|
|
|
*/
|
2006-05-26 05:29:17 +00:00
|
|
|
function makeUnique() {
|
|
|
|
return $this->value = array_unique($this->value);
|
|
|
|
}
|
2005-12-27 03:33:44 +00:00
|
|
|
/**
|
|
|
|
* Joins an array with myself using a key (like a join between database tables).
|
|
|
|
*
|
|
|
|
* Example:
|
|
|
|
*
|
2006-05-26 05:29:17 +00:00
|
|
|
* $alice = array('id'=>'1', 'name'=>'Alice');
|
|
|
|
* $bob = array('id'=>'2', 'name'=>'Bob');
|
2005-12-27 03:33:44 +00:00
|
|
|
*
|
2006-05-26 05:29:17 +00:00
|
|
|
* $users = new NeatArray(array($alice, $bob));
|
2005-12-27 03:33:44 +00:00
|
|
|
*
|
2006-05-26 05:29:17 +00:00
|
|
|
* $born = array
|
|
|
|
* (
|
|
|
|
* array('user_id'=>'1', 'born'=>'1980'),
|
|
|
|
* array('user_id'=>'2', 'born'=>'1976')
|
|
|
|
* );
|
2005-12-27 03:33:44 +00:00
|
|
|
*
|
2006-05-26 05:29:17 +00:00
|
|
|
* $users->joinWith($born, 'id', 'user_id');
|
2005-12-27 03:33:44 +00:00
|
|
|
*
|
|
|
|
* Result:
|
|
|
|
*
|
2006-05-26 05:29:17 +00:00
|
|
|
* $users->value == array
|
|
|
|
* (
|
|
|
|
* array('id'=>'1', 'name'=>'Alice', 'born'=>'1980'),
|
|
|
|
* array('id'=>'2', 'name'=>'Bob', 'born'=>'1976')
|
|
|
|
* );
|
2005-12-27 03:33:44 +00:00
|
|
|
*
|
|
|
|
*
|
|
|
|
* @param array $his The array to join with myself.
|
|
|
|
* @param string $onMine Key to use on myself.
|
|
|
|
* @param string $onHis Key to use on him.
|
|
|
|
* @return array
|
|
|
|
*/
|
2006-05-26 05:29:17 +00:00
|
|
|
function joinWith($his, $onMine, $onHis = null) {
|
|
|
|
if (empty($onHis)) {
|
|
|
|
$onHis = $onMine;
|
|
|
|
}
|
|
|
|
$his = new NeatArray($his);
|
|
|
|
$out = array();
|
|
|
|
|
|
|
|
foreach($this->value as $key => $val) {
|
|
|
|
if ($fromHis = $his->findIn($onHis, $val[$onMine])) {
|
|
|
|
list($fromHis) = array_values($fromHis);
|
|
|
|
$out[$key] = array_merge($val, $fromHis);
|
|
|
|
} else {
|
|
|
|
$out[$key] = $val;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return $this->value = $out;
|
|
|
|
}
|
2005-12-27 03:33:44 +00:00
|
|
|
/**
|
|
|
|
* Enter description here...
|
|
|
|
* @todo Explain this function. almost looks like it creates a tree
|
|
|
|
*
|
|
|
|
* @param string $root
|
|
|
|
* @param string $idKey
|
|
|
|
* @param string $parentIdKey
|
|
|
|
* @param string $childrenKey
|
|
|
|
* @return array
|
|
|
|
*/
|
2006-05-26 05:29:17 +00:00
|
|
|
function threaded($root = null, $idKey = 'id', $parentIdKey = 'parent_id', $childrenKey = 'children') {
|
|
|
|
$out = array();
|
|
|
|
$sizeof = sizeof($this->value);
|
|
|
|
|
|
|
|
for($ii = 0; $ii < $sizeof; $ii++) {
|
|
|
|
if ($this->value[$ii][$parentIdKey] == $root) {
|
|
|
|
$tmp = $this->value[$ii];
|
|
|
|
$tmp[$childrenKey]=isset($this->value[$ii][$idKey])
|
|
|
|
? $this->threaded($this->value[$ii][$idKey], $idKey, $parentIdKey, $childrenKey) : null;
|
|
|
|
$out[] = $tmp;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return $out;
|
|
|
|
}
|
2005-12-27 03:33:44 +00:00
|
|
|
/**
|
|
|
|
* Array multi search
|
|
|
|
*
|
|
|
|
* @param string $search_value
|
|
|
|
* @param array $the_array
|
|
|
|
* @return array
|
|
|
|
* @link http://php.net/array_search#47116
|
|
|
|
*/
|
2006-05-26 05:29:17 +00:00
|
|
|
function multi_search($search_value, $the_array = null) {
|
|
|
|
if ($the_array == null) {
|
|
|
|
$the_array = $this->value;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (is_array($the_array)) {
|
|
|
|
foreach($the_array as $key => $value) {
|
|
|
|
$result = $this->multi_search($search_value, $value);
|
|
|
|
|
|
|
|
if (is_array($result)) {
|
|
|
|
$return = $result;
|
|
|
|
array_unshift($return, $key);
|
|
|
|
return $return;
|
|
|
|
} elseif ($result == true) {
|
|
|
|
$return[]=$key;
|
|
|
|
return $return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
} else {
|
|
|
|
if ($search_value == $the_array) {
|
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
I've merged in Olle's changes.
Larry, I've merged in _some_ of your changes, I'll merge in the scaffolding and joins code when you tell me it's ready. But I don't want to break how the Controller class works, can't we really do without the constructClasses() method call? Which reminds me, with your joins code, will we be able to use constructs like $user->post->findAll() and $user->post->save()?
Also, what are your changes to the DBO_MySQL class? I mean the mysqlResultSet(), and fetchResult() methods. I didn't see any MySQL-specific code inside them, perhaps they belong to the DBO class itself?
- I've changed the headers on user-editable files in /app and /config. I hope they will constitute a compromise between readability and legality. I've left file Id, copyright, and licence notices.
- /libs/basic.php::uses() function logs included files in global $loaded. Please, consider it a note to myself. Also, I've moved the NeatArray class out of the /libs/basics.php (into /libs/neat_array.php).
- Some cleanups in the Controller and Dispatcher classes.
- DBO::Prepare() accepts strings _and_ arrays now. It's a step towards a unified params theory.
- I think I've added some comments to DBO sub-classes, but it might have been Olle.
- A fix in Model class (findAll didn't work properly)
- Object's constructor sets $this->db to &DBO, which means all Object-descendand classes have default access to the database if it's connected. We need to clean up the code accordingly (some classes set their own $this->db references).
git-svn-id: https://svn.cakephp.org/repo/trunk/cake@236 3807eeeb-6ff5-0310-8944-8be069107fe0
2005-06-05 11:05:24 +00:00
|
|
|
}
|
2005-12-27 03:33:44 +00:00
|
|
|
?>
|