I want to get products by id in Prestashop, and list them

I want to get products by id in Prestashop, and list them with

{include file="$tpl_dir./product-list.tpl" products=$my_products_array}

I tried

 foreach ($productIds as $key => $productIdsValues) {
        $products2[$key] = get_object_vars(new Product($productIds[$key]));
    }

and

 foreach ($productIds as $key => $productIdsValues) {
        $products2[$key] = new Product($productIds[$key]);
    }

But when i want to list my products, i get error for every products ..

Undefined index: price_without_reduction
Undefined index: allow_oosp 
id_product_attribute 

Original Prestashop 1.6 with original theme, downloaded from te prestashop.com

Upvotes: 1

Views: 9192

Answers (3)

Thanks for answers. I've created a new method for Product class

/**
 * Get products by ID
 *
 * @param int $id_lang Language id
 * @param id product
 * @return array New products
 */
public static function getProductById($id_lang,$product_id, $page_number = 0, $nb_products = 10, $count = false, $order_by = null, $order_way = null, Context $context = null)
{

    if (!$context) {
        $context = Context::getContext();
    }

    $front = true;
    if (!in_array($context->controller->controller_type, array('front', 'modulefront'))) {
        $front = false;
    }

    if ($page_number < 0) {
        $page_number = 0;
    }
    if ($nb_products < 1) {
        $nb_products = 10;
    }
    if (empty($order_by) || $order_by == 'position') {
        $order_by = 'date_add';
    }
    if (empty($order_way)) {
        $order_way = 'DESC';
    }
    if ($order_by == 'id_product' || $order_by == 'price' || $order_by == 'date_add' || $order_by == 'date_upd') {
        $order_by_prefix = 'product_shop';
    } elseif ($order_by == 'name') {
        $order_by_prefix = 'pl';
    }
    if (!Validate::isOrderBy($order_by) || !Validate::isOrderWay($order_way)) {
        die(Tools::displayError());
    }

    $sql = new DbQuery();
    $sql->select(
        'p.*, product_shop.*, stock.out_of_stock, IFNULL(stock.quantity, 0) as quantity, pl.`description`, pl.`description_short`, pl.`link_rewrite`, pl.`meta_description`,
        pl.`meta_keywords`, pl.`meta_title`, pl.`name`, pl.`available_now`, pl.`available_later`, image_shop.`id_image` id_image, il.`legend`, m.`name` AS manufacturer_name,
        product_shop.`date_add` > "'.date('Y-m-d', strtotime('-'.(Configuration::get('PS_NB_DAYS_NEW_PRODUCT') ? (int)Configuration::get('PS_NB_DAYS_NEW_PRODUCT') : 20).' DAY')).'" as new'
    );

    $sql->from('product', 'p');
    $sql->join(Shop::addSqlAssociation('product', 'p'));
    $sql->leftJoin('product_lang', 'pl', '
        p.`id_product` = pl.`id_product`
        AND pl.`id_lang` = '.(int)$id_lang.Shop::addSqlRestrictionOnLang('pl')
    );
    $sql->leftJoin('image_shop', 'image_shop', 'image_shop.`id_product` = p.`id_product` AND image_shop.cover=1 AND image_shop.id_shop='.(int)$context->shop->id);
    $sql->leftJoin('image_lang', 'il', 'image_shop.`id_image` = il.`id_image` AND il.`id_lang` = '.(int)$id_lang);
    $sql->leftJoin('manufacturer', 'm', 'm.`id_manufacturer` = p.`id_manufacturer`');

    $sql->where('product_shop.`active` = 1');
    $sql->where('p.`id_product`='.(int)$product_id .' ');

        if (Group::isFeatureActive()) {
        $groups = FrontController::getCurrentCustomerGroups();
        $sql->where('EXISTS(SELECT 1 FROM `'._DB_PREFIX_.'category_product` cp
            JOIN `'._DB_PREFIX_.'category_group` cg ON (cp.id_category = cg.id_category AND cg.`id_group` '.(count($groups) ? 'IN ('.implode(',', $groups).')' : '= 1').')
            WHERE cp.`id_product` = p.`id_product`)');
    }

    $sql->orderBy((isset($order_by_prefix) ? pSQL($order_by_prefix).'.' : '').'`'.pSQL($order_by).'` '.pSQL($order_way));
    $sql->limit($nb_products, $page_number * $nb_products);

    if (Combination::isFeatureActive()) {
        $sql->select('product_attribute_shop.minimal_quantity AS product_attribute_minimal_quantity, IFNULL(product_attribute_shop.id_product_attribute,0) id_product_attribute');
        $sql->leftJoin('product_attribute_shop', 'product_attribute_shop', 'p.`id_product` = product_attribute_shop.`id_product` AND product_attribute_shop.`default_on` = 1 AND product_attribute_shop.id_shop='.(int)$context->shop->id);
    }
    $sql->join(Product::sqlStock('p', 0));

    $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql);
    // var_dump($result);die();

    if (!$result) {
        return false;
    }

    if ($order_by == 'price') {
        Tools::orderbyPrice($result, $order_way);
    }

    $products_ids = array();
    foreach ($result as $row) {
        $products_ids[] = $row['id_product'];
    }
    // Thus you can avoid one query per product, because there will be only one query for all the products of the cart
    Product::cacheFrontFeatures($products_ids, $id_lang);
    return Product::getProductsProperties((int)$id_lang, $result);
}

Upvotes: 0

Ghazaleh Javaheri
Ghazaleh Javaheri

Reputation: 2117

in my case i use $product=new Product($product_id) you can also check id be a valid product id by this function :Validate::isLoadedObject($product_two = new Product($second_product_id))

Upvotes: 1

Alexander Grosul
Alexander Grosul

Reputation: 1814

If you want to use a default product-list.tpl you need to create your own SQL query that would get necessary products by their ids. You can peep into Product.php and browse methods getNewProducts, getRandomSpecial, getPricesDrop and make something similar or adjust one of them for your needs. I am not saying that it is the only way but in my opinion is the most stable and reliable one

Upvotes: 2

Related Questions