Пример #1
0
    /**
     * Displays a MySQL error message in the main panel when $exit is true.
     * Returns the error message otherwise.
     *
     * @param string|bool $server_msg     Server's error message.
     * @param string      $sql_query      The SQL query that failed.
     * @param bool        $is_modify_link Whether to show a "modify" link or not.
     * @param string      $back_url       URL for the "back" link (full path is
     *                                    not required).
     * @param bool        $exit           Whether execution should be stopped or
     *                                    the error message should be returned.
     *
     * @return string
     *
     * @global string $table The current table.
     * @global string $db    The current database.
     *
     * @access public
     */
    public static function mysqlDie(
        $server_msg = '',
        $sql_query = '',
        $is_modify_link = true,
        $back_url = '',
        $exit = true
    ) {
        global $table, $db;

        /**
         * Error message to be built.
         * @var string $error_msg
         */
        $error_msg = '';

        // Checking for any server errors.
        if (empty($server_msg)) {
            $server_msg = $GLOBALS['dbi']->getError();
        }

        // Finding the query that failed, if not specified.
        if ((empty($sql_query) && (!empty($GLOBALS['sql_query'])))) {
            $sql_query = $GLOBALS['sql_query'];
        }
        $sql_query = trim($sql_query);

        /**
         * The lexer used for analysis.
         * @var Lexer $lexer
         */
        $lexer = new Lexer($sql_query);

        /**
         * The parser used for analysis.
         * @var Parser $parser
         */
        $parser = new Parser($lexer->list);

        /**
         * The errors found by the lexer and the parser.
         * @var array $errors
         */
        $errors = ParserError::get(array($lexer, $parser));

        if (empty($sql_query)) {
            $formatted_sql = '';
        } elseif (count($errors)) {
            $formatted_sql = htmlspecialchars($sql_query);
        } else {
            $formatted_sql = self::formatSql($sql_query, true);
        }

        $error_msg .= '<div class="error"><h1>' . __('Error') . '</h1>';

        // For security reasons, if the MySQL refuses the connection, the query
        // is hidden so no details are revealed.
        if ((!empty($sql_query)) && (!(mb_strstr($sql_query, 'connect')))) {
            // Static analysis errors.
            if (!empty($errors)) {
                $error_msg .= '<p><strong>' . __('Static analysis:')
                    . '</strong></p>';
                $error_msg .= '<p>' . sprintf(
                    __('%d errors were found during analysis.'),
                    count($errors)
                ) . '</p>';
                $error_msg .= '<p><ol>';
                $error_msg .= implode(
                    ParserError::format(
                        $errors,
                        '<li>%2$s (near "%4$s" at position %5$d)</li>'
                    )
                );
                $error_msg .= '</ol></p>';
            }

            // Display the SQL query and link to MySQL documentation.
            $error_msg .= '<p><strong>' . __('SQL query:') . '</strong>' . "\n";
            $formattedSqlToLower = mb_strtolower($formatted_sql);

            // TODO: Show documentation for all statement types.
            if (mb_strstr($formattedSqlToLower, 'select')) {
                // please show me help to the error on select
                $error_msg .= self::showMySQLDocu('SELECT');
            }

            if ($is_modify_link) {
                $_url_params = array(
                    'sql_query' => $sql_query,
                    'show_query' => 1,
                );
                if (strlen($table) > 0) {
                    $_url_params['db'] = $db;
                    $_url_params['table'] = $table;
                    $doedit_goto = '<a href="tbl_sql.php'
                        . URL::getCommon($_url_params) . '">';
                } elseif (strlen($db) > 0) {
                    $_url_params['db'] = $db;
                    $doedit_goto = '<a href="db_sql.php'
                        . URL::getCommon($_url_params) . '">';
                } else {
                    $doedit_goto = '<a href="server_sql.php'
                        . URL::getCommon($_url_params) . '">';
                }

                $error_msg .= $doedit_goto
                   . self::getIcon('b_edit.png', __('Edit'))
                   . '</a>';
            }

            $error_msg .= '    </p>' . "\n"
                . '<p>' . "\n"
                . $formatted_sql . "\n"
                . '</p>' . "\n";
        }

        // Display server's error.
        if (!empty($server_msg)) {
            $server_msg = preg_replace(
                "@((\015\012)|(\015)|(\012)){3,}@",
                "\n\n",
                $server_msg
            );

            // Adds a link to MySQL documentation.
            $error_msg .= '<p>' . "\n"
                . '    <strong>' . __('MySQL said: ') . '</strong>'
                . self::showMySQLDocu('Error-messages-server')
                . "\n"
                . '</p>' . "\n";

            // The error message will be displayed within a CODE segment.
            // To preserve original formatting, but allow word-wrapping,
            // a couple of replacements are done.
            // All non-single blanks and  TAB-characters are replaced with their
            // HTML-counterpart
            $server_msg = str_replace(
                array('  ', "\t"),
                array('&nbsp;&nbsp;', '&nbsp;&nbsp;&nbsp;&nbsp;'),
                $server_msg
            );

            // Replace line breaks
            $server_msg = nl2br($server_msg);

            $error_msg .= '<code>' . $server_msg . '</code><br/>';
        }

        $error_msg .= '</div>';
        $_SESSION['Import_message']['message'] = $error_msg;

        if (!$exit) {
            return $error_msg;
        }

        /**
         * If this is an AJAX request, there is no "Back" link and
         * `Response()` is used to send the response.
         */
        $response = Response::getInstance();
        if ($response->isAjax()) {
            $response->setRequestStatus(false);
            $response->addJSON('message', $error_msg);
            exit;
        }

        if (!empty($back_url)) {
            if (mb_strstr($back_url, '?')) {
                $back_url .= '&amp;no_history=true';
            } else {
                $back_url .= '?no_history=true';
            }

            $_SESSION['Import_message']['go_back_url'] = $back_url;

            $error_msg .= '<fieldset class="tblFooters">'
                . '[ <a href="' . $back_url . '">' . __('Back') . '</a> ]'
                . '</fieldset>' . "\n\n";
        }

        exit($error_msg);
    }
Пример #2
0
 public function runLint()
 {
     $params = $this->parseLint();
     if ($params === false) {
         return 1;
     }
     if (isset($params['h'])) {
         $this->usageLint();
         return 0;
     }
     if (isset($params['q'])) {
         $lexer = new Lexer($params['q'], false);
         $parser = new Parser($lexer->list);
         $errors = Error::get(array($lexer, $parser));
         if (count($errors) == 0) {
             return 0;
         }
         $output = Error::format($errors);
         echo implode("\n", $output);
         echo "\n";
         return 10;
     }
     echo "ERROR: Missing parameters!\n";
     $this->usageLint();
     return 1;
 }
Пример #3
0
 public function testFormat()
 {
     $this->assertEquals(array('#1: error msg (near "token" at position 100)'), Error::format(array(array('error msg', 42, 'token', 100))));
 }
Пример #4
0
 /**
  * Runs the linting process.
  *
  * @param string $query The query to be checked.
  *
  * @return array
  */
 public static function lint($query)
 {
     // Disabling lint for huge queries to save some resources.
     if (mb_strlen($query) > 10000) {
         return array(array('message' => __('Linting is disabled for this query because it exceeds the ' . 'maximum length.'), 'fromLine' => 0, 'fromColumn' => 0, 'toLine' => 0, 'toColumn' => 0, 'severity' => 'warning'));
     }
     /**
      * Lexer used for tokenizing the query.
      *
      * @var Lexer
      */
     $lexer = new Lexer($query);
     /**
      * Parsed used for analysing the query.
      *
      * @var Parser
      */
     $parser = new Parser($lexer->list);
     /**
      * Array containing all errors.
      *
      * @var array
      */
     $errors = Error::get(array($lexer, $parser));
     /**
      * The response containing of all errors.
      *
      * @var array
      */
     $response = array();
     /**
      * The starting position for each line.
      *
      * CodeMirror requires relative position to line, but the parser stores
      * only the absolute position of the character in string.
      *
      * @var array
      */
     $lines = static::getLines($query);
     // Building the response.
     foreach ($errors as $idx => $error) {
         // Starting position of the string that caused the error.
         list($fromLine, $fromColumn) = static::findLineNumberAndColumn($lines, $error[3]);
         // Ending position of the string that caused the error.
         list($toLine, $toColumn) = static::findLineNumberAndColumn($lines, $error[3] + mb_strlen($error[2]));
         // Building the response.
         $response[] = array('message' => sprintf(__('%1$s (near <code>%2$s</code>)'), $error[0], $error[2]), 'fromLine' => $fromLine, 'fromColumn' => $fromColumn, 'toLine' => $toLine, 'toColumn' => $toColumn, 'severity' => 'error');
     }
     // Sending back the answer.
     return $response;
 }