=')) ? clone($object) : $object; return $result; # PHP internals need a tmp var to return by ref } /** * Append a line to a logfile in log/. Date will be added to filename and line * @param $name Name of logfile * @param $line1 Line to append (varargs) */ function log($name /* ... */) { $args = func_get_args(); $line = date("Y-m-d H:i:s") . "\t" . implode("\t", array_slice($args, 1)) . "\n"; if ($fh = fopen($GLOBALS['ULTRAHOME'] . "/log/$name-" . date('Ymd'), "a")) { fputs($fh, $line); fclose($fh); } } /** * Store timings for appending to log/timer_log-* in auto_append.php */ function timerlog($label = '') { if ($GLOBALS['debug_timerlog']) { $s = $GLOBALS['ULTRATIME']; $e = gettimeofday(); $msec= ($e['sec'] - $s['sec']) * 1000 + ($e['usec'] - $s['usec']) / 1000; $GLOBALS['ULTRATIMERLOG'] .= sprintf(" %s:%d", $label, $msec); } } /** * Send error report either to browser (on devel/twin machines) or by email to .diffnotice guys * @parma $title (optional) error title, one line * @param $body (optional) error body, multiline * @param $to (optional) comma separated recipient list * @param named parameter id identifier of error. if given, only subsequent errors of same id will trigger message * @param named parameter timewindow number of seconds within which the second error must occur * @param named parameter interval minimum number of seconds between alerts */ function error($p = array(), $body = "", $to = "") { if (is_array($p)) { $title = $p['title']; $body = $p['body']; $to = $p['to']; } else { $title = $p; $p = array(); } $p += array('timewindow' => 25*3600, 'interval' => 6*3600); if (!$to) $to = strtr(trim(@file_get_contents($GLOBALS['ULTRAHOME'] . "/.diffnotice")), array("\n"=>',', ' '=>'')); if ($p['id']) { $stampfn = $GLOBALS['ULTRAHOME'] . "/tmp/errstamp_" . urlencode($p['id']); $stampage = time() - @filemtime($stampfn); if ($stampage >= 60 && $stampage <= $p['timewindow']) $sendalert = true; if ($stampage >= 60) # constantly occurring errors should not suppress mail touch($stampfn); } else $sendalert = true; if ($sendalert) { $url = ($_SERVER['HTTPS'] ? "https://" : "http://") . $_SERVER['HTTP_HOST'] .$_SERVER['REQUEST_URI']; if (!$title) $title="Error in $url"; $body .= "\nUrl: $url\n\n\$_REQUEST: ".print_r($_REQUEST, true). "\nStack:\n" . print_r(array_slice(debug_backtrace(), 1), true) . "\n\$_SERVER: " . print_r($_SERVER, true); if (!ereg('live', $GLOBALS['ULTRASERVERTYPE'])) { echo "
$title\n$body\n"; } else { $cmd = "alert -l -i " . escapeshellarg($p['interval']) ." " . escapeshellarg($to) . " 4 " . escapeshellarg($title); EDC('exec', $cmd); if (($pipe = popen($cmd, "w"))) { fputs($pipe, $body); pclose($pipe); } error_log("it::error: ".$title); } } } /** * Same as error(), plus exit */ function fatal($title='', $body='', $to='') { it::error($title, $body, $to); exit; } /** * Return "db4" or "db2" depending on availability */ function dba_handler() { return in_array("db4", dba_handlers()) ? "db4" : "db2"; } /** * Convert a string to ASCII-only chars, map/strip ISO-8859-1 accents * @param $text Text to convert * @return mapped/stripped version of $text contains only chars [0..127] */ function toascii($text) { return strtr(strtr($text, 'ÇéâàåçêëèïîìÅÉôòûùÿøØáíóúñÑÁÂÀãÃÊËÈÍÎÏÓÔõÕÚÛÙýÝ', 'CeaaaceeeiiiAEoouuyooaiounNAAAaAEEEIIIOOoOUUUyY'), array('ä' => 'ae', 'ö' => 'oe', 'ü' => 'ue', 'Ä' => 'Ae', 'Ö' => 'Oe', 'Ü' => 'Ue', 'æ' => 'ae', 'Æ' => 'Ae', 'ß' => 'ss')); } /** * Convert regex for preg (redefines \w,\W,\b,\B, adds and escapes delimiter, adds modifiers) * @param $pattern Regex to convert * @param named parameter casesensitive Regex is case sensitive (omit modifier i) * @param named parameter multiline add modifier m * @param named parameter singleline add modifier s * @param named parameter utf8 add modifier u * @param named parameter extended add modifier x * @return converted regex to use with preg */ function convertregex( $pattern, $p = array() ) { $wordchar = 'a-zA-Z0-9_\xa0-\xff'; $nonwordchar = '\x00-\x2f\x3a-\x40\x5B-\x60\x7b-\x9f'; #matches only even number of backslashes (double escaped for php and preg) $nonesc = '(? "\$1$wordchar", # \W in character class "/($incharclass$nonesc)\\\\W/" => "\$1$nonwordchar", # normal \w "/($nonesc)\\\\w/" => "\$1[$wordchar]", # normal \W "/($nonesc)\\\\W/" => "\$1[$nonwordchar]", # \b (use negative assertions to match at end of string) "/($nonesc)\\\\b/" => "\$1(?:(? "\$1(?:(?<=[$wordchar])(?=[$wordchar])|(?<=[$nonwordchar])(?=[$nonwordchar]))", ); $pattern = preg_replace( array_keys( $replaces ), array_values( $replaces ), $pattern ); if( ! $p['casesensitive'] ) $modifiers .= 'i'; foreach( array( 'multiline' => 'm', 'singleline' => 's', 'utf8' => 'u', 'extended' => 'x', ) as $key => $mod ) if( $p[$key] ) $moifiers .= $mod; return "/" . $pattern . "/" . $modifiers; } /** * Try to match string against regex. See convertregex for additional named parameters. * @param $pattern Regex to match against * @param $string String to match * @param named parameter offset_capture Set flag preg_offset_capture (returns offsets with the matches). * @param named parameter all Return every match as array instead of first match. * @return Matched string or false */ function match( $pattern, $string, $p = array() ) { $flags = 0; if( $p['offset_capture'] ) $flags |= PREG_OFFSET_CAPTURE; if( $p['all'] ) $r = preg_match_all( it::convertregex( $pattern, $p ), $string, $m, $flags | PREG_PATTERN_ORDER, $p['offset'] ); else $r = preg_match( it::convertregex( $pattern, $p ), $string, $m, $flags, $p['offset'] ); # no match if( !$r ) return false; # no capture else if( count( $m ) == 1 ) return $m[0]; # one capture else if( count( $m ) == 2 ) return $m[1]; # captures, reorder pattern_order to set_order but without first element else if( $p['all'] && !$p['pattern_order'] ) return call_user_func_array( 'array_map', array_merge( array( null ), array_slice( $m, 1 ) ) ); # captures, don't return first element (matched string) else return array_slice( $m, 1 ); } /** * Replace parts of a string matched by a pattern with according replacement string. See convertregex for named parameters. * @param $replacementes Array with patterns as keys and replacement strings as values. * @param $string String to change. * @return New string. */ function replace( $replacements, $string, $p = array() ) { $patterns = array(); foreach( array_keys( $replacements ) as $pat ) $patterns[] = it::convertregex( $pat, $p ); return preg_replace( $patterns, array_values( $replacements ), $string, isset( $p['limit'] ) ? $p['limit'] : -1 ); } } ?>