db", we made a very tiny workaround here. In the first * instantiation of this class, we instantiate the database object * and store it into 'self::$db_shared_obj'. Any subsequent * instantiations will just point to the static one. */ if (!self::$db_shared_obj) self::$db_shared_obj = &Factory::getInstance('WorkflowObjects')->getDBGalaxia()->Link_ID; $this->db = &self::$db_shared_obj; if(!$this->db) { die('Invalid db object passed to '.$this->child_name.' constructor'); } //Force transactionnal mysql (Innodb) -> mysqlt if ($this->db->databaseType=='mysql') { $GLOBALS['phpgw']->db->disconnect(); $this->db = $GLOBALS['phpgw']->db->connect( $GLOBALS['phpgw_info']['server']['db_name'], $GLOBALS['phpgw_info']['server']['db_host'], $GLOBALS['phpgw_info']['server']['db_port'], $GLOBALS['phpgw_info']['server']['db_user'], $GLOBALS['phpgw_info']['server']['db_pass'], 'mysqlt' ); } } /** * Gets errors recorded by this object * Always call this function after failed operations on a workflow object to obtain messages * * @param bool $as_array if true the result will be send as an array of errors or an empty array. Else, if you do not give any parameter * or give a false parameter you will obtain a single string which can be empty or will contain error messages with
html tags * @param bool $debug is false by default, if true you wil obtain more messages * @param string $prefix string appended to the debug message * @return mixed Error and debug messages or an array of theses messages and empty the error messages * @access public */ function get_error($as_array=false, $debug=false, $prefix='') { //collect errors from used objects $this->collect_errors($debug, $prefix.$this->child_name.'::'); if ($as_array) { $result = $this->error; $this->error= Array(); return $result; } $result_str = implode('
',array_filter($this->error)); $this->error= Array(); return $result_str; } /** * Gets warnings recorded by this object * * @param bool $as_array if true the result will be send as an array of warnings or an empty array. Else, if you do not give any parameter * or give a false parameter you will obtain a single string which can be empty or will contain warning messages with
html tags * @return mixed Warning messages or an array of theses messages and empty the warning messages * @access public */ function get_warning($as_array=false) { if ($as_array) { $result = $this->warning; $this->warning= Array(); return $result; } $result_str = implode('
',array_filter($this->warning)); $this->warning= Array(); return $result_str; } /** * Collect errors from all linked objects which could have been used by this object * Each child class should instantiate this function with her linked objetcs, calling get_error(true) * * @param bool $debug is false by default, if true debug messages can be added to 'normal' messages * @param string $prefix is a string appended to the debug message * @abstract * @access public * @return void */ function collect_errors($debug=false, $prefix = '') { if ($debug) { $this->num_queries_total += $this->num_queries; $this->error[] = $prefix.': number of queries: new='.$this->num_queries.'/ total='.$this->num_queries_total; $this->num_queries = 0; } } /** * Performs a query on the AdoDB database object * * @param string $query sql query, parameters should be replaced with ? * @param array $values array containing the parameters (going in the ?), use it to avoid security problems. If * one of theses values is an array it will be serialized and encoded in Base64 * @param int $numrows maximum number of rows to return * @param int $offset starting row number * @param bool $reporterrors is true by default, if false no warning will be generated in the php log * @param string $sort is the sort sql string for the query (without the "order by ") * @param bool $bulk is false by default, if true the $values array parameters could contain arrays vars for bulk statement * (see ADOdb help) theses arrays wont be serialized and encoded in Base64 like current arrays parameters, * it will be checked for security reasons before being appended to the sql * @return mixed false if something went wrong or the resulting recordset array if it was ok * @access public */ function query($query, $values = null, $numrows = -1, $offset = -1, $reporterrors = true, $sort='', $bulk=false) { //clean the parameters $clean_values = Array(); if (!($values===null)) { if (!(is_array($values))) { $values= array($values); } foreach($values as $value) { $clean_values[] = $this->security_cleanup($value, !($bulk)); } } //clean sort order as well and add it to the query if (!(empty($sort))) { $sort = $this->security_cleanup($sort, true, true); $query .= " order by $sort"; } //conversion must be done after oder by is set $this->convert_query($query); // Galaxia needs to be call ADOdb in associative mode $this->db->SetFetchMode(ADODB_FETCH_ASSOC); if ($numrows == -1 && $offset == -1) $result = $this->db->Execute($query, $clean_values); else $result = $this->db->SelectLimit($query, $numrows, $offset, $clean_values); if (empty($result)) { $result = false; } $this->num_queries++; if (!$result) { $this->error[] = "there were some SQL errors in the database, please warn your sysadmin."; if ($reporterrors) $this->sql_error($query, $clean_values, $result); } return $result; } /** * @see Base::query * @param string $query sql query, parameters should be replaced with ? * @param array $values array containing the parameters (going in the ?), use it to avoid security problems * @param bool $reporterrors is true by default, if false no warning will be generated in the php log * @return mixed NULL if something went wrong or the first value of the first row if it was ok * @access public */ function getOne($query, $values = null, $reporterrors = true) { $this->convert_query($query); $clean_values = Array(); if (!($values===null)) { if (!(is_array($values))) { $values= array($values); } foreach($values as $value) { $clean_values[] = $this->security_cleanup($value); } } $result = $this->db->SelectLimit($query, 1, 0, $clean_values); if (empty($result)) { $result = false; } if (!$result && $reporterrors ) $this->sql_error($query, $clean_values, $result); if (!!$result) { $res = $result->fetchRow(); } else { $res = false; } $this->num_queries++; if ($res === false) return (NULL); //simulate pears behaviour list($key, $value) = each($res); return $value; } /** * Throws error warnings * * @param string $query * @param array $values * @param mixed $result * @access public * @return void */ function sql_error($query, $values, $result) { trigger_error($this->db->databaseType . " error: " . $this->db->ErrorMsg(). " in query:
" . $query . "
", E_USER_WARNING); // DO NOT DIE, if transactions are there, they will do things in a better way } /** * Clean the data before it is recorded on the database * * @param $value is a data we want to be stored in the database. * If it is an array we'll make a serialize and then an base64_encode * (you'll have to make an unserialize(base64_decode()) * If it is not an array we make an htmlspecialchars() on it * @param bool $flat_arrays is true by default, if false arrays won't be serialized and encoded * @param bool $check_for_injection is false by default, if true we'll perform some modifications * on the string to avoid SQL injection * @return mixed @access public */ function security_cleanup($value, $flat_arrays = true, $check_for_injection = false) { if (is_array($value)) { if ($flat_arrays) { //serialize and \' are a big #!%* $res = base64_encode(serialize($value)); } else { //recursive cleanup on the array $res = Array(); foreach ($value as $key => $item) { $res[$this->security_cleanup($key,$flat_arrays)] = $this->security_cleanup($item, $flat_arrays); } } } else { $res = ($check_for_injection)? addslashes(str_replace(';','',$value)) : $value; } return $res; } /** * Supports DB abstraction * * @param string &$query * @return void * @access public */ function convert_query(&$query) { switch ($this->db->databaseType) { case "oci8": $query = preg_replace("/`/", "\"", $query); // convert bind variables - adodb does not do that $qe = explode("?", $query); $query = ''; for ($i = 0; $i < sizeof($qe) - 1; $i++) { $query .= $qe[$i] . ":" . $i; } $query .= $qe[$i]; break; case "postgres7": case "sybase": $query = preg_replace("/`/", "\"", $query); break; } } /** * Supports DB abstraction * * @param string $sort_mode * @return string * @access public */ function convert_sortmode($sort_mode) { $sort_mode = str_replace("__", "` ", $sort_mode); $sort_mode = "`" . $sort_mode; return $sort_mode; } /** * Supports DB abstraction * * @return mixed * @access public */ function convert_binary() { switch ($this->db->databaseType) { case "pgsql72": case "oci8": case "postgres7": return; break; case "mysql3": case "mysql": return "binary"; break; } } } ?>