public function Handle_GetItemList($metadata, $request, $encoder)
    {
        // required arguments
        if (!isset($request['Paging'])) {
            CartAPI_Helpers::dieOnError($encoder, 'IncompleteRequest', 'Paging argument missing');
        }
        $sql_limit = CartAPI_Helpers::getSqlLimitFromPagingRequest($encoder, $request['Paging']);
        global $cookie;
        $id_lang = $cookie->id_lang;
        // allow to override filters before the command is executed
        if (isset($request['Filter'])) {
            $this->overrideItemListFilters($request['Filter']);
        }
        // go over the filters
        $sql_filters = array();
        $filters = CartAPI_Helpers::getDictionaryKeyAsArray($request, 'Filter');
        foreach ($filters as $filter) {
            $db_field_name_map = array('Title' => 'pl.`name`', 'CategoryId' => 'cp.`id_category`');
            $sql_filters[] = CartAPI_Helpers::getSqlFilterFromFilter($encoder, $filter, $db_field_name_map);
        }
        $sql_orderby = 'p.`id_product` desc';
        // default sort (newest items first)
        $this->overrideItemListSqlOrderBy($request, $sql_orderby);
        // complete the sql statement
        if (class_exists('Shop')) {
            $id_shop = Shop::getContextShopID(true);
            if ($id_shop !== null) {
                $sql_filters[] = 'pl.`id_shop` = ' . (int) $id_shop;
            }
        }
        $sql_filters[] = 'p.`active` = 1';
        $sql_filters[] = 'pl.`id_lang` = ' . (int) $id_lang;
        $sql_where = CartAPI_Helpers::getSqlWhereFromSqlFilters($sql_filters);
        $sql = '
			SELECT SQL_CALC_FOUND_ROWS p.`id_product`, pl.`name`, p.`active` 
			FROM `' . _DB_PREFIX_ . 'product` p 
			LEFT JOIN `' . _DB_PREFIX_ . 'category_product` cp ON cp.`id_product` = p.`id_product`
			LEFT JOIN `' . _DB_PREFIX_ . 'product_lang` pl ON p.`id_product` = pl.`id_product` 
			' . $sql_where . ' 
			GROUP BY `id_product` 
			ORDER BY ' . $sql_orderby . '
			' . $sql_limit;
        // load the products and the total element count
        $result = Db::getInstance()->ExecuteS($sql);
        $total_elements_row = Db::getInstance()->getRow('SELECT FOUND_ROWS()');
        $total_elements = intval(array_pop($total_elements_row));
        // change results before they are returned
        $this->overrideItemListResult($request, $result, $total_elements);
        // create the response
        $response = CartAPI_Helpers::createSuccessResponseWithPaging($encoder, $request['Paging'], $total_elements, CartAPI_Handlers_Helpers::getLocale());
        // add the items to the response if needed
        if (count($result) > 0) {
            $items =& $encoder->addArray($response, 'Item');
        }
        // encode each item
        foreach ($result as $row) {
            // to allow support for overrideItemListResult() to return objects instead of arrays, let's check if it's an object and fix as needed
            if (is_object($row) && $row instanceof ProductCore) {
                $arr = array();
                $arr['id_product'] = $row->id;
                $arr['name'] = $row->name;
                $row = $arr;
                // make the switch from object to array
            }
            // encode the item
            $item =& $encoder->addContainerToArray($items);
            $encoder->addNumber($item, 'Id', $row['id_product']);
            $encoder->addString($item, 'Title', $row['name']);
            $price = $this->getPriceFromProductId($row['id_product']);
            $encoder->addNumber($item, 'Price', $price);
            $referencePrice = $this->getReferencePriceFromProductId($row['id_product']);
            if ($referencePrice > $price) {
                $encoder->addNumber($item, 'ReferencePrice', $referencePrice);
            }
            $this->addThumbnailUrlFromProductId($encoder, $item, $row['id_product']);
            $this->addExtraFieldsFromProductId($metadata, $request, $encoder, $item, $row['id_product']);
        }
        // show the response
        $encoder->render($response);
    }
    public function getProductAttributeIdFromOrderItem($orderItem)
    {
        if (!isset($orderItem['ItemId'])) {
            return false;
        }
        $itemId = $orderItem['ItemId'];
        // make sure this is a combination item
        if (!isset($orderItem['Combination'])) {
            return false;
        }
        // make an array of the attribute ids
        $ascAttributeIds = array();
        $variations = CartAPI_Helpers::getDictionaryKeyAsArray($orderItem['Combination'], 'Variation');
        foreach ($variations as $variation) {
            $ascAttributeIds[] = (int) $variation['ValueId'];
        }
        sort($ascAttributeIds);
        // get all the attribute combinations for this product
        $sql = '
			SELECT pa.`id_product_attribute`, pac.`id_attribute`
			FROM `' . _DB_PREFIX_ . 'product_attribute` pa 
			LEFT JOIN `' . _DB_PREFIX_ . 'product_attribute_combination` pac ON pac.`id_product_attribute` = pa.`id_product_attribute`
			WHERE pa.`id_product` =  ' . (int) $itemId . '
			ORDER BY pac.`id_attribute` ASC';
        $result = Db::getInstance()->ExecuteS($sql);
        if (!$result or empty($result)) {
            return false;
        }
        // make a list of all attributes
        $productAttributes = array();
        foreach ($result as $row) {
            $productAttributes[$row['id_product_attribute']][] = (int) $row['id_attribute'];
        }
        // try to find a match
        foreach ($productAttributes as $productAttributeId => $ascAttributes) {
            if ($ascAttributes == $ascAttributeIds) {
                return $productAttributeId;
            }
        }
        // if here than not found
        return false;
    }