Example #1
0
/**
 * Parse query and replace placeholders with data
 *
 * @param string $query unparsed query
 * @param array $data data for placeholders
 * @return parsed query
 */
function db_process($pattern, $data = array(), $replace = true)
{
    static $session_vars_updated = false;
    $command = 'get';
    $group_concat_len = 3000;
    // 3Kb
    // Check if query updates data in the database
    if (preg_match("/^(UPDATE|INSERT INTO|REPLACE INTO|DELETE FROM) \\?\\:(\\w+) /", $pattern, $m)) {
        $table_name = $m[2];
        //str_replace(TABLE_PREFIX, '', $m[2]);
        Registry::set_changed_tables($table_name);
        Registry::register_cache('cached_queries', array(), CACHE_LEVEL_STATIC, true);
        $cached_queries = Registry::if_get('cached_queries', array());
        if (!empty($cached_queries)) {
            foreach ($cached_queries as $cquery => $ctables) {
                if (in_array($table_name, $ctables)) {
                    unset($cached_queries[$cquery]);
                }
            }
            Registry::set('cached_queries', empty($cached_queries) ? array(0 => array()) : $cached_queries);
        }
        $command = $m[1] == 'DELETE FROM' ? 'delete' : 'set';
    }
    if (strpos($pattern, 'GROUP_CONCAT(') !== false && $session_vars_updated == false) {
        db_query('SET SESSION group_concat_max_len = ?i', $group_concat_len);
        $session_vars_updated = true;
    }
    if (!empty($data) && preg_match_all("/\\?(i|s|l|d|a|n|u|e|p|w|f)+/", $pattern, $m)) {
        $offset = 0;
        foreach ($m[0] as $k => $ph) {
            if ($ph == '?u' || $ph == '?e') {
                $data[$k] = fn_check_table_fields($data[$k], $table_name);
                if (empty($data[$k])) {
                    return false;
                }
            }
            if ($ph == '?i') {
                // integer
                $pattern = db_str_replace($ph, db_intval($data[$k]), $pattern, $offset);
                // Trick to convert int's and longint's
            } elseif ($ph == '?s') {
                // string
                $pattern = db_str_replace($ph, "'" . addslashes($data[$k]) . "'", $pattern, $offset);
            } elseif ($ph == '?l') {
                // string for LIKE operator
                $pattern = db_str_replace($ph, "'" . addslashes(str_replace("\\", "\\\\", $data[$k])) . "'", $pattern, $offset);
            } elseif ($ph == '?d') {
                // float
                $pattern = db_str_replace($ph, sprintf('%01.2f', $data[$k]), $pattern, $offset);
            } elseif ($ph == '?a') {
                // array FIXME: add trim
                $data[$k] = !is_array($data[$k]) ? array($data[$k]) : $data[$k];
                $pattern = db_str_replace($ph, "'" . implode("', '", array_map('addslashes', $data[$k])) . "'", $pattern, $offset);
            } elseif ($ph == '?n') {
                // array of integer FIXME: add trim
                $data[$k] = !is_array($data[$k]) ? array($data[$k]) : $data[$k];
                $pattern = db_str_replace($ph, !empty($data[$k]) ? implode(', ', array_map('db_intval', $data[$k])) : "''", $pattern, $offset);
            } elseif ($ph == '?u' || $ph == '?w') {
                // update/condition with and
                $q = '';
                $clue = $ph == '?u' ? ', ' : ' AND ';
                foreach ($data[$k] as $field => $value) {
                    $q .= ($q ? $clue : '') . '`' . db_field($field) . "` = '" . addslashes($value) . "'";
                }
                $pattern = db_str_replace($ph, $q, $pattern, $offset);
            } elseif ($ph == '?e') {
                // insert
                $pattern = db_str_replace($ph, '(`' . implode('`, `', array_map('addslashes', array_keys($data[$k]))) . "`) VALUES ('" . implode("', '", array_map('addslashes', array_values($data[$k]))) . "')", $pattern, $offset);
            } elseif ($ph == '?f') {
                // field/table/database name
                $pattern = db_str_replace($ph, db_field($data[$k]), $pattern, $offset);
            } elseif ($ph == '?p') {
                // prepared statement
                //				$pattern = db_str_replace($ph, str_replace('?:', TABLE_PREFIX, $data[$k]), $pattern, $offset);
                $pattern = db_str_replace($ph, $data[$k], $pattern, $offset);
            }
        }
    }
    if ($replace) {
        if (Registry::is_exist('revisions') && !Registry::get('revisions.working')) {
            if (strpos($pattern, 'SELECT') === 0) {
                fn_revisions_process_select($pattern);
            }
            if (strpos($pattern, 'UPDATE') === 0) {
                fn_revisions_process_update($pattern);
            }
            if (strpos($pattern, 'INSERT') === 0 || strpos($pattern, 'REPLACE') === 0) {
                Registry::set('revisions.db_insert_id', 0);
                fn_revisions_process_insert($pattern);
            }
            if (strpos($pattern, 'DELETE') === 0) {
                fn_revisions_process_delete($pattern);
            }
        }
        // Replace table prefixes
        $pattern = str_replace('?:', TABLE_PREFIX, $pattern);
    }
    return $pattern;
}