function fn_search($params, $items_per_page = 0, $lang_code = CART_LANGUAGE) { $data = array(); $search = Registry::get('search_object'); $pieces = array(); $search_type = ''; if (empty($params['objects'])) { $params['objects'] = array(); } if (empty($params['page'])) { $params['page'] = 1; } foreach ($search['conditions']['functions'] as $object => $function) { if ($search['default'] == $object) { continue; } if (!in_array($object, $params['objects'])) { unset($search['conditions']['functions'][$object]); } } if (empty($params['q'])) { $params['q'] = ''; } if (empty($params['match'])) { $params['match'] = 'any'; } $params['search_string'] = $params['q']; foreach ($search['conditions']['functions'] as $object => $function) { if (!empty($function) && function_exists($function)) { $_params = $params; if (!empty($search['default_params'][$object])) { $_params = fn_array_merge($_params, $search['default_params'][$object]); } $search['conditions']['values'][$object] = $function($_params, $lang_code); } } fn_set_hook('search_by_objects', $search['conditions']['values']); if (count($search['conditions']['values']) == 1) { list($object) = each($search['conditions']['values']); return fn_search_simple($params, $search, $object, $items_per_page, $lang_code); } elseif (count($search['conditions']['values'])) { db_query("CREATE TEMPORARY TABLE _search (id int NOT NULL, object varchar(30) NOT NULL, sort_field varchar(255) NOT NULL)ENGINE=HEAP;"); foreach ($search['conditions']['values'] as $object => $entry) { $entry['table'] = !empty($entry['table']) ? $entry['table'] : "?:" . $object; $select = db_quote("SELECT {$entry['table']}.{$entry['key']}, '{$object}', {$entry['sort']} FROM ?:{$object} as {$entry['table']} {$entry['join']} WHERE {$entry['condition']} GROUP BY {$entry['table']}.{$entry['key']}"); if (AREA == 'A' && Registry::is_exist('revisions')) { fn_revisions_process_select($select); } db_query("INSERT INTO _search (id, object, sort_field) ?p", $select); } if ($items_per_page) { $total = db_get_field('SELECT COUNT(id) FROM _search'); $limit = fn_paginate($params['page'], $total, $items_per_page); if (preg_match("/\\s+(\\d+),/", $limit, $begin)) { $begin = intval($begin[1]); } else { $begin = 0; } } else { $limit = ''; $total = 0; $begin = 0; } $results = db_get_array('SELECT id, object FROM _search ORDER BY sort_field ' . $limit, 'id'); if ($results) { $ids = array(); foreach ($results as $id => $entry) { $ids[$entry['object']][] = $entry['id']; } $_data = array(); foreach ($search['conditions']['values'] as $object => $entry) { if (empty($ids[$object]) || !count($ids[$object])) { continue; } $entry['table'] = !empty($entry['table']) ? $entry['table'] : "?:" . $object; $_data[$object] = db_get_hash_array("SELECT " . implode(', ', $entry['fields']) . " FROM ?:{$object} as {$entry['table']} {$entry['join']} WHERE {$entry['condition']} AND {$entry['table']}.{$entry['key']} IN ('" . join("', '", $ids[$object]) . "') GROUP BY {$entry['table']}.{$entry['key']}", $entry['key']); } $num = 0; foreach ($results as $key => $entry) { $data[$num] = $_data[$entry['object']][$entry['id']]; $data[$num]['object'] = $entry['object']; if (!empty($search['more_data'][$entry['object']])) { $search['more_data'][$entry['object']]($data[$num]); } $data[$num]['result_number'] = $begin + $num + 1; if (count($_data) == 1) { $data[$num]['result_type'] = 'full'; } else { $data[$num]['result_type'] = 'short'; } $num++; } $data[0]['first'] = true; unset($_data); if (!$total) { $total = count($data); } } } return array($data, $params, $total); }
/** * 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; }