summaryrefslogtreecommitdiff
path: root/it.class
diff options
context:
space:
mode:
Diffstat (limited to 'it.class')
-rw-r--r--it.class74
1 files changed, 57 insertions, 17 deletions
diff --git a/it.class b/it.class
index 624f601..1be8f7c 100644
--- a/it.class
+++ b/it.class
@@ -123,6 +123,7 @@ static function timerlog($label = '')
* @param $p['graceperiod'] number of seconds within which additional errors are ignored if id is set
* @param $p['timewindow'] number of seconds after graceperiod within which the second error must occur if id is set
* @param $p['backtraceskip'] number of stack levels to drop
+ * @param $p['skipfiles'] files to skip in backtrace
* @param $p['blockmail'] number of seconds to block mails after having sent a mail [3600]
* @param $p['blockmailid'] block mail for $p['blockmail'] seconds with same id. Default: $p['to']
* @param $p['omitdebuginfo'] Do not add stack dump, locals and environment to output [false]
@@ -193,7 +194,7 @@ static function error($p = array(), $body = null, $to = null) # $body and $to de
if ($toscreen || $sendmail)
{
- $trace = it_debug::backtrace($p['backtraceskip']); # moved in here for performance in mass error case
+ $trace = it_debug::backtrace(array('skiplevels' => $p['backtraceskip'], 'skipfiles' => $p['skipfiles'])); # moved in here for performance in mass error case
if (strlen($p['body']) > 500000)
{
@@ -230,7 +231,7 @@ static function error($p = array(), $body = null, $to = null) # $body and $to de
it::mail(array('To' => $p['to'], 'Subject' => substr($p['title'], 0, 80), 'Body' => $body) + (($cc = $GLOBALS['it_defaultconfig']['error_cc']) ? array('Cc' => $cc) : array()));
}
else if ($_SERVER['REMOTE_ADDR']) # toscreen mode: web
- echo "<pre>{$p['title']}\n".rtrim($body)."</pre>";
+ echo "<pre>" . htmlspecialchars($p['title'] . "\n" . rtrim($body), ENT_COMPAT, "iso-8859-1") . "</pre>"; # works with iso-8859-1 or utf-8, UTF8SAFE
else # toscreen mode: shell (outputs to stderr)
error_log($p['title'] . " in " . ($trace ? $trace : "{$p['file']}:{$p['line']} Url: $url") . " " . (EDC('verbose') ? D($p['locals']) : ""));
}
@@ -334,7 +335,6 @@ static function convertregex($pattern, $p = null)
* @param $string String to match
* @param $p['offset_capture'] Set flag preg_offset_capture (returns offsets with the matches).
* @param $p['all'] Return every match as array instead of first match.
- * @param $p['locale'] Use given locale (default: de_CH), mainly affects handling of iso-latin chars
* @param $p contains pattern modifiers, @see convertregex()
* @return Matched string or false
*/
@@ -346,21 +346,18 @@ static function match($pattern, $string, $p = null)
{
$flags = $p['offset_capture'] ? PREG_OFFSET_CAPTURE : 0;
- $oldlocale = setlocale(LC_CTYPE, 0);
- setlocale(LC_CTYPE, $p['locale'] ? $p['locale'] : "de_CH");
-
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']);
-
- setlocale(LC_CTYPE, $oldlocale);
}
if (!$r) # no match
{
if (preg_last_error() == PREG_BACKTRACK_LIMIT_ERROR)
it::error("Exceeded pcre.backtrack_limit of " . ini_get('pcre.backtrack_limit') . " bytes");
+ else if (preg_last_error() == PREG_BAD_UTF8_ERROR)
+ it::error("Input to it::match is not valid utf-8");
$result = $p['all'] ? array() : null;
}
@@ -384,23 +381,66 @@ static function match($pattern, $string, $p = null)
*/
static function replace($replacements, $string, $p = array())
{
+ $encoding = ini_get('default_charset') == 'utf-8' ? 'u' : '';
foreach ($replacements as $pattern => $dummy)
- $patterns[] = !preg_match('/\\\\[wb]|[!\x80-\xff]|\[\[:/i', $pattern) && !$p ? "!$pattern!i" : it::convertregex($complex = $pattern, $p);
+ $patterns[] = !preg_match('/\\\\[wb]|[!\x80-\xff]|\[\[:/i', $pattern) && !$p ? "!$pattern!i$encoding" : it::convertregex($pattern, $p);
+
+ $result = preg_replace($patterns, $replacements, $string, isset($p['limit']) ? $p['limit'] : -1);
+
+ if ($result === null && preg_last_error() == PREG_BAD_UTF8_ERROR)
+ it::error("Input to it::replace is not valid utf-8");
- if (!$complex && !$p)
- $result = preg_replace($patterns, $replacements, $string);
+ return $result;
+}
+
+/**
+ * Returns only the array elements matching the given regex
+ * @param $pattern Regex to match against
+ * @param $array array to grep
+ * @return New array
+ */
+static function grep($pattern, $array, $p = array())
+{
+ if (!preg_match('/\\\\[wb]|[!\x80-\xff]|\[\[:/i', $pattern) && !$p)
+ $result = preg_grep('!' . $pattern . '!i' . (ini_get('default_charset') == 'utf-8' ? 'u' : ''), $array); # fast path for simple patterns
else
- {
- $oldlocale = setlocale(LC_CTYPE, 0);
- setlocale(LC_CTYPE, 'de_CH');
- $result = preg_replace($patterns, $replacements, $string, isset($p['limit']) ? $p['limit'] : -1);
- setlocale(LC_CTYPE, $oldlocale);
- }
+ $result = preg_grep(it::convertregex($pattern, $p), $array);
return $result;
}
/**
+ * Convert string to utf8 if it was not already utf-8 before
+ * @param $value String to convert
+ * @return Same string in utf-8 encoding
+ */
+function any2utf8($value)
+{
+ return grapheme_strlen($value) === null ? utf8_encode($value) : $value;
+}
+
+/**
+ * Uppercase first character similar to ucfirst() but for mbstring.internal_encoding
+ */
+static function ucfirst($string)
+{
+ return mb_strtoupper(mb_substr($string, 0, 1)) . mb_substr($string, 1);
+}
+
+/**
+ * Uppercase first character of each word similar to ucwords() but for mbstring.internal_encoding
+ */
+static function ucwords($string)
+{
+ return preg_replace_callback('/\b\w/u', function($m) { return mb_strtoupper($m[0]); }, mb_strtolower($string));
+}
+
+static function substr_replace($string, $replacement, $start, $length)
+{
+ return grapheme_substr($string, 0, $start) . $replacement . grapheme_substr($string, $start + $length);
+}
+
+/**
* Extract key => value pairs from assoc array by key
* @param $array array to filter
* @param $keys array or comma separated list of keys to keep