From 806a5297e7e99d455b97a4f0acaba2f40f470584 Mon Sep 17 00:00:00 2001 From: Urban Müller Date: Thu, 26 Jul 2007 13:02:24 +0000 Subject: renamed files for autoloader --- auto_prepend.php | 139 +++++++++++++ banner.class | 274 ------------------------- banner.lib | 2 +- browser.class | 178 ---------------- db.class | 250 ---------------------- db_record.class | 520 ---------------------------------------------- db_table.class | 326 ----------------------------- dbi.class | 591 ----------------------------------------------------- debug.class | 138 ------------- fax.class | 127 ------------ functions.php | 139 ------------- html.class | 551 ------------------------------------------------- html_form.class | 166 --------------- html_page.class | 215 ------------------- it_banner.class | 274 +++++++++++++++++++++++++ it_browser.class | 178 ++++++++++++++++ it_db.class | 250 ++++++++++++++++++++++ it_db_record.class | 520 ++++++++++++++++++++++++++++++++++++++++++++++ it_db_table.class | 326 +++++++++++++++++++++++++++++ it_dbi.class | 591 +++++++++++++++++++++++++++++++++++++++++++++++++++++ it_debug.class | 138 +++++++++++++ it_fax.class | 127 ++++++++++++ it_html.class | 551 +++++++++++++++++++++++++++++++++++++++++++++++++ it_html_form.class | 166 +++++++++++++++ it_html_page.class | 215 +++++++++++++++++++ it_mail.class | 483 +++++++++++++++++++++++++++++++++++++++++++ it_session.class | 231 +++++++++++++++++++++ it_text.class | 378 ++++++++++++++++++++++++++++++++++ it_url.class | 580 ++++++++++++++++++++++++++++++++++++++++++++++++++++ it_user.class | 512 ++++++++++++++++++++++++++++++++++++++++++++++ it_xml.class | 293 ++++++++++++++++++++++++++ itools.lib | 37 ++-- mail.class | 483 ------------------------------------------- session.class | 231 --------------------- tests/html.t | 99 --------- tests/it_html.t | 99 +++++++++ tests/it_url.t | 70 +++++++ tests/it_xml.t | 70 +++++++ tests/url.t | 70 ------- tests/xml.t | 70 ------- text.class | 378 ---------------------------------- url.class | 580 ---------------------------------------------------- user.class | 512 ---------------------------------------------- xml.class | 293 -------------------------- 44 files changed, 6210 insertions(+), 6211 deletions(-) create mode 100644 auto_prepend.php delete mode 100644 banner.class delete mode 100644 browser.class delete mode 100644 db.class delete mode 100644 db_record.class delete mode 100644 db_table.class delete mode 100644 dbi.class delete mode 100644 debug.class delete mode 100644 fax.class delete mode 100644 functions.php delete mode 100644 html.class delete mode 100644 html_form.class delete mode 100644 html_page.class create mode 100644 it_banner.class create mode 100644 it_browser.class create mode 100644 it_db.class create mode 100644 it_db_record.class create mode 100644 it_db_table.class create mode 100644 it_dbi.class create mode 100644 it_debug.class create mode 100644 it_fax.class create mode 100644 it_html.class create mode 100644 it_html_form.class create mode 100644 it_html_page.class create mode 100644 it_mail.class create mode 100644 it_session.class create mode 100644 it_text.class create mode 100644 it_url.class create mode 100644 it_user.class create mode 100644 it_xml.class delete mode 100644 mail.class delete mode 100644 session.class delete mode 100755 tests/html.t create mode 100755 tests/it_html.t create mode 100755 tests/it_url.t create mode 100755 tests/it_xml.t delete mode 100755 tests/url.t delete mode 100755 tests/xml.t delete mode 100644 text.class delete mode 100644 url.class delete mode 100644 user.class delete mode 100644 xml.class diff --git a/auto_prepend.php b/auto_prepend.php new file mode 100644 index 0000000..ddb6012 --- /dev/null +++ b/auto_prepend.php @@ -0,0 +1,139 @@ +debug($text, $level); +} + +/** + * Convert a htmlentities-encoded string back to normal + */ +function it_htmlentities_decode($string) +{ + return strtr($string, array_flip(get_html_translation_table(HTML_ENTITIES))); +} + +/** + * Clone an object and return copy, works for all PHP versions + */ +function &it_clone(&$object) +{ + $result = (is_object($object) && version_compare(zend_version(), 2, '>=')) ? clone($object) : $object; + return $result; # PHP internals need a tmp var to return by ref +} + +/** + * Return string containing names and values of all arguments + */ +function D() +{ + $args = func_get_args(); + return it_debug::dump($args); +} + +/** + * Echo string containing names and values of all arguments + */ +function ED() +{ + $args = func_get_args(); + echo it_debug::dump($args); + return $args[0]; +} + +/** + * Same as ED(), but first argument is string that must be in $_REQUEST['debug'] + */ +function EDC() +{ + $args = func_get_args(); + $var = array_shift($args); + $GLOBALS['ULTRADEBUGVARS'][$var] = 1; + + if (($result = $GLOBALS["debug_$var"]) && $args) + echo it_debug::dump($args); + + if (!$result || $result === true) # Compatibility with old map relying on 0|1 + $result = intval($result); + + return $result; +} + +/** + * Echo string containing names and values of all arguments, then exit + */ +function EDX() +{ + $args = func_get_args(); + exit(it_debug::dump($args)); +} + +/** + * Shortcut to $it_text->Text() + */ +function T($label, $raw = null, $language = null) +{ + it_text::init(); + return $GLOBALS['it_text']->text($label, $raw, $language); +} + + +/** + * Shortcut to $it_text->etext() + */ +function ET($label, $values = null, $language = null) +{ + it_text::init(); + return $GLOBALS['it_text']->etext($label, $values, $language); +} + +/** + * Return "db4" or "db2" depending on availability + */ +function db_version() +{ + return in_array("db4", dba_handlers()) ? "db4" : "db2"; +} + +/** + * Shortcut to $it_text->get_language() + */ +function T_lang() +{ + it_text::init(); + return isset($GLOBALS['it_text']) ? $GLOBALS['it_text']->get_language() : "de"; +} + +/** + * Shortcut to $it_text->get_language() + */ +function T_set_language($language, $setcookie = true) +{ + it_text::init(); + return $GLOBALS['it_text']->set_language($language, $setcookie); +} + +/** + * Shortcut to $it_text->text_exists() + */ +function T_exists($label, $language = null) +{ + it_text::init(); + return $GLOBALS['it_text']->text_exists($label, $language); +} + +?> diff --git a/banner.class b/banner.class deleted file mode 100644 index 9b876e3..0000000 --- a/banner.class +++ /dev/null @@ -1,274 +0,0 @@ -p = (array)$p + array( - 'server' => "http://localhost/", - 'serverbase' => "http://localhost/getbanner.html", - 'host' => $_SERVER['HTTP_HOST'], - 'uri' => str_replace('/doc_static', '', $_SERVER['PHP_SELF']), - 'place' => "", - 'language' => "", - 'keyword' => "", - 'category' => "", - 'region' => "", - 'vars' => array(), - 'ip' => $_SERVER['REMOTE_ADDR'], - 'uid' => $_COOKIE['UID'], - 'bgcolor' => "", - 'width' => "", - 'height' => "", - 'mx1' => "", - 'mx2' => "", - 'my1' => "", - 'my2' => "", - 'z' => "", - 'target' => "_top", - 'timeout' => 5, - 'uidcookie' => 'crustulum', - 'enablephpbanners' => false, - 'addextraline' => "", - 'bannerid' => $_REQUEST["bannerid"], - 'exclude' => $_REQUEST["exclude"], - ); - - $this->p += array('loc' => $this->p['region']); # Historical name -} - -function choose() -{ - if ($GLOBALS['debug_noads']) - return; - - $host = 'localhost'; - $port = 80; - $url = '/'; - - if (eregi('^[a-z]+://([^:/]+):([0-9]+)(.*)', $this->p['serverbase'], $regs)) - { - $host = $regs[1]; - $port = $regs[2]; - $url = $regs[3]; - } - else if (eregi('^[a-z]+://([^:/]+)(.*)', $this->p['serverbase'], $regs)) - { - $host = $regs[1]; - $port = 80; - $url = $regs[2]; - } - - if ($url == '') - $url = '/'; - - $params = array(); - - foreach (array('host', 'uri', 'place', 'language', 'keyword', 'category', 'loc', 'mx1', 'mx2', 'my1', 'my2', 'z', 'ip', 'uid', 'bgcolor', 'bannerid', 'exclude') as $key) - $params[$key] = $this->p[$key]; - - $request .= it_html::U($url, $params); - if ($GLOBALS['debug_adreq']) # can't use EDC since itools sometimes not included - ED("http://$host$request"); - - if ($fp = @fsockopen($host, $port, $errno, $errstr, $this->p['timeout'])) - { - if ($this->p['uid']) - $cookie = "Cookie: " . $this->p['uidcookie'] . "=" . urlencode($this->p['uid']) . "\r\n"; - else - $cookie = ''; - - fputs($fp, "GET $request HTTP/1.0\r\nHost: $host\r\n$cookie\r\n"); - - $b = array(); - - while (!feof($fp)) - { - $line = fgets($fp, 10240); - - if (!trim($line)) - $emptylines++; - - if ($emptylines == 0) - ; - else if (ereg("^data (.*)$", $line, $r)) - { - $len = (int)$r[1]; - $b['data'] = ''; - - while (!feof($fp) && (strlen($b['data']) < $len)) - $b['data'] .= fread($fp, $len - strlen($b['data'])); - - if (strlen($b['data']) < $len) - $b['data'] = ''; # Skip banners which got corrupted during transmission, very rare - } - else if (ereg("^([^ ]*) (.*)\n$", $line, $r)) - { - $b[$r[1]] = $r[2]; - } - else if (ereg("^", $line)) - { - # Doubleclick artificially delays banners for Mozilla/Linux so we do not show them to linux users - if (!(eregi('linux', $_SERVER['HTTP_USER_AGENT']) && eregi('\.doubleclick\.net', $b['data']))) - { - $this->bannersbyposition[$b['position'] ? $b['position'] : 'banner'] = $b; - $this->banners[] = $b; - } - - $b = array(); - } - } - - if ($GLOBALS['debug_adreq']) # can't use EDC since itools sometimes not included - ED($this->banners); - } - - srand((double)microtime()*1000000); - $this->rand = rand(); - $this->chosen = true; -} - -/** - * Show one or all banners for this banner position - * @param $nocount Switch off impression counting of true for multiple display - * @param $noecho Switch off automatic display of HTML snipplet with echo - * @return HTML snipplet to insert banner(s) if $noecho is set, undefined otherwise - */ -function show($nocount = false, $noecho = false) -{ - if (!$this->chosen) - $this->choose(); - - if (!is_array($this->banners)) - return; // none found or choose() not called yet - - $count = count($this->banners); - $number = 0; - - if ($noecho) - ob_start(); - - foreach ($this->banners as $banner) - { - $result .= $this->render($banner, $count, $number, $nocount); - $number++; - } - - if ($noecho) - { - $result = ob_get_contents(); - ob_end_clean(); - } - - return $result; -} - -/** - * Returns html code for a banner from a multi banner request - * @param $position Which position to return, e.g. 'feature' - * @param $nocount Suppress counting of this banner - */ -function showcombined($position = "banner", $nocount = false) -{ - ob_start(); - if ($this->bannersbyposition[$position]) - $this->render($this->bannersbyposition[$position], 1, 0, $nocount); - $result = ob_get_contents(); - ob_end_clean(); - - return $result; -} - -/** - * Renders a banner, to be overloaded e.g. to render sponsor banners in a table - * @param $banner Opaque structure representing the banner - * @param $count Total number of banners, also number of times this method gets called - * @param $position Current banner number, from 0 to $count - 1 - */ -function render($banner, $count, $number, $nocount = false) -{ - if ($number > 0) - echo "

"; - - $this->render_banner($banner, $nocount); -} - -/** - * Render one banner - * @param $banner Opaque banner structure to be rendered - */ -function render_banner($banner, $nocount = false) -{ - if ($banner['width'] <= 0) - $banner['width'] = 468; - if ($banner['height'] <= 0) - $banner['height'] = 60; - if ($this->p['width']) - $banner['width'] = $this->p['width']; - if ($this->p['height']) - $banner['height'] = $this->p['height']; - - $l = it::replace("/" => "_", rtrim($banner['locationid'] . "|" . $banner['matchingkeyword'] . "|" . $banner['matchingcategory'] . "|" . $banner['matchingregion'] . "|" . $banner['language'], "|")); - - $pathinfo = "/c=" . $banner['campaignid'] . ":" . urlencode($banner['campaignname']) . "/b=" . $banner['bannerid'] . ":" . urlencode($banner['bannername']) . "/l=" . urlencode($l); - $nocountinfo = $nocount ? "/nocount=1" : ""; - $keyword = it::replace(']*>' => "", '\]\[' => " ", '^\[ +' => "", ' +\]$' => "", $this->p['keyword']); - $viewpre = $this->p['server'] . "view.html$pathinfo$nocountinfo/img="; - $clickpre = $this->p['server'] . "click.html$pathinfo/url="; - - $vars = array( - 'viewpre' => $viewpre, - 'clickpre' => $clickpre, - 'clickpreenc' => urlencode($clickpre), - 'auditurl' => $viewpre . "empty.gif", - 'keyword' => $keyword, - 'keywordhtml' => substr($keyword, 0, 30), - 'keywordurl' => urlencode($keyword), - 'viewurl' => $viewpre . $banner['path'], - 'clickurl' => $clickpre . $banner['url'], - 'rand' => $this->rand, - ) + $this->p['vars']; - - foreach (array('alttext', 'extraline', 'path', 'url', 'data') as $field) - { - while ($var = it::match("__([a-z]+)__", $banner[$field])) - $banner[$field] = str_replace("__{$var}__", htmlspecialchars($vars[strtolower($var)]), $banner[$field]); - } - - switch ($banner['type']) - { - case 0: - if($banner['url'] != 'http://') - { - $linkstart = "p['target']) . "\">"; - $linkend = ""; - } - - echo "$linkstart\""$linkend"; - - if (strlen($banner['extraline']) > 0) - echo "
$linkstart" . $banner['extraline'] . $linkend; - - if (strlen($banner['extraline']) == 0 && $this->p['addextraline']) - echo "
 "; - break; - - case 1: - echo $banner['data']; - break; - - case 2: - if ($this->p['enablephpbanners']) - eval("?>" . $banner['data']); - break; - } -} - -} -?> diff --git a/banner.lib b/banner.lib index 0ec5eb5..ef2cbb3 100644 --- a/banner.lib +++ b/banner.lib @@ -1,3 +1,3 @@ diff --git a/browser.class b/browser.class deleted file mode 100644 index e67b658..0000000 --- a/browser.class +++ /dev/null @@ -1,178 +0,0 @@ -UserAgent = $_SERVER['HTTP_USER_AGENT']; - /* $this->UserAgent = "Mozilla/4.0 [de] (compatible; MSIE 5.0; Bill Gates 1.0; Windows 95)"; */ - - /* Find "Mozilla/4.0" */ - if (ereg("([^/]*)/([^ ]*)", $this->UserAgent, $regs)) - { - $this->Type = $regs[1]; - $this->Version = (double)$regs[2]; - } - - /* Find optional "(compatible; MSIE 3.0; Win95)" */ - if (preg_match("/\((.+)\)/U", $this->UserAgent, $regs)) - { - $optattr = preg_split("/;\s+/", $regs[1]); - if ($optattr[0] == "compatible") - { - if (ereg("([^/]*)[/ ]([^/]*)", $optattr[1], $regs)) - { - $this->Type = $regs[1]; - $this->Version = (double)$regs[2]; - } - else - $this->Type = $optattr[1]; - - $this->Platform = $optattr[count($optattr)-1]; - } - else - $this->Platform = $optattr[0]; - - for ($i=1; $i < count($optattr); $i++) - { - if (preg_match("/^([a-z]{2})(\-[a-z]{2})?$/i", $optattr[$i], $regs)) - $this->Language = $regs[1]; - if (preg_match("/^rv:([0-9\.]+)/", $optattr[$i], $regs)) - $this->Version = floatval($regs[1]); - if (strstr($optattr[$i], "Linux") || $optattr[$i] == "X11") - $this->Platform = "Linux"; - } - } - - /* Find optional "[de]" */ - if (!$this->Language && ereg("\[(.*)\]", $this->UserAgent, $regs)) - $this->Language = $regs[1]; - - /* Check for Safari/KHTML */ - if (preg_match("/(Safari|AppleWebKit)\/([0-9\.]+)/", $this->UserAgent, $regs)) - { - $this->Type = "Safari"; - $this->Version = floatval($regs[2]); - } - - /* Check for Gecko based browser */ - if ($this->Type == "Mozilla" && preg_match("/[^a-z]Gecko[^a-z]/", $this->UserAgent)) - $this->Type = "Gecko"; - else if ($this->Type == "Mozilla" && $this->Version < 5) - $this->Type = "Netscape"; - - - /* And now for the browser capabilities ... */ - if ($this->Type == "MSIE") - { - $this->MSIE = $this->Version; - $this->HTMLVersion = 4.0; - $this->JavaScript = true; - $this->VML = ($this->Version >= 5.5); - $this->XMLHTTP = ($this->Version >= 5); - $this->CSS = $this->Version >= 4.0 ? 2 : 1; - $this->CSSFilter = ($this->Version >= 5.0); - } - else if ($this->Type == "Opera") - { - $this->Opera = $this->Version; - if ($this->Version >= 3.5) - { - $this->HTMLVersion = 4.0; - $this->CSS = 2; - } - else - { - $this->HTMLVersion = 3.2; - $this->CSS = 1; - } - $this->JavaScript = true; - $this->XMLHTTP = ($this->Version >= 8); - } - else if ($this->Type == "Konqueror") - { - $this->HTMLVersion = 4.0; - $this->CSS = 2; - $this->JavaScript = true; - $this->XMLHTTP = ($this->Version >= 3); - } - else if ($this->Type == "Netscape") - { - $this->NS = $this->Version; - $this->HTMLVersion = 4.0; - $this->JavaScript = true; - - if ($this->Version >= 5.0) - $this->CSS = 2; - } - else if ($this->Type == "Gecko") - { - $this->HTMLVersion = 4.0; - $this->CSS = 2; - $this->JavaScript = true; - $this->XMLHTTP = true; - $this->Canvas = ($this->Version >= 1.8); - } - else if ($this->Type == "Safari") - { - $this->HTMLVersion = 4.0; - $this->JavaScript = true; - $this->CSS = 2; - $this->XMLHTTP = true; - $this->Canvas = ($this->Version >= 418); - } - else if ($this->Type == "Lynx") - $this->TextOnly = 1; -} - -} /* End Class it_Browser */ -?> diff --git a/db.class b/db.class deleted file mode 100644 index 781432c..0000000 --- a/db.class +++ /dev/null @@ -1,250 +0,0 @@ -link = @mysql_connect($host, $username, $password, true)) - { - if (mysql_select_db($databasename, $this->link)) - { - $this->host = $host; - $this->name = $databasename; - } - else - it::fatal("Can't select database \"$databasename\" on host \"$host\"."); - } - else - it::fatal("Can't connect to database server \"$host\" as user \"$username\"."); - - if ($host_update) - { - $this->host_update = $host_update; - $this->username = $username; - $this->password = $password; - } -} - - -/** - * Perform an SQL query. - * @see ::safe_sql_query, mysql_query - * @param $sql SQL query - * @return SQL handle or false in case of failure - */ -function sql_query($sql) -{ - debug("it_db::sql_query($sql) on {$this->host}", 5); - - /* - ** If we have a special update host, and an update operation is to be - ** performed, we switch to this host. And we stay forever and ever and ever... - */ - if ($this->host_update && eregi('^(UPDATE|INSERT|REPLACE|DELETE|ALTER) ', $sql)) - { - /*debug('it_db::sql_query(): switching to update host "'.$this->host_update.'"', 3); */ - if ($this->link = @mysql_connect($this->host_update, $this->username, $this->password, true)) - { - if (mysql_select_db($this->name, $this->link)) - $this->host = $this->host_update; - else - it::fatal('Error selecting update database "'.$this->name.'" on host "'.$this->host_update.'".'); - - $this->host_update=''; - } - else - it::fatal('Error connecting to update database server "'.$this->host_update.'" as user "'.$this->username.'".'); - } - - return mysql_query($sql, $this->link); -} - - -/** - * Perform an SQL query. If the query fails, issue an error message - * and terminate program execution. No matching rows does not mean failure. - * @see ::sql_query, mysql_query - * @param $sql SQL query - * @return SQL handle - */ -function safe_sql_query($sql) -{ - /* debug("it_db::safe_sql_query($sql)", 4); */ - if ($result = $this->sql_query($sql)) - return $result; - else - { - if ($this->errno() == 1062) /* Duplicate entry */ - return 0; - - fail('SQL-Query db "'.$this->name.'" host "'.$this->host."\" failed: \"$sql\":
".$this->error().' ('.$this->errno().')'); - } -} - - -/** - * Free resources used by SQL handle - * @see mysql_free_result - * @param $handle SQL handle - * @return - */ -function free($handle) -{ - return mysql_free_result($handle); -} - - -/** - * Fetch a row as an array - * @see mysql_fetch_array - * @param $handle SQL handle - * @return numeric & associative array with contents of table row - */ -function fetch_array($handle) -{ - return mysql_fetch_array($handle); -} - - -/** - * Fetch a row as an associative array - * @see mysql_fetch_array - * @param $handle SQL handle - * @return associative array with contents of table row - */ -function fetch_assoc($handle) -{ - return mysql_fetch_assoc($handle); -} - - -/** - * Return number of rows of a query - * @see mysql_num_rows - * @param $handle SQL handle - * @return number of rows the query returned - */ -function num_rows($handle) -{ - return mysql_num_rows($handle); -} - - -/** - * Return number of found rows of a limited query that had SQL_COUNT_FOUND_ROWS set - * @return number of rows the query would have returned without LIMIT - */ -function found_rows() -{ - list($count) = mysql_fetch_row($this->safe_sql_query('SELECT FOUND_ROWS()')); - return intval($count); -} - - -/* Internal: get information about tables */ -function _get_table_info() -{ - if ($this->numtables > 0) /* Already done! */ - return; - - if(($tables = mysql_list_tables($this->name,$this->link)) >= 0) - { - $this->numtables = mysql_numrows($tables); - for ($i=0; $i < $this->numtables; ++$i) - { - $name = mysql_tablename($tables, $i); - $this->tablenames[$i] = $name; - } - } - else it::fatal("mysql_list_tables($this->name,$this->link) failed."); -} - - -/** - * Return a list of all table names of this database - * @return array with tablenames of this Database - */ -function table_names() -{ - $this->_get_table_info(); - return $this->tablenames; -} - - -/** - * Return number of tables in this database - */ -function num_tables() -{ - $this->_get_table_info(); - return $this->numtables; -} - - -/** - * Return last error number - * @see ::sql_query, ::safe_sql_query, mysql_errno - * @return last mySQL error number - */ -function errno() -{ - return mysql_errno($this->link); -} - - -/** - * Return last error string - * @see ::sql_query, ::safe_sql_query, mysql_error - * @return last mySQL error message - */ -function error() -{ - return mysql_error($this->link); -} - -} /* End class it_db */ -?> diff --git a/db_record.class b/db_record.class deleted file mode 100644 index a716117..0000000 --- a/db_record.class +++ /dev/null @@ -1,520 +0,0 @@ -table = &$table; - $this->keyfieldname = $keyfieldname; -} - - -/** - * Change active key field - * @param $keyfieldname Optional name of primary key field, defaults to 'ID' - */ -function set_key_field($keyfieldname='ID') -{ - $this->keyfieldname = $keyfieldname; - $this->key = isset($this->data[$keyfieldname]) ? $this->data[$keyfieldname] : ''; -} - - -/** - * Select a set of records of this table according to an array of selection - * and sorting criteria. - * Use fetch_next() to iterate through the result set
- * Example:
- * $record->select(array('Type' => 'bar', 'Date >=' => '1999-01-01', - * '-Date <' => 'NOW()', 'User NI' => 'chris'), 'ORDER BY Date'); - * - * @param $params optional array of fieldname => value tupels. - * These are ANDed to form a WHERE clause. - * fieldname can contain an operator (separated by space), the - * default operator is '='. The special operator 'NI' specifies - * that the argument must be contained in a comma-separated list. - * - * @param $sql Optional SQL addendum added after $params (ORDER BY etc.) - * @param $fields Optional field list to select (defaults to '*') - * @return Number of rows that matched this query - * @see it_db_record::fetch_next, it_db_table::construct_sql_clause - * - */ -function select($params='', $sql='', $fields='*') -{ - $this->handle = $this->table->safe_sql_select($this->table->construct_sql_clause($params, $sql), $fields); - return $this->table->db->num_rows($this->handle); -} - - -/** - * Post-process data after reading a record. - * This is a stub-function that can be overloaded. - */ -function _read_post_process() -{ -} - - -/** - * Pre-process data before writing a record. - * This is a stub-function that can be overloaded. - * @param $tags Reference to update/create tags, can be modified as needed - */ -function _write_pre_process(&$tags) -{ -} - - -/** - * Fetch the next record of a select() query - * @return true if a record was successfully fetched, false otherwise - * @see it_db_record::select - */ -function fetch_next() -{ - return $this->fetch($this->handle); -} - - -/** - * Fetch the next record from an SQL result into this object. - * If no more records are pending, clear the object's data. - * @param $sqlresult Result of table::sql_select() or similar - * @return 1 if a record was successfully fetched, 0 otherwise - */ -function fetch(&$sqlresult) -{ - $result = 0; - - if ($this->data = $this->table->db->fetch_assoc($sqlresult)) - { - $this->key = $this->data[$this->keyfieldname]; - $result = 1; - } - else - { - $this->key = ""; /* "No record is loaded" */ - $this->data = array(); /* Clear local record data */ - } - - $this->_read_post_process(); - - return $result; -} - - -/** - * Read a record from table - * @param $key key field value of the desired row - * @return 1 on success, 0 otherwise - */ -function read($key) -{ - $result = 0; - - if ($key != "") - { - $result = $this->fetch($this->table->safe_sql_select("WHERE $this->keyfieldname='" . mysql_real_escape_string($key) . "'")); - } - else - { - $this->key = ""; /* "No record is loaded" */ - $this->data = array(); /* Clear local record data */ - } - - $this->_read_post_process(); - - return $result; -} - - -/** - * Create a new record in the table - * @see it_db_record::record_create, it_db_record::safe_create - * @param $tags array of Fieldname/Value pairs - * @param $replace use REPLACE (1) instead of INSERT (otherwise) - * @return MySQL result (0 means failure) - */ -function create($tags, $replace=0) -{ - /* Pre-processing, $tags is passed by reference and may be modified here */ - $this->_write_pre_process($tags); - - $sql = $replace ? "REPLACE" : "INSERT"; - $sql .= " INTO " . $this->table->name . " ("; - $sql2 = ''; - - unset($this->data); - for ($sep=""; $ti = each($tags); $sep=",") - { - /* If the field name starts with '-', the value is taken as raw, no escaping - is done and no quotes are put around it. */ - if (substr($ti[0], 0, 1) == '-') - { - $ti[0] = substr($ti[0], 1); /* Strip that '-' sign */ - $val = $ti[1]; - } - else - $val = isset($ti[1]) ? "'".mysql_real_escape_string($ti[1])."'" : 'NULL'; - - $this->data[$ti[0]] = $ti[1]; /* Store data for later use */ - - $sql .= $sep . $ti[0]; - $sql2 .= "$sep$val"; - } - - $sql .= ") VALUES ($sql2)"; - - if ($result = $this->table->db->sql_query($sql)) - { - /* If the key element was not given, it means it's an AUTO_INCREMENT thingy. */ - if (($this->key = $this->data[$this->keyfieldname]) == "") - { - $result = $this->table->db->safe_sql_query("SELECT LAST_INSERT_ID()"); - $this->key = mysql_result($result, 0, 0); - } - - /* We need all fields from record, not only those we initialised */ - $this->read($this->key); - } - - return $result; -} - - -/** - * Safe version of create (doesn't return in case of failure) - * @see it_db_record::create, it_db_record::record_create - * @param $tags array of Fieldname/Value pairs - * @param $replace use REPLACE (1) instead of INSERT (otherwise) - * @return MySQL result (0 means failure) - */ -function safe_create($tags, $replace=0) -{ - if ($result = $this->create($tags, $replace)) - return $result; - else - fail("it_db_record::safe_create() failed: " . $this->table->db->error()); -} - - -/** - * Update a record in the table - * @param $tags array of Fieldname/Value pairs - * @return MySQL result (0 means failure) - */ -function update($tags) -{ - /* Pre-processing, $tags is passed by reference and may be modified here */ - $this->_write_pre_process($tags); - - if ($this->key == "") - it::fatal("it_db_record::update(): can't update undefined record"); - - /* If we have nothing to do, return instead of performing an invalid SQL query */ - if (!count($tags)) - return true; - - $sql = "UPDATE " . $this->table->name . " SET "; - - for ($sep="", $raw=0; $ti = each($tags); $sep=",") - { - /* If the field name starts with '-', the value is taken as raw, no escaping - is done and no quotes are put around it. */ - if (substr($ti[0], 0, 1) == '-') - { - $ti[0] = substr($ti[0], 1); /* Strip that '-' sign */ - $val = $ti[1]; - $raw++; - } - else - $val = "'".mysql_real_escape_string($ti[1])."'"; - - $sql .= $sep.$ti[0].'='.$val; - - if ($ti[0] == $this->key) - { - if ($this->data[$this->keyfieldname] != $ti[0]) - it::fatal("$sql: trying to change key from $this->key."); - } - - $this->data[$ti[0]] = $ti[1]; - } - - $sql .= " WHERE " . $this->keyfieldname . "='" . mysql_real_escape_string($this->key) . "'"; - - /* debug("it_db_record::update(): $sql"); */ - $ret = $this->table->db->safe_sql_query($sql); - - /* Only re-read record if necessary (for performance), but always do post-processing. */ - if ($raw) - $this->read($this->key); - else - $this->_read_post_process(); - - return $ret; -} - - -/** - * Delete the current record from the database - * @param $key keyfield value of the record to be deleted. If this is missing, the current record is deleted. - * @return MySQL result (0 means failure) - */ -function delete($key="") -{ - if (!$key) $key = $this->key; - - if (($this->table->name == "") || ($this->keyfieldname == "") || ($key == "")) - it::fatal("it_db_record::delete(): no record\n"); - - $sql = "DELETE FROM " . $this->table->name . " WHERE ". $this->keyfieldname . "='" . mysql_real_escape_string($key) . "'"; - if ($result = $this->table->db->sql_query($sql)) - { - $this->key = ""; - $this->data = array(); - } - return $result; -} - - -/** - * Return a field of a record. - * @param $field field name - * @return field value. If the field does not exists, issue an - * error message and terminate program execution. - */ -function safe_get_field($field) -{ - if ($field) - { - if (isset($this->data[$field])) - return $this->data[$field]; - else it::fatal("it_db_record::safe_get_field(): field \"$field\" not present in record."); - } - else it::fatal("it_db_record::safe_get_field(): empty field name"); -} - - -/** - * Output all fields of a record in (ugly) html format - */ -function dump_html() -{ - echo "
Dump of table " . $this->table->name . ", record " . $this->keyfieldname . " = \"" . $this->key . "\":
\n";
-	reset($this->data); next($this->data);
-	while(list($key, $value) = each($this->data))
-	{
-		if ($key > 0) continue;	/* $$$ ugly */
-		echo $key . " = \"" . htmlspecialchars($value) . "\"\n";
-	}
-	echo "

\n"; -} - - -/** - * Edit a record of a table. Create a new record if necessary.
- * Example:
- * $record->edit($id, array('ID' => $id)); - * - * @param $key key value of the row to edit - * @param $fixfields Array of fields not editable (with fixed values) - * @return 1=changed, 2=created, -1=deleted, 0=nothing changed - */ -function edit($key, $fixfields = array()) -{ - $returnresult = 0; - $numfields = $this->table->num_fields(); - - if ($_REQUEST['_COMMAND']) - { - /* - ** If the key field is changed, $key will carry a wrong value, so we - ** take the correct one from $_RECORD_KEY_VALUE - */ - $key = $_REQUEST['_RECORD_KEY_VALUE']; - - switch($_REQUEST['_COMMAND']) - { - case "EDIT": - $this->read($key); - $newdata = array(); - $changes = 0; - for ($i=0; $i < $numfields; ++$i) - { - $fieldname = $this->table->fieldnames[$i]; - - /* Assumes field order is fixed */ - if (isset($fixfields[$fieldname])) - $newvalue = $fixfields[$fieldname]; - else if (is_array($_REQUEST["_RECORD_$fieldname"])) - $newvalue = join(',', $_REQUEST["_RECORD_$fieldname"]); - else - $newvalue = $_REQUEST["_RECORD_$fieldname"]; - - if ($this->data[$fieldname] != $newvalue) - { - $newdata[$fieldname] = $newvalue; - $changes = 1; - } - } - - if ($changes) - { - if ($this->update($newdata)) - { - echo "Änderung erfolgreich durchgeführt.
\n"; - $returnresult = 1; - } - else - fail("Update failed."); - } - else echo "Keine Änderungen.
\n"; - break; - - case "CREATE": - $newdata = array(); - for ($i=0; $i < $numfields; ++$i) - { - $fieldname = $this->table->fieldnames[$i]; - - if (isset($fixfields[$fieldname])) - $newvalue = $fixfields[$fieldname]; - else if (is_array($_REQUEST["_RECORD_$fieldname"])) - $newvalue = join(',', $_REQUEST["_RECORD_$fieldname"]); - else - $newvalue = $_REQUEST["_RECORD_$fieldname"]; - - $newdata[$fieldname] = $newvalue; - } - - if ($this->create($newdata)) - { - $key = $this->key; - echo "Datensatz erzeugt.
\n"; - $returnresult = 2; - } - else - fail("Datensatz konnte nicht erzeugt werden."); - break; - - case "DELETE": - if ($this->delete($key)) - { - echo "Datensatz gelöscht.
\n"; - $returnresult = -1; - } - else - fail("Datensatz konnte nicht gelöscht werden."); - break; - - default: - fail("Unknown _COMMAND \"{$_REQUEST['_COMMAND']}\""); - /* NOT REACHED */ - } - } - - if ($key != "") - { - $this->read($key); - $cmd = "EDIT"; - $buttontext = "Änderungen übernehmen"; - } - else - { - $cmd = "CREATE"; - $buttontext = "Datensatz erzeugen"; - } - - echo "
keyfieldname\">key\">\n"; - echo "\n"; - for ($i=0; $i < $numfields; ++$i) - { - $fieldname = $this->table->fieldnames[$i]; - - /* Do not display fix fields */ - if (isset($fixfields[$fieldname])) - continue; - - $fieldflags = $this->table->fieldflags[$i]; - $fieldlen = $this->table->fieldlengths[$i]; - $size = min($fieldlen, 65); - - if ($fieldname == $this->keyfieldname) - echo ""; - else - echo ""; - - if (strstr($fieldflags, "blob")) - { - if (strlen($this->data["$fieldname"]) < 256) - echo "\n"; - else - echo "\n"; - } - else if (strstr($fieldflags, "enum")) - { - $result = $this->table->db->safe_sql_query("SHOW columns FROM ". $this->table->name . " LIKE '$fieldname'"); - $options = split("'", mysql_result($result, 0, 1)); - - $vals = explode(',', $this->data[$fieldname]); - - for ($j = 0; $j < count($vals); $j++) - $values[$vals[$j]] = 1; - - if (strstr($options[0], 'set')) - $attr = 'multiple'; - else - $attr = 'set="1"'; - - echo "\n"; - } - else - echo "\n"; - } - echo "
$fieldname
$fieldname
data["$fieldname"]) . "\">

\n"; - - if ($this->key != "") - echo "
keyfieldname\">key\">
\n"; - - return $returnresult; -} - -} /* End class it_db_record */ -?> diff --git a/db_table.class b/db_table.class deleted file mode 100644 index 5536ccf..0000000 --- a/db_table.class +++ /dev/null @@ -1,326 +0,0 @@ -db = &$db; - $this->name = $name; -} - - -/** - * Perform a safe SQL SELECT query on this table - * @see it_db::safe_sql_query - * @param $query additional query string, appended at the end of the generated query - * @param $fields comma seperated list of the columns to be returned - */ -function safe_sql_select($query, $fields="*") -{ - return $this->db->safe_sql_query("SELECT $fields FROM " . $this->name . " $query"); -} - - -/** - * Create an SQL query (the stuff after 'WHERE'). - * @see it_dbi::_where() for more details. - */ -function construct_sql_clause($params='', $sql='', $omit_where=false) -{ - return it_dbi::_where($params, $sql, $omit_where); -} - - -/** - * Return the count of rows on this table with optional WHERE clause - * @param $where Optional WHERE clause to narrow the set of rows to count - * @return Number of rows matching the WHERE clause - */ -function count($where='') -{ - $result = $this->safe_sql_select($where, 'COUNT(*)'); - $row = $this->db->fetch_assoc($result); - return $row['COUNT(*)']; -} - - -/* Internal: get information about fields */ -function _get_field_info() -{ - if ($this->numfields > 0) /* Already done! */ - return; - - if(($fields = mysql_list_fields($this->db->name, $this->name, $this->db->link)) >= 0) - { - $this->numfields = mysql_num_fields($fields); - for ($i=0; $i < $this->numfields; ++$i) - { - $name = mysql_field_name($fields, $i); - $this->fieldnames[$i] = $name; - $this->fieldtypes[$i] = $this->fieldtypes[$name] = mysql_field_type($fields, $i); - $this->fieldlengths[$i] = $this->fieldlengths[$name] = mysql_field_len($fields, $i); - $this->fieldflags[$i] = $this->fieldflags[$name] = mysql_field_flags($fields, $i); - /* debug("name='" . $this->fieldnames[$i] . "', len=" . $this->fieldlengths[$i] . ", type='" . $this->fieldtypes[$i] . "', flags='" . $this->fieldflags[$i] . "'\n", 6); */ - } - } - else it::fatal("mysql_list_fields($this->db->name, $this->name, $this->db->link) failed."); -} - - -/** - * Return a comma separated list of all field names of this table - */ -function field_names() -{ - $result = ''; - $this->_get_field_info(); - for ($i=0; $i < $this->numfields; ++$i) - { - if ($i > 0) $result .= ","; - $result .= $this->fieldnames[$i]; - } - return $result; -} - - -/** - * Return the length of a field - * @param $fieldname Name of the field - */ -function get_field_length($name) -{ - $this->_get_field_info(); - return $this->fieldlengths[$name]; -} - - -/** - * Return number of fields of a record of this table - */ -function num_fields() -{ - $this->_get_field_info(); - return $this->numfields; -} - - -/** - * Variable name used to propagate sort criteria - */ -function get_sort_variable_name() -{ - return "Sort" . md5($this->db->name . $this->name); -} - - -/** - * Print an SQL table as an HTML table. Supports user-sorting by column, - * limited WHERE clause, lists of fields to display and header texts, and - * a list of links for each field. - * @param $tableargs format string for the table or "" for default - * @param $sqlwhere SQL WHERE clause to restrict elements - * @param $c_fields comma seperated list of the fields to print - * @param $c_descriptions comma seperated list of the header labels to print - * @param $c_links dito with links to the respective elements - * @param $default_order default sort order: "fieldname" or "fieldname DESC" - * @param $rows_limit limit and position: "10" or "20,5" - */ -function dump_html($tableargs="", $sqlwhere="", $c_fields="", $c_descriptions="", $c_links="", $default_order="", $rows_limit="", $thispage="", $strip_tags=0) -{ - /* Unique identifier of this table */ - $table_sort = $this->get_sort_variable_name(); - - /* Default HTML table */ - if ($tableargs=="") - $tableargs="border=1 cellspacing=0 cellpadding=5"; - - /* Default field list: show them all */ - if ($c_fields == "") - $c_fields = $this->field_names(); - - /* Default list title: Field names */ - if ($c_descriptions == "") - $c_descriptions = $c_fields; - - $fields = split(",", $c_fields); - $descriptions = split(",", $c_descriptions); - $links = split(",", $c_links); - $numfields = count($fields); - - /* Default sort criterium: Ascending sort by first column */ - if ($default_order == "") - $default_order = $fields[0]; - - if (!in_array(it::replace(array(' DESC$' => ""), $_REQUEST[$table_sort]), $fields)) - $_REQUEST[$table_sort] = $default_order; - - $sql = "SELECT $c_fields FROM $this->name"; - - if ($sqlwhere) - $sql .= " WHERE $sqlwhere"; - - $sql .= " ORDER BY $_REQUEST[$table_sort]"; - - if ($rows_limit != "") - $sql .= " LIMIT $rows_limit"; - - $result = $this->db->safe_sql_query($sql); - - if ($this->db->num_rows($result) == 0) - { - if (is_object($GLOBALS['it_text'])) - echo T("db_NoObjectsFound"). "
\n"; - return; - } - - echo "\n"; - - /* Wenn man keine Titelzeile will, für c_descriptions einfach "," angeben */ - if ($descriptions[0]) - { - echo ''; - for ($i=0; $i < $numfields; ++$i) - { - if ($_REQUEST[$table_sort] == $fields[$i]) - { - $newsort = "$_REQUEST[$table_sort] DESC"; - $sortimg = ''; - } - else if ($_REQUEST[$table_sort] == "$fields[$i] DESC") - { - $newsort = $fields[$i]; - $sortimg = ''; - } - else - { - $newsort = $fields[$i]; - $sortimg = ''; - } - - echo "\n"; - } - echo "\n"; - } - - while ($f = $this->db->fetch_array($result)) - { - echo ""; - for ($i=0; $i<$numfields; ++$i) - { - $fieldspec = $f[$fields[$i]]; - if (!$fieldspec) $fieldspec = "  "; - if ($fieldspec == "0.00") $fieldspec = "-"; - /*if (strlen($fieldspec) > 80) $fieldspec = substr($fieldspec, 0, 80) . "..."; */ - - if (isset($links[$i])) - { - if (strstr($links[$i], "?")) $ch = "&"; else $ch = "?"; - $anchor=""; - $anchor2=""; - } - else - $anchor = $anchor2 = ""; - - if ($strip_tags) - $fieldspec = strip_tags($fieldspec); - echo ""; - } - echo "\n"; - } - echo "
\n"; - echo "\n\n"; - echo ''; - echo ''; - echo "\n
'. $descriptions[$i] .''. $sortimg .'
\n"; - echo "
$anchor" . $fieldspec . "$anchor2
\n"; -} - - -/** - * Make a 'select form field' ("Select-Form-Feld") from a table and pre-select an entry - * @param $name Name of FORM object to generate - * @param $selected Selected record - * @param $globaloption Option to add as first value, syntax: key,text - * @param $optionfield Table field to use for option keys - * @param $descriptionfield Table field to display - * @param $query SQL Query after "FROM ...", defaults to "ORDER BY $descriptionfield" - */ -function make_select($name, $selected, $globaloption, $optionfield, $descriptionfield, $query="") -{ - $globalopt = split(",", $globaloption); - - if (empty($query)) - $query = "ORDER BY $descriptionfield"; - $query = "SELECT * FROM $this->name $query"; - - echo "\n"; -} - - -/** - * Drops the current table from the database - * @return MySQL result (0 means failure) - */ -function drop() -{ - if ($this->name == '') - it::fatal("it_db_table::drop(): no table\n"); - - if ($result = $this->db->sql_query('DROP TABLE IF EXISTS '.$this->name)) - { - $this->name = ''; - $numfields = 0; - $fieldnames = array(); - $fieldtypes = array(); - $fieldlengths = array(); - $fieldflags = array(); - } - - return $result; -} - -} /* End class it_db_table */ -?> diff --git a/dbi.class b/dbi.class deleted file mode 100644 index 5666d28..0000000 --- a/dbi.class +++ /dev/null @@ -1,591 +0,0 @@ - null, - 'server' => "localhost", - 'server_update' => null, - 'user' => "itools", - 'pw' => "24%^jXC~", - 'safety' => 1, /* 0= never die, 1=die if query invalid, 2=die also if no results */ - 'keyfield' => "ID", - 'createclasses' => false, - 'classprefix' => "", - 'autoincrement' => true, - 'randomid' => false, - 'sqllog' => false, - 'persistent' => false, - ); - - # Key of currently loaded record or null (public readonly) - var $_key; - - # Array of name => length of table fields - var $_fields; - - -/** - * Constructor: Initialize the DBI interface - * @param $config array(key => value) of configuration data - * @param $query Optional initial query to run - */ -function it_dbi($config = array(), $query = null) -{ - # Shortcut: String config means use this table with default values - if (!is_array($config)) - $config = array('table' => $config); - - # Create current settings - foreach ($config + $this->_defaultconfig as $key => $value) - { - $var = "_$key"; - $this->$var = $value; - } - unset($this->_defaultconfig); /* to shorten print_r() output */ - - if (!isset($this->_db)) - if($config['home'] && ($site = it::match( "/www/([^/]+)", $config['home']))) - $this->_db = strtr( $site, ".-", "__" ); - else - $this->_db = $GLOBALS['ULTRADB']; - - $this->_dbid = "$this->_db/$this->_server/$this->_user"; - - $this->_defaults = ""; - foreach($config as $key => $value) - if ($key != 'createclasses') - $this->_defaults .= "'$key' => '".strtr($value, array('\'' => '\\\'', '$' => '\\$'))."', "; - - if ($this->_createclasses) - { - $this->_connect(); - - if (!($tables = mysql_list_tables($this->_db, $this->_link))) - $this->_fatal("it_dbi(): can't list on tables \"$this->_db\": " . mysql_error($this->_link)); - - for ($i = 0; $i < mysql_num_rows($tables); $i++) - $this->createclass(mysql_tablename($tables, $i)); - } - - if (!$GLOBALS['it_dbi'] && !$config['table']) - $GLOBALS['it_dbi'] =& $this; - - if (isset($query)) - { - if (is_array($query)) - $this->select($query); - else - $this->read($query); - } -} - -function _connect() -{ - if (!($this->_link = $GLOBALS['it_dbi_link'][$this->_dbid])) - { - # Use persistent connections but prevent reuse if only DB differs - if (!$this->_persistent || $GLOBALS['it_dbi_connected']["$this->_server/$this->_user"]++) - $this->_link = @mysql_connect($this->_server, $this->_user, $this->_pw, true); - else - $this->_link = @mysql_pconnect($this->_server, $this->_user, $this->_pw); - - if (!$this->_link) - { - # One retry after a short delay (always non-persistent) - it::log('sqllog', "it_dbi(): retrying DB link (mysql_connect $this->_server, $this->_db): " . mysql_error()); - sleep(1); - $this->_link = @mysql_connect($this->_server, $this->_user, $this->_pw, true); - } - - if (!$this->_link) - $this->_fatal("it_dbi(): can't create DB link (mysql_connect $this->_server, $this->_db): " . mysql_error()); - - if (!(@mysql_select_db($this->_db, $this->_link))) - $this->_fatal("it_dbi(): can't select database \"$this->_db\": " . mysql_error($this->_link)); - - $GLOBALS['it_dbi_link'][$this->_dbid] = $this->_link; - } -} - - -/** - * Convert table given by name into a class - */ -function createclass($table) -{ - $this->_connect(); - $classname = "$this->_classprefix$table"; - - if (!($result = @mysql_list_fields($this->_db, $table, $this->_link))) - $this->_fatal("it_dbi(): can't list fields \"$this->_db\": " . mysql_error($this->_link)); - - for ($fields=array(), $j=0; $j < mysql_num_fields($result); $j++) - { - $fields[mysql_field_name($result, $j)] = mysql_field_len($result, $j); - $flags = mysql_field_flags($result, $j); - - if (strstr($flags, "primary_key")) - { - $keyfield = mysql_field_name($result, $j); - $autoincrement = (bool)strstr($flags, "auto_increment"); - $randomid = (mysql_field_type($result, $j) == "string"); - } - } - - $fields = var_export($fields, true); - - if ((substr($classname, 0, 4) != 'PMA_') && !class_exists($classname)) - { - debug("it_dbi: creating class $classname", 5); - eval(" - class $classname extends it_dbi - { - function $classname(\$query = null, \$config = array()) - { - \$config += array({$this->_defaults}'table' => '$table', 'keyfield' => '$keyfield', 'autoincrement' => '$autoincrement', 'randomid' => '$randomid'); - \$this->_fields = $fields; - \$this->it_dbi(\$config, \$query); - } - } - "); - } -} - - - -/** - * Internal: construct SQL SET clause of changed values from member vars and tags array. - * Merge current values into $tags. Modifies caller's array (callers rely on it)! - */ -function _set(&$tags) -{ - $this->_connect(); - - # Add member vars to tags, considering unquoted fields - foreach (get_object_vars($this) as $field => $value) - # Don't use isset($tags[$field]) (would not handle null values correctly) - if (isset($this->_fields[$field]) && !array_key_exists('-'.$field, $tags) && !array_key_exists($field, $tags)) - $tags[$field] = $value; - - # Create SQL - $r = array(); - foreach((array)$tags as $key => $value) - { - if (substr($key, 0, 1) == '-') # Unquoted value (always added) - $r[] = substr($key, 1)."=$value"; - elseif (!isset($this->_data) || ($value !== $this->_data[$key])) # Add to SQL if value has changed - $r[] = "$key=".(isset($value) ? "'".mysql_real_escape_string($value, $this->_link)."'" : 'NULL'); - } - - return $r ? 'SET '.implode(', ', $r) : ''; -} - - -/** - * Create an SQL query (the stuff after 'WHERE') according to - * an array of selection criteria.
- * Example:
- * $sql = $table->construct_sql_clause(array('Type' => 'bar', - * 'Date >=' => '1999-01-01', '-Date <' => 'NOW()', - * 'User NI' => 'chris'), 'ORDER BY Date'); - * - * @param $params optional array of fieldname => value tupels. - * These are ANDed to form a WHERE clause. - * fieldname can contain an operator (separated by space), the - * default operator is '='. The special operator 'NI' specifies - * that the argument must be contained in a comma-separated list. - * @param $sql Optional SQL addendum (added after $params), for ORDER BY etc. - * @param $omit_where (optional) Do not add 'WHERE ' at beginning of result (default: false) - * @return The generated SQL clause - * @see it_db_record::select, it_db_record::fetch_next - */ -function _where($params='', $sql='', $omit_where=false) -{ - if (is_array($params) && (count($params) > 0)) - { - $query = ''; - $sep = ''; - - foreach($params as $field => $value) - { - if (is_int($field)) /* no key specified; just append */ - { - if ($field === $value) /* ignore array(1 => 1) et al */ - continue; - - $query .= " $value"; - } - else - { - $needs_where = true; - - if (!isset($value)) - { - $op = 'IS'; - $qval = 'NULL'; - } - else - { - if (preg_match('/^(\S+)\s+(\S.*)$/', $field, $regs)) - { - $field = $regs[1]; - $op = strtoupper($regs[2]); - } - else - $op = '='; - - /* If the field name starts with '-', the value is taken as raw, - no escaping is done and no quotes are put around it. */ - if (substr($field, 0, 1) == '-') - { - $field = substr($field, 1); /* Strip that '-' sign */ - $qval = $value; - } - else if (!is_array($value)) - $qval = "'".mysql_real_escape_string((string)$value)."'"; - } - - switch ($op) - { - case 'NI': - $query .= $sep."CONCAT(',',$field,',') LIKE '%,$value,%'"; - break; - - case 'IN': - case 'NOT IN': - if (is_array($value)) - { - if ($value) - $query .= "$sep$field $op ('" . join("','", array_map('mysql_real_escape_string', $value)) . "')"; # null is mapped to '' - else - $query .= $sep . "0"; - - break; - } - /* FALLTHROUGH */ - - default: - if (isset($qval)) - $query .= "$sep$field $op $qval"; - else - it::fatal('Undefined $qval when constructing query due to invalid $value (array)'); - break; - } - $sep = ' AND '; - } - } - - if ($needs_where && !$omit_where) - $query = 'WHERE '.$query; - - if ($sql) - $query .= ' '; - } - $query .= $sql; - - return $query; -} - - -/** - * Internal: Output class name::error message and terminate execution. - */ -function _fatal($text) -{ - it::fatal(get_class($this).'::'.$text); - /* NOT REACHED */ -} - - -/** - * Post-process data after reading a record. - * This is a stub-function that can be overloaded. - */ -function _read_post_process() -{ -} - - -/** - * Pre-process data before writing a record. - * This is a stub-function that can be overloaded. - * @param $tags Reference to update/create tags, can be modified as needed - */ -function _write_pre_process(&$tags) -{ -} - - -/** - * Clear record - */ -function clear($pp = true) -{ - foreach ((array)$this->_fields as $key => $value) - unset($this->$key); - unset($this->_data); - unset($this->_key); - $pp && $this->_read_post_process(); -} - - -/** - * Semi-internal: send a raw SQL query and return mysql result value - * @param $query complete SQL query string - * @return raw MySQL result. May die if query fails and safety is big enough - */ -function query($query) -{ - $this->_connect(); - debug(get_class($this)."::query(\"$query\")", 4); - - $start = gettimeofday(); - - if ($this->_server_update && !preg_match('/^(EXPLAIN|SELECT|SHOW) /i', $query)) - { - if ($this->_link = @mysql_connect($this->_server_update, $this->_user, $this->_pw, true)) - { - if (!mysql_select_db($this->_db, $this->_link)) - $this->_fatal("Error selecting update database '$this->_db' on host '$this->_server_update'."); - - $this->_server = $this->_server_update; - unset($this->_server_update); - $GLOBALS['it_dbi_link'][$this->_dbid] = $this->_link; # Update link cache for switching between databases - #it::log('sqllog', "switched to update server $this->_server"); - } - else - $this->_fatal("Error connecting to update database server '$this->_server_update' as user '$this->_user'."); - } - - if (!($result = mysql_query($query, $this->_link)) && $this->_safety) - { - if (($this->_safety < 2) && (mysql_errno($this->_link) == 1062)) /* Duplicate entry */ - return false; - - $error = mysql_errno($this->_link).' ('.mysql_error($this->_link).')'; - $trace = debug_backtrace(); - $res = mysql_fetch_row(mysql_query('select database()', $this->_link)); - $this->_fatal("query(\"$query\") on {$res[0]} failed: $error\nfile {$trace[1]['file']} line {$trace[1]['line']}"); - } - - - if ($this->_sqllog || EDC('sqllog')) - { - $end = gettimeofday(); - $msec = round(($end['sec'] - $start['sec']) * 1000 + ($end['usec'] - $start['usec']) / 1000); - it::log('sqllog', "$msec\t$query"); - } - - return $result; -} - - -/** - * Read a single record by primary key, not destroying old query result $this->_result - * @param $id primary key. If null, record is cleared - * @return True if record could be read, false if not. - */ -function read($id=null) -{ - $mres = $this->_result; - $result = $this->select(array($this->_keyfield => $id)); - $this->_result = $mres; - return $result; -} - - -/** - * Select a set of records from table and fetch the first one - * @param $query Optional array of (field => value) or (int => sqlstring) pairs. Defaults to null (select all records) - * Can contain magic field 'SELECT' for things like 'COUNT(*)' or 'DISTINCT foo', defaults to '*' - * Can contain magic field 'JOIN' for things like 'tableA LEFT JOIN tableB ON a=b', defaults to table name - * If magic field 'CALC_FOUND_ROWS' is true, sets member var _found_rows to number of matching rows without LIMIT - * If magic field 'NOFETCH' is true, then the first row is not prefetched (e.g. when directly using _result) - * @return Number of matching rows, use iterate() to fetch the next record - * @see it_dbi::iterate(), it_db_table::construct_sql_clause() - */ -function select($query = null) -{ - $result = 0; - $calc_found_rows = false; - - $what = '*'; - if (isset($query['SELECT'])) - { - $what = $query['SELECT']; - unset($query['SELECT']); - } - - $join = $this->_table; - if (isset($query['JOIN'])) # WARNING: this field gets abused for "tablename USE INDEX (fast2) - { - $join = $query['JOIN']; - unset($query['JOIN']); - } - - unset($this->_found_rows); - if (isset($query['CALC_FOUND_ROWS']) && $query['CALC_FOUND_ROWS']) - { - $calc_found_rows = true; - $what = 'SQL_CALC_FOUND_ROWS '.$what; - unset($query['CALC_FOUND_ROWS']); - } - - $nofetch = $this->_nofetch = isset($query['NOFETCH']) ? $query['NOFETCH'] : false; - unset(