PrestaShop Forum

The best place in the world to ask questions about PrestaShop and get advice from our passionate community!

PrestaShop Forum

Jump to content

 

Sort Product «Attributes»

32 replies to this topic
#1
Infordesign

    PrestaShop Newbie

  • Members
  • Pip
  • 24 posts
Hello all!

I've realized that the current SVN version of PrestaShop is not sorting correctly product attributes. To correct this you can do the following changes on your source code:

(obviously, you don't have to include «[INI] Infordesign» and «[END] Infordesign» comments, they're on the code I posted just to indicate were the changes have been done.)

NOTE: The idea of hiding "01.", "02.", ... from the Attribute name was from «vinoalvino» user, from this forum, as posted here: http://www.prestasho...iewthread/3139/

FILE: /classes/Product.php
TODO: Change «getAttributesGroups» to this:


public function getAttributesGroups($id_lang)
{
$result = Db::getInstance()->ExecuteS('
SELECT ag.`id_attribute_group`, agl.`name` AS group_name, agl.`public_name` AS public_group_name, a.`id_attribute`, al.`name` AS attribute_name,
a.`color` AS attribute_color, pa.`id_product_attribute`, pa.`quantity`, pa.`price`, pa.`ecotax`, pa.`weight`, pa.`default_on`, pa.`reference`
FROM `'._DB_PREFIX_.'product_attribute` pa
LEFT JOIN `'._DB_PREFIX_.'product_attribute_combination` pac ON pac.`id_product_attribute` = pa.`id_product_attribute`
LEFT JOIN `'._DB_PREFIX_.'attribute` a ON a.`id_attribute` = pac.`id_attribute`
LEFT JOIN `'._DB_PREFIX_.'attribute_group` ag ON ag.`id_attribute_group` = a.`id_attribute_group`
LEFT JOIN `'._DB_PREFIX_.'attribute_lang` al ON a.`id_attribute` = al.`id_attribute`
LEFT JOIN `'._DB_PREFIX_.'attribute_group_lang` agl ON ag.`id_attribute_group` = agl.`id_attribute_group`
WHERE pa.`id_product` = '.intval($this->id).'
AND al.`id_lang` = '.intval($id_lang).'
AND agl.`id_lang` = '.intval($id_lang).

// [INI] Infordesign
'ORDER BY agl.`name`, al.`name`, pa.`id_product_attribute`');

$resultsArray = array();
foreach ($result AS $row)
{
$row['attribute_name'] = preg_replace('/^[0-9]+\./', '', $row['attribute_name']);
$resultsArray[] = $row;
}
return $resultsArray;
// [END] Infordesign
}

I N F O R D E S I G N ®

Infordesign - Unipessoal, Lda.
WEB: www.infordesign.com | MAIL: mail [at] infordesign [dot] com

#2
Infordesign

    PrestaShop Newbie

  • Members
  • Pip
  • 24 posts
FILE: /classes/Cart.php
TODO: Change «getProducts» to this:


public function getProducts($refresh = false, $id_product = false)
{

( . . . )

/* Add attributes to the SQL result if needed */
if (isset($row['id_product_attribute']) AND Validate::isUnsignedInt($row['id_product_attribute']))
{
$result2 = Db::getInstance()->ExecuteS('
SELECT agl.`public_name` AS public_group_name, al.`name` AS attribute_name
FROM `'._DB_PREFIX_.'product_attribute_combination` pac
LEFT JOIN `'._DB_PREFIX_.'attribute` a ON a.`id_attribute` = pac.`id_attribute`
LEFT JOIN `'._DB_PREFIX_.'attribute_group` ag ON ag.`id_attribute_group` = a.`id_attribute_group`
LEFT JOIN `'._DB_PREFIX_.'attribute_lang` al ON (a.`id_attribute` = al.`id_attribute` AND al.`id_lang` = '.intval($this->id_lang).')
LEFT JOIN `'._DB_PREFIX_.'attribute_group_lang` agl ON (ag.`id_attribute_group` = agl.`id_attribute_group` AND agl.`id_lang` = '.intval($this->id_lang).')
WHERE pac.`id_product_attribute` = '.intval($row['id_product_attribute'].' ORDER BY al.`name`'));

$attributesList = '';
$attributesListSmall = '';
if ($result2)
foreach ($result2 AS $k2 => $row2)
{
// [INI] Infordesign
$attributesList .= $row2['public_group_name'].': '.preg_replace('/^[0-9]+\./', '', $row2['attribute_name']).', ';
$attributesListSmall .= preg_replace('/^[0-9]+\./', '', $row2['attribute_name']).', ';
// [END] Infordesign
}
$attributesList = rtrim($attributesList, ', ');
$attributesListSmall = rtrim($attributesListSmall, ', ');
$row['attributes'] = $attributesList;
$row['attributes_small'] = $attributesListSmall;
$row['stock_quantity'] = $row['quantity_attribute'];
}
$products[] = $row;
}
$this->_products = $products;
return $this->_products;
}

I N F O R D E S I G N ®

Infordesign - Unipessoal, Lda.
WEB: www.infordesign.com | MAIL: mail [at] infordesign [dot] com

#3
Infordesign

    PrestaShop Newbie

  • Members
  • Pip
  • 24 posts
FILE: /classes/Attribute.php
TODO: Change «getAttributes» to this:


static public function getAttributes($id_lang, $notNull = false)
{
$result = Db::getInstance()->ExecuteS('
SELECT ag.*, agl.*, a.`id_attribute`, al.`name`, agl.`name` AS `attribute_group`
FROM `'._DB_PREFIX_.'attribute_group` ag
LEFT JOIN `'._DB_PREFIX_.'attribute_group_lang` agl ON (ag.`id_attribute_group` = agl.`id_attribute_group` AND agl.`id_lang` = '.intval($id_lang).')
LEFT JOIN `'._DB_PREFIX_.'attribute` a ON a.`id_attribute_group` = ag.`id_attribute_group`
LEFT JOIN `'._DB_PREFIX_.'attribute_lang` al ON (a.`id_attribute` = al.`id_attribute` AND al.`id_lang` = '.intval($id_lang).')
'.($notNull ? 'WHERE a.`id_attribute` IS NOT NULL AND al.`name` IS NOT NULL' : '').

// [INI] Infordesign
'ORDER BY agl.`name` ASC, al.`name` ASC');

$resultsArray = array();
foreach ($result AS $row)
{
$row['name'] = preg_replace('/^[0-9]+\./', '', $row['name']);
$resultsArray[] = $row;
}
return $resultsArray;
// [END] Infordesign
}

I N F O R D E S I G N ®

Infordesign - Unipessoal, Lda.
WEB: www.infordesign.com | MAIL: mail [at] infordesign [dot] com

#4
Infordesign

    PrestaShop Newbie

  • Members
  • Pip
  • 24 posts
FILE: /classes/AttributeGroup.php
TODO: Change «getAttributes» to this:


static public function getAttributes($id_lang, $id_attribute_group)
{
$result = Db::getInstance()->ExecuteS('
SELECT *
FROM `'._DB_PREFIX_.'attribute` a
LEFT JOIN `'._DB_PREFIX_.'attribute_lang` al ON (a.`id_attribute` = al.`id_attribute` AND al.`id_lang` = '.intval($id_lang).')
WHERE a.`id_attribute_group` = '.intval($id_attribute_group).

// [INI] Infordesign
'ORDER BY `name`');

$resultsArray = array();
foreach ($result AS $row)
{
$row['name'] = preg_replace('/^[0-9]+\./', '', $row['name']);
$resultsArray[] = $row;
}
return $resultsArray;
// [END] Infordesign
}

I N F O R D E S I G N ®

Infordesign - Unipessoal, Lda.
WEB: www.infordesign.com | MAIL: mail [at] infordesign [dot] com

#5
Gekko

    PrestaShop Newbie

  • Members
  • Pip
  • 11 posts
Thank you! I had the same problem too :-) Very well done, do you have a little hack for making attributes that doesn't affect Quantity as well? :-P

#6
Jack

    PrestaShop Apprentice

  • Members
  • PipPip
  • 239 posts
It works great. Thanks for sharing...

#7
JARNO

    PrestaShop Newbie

  • Members
  • Pip
  • 3 posts
Hi,

I copied the code as per the above, but i just get a blank screen?

Any ideas

Thanks

Jarno

#8
Infordesign

    PrestaShop Newbie

  • Members
  • Pip
  • 24 posts

From 1236528541:

Hi,

I copied the code as per the above, but i just get a blank screen?

Any ideas

Thanks

Jarno


Well, that could be a result of a php error somewhere (could be a missing ";", a non-closed "{", or any syntax error). Please, check your code and see your php error log to find out what is causing that error.
I N F O R D E S I G N ®

Infordesign - Unipessoal, Lda.
WEB: www.infordesign.com | MAIL: mail [at] infordesign [dot] com

#9
JARNO

    PrestaShop Newbie

  • Members
  • Pip
  • 3 posts
Many thanks for the reply, I had copied the whole code instead of the just the modified code where you had highlighted. now works great.

Thanks for the reply.

Jarno

#10
zOOge

    PrestaShop Newbie

  • Members
  • Pip
  • 10 posts
Hi there,
I got this error after changing the above:
Warning: Invalid argument supplied for foreach() in /sites/prestabuild/classes/Product.php on line 1404
I'm running on Apache 2.2.3, PHP 5.2.1 and MySQL 5.0.38

// Fredrik

#11
Infordesign

    PrestaShop Newbie

  • Members
  • Pip
  • 24 posts
Please check your code and see if you are not using the variable names on other part of the code, and if you have:

$result = Db::getInstance()->ExecuteS(' ... ');
$resultsArray = array();
foreach ($result AS $row) { ... }
I N F O R D E S I G N ®

Infordesign - Unipessoal, Lda.
WEB: www.infordesign.com | MAIL: mail [at] infordesign [dot] com

#12
stevenh

    PrestaShop Newbie

  • Members
  • Pip
  • 6 posts
Could someone please post just the exact code to remove and which code to replace it with. I've tried several times with no luck. Have any of these files changed since this fix was posted 3 months ago?

Thanks

#13
logz05

    PrestaShop Newbie

  • Members
  • Pip
  • 12 posts
Hi,

I have been pulling my hair out over this for the last couple of days.

I have implemented the code and order the attributes 01.S , 02.M , 03.L

When I make the changes I actually lose the attributes in the cart box - and the only error I come up with in the error log is related to the LoyaltyModule.php on line 111 - it is:

foreach ($attributesGroups AS $attributesGroup)

so obviously (dangerous word) is has to with the variable $attributesGroups which I guess are defined in getAttributesGroups in product.php

Could someone please post the four files to see if they work on my site (Version 1.1.0.5)?

Thanks

#14
logz05

    PrestaShop Newbie

  • Members
  • Pip
  • 12 posts
OK I sorted it!

The code I used was the following (from the Spanish forum - you have to be multilingual round here!)
    public function getAttributesGroups($id_lang)
{
$result = Db::getInstance()->ExecuteS('
SELECT ag.`id_attribute_group`, agl.`name` AS group_name, agl.`public_name` AS public_group_name, a.`id_attribute`, al.`name` AS attribute_name,
a.`color` AS attribute_color, pa.`id_product_attribute`, pa.`quantity`, pa.`price`, pa.`ecotax`, pa.`weight`, pa.`id_image`,pa.`default_on`, pa.`reference`
FROM `'._DB_PREFIX_.'product_attribute` pa
LEFT JOIN `'._DB_PREFIX_.'product_attribute_combination` pac ON pac.`id_product_attribute` = pa.`id_product_attribute`
LEFT JOIN `'._DB_PREFIX_.'attribute` a ON a.`id_attribute` = pac.`id_attribute`
LEFT JOIN `'._DB_PREFIX_.'attribute_group` ag ON ag.`id_attribute_group` = a.`id_attribute_group`
LEFT JOIN `'._DB_PREFIX_.'attribute_lang` al ON a.`id_attribute` = al.`id_attribute`
LEFT JOIN `'._DB_PREFIX_.'attribute_group_lang` agl ON ag.`id_attribute_group` = agl.`id_attribute_group`
WHERE pa.`id_product` = '.intval($this->id).'
AND al.`id_lang` = '.intval($id_lang).'
AND agl.`id_lang` = '.intval($id_lang).'
ORDER BY agl.`name`, al.`name`, pa.`id_product_attribute`');

/* Modify SQL result - hide 01. 02. */
$resultsArray = array();
foreach ($result AS $row)
{
$row['attribute_name'] = preg_replace('/^[0-9]+\./', '', $row['attribute_name']);
$resultsArray[] = $row;
}
return $resultsArray;
}


Note that this is slightly different to the code in http://www.prestasho...iewthread/3139/ by
Infordesign

Thanks to everyone

What I would like to do now is to write it so that if an attribute has a number (begining with 0) then this reordering is done but if not then the order by name is used.

That way I can get 01.S, 02.M and 03.L working and 60 x 200, 100 x 200 in the right order without having to put the 01. etc. I have about 300 sizes to edit otherwise!

Up to now I can identify those attributes with zero in front and those without:

$resultsArray = array();
foreach ($result AS $row)
{
$zero = substr($row['attribute_name'],0,1);
if ( $zero =="0")
{

$row['attribute_name'] = preg_replace('/^[0-9]+\./', '', $row['attribute_name']);
$resultsArray[] = $row;
}
else {
$row['attribute_name'] = $row['attribute_name'];
$resultsArray[] = $row;
}

}
return $resultsArray;


but I can't see how to re-order the sort to show those that don't have zero in teh standard way?

#15
logz05

    PrestaShop Newbie

  • Members
  • Pip
  • 12 posts
Solved - this was easier than I thought.

$resultsArray = array();
foreach ($result AS $row)
{
$zero = substr($row['attribute_name'],0,1);
if ( $zero =="0")
{ echo "0 case";

$row['attribute_name'] = preg_replace('/^[0-9]+\./', '', $row['attribute_name']);
$resultsArray[] = $row;
}
else {

$row['attribute_name'] = $row['attribute_name'];

$resultsArray[] = $row;

sort($resultsArray);
}

}
return $resultsArray;


This displays 01.S, 02.M, 03.L in the correct order and it shows attributes for size as 80x120, 105x120 in the right order without the need to place the 01. etc in front of all the measurements.

Hope this helps someone.

#16
Zodiack

    PrestaShop Newbie

  • Members
  • Pip
  • 9 posts
I used this but now have problems. The problem is that nothing is shown under "products in this catagory" in the admin part. The products are still on my shop, but i just can't see them in the admin part. Any inputs on where I went wrong?

#17
Informatique

    PrestaShop Newbie

  • Members
  • Pip
  • 17 posts
This is a great post and really help me to organise the order of my attributes.

Is there a similar way of ordering the data within the attributes drop down menus as well? It defaults to alphabetical, which is a disaster if you want to do sizes or something similar. How about changing it to sort by the id? At least this way you can order them in the same order as you enter the attributes.

Any help would be very much appreciated.

#18
Informatique

    PrestaShop Newbie

  • Members
  • Pip
  • 17 posts
Has anyone got this fix to work for 1.2.3?

#19
mantobani

    PrestaShop Apprentice

  • Members
  • PipPip
  • 25 posts

From 1253004889:

Has anyone got this fix to work for 1.2.3?


I have the same problem.
mantobani · Web & Graphic designer · Portfolio

#20
tokuan

    PrestaShop Newbie

  • Members
  • Pip
  • 11 posts
I just wonder if these changes can still be used to solve sorting problem.Running Prestashop 1.2.5

I try to use it, but get an

Warning: Invalid argument supplied for foreach() in /var/www/vhosts/myshop.com/httpdocs/classes/Attribute.php on line 94

In getAttributes function I have changed $result variable to not get in any name conflict.

Any help will be appreciated

Kind Regards
Tom