Conner Burnett
Conner Burnett

Reputation: 512

Prestashop product features PHP SQL

We are wanting to do a quick compare on the product page that compares the current product and then the two top sellers in that category after that. I have all the SQL to get the current product and the two that are top sellers, but am having trouble adding the features to those. This is what I am facing.

This is just as an example. This SQL would pull the product features within a category.

SELECT ps_product.id_product, ps_feature_lang.name, ps_feature_value_lang.value FROM ps_product LEFT JOIN ps_feature_product ON ps_feature_product.id_product = ps_product.id_product LEFT JOIN ps_feature_lang ON ps_feature_lang.id_feature = ps_feature_product.id_feature LEFT JOIN ps_feature_value_lang ON ps_feature_value_lang.id_feature_value = ps_feature_product.id_feature_value WHERE ps_product.id_category_default = '6' AND ps_feature_lang.id_feature IS NOT NULL

It returns

id_product | name | value
 9          Height  5
 9          Width   5
 9          Depth   5
 9          Weight  5
10          Height  10

I have tried to group by id_product, but of course that will only show on of the values from the features list for that product. I have also tried putting them into arrays by products, but can't get them to line up correctly on the front end.

I wasn't sure if prestashop already had a built in function to pull product features

Upvotes: 2

Views: 6226

Answers (1)

Bruno Leveque
Bruno Leveque

Reputation: 2811

With MySQL you can try to use GROUP_CONCAT() that could help for this query. However, we wrote a quick code snippet to give you an overview of what you can do.

This code:

  • Retrieves the two best sellers of the current product's category
  • Retrieves the features list for the 3 products (Current product + 2 best sellers)
  • Group these and display them into an HTML table

Here is the final result:

Product comparison

Code:

    <?php

include(dirname(__FILE__).'/config/config.inc.php');
include(dirname(__FILE__).'/init.php');
ini_set('display_errors', 'On');

$id_product = 1; /* Current Product ID */
$id_category = 2; /* Current Category ID */
$id_lang = 1; /* Current Language ID */

/* Retrieve the two Best sellers for this category, excluding the current product */
$best_sellers = Db::getInstance()->ExecuteS('
SELECT ps.id_product, pl.name product_name
FROM '._DB_PREFIX_.'product_sale ps
LEFT JOIN '._DB_PREFIX_.'category_product cp ON (cp.id_product = ps.id_product)
LEFT JOIN '._DB_PREFIX_.'product p ON (p.id_product = cp.id_product)
LEFT JOIN '._DB_PREFIX_.'product_lang pl ON (pl.id_product = p.id_product)
WHERE cp.id_category = '.(int)$id_category.' AND cp.id_product != '.(int)$id_product.' AND p.active = 1 AND pl.id_lang = '.(int)$id_lang.'
ORDER BY ps.sale_nbr DESC
LIMIT 2');

if (count($best_sellers))
{
    $products_to_compare = array();
    $products_names = array();
    foreach ($best_sellers as $best_seller)
    {
        $products_to_compare[] = (int)$best_seller['id_product'];
        $products_names[(int)$best_seller['id_product']] = $best_seller['product_name'];
    }
    $products_to_compare[] = (int)$id_product;
    $products_names[(int)$id_product] = 'Current product'; /* Replace by the current product name */

    $features = Db::getInstance()->ExecuteS('
    SELECT fp.id_product, fp.id_feature, fl.name feature_name, fvl.value feature_value
    FROM '._DB_PREFIX_.'feature_product fp
    LEFT JOIN '._DB_PREFIX_.'feature_lang fl ON (fl.id_feature = fp.id_feature)
    LEFT JOIN '._DB_PREFIX_.'feature_value_lang fvl ON (fvl.id_feature_value = fp.id_feature_value)
    WHERE fp.id_product IN ('.pSQL(implode(',', $products_to_compare)).')');

    $features_to_display = array();
    foreach ($features as $feature)
    {
        if (!isset($features_to_display[(int)$feature['id_feature']]))
        {
            $features_to_display[(int)$feature['id_feature']] = array();
            $features_to_display[(int)$feature['id_feature']]['name'] = $feature['feature_name'];
        }

        $features_to_display[(int)$feature['id_feature']][(int)$feature['id_product']] = $feature['feature_value'];
    }

    echo '
    <table cellpadding="5" cellspacing="0" border="1">
        <tr>
            <td></td>';

    foreach ($products_to_compare as $product_to_compare)
            echo '<td>'.($product_to_compare == $id_product ? '<b>' : '').Tools::safeOutput($products_names[(int)$product_to_compare]).($product_to_compare == $id_product ? '</b>' : '').'</td>';

    echo '</tr>';

    foreach ($features_to_display as $feature_to_display)
    {
        echo '
        <tr>
            <td>'.Tools::safeOutput($feature_to_display['name']).'</td>';

        foreach ($products_to_compare as $product_to_compare)
            echo '<td>'.($product_to_compare == $id_product ? '<b>' : '').Tools::safeOutput($feature_to_display[(int)$product_to_compare]).($product_to_compare == $id_product ? '</b>' : '').'</td>';

        echo '
        </tr>';
    }

    echo '
    </table>';

}
else
    die('Sorry, no best sellers for this category');

This code can be improved to save memory and transmit the results to Smarty (instead of displaying these directly in the controller).

Upvotes: 2

Related Questions