X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=extlib%2FDB%2FDataObject.php;h=811d775965012ba5fd0cd037dad8cc23222c8a26;hb=35ff64323076d8b543e12293e7aa2b0733db6c55;hp=a69fbae86bdf35ce156bf13e77b4a17d1bcc0a8e;hpb=dfba47bdf4d3a8eda1778007e274c57de4c3451c;p=quix0rs-gnu-social.git diff --git a/extlib/DB/DataObject.php b/extlib/DB/DataObject.php index a69fbae86b..811d775965 100644 --- a/extlib/DB/DataObject.php +++ b/extlib/DB/DataObject.php @@ -15,7 +15,7 @@ * @author Alan Knowles * @copyright 1997-2006 The PHP Group * @license http://www.php.net/license/3_01.txt PHP License 3.01 - * @version CVS: $Id: DataObject.php 291349 2009-11-27 09:15:18Z alan_k $ + * @version CVS: $Id: DataObject.php 301030 2010-07-07 02:26:31Z alan_k $ * @link http://pear.php.net/package/DB_DataObject */ @@ -235,7 +235,7 @@ class DB_DataObject extends DB_DataObject_Overload * @access private * @var string */ - var $_DB_DataObject_version = "1.9.0"; + var $_DB_DataObject_version = "1.9.5"; /** * The Database table (used by table extends) @@ -369,6 +369,32 @@ class DB_DataObject extends DB_DataObject_Overload return $_DB_DATAOBJECT['CACHE'][$lclass][$key]; } + /** + * build the basic select query. + * + * @access private + */ + + function _build_select() + { + global $_DB_DATAOBJECT; + $quoteIdentifiers = !empty($_DB_DATAOBJECT['CONFIG']['quote_identifiers']); + if ($quoteIdentifiers) { + $this->_connect(); + $DB = &$_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5]; + } + $sql = 'SELECT ' . + $this->_query['data_select'] . " \n" . + ' FROM ' . ($quoteIdentifiers ? $DB->quoteIdentifier($this->__table) : $this->__table) . " \n" . + $this->_join . " \n" . + $this->_query['condition'] . " \n" . + $this->_query['group_by'] . " \n" . + $this->_query['having'] . " \n"; + + return $sql; + } + + /** * find results, either normal or crosstable * @@ -411,20 +437,21 @@ class DB_DataObject extends DB_DataObject_Overload $query_before = $this->_query; $this->_build_condition($this->table()) ; - $quoteIdentifiers = !empty($_DB_DATAOBJECT['CONFIG']['quote_identifiers']); + $this->_connect(); $DB = &$_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5]; - /* We are checking for method modifyLimitQuery as it is PEAR DB specific */ - $sql = 'SELECT ' . - $this->_query['data_select'] . " \n" . - ' FROM ' . ($quoteIdentifiers ? $DB->quoteIdentifier($this->__table) : $this->__table) . " \n" . - $this->_join . " \n" . - $this->_query['condition'] . " \n" . - $this->_query['group_by'] . " \n" . - $this->_query['having'] . " \n" . - $this->_query['order_by'] . " \n"; + $sql = $this->_build_select(); + + foreach ($this->_query['unions'] as $union_ar) { + $sql .= $union_ar[1] . $union_ar[0]->_build_select() . " \n"; + } + + $sql .= $this->_query['order_by'] . " \n"; + + + /* We are checking for method modifyLimitQuery as it is PEAR DB specific */ if ((!isset($_DB_DATAOBJECT['CONFIG']['db_driver'])) || ($_DB_DATAOBJECT['CONFIG']['db_driver'] == 'DB')) { /* PEAR DB specific */ @@ -578,6 +605,85 @@ class DB_DataObject extends DB_DataObject_Overload return true; } + + /** + * fetches all results as an array, + * + * return format is dependant on args. + * if selectAdd() has not been called on the object, then it will add the correct columns to the query. + * + * A) Array of values (eg. a list of 'id') + * + * $x = DB_DataObject::factory('mytable'); + * $x->whereAdd('something = 1') + * $ar = $x->fetchAll('id'); + * -- returns array(1,2,3,4,5) + * + * B) Array of values (not from table) + * + * $x = DB_DataObject::factory('mytable'); + * $x->whereAdd('something = 1'); + * $x->selectAdd(); + * $x->selectAdd('distinct(group_id) as group_id'); + * $ar = $x->fetchAll('group_id'); + * -- returns array(1,2,3,4,5) + * * + * C) A key=>value associative array + * + * $x = DB_DataObject::factory('mytable'); + * $x->whereAdd('something = 1') + * $ar = $x->fetchAll('id','name'); + * -- returns array(1=>'fred',2=>'blogs',3=> ....... + * + * D) array of objects + * $x = DB_DataObject::factory('mytable'); + * $x->whereAdd('something = 1'); + * $ar = $x->fetchAll(); + * + * E) array of arrays (for example) + * $x = DB_DataObject::factory('mytable'); + * $x->whereAdd('something = 1'); + * $ar = $x->fetchAll(false,false,'toArray'); + * + * + * @param string|false $k key + * @param string|false $v value + * @param string|false $method method to call on each result to get array value (eg. 'toArray') + * @access public + * @return array format dependant on arguments, may be empty + */ + function fetchAll($k= false, $v = false, $method = false) + { + // should it even do this!!!?!? + if ($k !== false && + ( // only do this is we have not been explicit.. + empty($this->_query['data_select']) || + ($this->_query['data_select'] == '*') + ) + ) { + $this->selectAdd(); + $this->selectAdd($k); + if ($v !== false) { + $this->selectAdd($v); + } + } + + $this->find(); + $ret = array(); + while ($this->fetch()) { + if ($v !== false) { + $ret[$this->$k] = $this->$v; + continue; + } + $ret[] = $k === false ? + ($method == false ? clone($this) : $this->$method()) + : $this->$k; + } + return $ret; + + } + + /** * Adds a condition to the WHERE statement, defaults to AND * @@ -622,6 +728,47 @@ class DB_DataObject extends DB_DataObject_Overload return $r; } + /** + * Adds a 'IN' condition to the WHERE statement + * + * $object->whereAddIn('id', $array, 'int'); //minimal usage + * $object->whereAddIn('price', $array, 'float', 'OR'); // cast to float, and call whereAdd with 'OR' + * $object->whereAddIn('name', $array, 'string'); // quote strings + * + * @param string $key key column to match + * @param array $list list of values to match + * @param string $type string|int|integer|float|bool cast to type. + * @param string $logic optional logic to call whereAdd with eg. "OR" (defaults to "AND") + * @access public + * @return string|PEAR::Error - previous condition or Error when invalid args found + */ + function whereAddIn($key, $list, $type, $logic = 'AND') + { + $not = ''; + if ($key[0] == '!') { + $not = 'NOT '; + $key = substr($key, 1); + } + // fix type for short entry. + $type = $type == 'int' ? 'integer' : $type; + + if ($type == 'string') { + $this->_connect(); + } + + $ar = array(); + foreach($list as $k) { + settype($k, $type); + $ar[] = $type =='string' ? $this->_quote($k) : $k; + } + if (!$ar) { + return $not ? $this->_query['condition'] : $this->whereAdd("1=0"); + } + return $this->whereAdd("$key $not IN (". implode(',', $ar). ')', $logic ); + } + + + /** * Adds a order by condition * @@ -1175,7 +1322,7 @@ class DB_DataObject extends DB_DataObject_Overload $seq = $this->sequenceKey(); if ($seq[0] !== false) { $keys = array($seq[0]); - if (empty($this->{$keys[0]}) && $dataObject !== true) { + if (!isset($this->{$keys[0]}) && $dataObject !== true) { $this->raiseError("update: trying to perform an update without the key set, and argument to update is not DB_DATAOBJECT_WHEREADD_ONLY @@ -1670,6 +1817,7 @@ class DB_DataObject extends DB_DataObject_Overload 'limit_start' => '', // the LIMIT condition 'limit_count' => '', // the LIMIT condition 'data_select' => '*', // the columns to be SELECTed + 'unions' => array(), // the added unions ); @@ -2032,9 +2180,9 @@ class DB_DataObject extends DB_DataObject_Overload $seqname = false; if (!empty($_DB_DATAOBJECT['CONFIG']['sequence_'.$this->__table])) { - $usekey = $_DB_DATAOBJECT['CONFIG']['sequence_'.$this->__table]; - if (strpos($usekey,':') !== false) { - list($usekey,$seqname) = explode(':',$usekey); + $seqname = $_DB_DATAOBJECT['CONFIG']['sequence_'.$this->__table]; + if (strpos($seqname,':') !== false) { + list($usekey,$seqname) = explode(':',$seqname); } } @@ -3068,9 +3216,9 @@ class DB_DataObject extends DB_DataObject_Overload } /** - * IS THIS SUPPORTED/USED ANYMORE???? - *return a list of options for a linked table - * + * getLinkArray + * Fetch an array of related objects. This should be used in conjunction with a .links.ini file configuration (see the introduction on linking for details on this). + * You may also use this with all parameters to specify, the column and related table. * This is highly dependant on naming columns 'correctly' :) * using colname = xxxxx_yyyyyy * xxxxxx = related table; (yyyyy = user defined..) @@ -3078,7 +3226,21 @@ class DB_DataObject extends DB_DataObject_Overload * stores it in $this->_xxxxx_yyyyy * * @access public - * @return array of results (empty array on failure) + * @param string $column - either column or column.xxxxx + * @param string $table - name of table to look up value in + * @return array - array of results (empty array on failure) + * + * Example - Getting the related objects + * + * $person = new DataObjects_Person; + * $person->get(12); + * $children = $person->getLinkArray('children'); + * + * echo 'There are ', count($children), ' descendant(s):
'; + * foreach ($children as $child) { + * echo $child->name, '
'; + * } + * */ function &getLinkArray($row, $table = null) { @@ -3123,6 +3285,46 @@ class DB_DataObject extends DB_DataObject_Overload return $ret; } + /** + * unionAdd - adds another dataobject to this, building a unioned query. + * + * usage: + * $doTable1 = DB_DataObject::factory("table1"); + * $doTable2 = DB_DataObject::factory("table2"); + * + * $doTable1->selectAdd(); + * $doTable1->selectAdd("col1,col2"); + * $doTable1->whereAdd("col1 > 100"); + * $doTable1->orderBy("col1"); + * + * $doTable2->selectAdd(); + * $doTable2->selectAdd("col1, col2"); + * $doTable2->whereAdd("col2 = 'v'"); + * + * $doTable1->unionAdd($doTable2); + * $doTable1->find(); + * + * Note: this model may be a better way to implement joinAdd?, eg. do the building in find? + * + * + * @param $obj object|false the union object or false to reset + * @param optional $is_all string 'ALL' to do all. + * @returns $obj object|array the added object, or old list if reset. + */ + + function unionAdd($obj,$is_all= '') + { + if ($obj === false) { + $ret = $this->_query['unions']; + $this->_query['unions'] = array(); + return $ret; + } + $this->_query['unions'][] = array($obj, 'UNION ' . $is_all . ' ') ; + return $obj; + } + + + /** * The JOIN condition * @@ -3248,31 +3450,46 @@ class DB_DataObject extends DB_DataObject_Overload /* otherwise see if there are any links from this table to the obj. */ //print_r($this->links()); if (($ofield === false) && ($links = $this->links())) { - foreach ($links as $k => $v) { - /* link contains {this column} = {linked table}:{linked column} */ - $ar = explode(':', $v); - // Feature Request #4266 - Allow joins with multiple keys - if (strpos($k, ',') !== false) { - $k = explode(',', $k); - } - if (strpos($ar[1], ',') !== false) { - $ar[1] = explode(',', $ar[1]); + // this enables for support for arrays of links in ini file. + // link contains this_column[] = linked_table:linked_column + // or standard way. + // link contains this_column = linked_table:linked_column + foreach ($links as $k => $linkVar) { + + if (!is_array($linkVar)) { + $linkVar = array($linkVar); } + foreach($linkVar as $v) { + + + + /* link contains {this column} = {linked table}:{linked column} */ + $ar = explode(':', $v); + // Feature Request #4266 - Allow joins with multiple keys + if (strpos($k, ',') !== false) { + $k = explode(',', $k); + } + if (strpos($ar[1], ',') !== false) { + $ar[1] = explode(',', $ar[1]); + } - if ($ar[0] == $obj->__table) { + if ($ar[0] != $obj->__table) { + continue; + } if ($joinCol !== false) { if ($k == $joinCol) { + // got it!? $tfield = $k; $ofield = $ar[1]; break; - } else { - continue; - } - } else { - $tfield = $k; - $ofield = $ar[1]; - break; - } + } + continue; + + } + $tfield = $k; + $ofield = $ar[1]; + break; + } } } @@ -3280,23 +3497,30 @@ class DB_DataObject extends DB_DataObject_Overload //print_r($obj->links()); if (!$ofield && ($olinks = $obj->links())) { - foreach ($olinks as $k => $v) { - /* link contains {this column} = {linked table}:{linked column} */ - $ar = explode(':', $v); - - // Feature Request #4266 - Allow joins with multiple keys - - $links_key_array = strpos($k,','); - if ($links_key_array !== false) { - $k = explode(',', $k); - } - - $ar_array = strpos($ar[1],','); - if ($ar_array !== false) { - $ar[1] = explode(',', $ar[1]); + foreach ($olinks as $k => $linkVar) { + /* link contains {this column} = array ( {linked table}:{linked column} )*/ + if (!is_array($linkVar)) { + $linkVar = array($linkVar); } - - if ($ar[0] == $this->__table) { + foreach($linkVar as $v) { + + /* link contains {this column} = {linked table}:{linked column} */ + $ar = explode(':', $v); + + // Feature Request #4266 - Allow joins with multiple keys + $links_key_array = strpos($k,','); + if ($links_key_array !== false) { + $k = explode(',', $k); + } + + $ar_array = strpos($ar[1],','); + if ($ar_array !== false) { + $ar[1] = explode(',', $ar[1]); + } + + if ($ar[0] != $this->__table) { + continue; + } // you have explictly specified the column // and the col is listed here.. @@ -3315,6 +3539,7 @@ class DB_DataObject extends DB_DataObject_Overload $ofield = $k; $tfield = $ar[1]; break; + } } } @@ -3573,7 +3798,14 @@ class DB_DataObject extends DB_DataObject_Overload if (!$k) { continue; // ignore empty keys!!! what } - if (is_object($from) && isset($from->{sprintf($format,$k)})) { + + $chk = is_object($from) && + (version_compare(phpversion(), "5.1.0" , ">=") ? + property_exists($from, sprintf($format,$k)) : // php5.1 + array_key_exists( sprintf($format,$k), get_class_vars($from)) //older + ); + // if from has property ($format($k) + if ($chk) { $kk = (strtolower($k) == 'from') ? '_from' : $k; if (method_exists($this,'set'.$kk)) { $ret = $this->{'set'.$kk}($from->{sprintf($format,$k)});