Jump to content

productAttributeExists query


scaryjones
 Share

Recommended Posts

Hi,

I'm trying to understand (as someone who knows C# programming but not PHP) the following function productAttributeExists that checks if a particular product attribute combo already exists.

Here's the code for those unfamiliar with it:

public function productAttributeExists($attributesList, $currentProductAttribute = false)
   {
       $result = Db::getInstance()->ExecuteS('SELECT pac.`id_attribute`, pac.`id_product_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` = '.intval($this->id));
       /* If something's wrong */
       if (!$result OR empty($result))
           return false;
       /* Product attributes simulation */
       $productAttributes = array();
       foreach ($result AS $productAttribute)
           $productAttributes[$productAttribute['id_product_attribute']][] = $productAttribute['id_attribute'];
       /* Checking product's attribute existence */
       foreach ($productAttributes AS $key => $productAttribute)
           if (sizeof($productAttribute) == sizeof($attributesList))
           {
               $diff = false;
               for ($i = 0; $diff == false AND isset($productAttribute[$i]); $i++)
                   if (!in_array($productAttribute[$i], $attributesList) OR $key == $currentProductAttribute)
                       $diff = true;
               if (!$diff)
                   return true;
           }
       return false;
   }



My query is with the lines:

$productAttributes = array();
       foreach ($result AS $productAttribute)
           $productAttributes[$productAttribute['id_product_attribute']][] = $productAttribute['id_attribute'];




It appears like the code here is somehow grouping the columns of results (or maybe it isn't, it's not clear to me).
The function gets a list of attribute Ids and product attribute Ids and adds them to the productAttributes array, but what exactly is going on in the line:

$productAttributes[$productAttribute['id_product_attribute']][] = $productAttribute['id_attribute'];



It's not clear to me how they're being linked / grouped. In essence this is the raw line of code:

$productAttributes[][] = $productAttribute['id_attribute'];



So what does putting those two square braces together mean?

Share this post


Link to post
Share on other sites

First you have to understand the way Prestashop stores attributes. You first create different attributes. And a product might have several different combinations of these attributes. So a product has multiple combinations of a set of attributes. `id_product_attribute` is the id of this combination for that product. There are several `id_product_attribute` for a product, and each of them have several product attributes (id_attribute).
This function first creates a list of combinations, each combination containing several attributes. And then it checks them against the set of attributes passed and finds if any of the combinations contain all the attributes.

Share this post


Link to post
Share on other sites

Thanks for the replies guys, I understand how the function is working, I'm just a little unclear as to how it's grouping those IDs.

From what I can tell the SQL query is returning two columns, listing the attributeIds and productAttributeIds.

The loop / multi-dimensional array creation seems to be able to group them by ProductAttributeId, so it's saying in essence:

"For each of the results returned, create an array of product attribute Ids where the product attribute ids are similar and - on the other side, show the corresponding attributeIds."

I just don't understand how it knows the product attribute Ids are the same. I can't see it in the code, but I think it's cause of my lack of PHP knowledge.

Share this post


Link to post
Share on other sites

Let me try to explain it with an example. Let's say you have two attribute groups, with two attributes in each.
Capacity: 8gb, 16gb
Color: blue, black

In the attributes table you will have 4 entries, one for each attribute. Now, when you want to add these to a product, you add them in combinations. In total you will have 4 combinations (2x2) max, you can choose to have less combinations than this. Let's add three such combinations:
8gb blue
16gb blue
16gb black

In this example 8gb black won't be available, you will get an error if you try to add that to the cart. Now this is where id_product_attribute comes in. In the product attribute table you will have 2 entries for each combination. That is because each combination contains 2 attributes. If we had added another attribute, then we would have 3. For this case our table will look like this, with ids instead of the attribute names:
id_product_attribute_1 8gb
id_product_attribute_1 blue
id_product_attribute_2 16gb
id_product_attribute_2 blue
id_product_attribute_3 16gb
id_product_attribute_3 black

So this function groups them into indexed arrays
$attributes[id_product_attribute_1]=array(8gb, blue)
...
..
.

Then it goes trough them and checks if any of them have all the attributes matching.

Share this post


Link to post
Share on other sites

Let me try to explain it with an example. Let's say you have two attribute groups, with two attributes in each.
Capacity: 8gb, 16gb
Color: blue, black

In the attributes table you will have 4 entries, one for each attribute. Now, when you want to add these to a product, you add them in combinations. In total you will have 4 combinations (2x2) max, you can choose to have less combinations than this. Let's add three such combinations:
8gb blue
16gb blue
16gb black

In this example 8gb black won't be available, you will get an error if you try to add that to the cart. Now this is where id_product_attribute comes in. In the product attribute table you will have 2 entries for each combination. That is because each combination contains 2 attributes. If we had added another attribute, then we would have 3. For this case our table will look like this, with ids instead of the attribute names:
id_product_attribute_1 8gb
id_product_attribute_1 blue
id_product_attribute_2 16gb
id_product_attribute_2 blue
id_product_attribute_3 16gb
id_product_attribute_3 black

So this function groups them into indexed arrays
$attributes[id_product_attribute_1]=array(8gb, blue)
...
..
.

Then it goes trough them and checks if any of them have all the attributes matching.


Thanks so much for taking the time to explain this, it now -finally - makes sense! Really appreciate the detail and effort you went to, very rare in these days of "RTFM!!" responses you can sometimes get when asking questions like this online.

Share this post


Link to post
Share on other sites

Let me try to explain it with an example. Let's say you have two attribute groups, with two attributes in each.
Capacity: 8gb, 16gb
Color: blue, black

In the attributes table you will have 4 entries, one for each attribute. Now, when you want to add these to a product, you add them in combinations. In total you will have 4 combinations (2x2) max, you can choose to have less combinations than this. Let's add three such combinations:
8gb blue
16gb blue
16gb black

In this example 8gb black won't be available, you will get an error if you try to add that to the cart. Now this is where id_product_attribute comes in. In the product attribute table you will have 2 entries for each combination. That is because each combination contains 2 attributes. If we had added another attribute, then we would have 3. For this case our table will look like this, with ids instead of the attribute names:
id_product_attribute_1 8gb
id_product_attribute_1 blue
id_product_attribute_2 16gb
id_product_attribute_2 blue
id_product_attribute_3 16gb
id_product_attribute_3 black

So this function groups them into indexed arrays
$attributes[id_product_attribute_1]=array(8gb, blue)
...
..
.

Then it goes trough them and checks if any of them have all the attributes matching.


Thanks man !

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...

Important Information

Cookies ensure the smooth running of our services. Using these, you accept the use of cookies. Learn More