richtext_fields ); } protected function extendedFilterOptions() : array { return [ "price" => array('max' => 0, 'min'=> 0), "brand" => array(), // array(1,2,3,) "collection" => array(), // array(1,2,3,) "supplier" => array(), // array(1,2,3,) "rating" => array(), // array(1,2,3,) "category" => array(), // array(1,2,3,) "status" => array(), // array(1,2,3,) "hotType" => array(),// array(saleoff | not | new) "attribute" => array(), // array(1,2,3,) "promotion" => "", "other_filter" => array(), // array(in-stock, has-promotion etc...) "spec_group_id" => array(), // array(1,2,3,) ]; } public function getProductInfoBySKU(string $sku) { $query = $this->db->runQuery( "SELECT * FROM `".$this->tb_entity."` basic, `".$this->tb_product_info."` info WHERE basic.`id` = info.`id` AND basic.sku = ? LIMIT 1 ", ['d'], [$sku] ); if( $item_info = $this->db->fetchAssoc($query)){ return $item_info; } return false; } public function getFullInfo($id) { $query = $this->db->runQuery( "SELECT * FROM `".$this->tb_entity."` basic, `".$this->tb_product_info."` info WHERE basic.`id` = info.`id` AND basic.id = ? LIMIT 1 ", ['d'], [$id] ); if( $item_info = $this->db->fetchAssoc($query)){ return $item_info; } return null; } public function getProductCategoryList($pro_id) { $query = $this->db->runQuery( "SELECT `category_id` FROM ".$this->tb_product_per_category." WHERE `item_id` = ? ", ['d'], [ $pro_id ] ) ; $pro_cat = []; foreach ( $this->db->fetchAll($query) as $rs ) { $pro_cat[] = $rs['category_id']; } return $pro_cat; } protected function _buildQueryConditionExtend(array $filter_condition) : ?array { $where_query = []; $bind_types = []; $bind_values = []; //------------------- //other filters if( array_key_exists("other_filter", $filter_condition) && sizeof($filter_condition["other_filter"])) { foreach ($filter_condition["other_filter"] as $_filter) { switch ($_filter) { case "in-stock"; $where_query[] = " AND quantity > 0 "; break; case "has-vat"; $where_query[] = " AND `has_vat` = 1 "; break; case "out-stock"; $where_query[] = " AND `quantity` = 0 "; break; case "has-market-price"; $where_query[] = " AND `market_price` > 0 "; break; case "no-price"; $where_query[] = " AND `price` = 0 "; break; case "no-warranty"; $where_query[] = " AND LENGTH(`warranty`) < 2 "; break; case "no-sku"; $where_query[] = " AND LENGTH(`sku`) < 2 "; break; case "has-config"; $where_query[] = " AND `config_count` > 0 "; break; case "no-image"; $where_query[] = " AND `image_count` = 0 "; break; case "no-category"; $where_query[] = " AND `category` = '0' "; break; case "display-off"; $where_query[] = " AND `status`=0 "; break; case "display-on"; $where_query[] = " AND `status`=1 "; break; case "has-promotion": $where_query[] = " AND LENGTH(`special_offer`) < 5 "; break; //...add more } } } //- brand id or ids or brand_indexes if( array_key_exists("brand", $filter_condition) && sizeof($filter_condition["brand"])) { $condition = array(); foreach ($filter_condition["brand"] as $brand_id) { if(!intval($brand_id)) continue; $condition[] = " brand_id = ? "; $bind_types[] = 'd'; $bind_values[] = $brand_id; } if(sizeof($condition)) { $where_query[] = " AND ( ".join(" OR ", $condition)." )"; } } //- collection id or ids if( array_key_exists("collection", $filter_condition) && sizeof($filter_condition["collection"])) { $condition = array(); foreach ($filter_condition["collection"] as $_id) { if(!intval($_id)) continue; $condition[] = " `id` IN ( SELECT `product_id` FROM ".$this->tb_collection_product." WHERE `collection_id` = ? ) "; $bind_types[] = 'd'; $bind_values[] = $_id; } $where_query[] = " AND ( ".join(" OR ", $condition)." )"; } //- rating: 1-> 5 if( array_key_exists("rating", $filter_condition) && sizeof($filter_condition["rating"])) { $condition = array(); foreach ($filter_condition["rating"] as $_id) { $condition[] = " `rating` = ? "; $bind_types[] = 'd'; $bind_values[] = $_id; } $where_query[] = " AND ( ".join(" OR ", $condition)." )"; } //- category id or ids if( array_key_exists("category", $filter_condition) && sizeof($filter_condition["category"])) { $objProductCategoryModel = new ProductCategoryModel(); $condition = array(); foreach ($filter_condition["category"] as $cat_id) { $cat_info = $objProductCategoryModel->getInfo($cat_id); if(!$cat_info) continue; if($cat_info["is_parent"]) { $childListId = ($cat_info["child_ids"]) ?: '0'; $condition[] = " `category_id` IN (".$childListId .") "; }else{ $condition[] = " `category_id` = ? "; $bind_types[] = 'd'; $bind_values[] = $cat_id; } } if(sizeof($condition)) { $where_query[] = " AND `id` IN ( SELECT DISTINCT `item_id` FROM ".$this->tb_product_per_category." WHERE " . join(" OR ", $condition) . " )"; } } // spec_group_id if( array_key_exists("spec_group_id", $filter_condition) && sizeof($filter_condition["spec_group_id"])) { $condition = array(); foreach ($filter_condition["spec_group_id"] as $_id) { if(!$_id) continue; $condition[] = " `spec_group_id` = ? "; $bind_types[] = 'd'; $bind_values[] = $_id; } $where_query[] = " AND ( ".join(" OR ", $condition )." ) "; } //- hotType: saleoff | not | new | or combination of types if( array_key_exists("hotType", $filter_condition) && sizeof($filter_condition["hotType"])) { $config_hottype = Config::getProductHotTypeList(); $condition = array(); foreach ($filter_condition["hotType"] as $_id) { if(!array_key_exists($_id, $config_hottype)) continue; $condition[] = " `hot_type` = ? "; $bind_types[] = 's'; $bind_values[] = $_id; } if(sizeof($condition)) { $where_query[] = " AND `id` IN (SELECT `pro_id` FROM ".$this->tb_product_hot." WHERE 1 AND ( ".join(" OR ", $condition)." ) ) "; } } //- attribute values /* if( array_key_exists("attribute", $filter_condition) && sizeof($filter_condition["attribute"])) { $filter_attr_value_list = $filter_condition["attribute"]; //filter = attr_value_1-attr_value_2-attr_value_3, $query_attr_id = []; $count_filter = 0; foreach($filter_attr_value_list as $attr_id){ $attr_id = (int) $attr_id; if($attr_id) { $query_attr_id[] = $attr_id; $count_filter ++; } } $product_filter_id_match = array(); if(sizeof($query_attr_id)) { $query = $this->db->runQuery(" SELECT DISTINCT pro_id , COUNT(*) as num_pro FROM ".TB_PRODUCT_ATTRIBUTE." WHERE attr_value_id IN (".join(',', $query_attr_id).") GROUP BY pro_id HAVING num_pro = ".$count_filter." LIMIT 10000 "); foreach ( $this->db->fetchAll($query) as $rs ) { $product_filter_id_match[] = $rs["pro_id"]; } } $where_query[] = (sizeof($product_filter_id_match)) ? " AND `id` IN (".join(', ', $product_filter_id_match).") " : " AND `id` = 0 " ; //xay lai url de back if(!$this->objCategoryProduct) $this->objCategoryProduct = new CategoryProduct(); foreach($filter_attr_value_list as $value_id ){ $att_name = $this->objCategoryProduct->atrValueName($value_id); $filterPath["attribute"][] = array( "id" => $value_id, "name" => $att_name, ); $filter_messages[] = [ 'title' => $att_name, 'reset' => Url::buildUrl($this->_request_url, ['filter' => join(FILTER_VALUE_SEPARATOR, remove_item_from_array($filter_condition["attribute"], $value_id))] ), ]; } } */ //- attribute values if( array_key_exists("attribute", $filter_condition) && sizeof($filter_condition["attribute"])) { $filter_attr_value_list = $filter_condition["attribute"]; $attr_values_per_attribute = $this->groupAttributeValuesByAttributeId($filter_attr_value_list); $having_match_count = sizeof(array_keys($attr_values_per_attribute)); $attribute_info_list = $this->groupAttributeListInfo(array_keys($attr_values_per_attribute)); $attr_where_query = []; foreach ($attr_values_per_attribute as $_att_id => $_att_value_list) { // if same attribute : find products that match either ONE of these values (not match ALL values) $_att_info = $attribute_info_list[$_att_id]; if (!$_att_info) continue; // this attribute requires all products must have ALL selected values if ($_att_info['value_match_all'] && sizeof($_att_value_list) > 1) { $_product_id_match_all = $this->getProductMatchAllAttributeValueIds($_att_value_list); if (sizeof($_product_id_match_all) > 0) { $attr_where_query[] = " ( `id` IN (" . join(",", $_product_id_match_all) . ") ) "; } else { $attr_where_query[] = " ( `id` = -1 ) "; } } else { $attr_where_query[] = " ( SELECT DISTINCT `pro_id` FROM " . TB_PRODUCT_ATTRIBUTE . " WHERE (" . join(" OR ", array_map(function ($_item) { return " `attr_value_id` = '" . intval($_item['id']) . "' "; }, $_att_value_list)) . " ) ) "; } } $product_filter_id_match = array(); if (sizeof($attr_where_query)) { $query = $this->db->runQuery(" SELECT `pro_id` , COUNT(*) AS num_pro FROM ( " . join(" UNION ALL ", $attr_where_query) . " ) AS tpm_tb GROUP BY pro_id HAVING num_pro = " . $having_match_count . " LIMIT 10000 "); foreach ($this->db->fetchAll($query) as $rs) { $product_filter_id_match[] = $rs["pro_id"]; } } $where_query[] = (sizeof($product_filter_id_match)) ? " AND " . TB_PRODUCT_LIGHT . ".`id` IN (" . join(', ', $product_filter_id_match) . ") " : " AND " . TB_PRODUCT_LIGHT . ".`id` = 0 "; } //- price range if( isset($filter_condition["price"]) && sizeof($filter_condition["price"]) && ($filter_condition["price"]['min'] > 0 || $filter_condition["price"]['max'] > 0) ) { //limit by price range $maxPrice = DataClean::makeInputSafe($filter_condition["price"]['max'], DataType::INTEGER); $minPrice = DataClean::makeInputSafe($filter_condition["price"]['min'], DataType::INTEGER); $price_range_query = ''; if($maxPrice > 0 && $minPrice > 0){ $price_range_query = " ( `price` BETWEEN '".$minPrice."' AND '".$maxPrice."' ) "; }else if($maxPrice > 0){ $price_range_query = " `price` < '".$maxPrice."' "; }else if($minPrice > 0){ $price_range_query = " `price` >='".$minPrice."' "; } $where_query[] = " AND ". $price_range_query; } // ------------ return array( join(" ", $where_query), $bind_types, $bind_values); } }