/** * Get all schema files (e.g. exim schemas, admin area menu) * * @param string $schema_dir schema name (subdirectory in /schema directory) * @param string $name file name/prefix * @param string $type schema type (php/xml) * @param bool $caching enable/disable schema caching * @param bool $force_addon_init initialize disabled addons also * @return array schema definition (if exists) */ function fn_get_schema($schema_dir, $name, $type = 'php', $caching = true, $force_addon_init = false) { static $permission_schemas; if ($schema_dir == 'permissions' && !empty($permission_schemas[$name])) { return $permission_schemas[$name]; } if ($caching == true) { Registry::register_cache('schema_' . $schema_dir . '_' . $name, array('settings', 'addons'), CACHE_LEVEL_STATIC); // FIXME: hardcoded for settings-based schemas if (Registry::is_exist('schema_' . $schema_dir . '_' . $name) == true) { return Registry::get('schema_' . $schema_dir . '_' . $name); } } $files = array(); if (file_exists(DIR_SCHEMAS . $schema_dir . '/' . $name . '.' . $type)) { $files[] = DIR_SCHEMAS . $schema_dir . '/' . $name . '.' . $type; } $addons = Registry::get('addons'); if (!empty($addons)) { foreach ($addons as $k => $v) { if ($v['status'] == 'D' && $force_addon_init && file_exists(DIR_ADDONS . $k . '/func.php')) { // force addon initialization include_once DIR_ADDONS . $k . '/func.php'; } if ($v['status'] == 'A' || $force_addon_init) { if (file_exists(DIR_ADDONS . $k . '/schemas/' . $schema_dir . '/' . $name . '.' . $type)) { array_unshift($files, DIR_ADDONS . $k . '/schemas/' . $schema_dir . '/' . $name . '.' . $type); continue; } elseif (file_exists(DIR_ADDONS . $k . '/schemas/' . $schema_dir . '/' . $name . '.post.' . $type)) { $files[] = DIR_ADDONS . $k . '/schemas/' . $schema_dir . '/' . $name . '.post.' . $type; continue; } } } } $schema = ''; foreach ($files as $file) { if ($type == 'php') { include $file; } else { $schema .= file_get_contents($file); } } if ($caching == true) { Registry::set('schema_' . $schema_dir . '_' . $name, $schema); } if ($schema_dir == 'permissions') { $permission_schemas[$name] = $schema; } return $schema; }
function fn_clone_image_pairs($target_object_id, $object_id, $object_type, $action = null, $parent_object_id = 0, $parent_object_type = '', $rev_data = array(), $lang_code = CART_LANGUAGE) { $table = 'images_links'; $itable = 'images'; $cond = ''; if (AREA == 'A' && Registry::is_exist('revisions') && !Registry::get('revisions.working')) { if (!empty($rev_data)) { $cond = db_quote(" AND revision = ?s AND revision_id = ?i", $rev_data['revision'], $rev_data['revision_id']); $table = 'rev_images_links'; $itable = 'rev_images'; } } // Get all pairs $pair_data = db_get_hash_array("SELECT pair_id, image_id, detailed_id, type FROM ?:{$table} WHERE object_id = ?i AND object_type = ?s ?p", 'pair_id', $object_id, $object_type, $cond); if (empty($pair_data)) { return false; } $icons = $detailed = $pairs_data = array(); foreach ($pair_data as $pair_id => $p_data) { if (!empty($p_data['image_id'])) { $icons[$pair_id] = fn_get_image($p_data['image_id'], $object_type, $rev_data, $lang_code); if (!empty($icons[$pair_id])) { $p_data['image_alt'] = empty($icons[$pair_id]['alt']) ? '' : $icons[$pair_id]['alt']; // Image is stored on the filesystem if (empty($icons[$pair_id]['image'])) { $path = str_replace(Registry::get('config.images_path'), DIR_IMAGES, $icons[$pair_id]['image_path']); $icons[$pair_id]['image'] = fn_get_contents($path); $name = ($action === null ? $target_object_id . '_' : '') . basename($path); } else { $name = ($action === null ? $target_object_id . '_' : '') . $object_type . '_image'; } $tmp_name = tempnam(DIR_COMPILED, 'image_clone'); fn_put_contents($tmp_name, $icons[$pair_id]['image']); $icons[$pair_id] = array('path' => $tmp_name, 'size' => filesize($tmp_name), 'error' => 0, 'name' => $name); } } if (!empty($p_data['detailed_id'])) { $detailed[$pair_id] = fn_get_image($p_data['detailed_id'], 'detailed', $rev_data, $lang_code); if (!empty($detailed[$pair_id])) { $p_data['detailed_alt'] = empty($detailed[$pair_id]['alt']) ? '' : $detailed[$pair_id]['alt']; // Image is stored on the filesystem if (empty($detailed[$pair_id]['image'])) { $path = str_replace(Registry::get('config.images_path'), DIR_IMAGES, $detailed[$pair_id]['image_path']); $detailed[$pair_id]['image'] = fn_get_contents($path); $name = ($action === null ? $target_object_id . '_' : '') . basename($path); } else { $name = ($action === null ? $target_object_id . '_' : '') . '_detailed_image'; } $tmp_name = tempnam(DIR_COMPILED, 'detailed_clone'); fn_put_contents($tmp_name, $detailed[$pair_id]['image']); $detailed[$pair_id] = array('path' => $tmp_name, 'size' => filesize($tmp_name), 'error' => 0, 'name' => $name); } } $pairs_data = array($pair_id => array('type' => $p_data['type'], 'image_alt' => !empty($p_data['image_alt']) ? $p_data['image_alt'] : '', 'detailed_alt' => !empty($p_data['detailed_alt']) ? $p_data['detailed_alt'] : '')); if ($action == 'publish') { Registry::set('revisions.working', true); } fn_update_image_pairs($icons, $detailed, $pairs_data, $target_object_id, $object_type, array(), $parent_object_type, $parent_object_id, true, false, $lang_code); if ($action == 'publish') { Registry::set('revisions.working', false); } } }
unset($_SESSION['current_category_id']); } fn_add_breadcrumb(fn_get_lang_var('home'), $index_script); $request_params = $_REQUEST; $request_params['location'] = fn_get_blocks_location(CONTROLLER); list($blocks) = fn_get_blocks($request_params); $view->assign('blocks', $blocks); $view->assign('location_data', fn_get_location_data($request_params['location'], true)); // Get quick links Registry::register_cache('quick_links', array('static_data'), CACHE_LEVEL_LOCALE); if (Registry::is_exist('quick_links') == false) { Registry::set('quick_links', fn_get_static_data_section('N')); } // Get top menu Registry::register_cache('top_menu', array('static_data', 'categories', 'pages'), CACHE_LEVEL_LOCALE_AUTH); if (Registry::is_exist('top_menu') == false) { Registry::set('top_menu', fn_top_menu_form(fn_get_static_data_section('A', true))); } $quick_links =& Registry::get('quick_links'); $top_menu =& Registry::get('top_menu'); $top_menu = fn_top_menu_select($top_menu, $controller, $mode, Registry::get('current_url')); // Init cart if not set if (empty($_SESSION['cart'])) { fn_clear_cart($_SESSION['cart']); } // Display products in comparison list if (!empty($_SESSION['comparison_list'])) { $compared_products = array(); $_products = db_get_hash_array("SELECT product_id, product FROM ?:product_descriptions WHERE product_id IN (?n) AND lang_code = ?s", 'product_id', $_SESSION['comparison_list'], CART_LANGUAGE); foreach ($_SESSION['comparison_list'] as $k => $p_id) { if (empty($_products[$p_id])) {
/** * Register variable in the cache * * @param string $key key name * @param mixed $condition cache reset condition - array with table names of expiration time (int) * @param string $cache_level indicates the cache dependencies on controller, language, user group, etc * @param bool $track if set to true, cache data will be collection during script execution and saved when it finished * * @return boolean true if data is cached and valid, false - otherwise */ static function register_cache($key, $condition, $cache_level = NULL, $track = false) { static $init = false; if ($init == false) { self::_cache_actions('init'); $init = true; } if (empty(self::$_cached_keys[$key])) { self::$_cached_keys[$key] = array('condition' => $condition, 'cache_level' => $cache_level, 'track' => $track, 'hash' => ''); if (!Registry::is_exist($key) && ($val = self::_get_cache($key, $cache_level)) !== NULL) { Registry::set($key, $val, true); // Get hash of original value for tracked data if ($track == true) { self::$_cached_keys[$key]['hash'] = md5(serialize($val)); } return true; } } return false; }
function fn_clone_attachments($object_type, $target_object_id, $object_id, $action = null) { $revision_id = 0; $revision = null; if (AREA == 'A' && Registry::is_exist('revisions') && !Registry::get('revisions.working')) { $revisions = Registry::get('revisions'); if (!empty($revisions['objects'][$object_type]) && !empty($revisions['objects'][$object_type]['tables'])) { $object_data = $revisions['objects'][$object_type]; if ($object_data['attachments']) { $rev_data = db_get_row("SELECT max(revision) as revision, revision_id FROM ?:revisions WHERE object = ?s AND object_id = ?i GROUP BY revision_id", $object_type, $object_id); $revision = $rev_data['revision']; $revision_id = $rev_data['revision_id']; } } } if ($revision_id && $action != 'create') { $_ = 'rev_'; $revision_condition = db_quote(" AND revision = ?s AND revision_id = ?i", $revision, $revision_id); } else { $_ = ''; $revision_condition = ''; } $data = db_get_array("SELECT * FROM ?:{$_}attachments WHERE object_type = ?s AND object_id = ?i ?p", $object_type, $object_id, $revision_condition); $files = array(); $add_data = array(); $descriptions = array(); $directory = DIR_ATTACHMENTS . '/' . $object_type . ($revision_condition ? '_rev' : '') . '/' . $target_object_id; $i = 1; if ($action == 'publish') { Registry::set('revisions.working', true); } foreach ($data as $entry) { $files = array(); if (!empty($entry['filename'])) { $f_name = $directory . '/' . $entry['filename']; $files[0] = array('path' => $f_name, 'size' => filesize($f_name), 'error' => 0, 'name' => $entry['filename']); } $add_data = array('attachment_id' => $entry['attachment_id'], 'usergroup_ids' => implode(',', $entry['usergroup_ids']), 'position' => $entry['position'], 'type' => $entry['type'], 'description' => db_get_hash_single_array("SELECT * FROM ?:{$_}attachment_descriptions WHERE attachment_id = ?i ?p", array('lang_code', 'description'), $entry['attachment_id'], $revision_condition)); fn_add_attachments($add_data, $object_type, $target_object_id, $entry['type'], $files); } if ($action == 'publish') { Registry::set('revisions.working', false); } }
if (isset($_GET['cc']) && (AREA == 'A' || defined('DEVELOPMENT'))) { fn_rm(DIR_COMPILED, false); fn_rm(DIR_CACHE, false); Registry::cleanup(); } if (defined('MYSQL5')) { db_query("set @@sql_mode = ''"); } register_shutdown_function(array('Registry', 'save')); // define lifetime for the cache data define('CACHE_LEVEL_TIME', 'time'); // First-level cache: static - the same for all requests define('CACHE_LEVEL_STATIC', 'cache'); Registry::register_cache('settings', array('settings'), CACHE_LEVEL_STATIC); // Get settings if (Registry::is_exist('settings') == false) { Registry::set('settings', fn_get_settings()); } // detect user agent fn_init_ua(); // initialize ajax handler fn_init_ajax(); // Start session mechanism Session::init(); if (PRODUCT_TYPE == 'MULTIVENDOR') { if (AREA == 'A' && !empty($_SESSION['auth']['company_id'])) { fn_define('COMPANY_ID', $_SESSION['auth']['company_id']); } } // Init addons fn_init_addons();
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); }
/** * Get list of templates that should be overriden by addons * * @param string $resource_name base template name * @param object $view templater object * @return string overridden template name */ function fn_addon_template_overrides($resource_name, &$view) { static $init = false; $o_name = 'template_overrides_' . AREA; if ($init == false) { Registry::register_cache($o_name, array(), CACHE_LEVEL_STATIC); if (!Registry::is_exist($o_name)) { $template_overrides = array(); foreach (Registry::get('addons') as $a => $_settings) { $odir = $view->template_dir . '/addons/' . $a . '/overrides'; if (is_dir($odir)) { $tpls = fn_get_dir_contents($odir, false, true, '', '', true); foreach ($tpls as $k => $t) { if (empty($template_overrides[md5($t)])) { $template_overrides[md5($t)] = 'addons/' . $a . '/overrides/' . $t; } } } } if (empty($template_overrides)) { $template_overrides['plug'] = true; } Registry::set($o_name, $template_overrides); } $init = true; } return Registry::if_get($o_name . '.' . md5($resource_name), $resource_name); }
function fn_get_rss_feed($data) { if (!empty($data['feed_url'])) { $data_key = 'rss_data_cache_' . (isset($data['block_data']['block_id']) ? $data['block_data']['block_id'] : 0); Registry::register_cache($data_key, SECONDS_IN_HOUR, CACHE_LEVEL_TIME); if (Registry::is_exist($data_key) == false) { $limit = !empty($data['max_item']) ? $data['max_item'] : 3; static $included; if (empty($included)) { require DIR_CORE . 'class.rss_reader.php'; $included = true; } $rss = new RssReader(); $rss->loadData($data['feed_url']); $rss_items = $rss->getItems(); if (!empty($rss_items)) { $rss_items = array_slice($rss_items, 0, $limit); $rss_chanel = $rss->getChannel(); $rss_data = array(array($rss_items, $rss_chanel['link'], $data['feed_url'])); Registry::set($data_key, $rss_data); return $rss_data; } } else { return Registry::get($data_key); } } return array(); }
/** * Get cached resul from query * * @param string $query cached query */ function db_get_cached_result($query, $args) { return array(); $memc = new Memcache(); $memc->connect('127.0.0.1', 11211) or die("Could not connect"); if ($memc == null) { //return false; } else { $cache_name = serialize(array('query' => $query, 'args' => $args)); $key = "c" . md5($cache_name); $var_key = $memc->get($key); $result = unserialize($var_key); //var_dump("111111".$key); //if(!empty($var_key)) var_dump(11111111); return !empty($result) ? $result : array(); } $memc->close(); if (Registry::get('runtime.database.skip_cache') != true) { $cache_name = serialize(array('query' => $query, 'args' => $args)); Registry::register_cache('cached_queries', array(), CACHE_LEVEL_STATIC, true); $cached_queries = Registry::if_get('cached_queries', array()); if (!empty($cached_queries['cquery_' . md5($cache_name)])) { Registry::register_cache('cquery_' . md5($cache_name), array(), CACHE_LEVEL_STATIC); if (Registry::is_exist('cquery_' . md5($cache_name)) == true) { $result = Registry::get('cquery_' . md5($cache_name)); $query = db_process($query, array_slice($args, 1)); Registry::set('runtime.database.last_query', $query); Registry::set('runtime.database.long_query', true); } } } return !empty($result) ? $result : array(); }
} } $suffix = ".apply"; } if ($mode == 'update') { if (!empty($_REQUEST['option_id'])) { $condition = fn_get_company_condition(); $option_id = db_get_field("SELECT option_id FROM ?:product_options WHERE option_id = ?i {$condition}", $_REQUEST['option_id']); if (empty($option_id)) { fn_set_notification('W', fn_get_lang_var('warning'), fn_get_lang_var('access_denied')); return array(CONTROLLER_STATUS_REDIRECT, "product_options.manage"); } } fn_trusted_vars('option_data', 'regexp'); $option_id = fn_update_product_option($_REQUEST['option_data'], $_REQUEST['option_id'], DESCR_SL); if (Registry::is_exist('revisions') && empty($_REQUEST['product_id'])) { $revision = db_get_field("SELECT MAX(revision) as revision FROM ?:product_options WHERE option_id = ?i", $option_id); $global_opt_data = db_get_row("SELECT * FROM ?:product_options WHERE option_id = ?i AND revision = ?i", $option_id, $revision); $global_opt_descr = db_get_row("SELECT * FROM ?:product_options_descriptions WHERE option_id = ?i AND revision = ?i AND lang_code = ?s", $option_id, $revision, DESCR_SL); $status = Registry::get('revisions.working'); Registry::set('revisions.working', true); db_query("REPLACE INTO ?:product_options ?e", $global_opt_data); db_query("REPLACE INTO ?:product_options_descriptions ?e", $global_opt_descr); fn_update_product_option($_REQUEST['option_data'], $option_id, DESCR_SL); Registry::set('revisions.working', $status); } if (!empty($_REQUEST['product_id'])) { // FIXME (when assigning page and current url will be removed from ajax) return array(CONTROLLER_STATUS_OK, "products.update?product_id={$_REQUEST['product_id']}&selected_section=options"); } $suffix = ".manage";
function fn_get_filters_products_count($params = array()) { $key = 'pfilters_' . md5(serialize($params)); Registry::register_cache($key, array('products', 'product_features', 'product_filters', 'product_features_values'), CACHE_LEVEL_USER); if (Registry::is_exist($key) == false) { if (!empty($params['check_location'])) { // FIXME: this is bad style, should be refactored $valid_locations = array('index.index', 'products.search', 'categories.view', 'product_features.view'); if (!in_array($params['dispatch'], $valid_locations)) { return array(); } if ($params['dispatch'] == 'categories.view') { $params['simple_link'] = true; // this parameter means that extended filters on this page should be displayed as simple $params['filter_custom_advanced'] = true; // this parameter means that extended filtering should be stayed on the same page } else { if ($params['dispatch'] == 'product_features.view') { $params['simple_link'] = true; $params['features_hash'] = (!empty($params['features_hash']) ? $params['features_hash'] . '.' : '') . 'V' . $params['variant_id']; //$params['exclude_feature_id'] = db_get_field("SELECT feature_id FROM ?:product_features_values WHERE variant_id = ?i", $params['variant_id']); } $params['get_for_home'] = 'Y'; } } if (!empty($params['skip_if_advanced']) && !empty($params['advanced_filter']) && $params['advanced_filter'] == 'Y') { return array(); } // Base fields for the SELECT queries $values_fields = array('?:product_features_values.feature_id', 'COUNT(DISTINCT ?:products.product_id) as products', '?:product_features_values.variant_id as range_id', '?:product_feature_variant_descriptions.variant as range_name', '?:product_features.feature_type', '?:product_filters.filter_id'); $ranges_fields = array('?:product_features_values.feature_id', 'COUNT(DISTINCT ?:products.product_id) as products', '?:product_filter_ranges.range_id', '?:product_filter_ranges_descriptions.range_name', '?:product_filter_ranges.filter_id', '?:product_features.feature_type'); $condition = $where = $join = $filter_vq = $filter_rq = ''; $variants_ids = $ranges_ids = $field_filters = $feature_ids = $field_ranges_ids = $field_ranges_counts = array(); if (!empty($params['features_hash'])) { list($variants_ids, $ranges_ids, $_field_ranges_ids) = fn_parse_features_hash($params['features_hash']); $field_ranges_ids = array_flip($_field_ranges_ids); } if (!empty($params['category_id'])) { $id_path = db_get_field("SELECT id_path FROM ?:categories WHERE category_id = ?i", $params['category_id']); $category_ids = db_get_fields("SELECT category_id FROM ?:categories WHERE id_path LIKE ?l", $id_path . '/%'); $category_ids[] = $params['category_id']; $condition .= db_quote(" AND (categories_path = '' OR FIND_IN_SET(?i, categories_path))", $params['category_id']); $where .= db_quote(" AND ?:products_categories.category_id IN (?n)", $category_ids); } elseif (empty($params['get_for_home']) && empty($params['get_custom'])) { $condition .= " AND categories_path = ''"; } if (!empty($params['filter_id'])) { $condition .= db_quote(" AND ?:product_filters.filter_id = ?i", $params['filter_id']); } if (!empty($params['get_for_home'])) { $condition .= db_quote(" AND ?:product_filters.show_on_home_page = ?s", $params['get_for_home']); } if (!empty($params['exclude_feature_id'])) { $condition .= db_quote(" AND ?:product_filters.feature_id NOT IN (?n)", $params['exclude_feature_id']); } $filters = db_get_hash_array("SELECT ?:product_filters.feature_id, ?:product_filters.filter_id, ?:product_filters.field_type, ?:product_filter_descriptions.filter, ?:product_features_descriptions.prefix, ?:product_features_descriptions.suffix FROM ?:product_filters LEFT JOIN ?:product_filter_descriptions ON ?:product_filter_descriptions.filter_id = ?:product_filters.filter_id AND ?:product_filter_descriptions.lang_code = ?s LEFT JOIN ?:product_features_descriptions ON ?:product_features_descriptions.feature_id = ?:product_filters.feature_id AND ?:product_features_descriptions.lang_code = ?s WHERE ?:product_filters.status = 'A' ?p ORDER by position", 'filter_id', CART_LANGUAGE, CART_LANGUAGE, $condition); $fields = fn_get_product_filter_fields(); if (empty($filters) && empty($params['advanced_filter'])) { return array(array(), false); } else { foreach ($filters as $k => $v) { if (!empty($v['feature_id'])) { // Feature filters $feature_ids[] = $v['feature_id']; } else { // Product field filters $_field = $fields[$v['field_type']]; $field_filters[$v['filter_id']] = array_merge($v, $_field); $filters[$k]['condition_type'] = $_field['condition_type']; } } } // Variants if (!empty($variants_ids)) { $join .= " LEFT JOIN (SELECT product_id, GROUP_CONCAT(?:product_features_values.variant_id) AS simple_variants FROM ?:product_features_values WHERE lang_code = '" . CART_LANGUAGE . "' GROUP BY product_id) AS pfv_simple ON pfv_simple.product_id = ?:products.product_id"; $where_condtions = array(); foreach ($variants_ids as $k => $variant_id) { $where_condtions[] = db_quote(" FIND_IN_SET('?i', simple_variants)", $variant_id); } $where .= ' AND ' . implode(' AND ', $where_condtions); } // Ranges if (!empty($ranges_ids)) { $range_conditions = db_get_array("SELECT `from`, `to`, feature_id FROM ?:product_filter_ranges WHERE range_id IN (?n)", $ranges_ids); foreach ($range_conditions as $k => $condition) { $join .= db_quote(" LEFT JOIN ?:product_features_values as var_val_{$k} ON var_val_{$k}.product_id = ?:products.product_id AND var_val_{$k}.lang_code = ?s", CART_LANGUAGE); $where .= db_quote(" AND (var_val_{$k}.value_int >= ?i AND var_val_{$k}.value_int <= ?i AND var_val_{$k}.value = '' AND var_val_{$k}.feature_id = ?i)", $condition['from'], $condition['to'], $condition['feature_id']); } } if (!empty($params['filter_id']) && empty($params['view_all'])) { $filter_vq .= db_quote(" AND ?:product_filters.filter_id = ?i", $params['filter_id']); $filter_rq .= db_quote(" AND ?:product_filter_ranges.filter_id = ?i", $params['filter_id']); } if (!empty($params['view_all'])) { $values_fields[] = "UPPER(SUBSTRING(?:product_feature_variant_descriptions.variant, 1, 1)) AS `index`"; } $_join = $join; // Build condition for the standart fields if (!empty($_field_ranges_ids)) { foreach ($_field_ranges_ids as $rid => $field_type) { $structure = $fields[$field_type]; if ($structure['table'] !== 'products' && strpos($join, 'JOIN ?:' . $structure['table']) === false) { $join .= " LEFT JOIN ?:{$structure['table']} ON ?:{$structure['table']}.product_id = ?:products.product_id"; } if ($structure['condition_type'] == 'D') { $range_condition = db_get_row("SELECT `from`, `to` FROM ?:product_filter_ranges WHERE range_id = ?i", $rid); if (!empty($range_condition)) { $where .= db_quote(" AND ?:{$structure['table']}.{$structure['db_field']} >= ?i AND ?:{$structure['table']}.{$structure['db_field']} <= ?i", $range_condition['from'], $range_condition['to']); } } elseif ($structure['condition_type'] == 'F') { $where .= db_quote(" AND ?:{$structure['table']}.{$structure['db_field']} = ?i", $rid); } elseif ($structure['condition_type'] == 'C') { $where .= db_quote(" AND ?:{$structure['table']}.{$structure['db_field']} = ?s", $rid == 1 ? 'Y' : 'N'); } if (!empty($structure['join_params'])) { foreach ($structure['join_params'] as $field => $param) { $join .= db_quote(" AND ?:{$structure['table']}.{$field} = ?s ", $param); } } } } // Product availability conditions $where .= ' AND (' . fn_find_array_in_set($_SESSION['auth']['usergroup_ids'], '?:categories.usergroup_ids', true) . ')'; $where .= ' AND (' . fn_find_array_in_set($_SESSION['auth']['usergroup_ids'], '?:products.usergroup_ids', true) . ')'; $where .= db_quote(" AND ?:categories.status IN (?a) AND ?:products.status IN (?a)", array('A', 'H'), array('A')); $_j = " INNER JOIN ?:products_categories ON ?:products_categories.product_id = ?:products.product_id LEFT JOIN ?:categories ON ?:categories.category_id = ?:products_categories.category_id"; if (Registry::get('settings.General.show_out_of_stock_products') == 'N' && AREA == 'C') { $_j .= " LEFT JOIN ?:product_options_inventory as inventory ON inventory.product_id = ?:products.product_id"; $where .= " AND IF(?:products.tracking = 'O', inventory.amount > 0, ?:products.amount > 0)"; } $_join .= $_j; $join .= $_j; // Localization $where .= fn_get_localizations_condition('?:products.localization', true); $where .= fn_get_localizations_condition('?:categories.localization', true); $variants_counts = db_get_hash_multi_array("SELECT " . implode(', ', $values_fields) . " FROM ?:product_features_values LEFT JOIN ?:products ON ?:products.product_id = ?:product_features_values.product_id LEFT JOIN ?:product_filters ON ?:product_filters.feature_id = ?:product_features_values.feature_id LEFT JOIN ?:product_feature_variants ON ?:product_feature_variants.variant_id = ?:product_features_values.variant_id LEFT JOIN ?:product_feature_variant_descriptions ON ?:product_feature_variant_descriptions.variant_id = ?:product_feature_variants.variant_id AND ?:product_feature_variant_descriptions.lang_code = ?s LEFT JOIN ?:product_features ON ?:product_features.feature_id = ?:product_filters.feature_id ?p WHERE ?:product_features_values.feature_id IN (?n) AND ?:product_features_values.lang_code = ?s AND ?:product_features_values.variant_id ?p ?p AND ?:product_features.feature_type IN ('S', 'M', 'E') GROUP BY ?:product_features_values.variant_id ORDER BY ?:product_feature_variants.position, ?:product_feature_variant_descriptions.variant", array('filter_id', 'range_id'), CART_LANGUAGE, $join, $feature_ids, CART_LANGUAGE, $where, $filter_vq); $ranges_counts = db_get_hash_multi_array("SELECT " . implode(', ', $ranges_fields) . " FROM ?:product_filter_ranges LEFT JOIN ?:product_features_values ON ?:product_features_values.feature_id = ?:product_filter_ranges.feature_id AND ?:product_features_values.value_int >= ?:product_filter_ranges.from AND ?:product_features_values.value_int <= ?:product_filter_ranges.to LEFT JOIN ?:products ON ?:products.product_id = ?:product_features_values.product_id LEFT JOIN ?:product_filter_ranges_descriptions ON ?:product_filter_ranges_descriptions.range_id = ?:product_filter_ranges.range_id AND ?:product_filter_ranges_descriptions.lang_code = ?s LEFT JOIN ?:product_features ON ?:product_features.feature_id = ?:product_filter_ranges.feature_id ?p WHERE ?:product_features_values.feature_id IN (?n) AND ?:product_features_values.lang_code = ?s ?p ?p GROUP BY ?:product_filter_ranges.range_id ORDER BY ?:product_filter_ranges.position, ?:product_filter_ranges_descriptions.range_name", array('filter_id', 'range_id'), CART_LANGUAGE, $join, $feature_ids, CART_LANGUAGE, $where, $filter_rq); if (!empty($field_filters)) { // Field ranges foreach ($field_filters as $filter_id => $field) { $fields_join = $fields_where = ''; // Dinamic ranges (price, amount etc) if ($field['condition_type'] == 'D') { $fields_join = " LEFT JOIN ?:{$field['table']} ON ?:{$field['table']}.{$field['db_field']} >= ?:product_filter_ranges.from AND ?:{$field['table']}.{$field['db_field']} <= ?:product_filter_ranges.to "; if (strpos($fields_join . $_join, 'JOIN ?:products ') === false) { $fields_join .= db_quote(" LEFT JOIN ?:products ON ?:products.product_id = ?:product_prices.product_id AND ?:product_prices.lower_limit = 1 AND ?:product_prices.usergroup_id IN (?n)", array_merge(array(USERGROUP_ALL), $_SESSION['auth']['usergroup_ids'])); } elseif (strpos($fields_join . $_join, 'JOIN ?:product_prices ') === false) { $fields_join .= " LEFT JOIN ?:product_prices ON ?:product_prices.product_id = ?:products.product_id"; } if ($field['table'] == 'product_prices') { $fields_join .= db_quote(" LEFT JOIN ?:product_prices as prices_2 ON ?:product_prices.product_id = prices_2.product_id AND ?:product_prices.price > prices_2.price AND prices_2.lower_limit = 1 AND prices_2.usergroup_id IN (?n)", array_merge(array(USERGROUP_ALL), $_SESSION['auth']['usergroup_ids'])); $fields_where .= " AND prices_2.price IS NULL"; } $field_ranges_counts[$filter_id] = db_get_hash_array("SELECT COUNT(DISTINCT ?:{$field['table']}.product_id) as products, ?:product_filter_ranges.range_id, ?:product_filter_ranges_descriptions.range_name, ?:product_filter_ranges.filter_id FROM ?:product_filter_ranges LEFT JOIN ?:product_filter_ranges_descriptions ON ?:product_filter_ranges_descriptions.range_id = ?:product_filter_ranges.range_id AND ?:product_filter_ranges_descriptions.lang_code = ?s ?p WHERE ?:products.status IN ('A') AND ?:product_filter_ranges.filter_id = ?i ?p GROUP BY ?:product_filter_ranges.range_id HAVING products != 0 ORDER BY ?:product_filter_ranges.position, ?:product_filter_ranges_descriptions.range_name", 'range_id', CART_LANGUAGE, $fields_join . $_join, $filter_id, $where . $fields_where); // Char values (free shipping etc) } elseif ($field['condition_type'] == 'C') { $field_ranges_counts[$filter_id] = db_get_hash_array("SELECT COUNT(DISTINCT ?:{$field['table']}.product_id) as products, ?:{$field['table']}.{$field['db_field']} as range_name FROM ?:{$field['table']} ?p WHERE ?:products.status = 'A' ?p GROUP BY ?:{$field['table']}.{$field['db_field']}", 'range_name', $join, $where); if (!empty($field_ranges_counts[$filter_id])) { foreach ($field_ranges_counts[$filter_id] as $range_key => $range) { $field_ranges_counts[$filter_id][$range_key]['range_name'] = $field['variant_descriptions'][$range['range_name']]; $field_ranges_counts[$filter_id][$range_key]['range_id'] = $range['range_name'] == 'Y' ? 1 : 0; } } // Fixed values (supplier etc) } elseif ($field['condition_type'] == 'F') { $field_ranges_counts[$filter_id] = db_get_hash_array("SELECT COUNT(DISTINCT ?:{$field['table']}.product_id) as products, ?:{$field['foreign_table']}.{$field['range_name']} as range_name, ?:{$field['foreign_table']}.{$field['foreign_index']} as range_id FROM ?:{$field['table']} LEFT JOIN ?:{$field['foreign_table']} ON ?:{$field['foreign_table']}.{$field['foreign_index']} = ?:{$field['table']}.{$field['db_field']} ?p WHERE ?:products.status IN ('A') ?p GROUP BY ?:{$field['table']}.{$field['db_field']}", 'range_id', $join, $where); } } } $merged = fn_array_merge($variants_counts, $ranges_counts, $field_ranges_counts); $view_all = array(); foreach ($filters as $filter_id => $filter) { if (!empty($merged[$filter_id]) && empty($params['view_all']) || !empty($params['filter_id']) && $params['filter_id'] != $filter_id) { // Check if filter range was selected if (empty($filters[$filter_id]['feature_id'])) { $intersect = array_intersect(array_keys($merged[$filter_id]), $field_ranges_ids); } else { $intersect = array_intersect(array_keys($merged[$filter_id]), $variants_ids); } if (!empty($intersect)) { foreach ($merged[$filter_id] as $k => $v) { if (!in_array($v['range_id'], $intersect)) { // Unset unselected ranges unset($merged[$filter_id][$k]); } } } // Calculate number of ranges and compare with constant $count = count($merged[$filter_id]); if ($count > FILTERS_RANGES_MORE_COUNT && empty($params['get_all'])) { $merged[$filter_id] = array_slice($merged[$filter_id], 0, FILTERS_RANGES_MORE_COUNT, true); $filters[$filter_id]['more_cut'] = true; } $filters[$filter_id]['ranges'] =& $merged[$filter_id]; // Add feature type to the filter $_first = reset($merged[$filter_id]); if (!empty($_first['feature_type'])) { $filters[$filter_id]['feature_type'] = $_first['feature_type']; } if (!empty($params['simple_link']) && $filters[$filter_id]['feature_type'] == 'E') { $filters[$filter_id]['simple_link'] = true; } if (empty($params['skip_other_variants'])) { foreach ($filters[$filter_id]['ranges'] as $_k => $r) { if (!fn_check_selected_filter($r['range_id'], !empty($r['feature_type']) ? $r['feature_type'] : '', $params, $filters[$filter_id]['field_type'])) { // selected variant $filters[$filter_id]['ranges'] = array($_k => $r); $filters[$filter_id]['ranges'][$_k]['selected'] = true; // mark selected variant // Get other variants $_params = $params; $_params['filter_id'] = $filter_id; $_params['req_range_id'] = $r['range_id']; $_params['features_hash'] = fn_delete_range_from_url($params['features_hash'], $r, $filters[$filter_id]['field_type']); $_params['skip_other_variants'] = true; unset($_params['variant_id'], $_params['check_location']); list($_f) = fn_get_filters_products_count($_params); if (!empty($_f)) { $_f = reset($_f); // delete current range foreach ($_f['ranges'] as $_rid => $_rv) { if ($_rv['range_id'] == $r['range_id']) { unset($_f['ranges'][$_rid]); break; } } $filters[$filter_id]['other_variants'] = $_f['ranges']; } break; } } } else { if (!empty($params['variant_id']) && !empty($filters[$filter_id]['ranges'][$params['variant_id']])) { $filters[$filter_id]['ranges'][$params['variant_id']]['selected'] = true; // mark selected variant } } continue; // If its "view all" page, return all ranges } elseif (!empty($params['filter_id']) && $params['filter_id'] == $filter_id && !empty($merged[$filter_id])) { foreach ($merged[$filter_id] as $range) { if (!empty($range['index'])) { // feature $view_all[$range['index']][] = $range; } else { // custom range $view_all[$filters[$range['filter_id']]['filter']][] = $range; } } ksort($view_all); } // Unset filter if he is empty unset($filters[$filter_id]); } if (!empty($params['advanced_filter'])) { $_params = array('feature_types' => array('C', 'T'), 'plain' => true, 'category_ids' => array(empty($params['category_id']) ? 0 : $params['category_id'])); list($features) = fn_get_product_features($_params); if (!empty($features)) { $filters = array_merge($filters, $features); } } Registry::set($key, array($filters, $view_all)); } else { list($filters, $view_all) = Registry::get($key); } return array($filters, $view_all); }