diff --git a/core/model/Database.php b/core/model/Database.php index 363d57293..69a3e7569 100755 --- a/core/model/Database.php +++ b/core/model/Database.php @@ -423,7 +423,7 @@ abstract class Database extends Object { * @param int $errorLevel The level of the error to throw. */ function databaseError($msg, $errorLevel = E_USER_ERROR) { - user_error("DATABASE ERROR: $msg", $errorLevel); + user_error($msg, $errorLevel); } /** diff --git a/core/model/MySQLDatabase.php b/core/model/MySQLDatabase.php index 3575cc6ec..b4d170891 100644 --- a/core/model/MySQLDatabase.php +++ b/core/model/MySQLDatabase.php @@ -385,6 +385,16 @@ class MySQLDatabase extends Database { public function affectedRows() { return mysql_affected_rows($this->dbConn); } + + function databaseError($msg, $errorLevel = E_USER_ERROR) { + // try to extract and format query + if(preg_match('/Couldn\'t run query: ([^\|]*)\|\s*(.*)/', $msg, $matches)) { + $formatter = new SQLFormatter(); + $msg = "Couldn't run query: \n" . $formatter->formatPlain($matches[1]) . "\n\n" . $matches[2]; + } + + user_error($msg, $errorLevel); + } } /** diff --git a/dev/Debug.php b/dev/Debug.php index bf03e078a..925553024 100644 --- a/dev/Debug.php +++ b/dev/Debug.php @@ -284,7 +284,7 @@ class Debug { * Create an instance of an appropriate DebugView object. */ static function create_debug_view() { - if(Director::is_cli()) return new CliDebugView(); + if(Director::is_cli() || Director::is_ajax()) return new CliDebugView(); else return new DebugView(); } @@ -304,33 +304,32 @@ class Debug { $errText = str_replace(array("\n","\r")," ",$errText); header("HTTP/1.0 500 $errText"); } - if(Director::is_ajax()) { - echo "ERROR:Error $errno: $errstr\n At l$errline in $errfile\n"; - Debug::backtrace(); - } else { - $reporter = self::create_debug_view(); - - // Coupling alert: This relies on knowledge of how the director gets its URL, it could be improved. - $httpRequest = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : $_REQUEST['url']; - if(isset($_SERVER['REQUEST_METHOD'])) $httpRequest = $_SERVER['REQUEST_METHOD'] . ' ' . $httpRequest; + + // Legacy error handling for customized prototype.js Ajax.Base.responseIsSuccess() + // if(Director::is_ajax()) echo "ERROR:\n"; + + $reporter = self::create_debug_view(); + + // Coupling alert: This relies on knowledge of how the director gets its URL, it could be improved. + $httpRequest = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : $_REQUEST['url']; + if(isset($_SERVER['REQUEST_METHOD'])) $httpRequest = $_SERVER['REQUEST_METHOD'] . ' ' . $httpRequest; - $reporter->writeHeader($httpRequest); - $reporter->writeError($httpRequest, $errno, $errstr, $errfile, $errline, $errcontext); + $reporter->writeHeader($httpRequest); + $reporter->writeError($httpRequest, $errno, $errstr, $errfile, $errline, $errcontext); - $lines = file($errfile); + $lines = file($errfile); - // Make the array 1-based - array_unshift($lines,""); - unset($lines[0]); + // Make the array 1-based + array_unshift($lines,""); + unset($lines[0]); - $offset = $errline-10; - $lines = array_slice($lines, $offset, 16, true); - $reporter->writeSourceFragment($lines, $errline); + $offset = $errline-10; + $lines = array_slice($lines, $offset, 16, true); + $reporter->writeSourceFragment($lines, $errline); - $reporter->writeTrace($lines); - $reporter->writeFooter(); - exit(1); - } + $reporter->writeTrace($lines); + $reporter->writeFooter(); + exit(1); } /** diff --git a/parsers/SQLFormatter.php b/parsers/SQLFormatter.php new file mode 100644 index 000000000..cf1aa2afd --- /dev/null +++ b/parsers/SQLFormatter.php @@ -0,0 +1,58 @@ +@silverstripe.com) + * @usedby Database->databaseError() + */ +class SQLFormatter extends Object { + + protected static $newline_before_tokens = array( + 'SELECT', + 'UPDATE', + 'INSERT', + 'DELETE', + 'FROM', + 'INNER JOIN', + 'FULL JOIN', + 'LEFT JOIN', + 'RIGHT JOIN', + 'WHERE', + 'ORDER BY', + 'GROUP BY', + 'LIMIT', + ); + + public function formatPlain($sql) { + $sql = $this->addNewlines($sql, false); + + return $sql; + } + + public function formatHTML($sql) { + $sql = $this->addNewlines($sql, true); + + return $sql; + } + + /** + * Newlines for tokens defined in $newline_before_tokens. + * Case-sensitive, only applies to uppercase SQL to avoid + * messing with possible content fragments in the query. + */ + protected function addNewlines($sql, $useHtmlFormatting = false) { + foreach(self::$newline_before_tokens as $token) { + $breakToken = ($useHtmlFormatting) ? "
\n" : "\n"; + $sql = preg_replace('/[^\n](' . $token . ')/', $breakToken . '$1', $sql); + } + + return $sql; + } + +} +?> \ No newline at end of file diff --git a/tests/SQLFormatterTest.php b/tests/SQLFormatterTest.php new file mode 100644 index 000000000..0c1028b3b --- /dev/null +++ b/tests/SQLFormatterTest.php @@ -0,0 +1,41 @@ +assertEquals($formatter->formatPlain($sqlBefore), $sqlAfter, + 'correct replacement of newlines and don\'t replace non-uppercase tokens' + ); + + $sqlBefore = <<assertEquals($formatter->formatPlain($sqlBefore), $sqlAfter, + 'Leave existing newlines and indentation in place' + ); + } + +} +?> \ No newline at end of file