W Presta Shop atrybuty podzielone są na grupy atrybutów. W każdej grupie są pojedyncze wartości atrybutów. Taką pojedynczą wartość atrybutu możemy deklarować w zależności od typu grupy. Wtedy do dyspozycji mamy różne pola.
Jeśli grupa atrybutu jest „listą rozwijaną” lub „przyciskami jednokrotnego wyboru” do dyspozycji mamy pola:
- Listę grupy do wyboru (obowiązkowe)
- Wartość (obowiązkowe)
- URL
- Meta-tytuł
Natomiast jeśli grupa atrybutu jest typu „kolor lub tekstura” mamy także powyższe pola do wyboru oraz dodatkowo punkt 5) i 6) :
- Listę grupy do wyboru (obowiązkowe)
- Wartość (obowiązkowe)
- URL
- Meta-tytuł
- Wybór koloru (z palety)
- Tekstura
Czasem w celach programistycznych gdy chcemy dodać dodatkową funkcjonalność (np. opis, lub inną cechę reprezentującą pojedynczą wartość atrybutu) – potrzebne jest dodatkowe pole. W tym tutorialu pokażemy jak dodać dodatkowe pole z ceną.
Oczywiście ma się ono nijak do cen ustalanych przez kombinacje produktów. Było nam ono potrzebne w SmartProjects.pl przy realizacji jednego sklepu do specyficznego wyliczania ceny.
Pole nie będzie miało możliwości tłumaczenia na inne języki. Aby dodać tę funkcjonalność konieczne są inne modyfikacje. My się tutaj skupimy jak w ogóle to zrobić.
I. Modyfikacja bazy danych.
Logujemy się do programy PhpMyAdmin, wskazujemy naszą bazę danych i otwieramy tabelę ps_attribute. Jeśli mamy inny prefix w naszej inslalacji niż „ps_” oczywiście nazwa tabeli będzie inna. Następnie poprzez zakładkę Struktura dodajemy kolejne pole o nazwie price. Pole będzie typu Decimal i będzie miało Długość/Wartość o wartości „6,2„. Oznacza to, że dopuszczamy 6 cyfr przed przeciniem i 2 za przecinkiem.
Możemy to wykonać za pośrednictwem poniższego kodu SQL:
ALTER TABLE `ps_attribute` ADD `price` DECIMAL( 6, 2 ) NOT NULL ;
II. Modyfikacje plików PHP
Otwieramy plik:
classes/Attribute.php
Na początku klasy AttributeCore deklarujemy dodatkową zmienną publiczną. Zamieniamy kod:
public $name; public $color; public $position; public $default;
na:
public $name; public $price; public $color; public $position; public $default;
Określamy definicję tego pola. Zamieniamy kod:
'name' => array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isGenericName', 'required' => true, 'size' => 128),
Na:
'price' => array('type' => self::TYPE_STRING, 'lang' => false, 'validate' => 'isFloat', 'required' => false, 'size' => 128), 'name' => array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isGenericName', 'required' => true, 'size' => 128),
Jak widać nowe pole jest bez możliwości tłumaczenia, musi być polem typu Float i nie jest obowiązkowe.
Modyfikujemy metodę (funkcję obiektową w PHP) o nazwie getAttributes(). Zamieniamy kod SQL:
SELECT DISTINCT ag.*, agl.*, a.`id_attribute`, al.`name`, agl.`name` AS `attribute_group`
Na:
SELECT DISTINCT ag.*, agl.*, a.`id_attribute`, a.`price`, al.`name`, agl.`name` AS `attribute_group`
Modyfikujemy plik:
controllers/admin/AdminAttributesGroupsController.php
W metodzie o nazwie renderFormAttributes() znajdujemy tablicę o nazwie:
$this->fields_form
Na jej końcu dodajemy kolejny element. Zamieniamy kod:
array( 'type' => 'text', 'label' => $this->l('Value'), 'name' => 'name', 'lang' => true, 'required' => true, 'hint' => $this->l('Invalid characters:').' <>;=#{}' )
Na:
array( 'type' => 'text', 'label' => $this->l('Value'), 'name' => 'name', 'lang' => true, 'required' => true, 'hint' => $this->l('Invalid characters:').' <>;=#{}' ), array( 'type' => 'text', 'label' => $this->l('Price'), 'name' => 'price', 'lang' => false, 'required' => false, 'hint' => $this->l('Invalid characters:').' <>;=#{}' )
Gotowe! Po zapisaniu plików i przeładowaniu cache sklepu (Parametry zaawansowane >> Wydajność >> Wyczyść pamięć podręczną) powinniśmy podczas edycji wartości atrybutu (oraz co ważne – przy dodawaniu nowej wartości) zobaczyć nasze pole:
Jak się do tego odnieść w product.tpl?
Jak wyświetlić pole $price na stronie produktu we front office?
Jest tutaj w ogóle ktoś?
Miałem urlop. Nie bardzo rozumiem. Chcesz wyświetlić cenę
produktu na stronie produktu i ten nowo dodany atrybut ?
A to przepraszam że w urlopie przeszkadzałem :). Dokładnie to wykorzystałem tą metodę aby dodać tooltip do atrybutu i nie mogę tego wyświetlić na stronie produktu. Powiedzmy że utworzyłem $tooltip i analogicznie do tego wszystko po kolei z tutoriala ale po wpisaniu np: w product.tpl, tam gdzie generują się atrubuty $tooltip nie wyświetla mi tekstu z tabeli. Do bazy danych zapisuje i pobiera do pola tekstowego w Adminie dane ale nie wiem jak to wyświetlić na stronie produktu? Dziękuję za pomoc. Pozdrawiam
A jak zrzutujesz zmienną w szablonie product.tpl poprzez {$tooltip|var_dump} to jaki kod Ci zwraca?
Zwraca „null”, tak jakby szablon nie pobierał wartości z tabeli ps_attribute.
To idąc za ciosem napisz co dokładnie przekazujesz w tej zmiennej do szablonu product.tpl poprzez PHP i metodę smarty assign? 🙂
Po kolei, zmiany w pliku Attribute.php:
/** @var string Name */
public $name;
public $tooltip;
public $color;
public $position;
public $default;
/**
* @see ObjectModel::$definition
*/
public static $definition = array(
'table’ => 'attribute’,
'primary’ => 'id_attribute’,
'multilang’ => true,
'fields’ => array(
'id_attribute_group’ => array(’type’ => self::TYPE_INT, 'validate’ => 'isUnsignedId’, 'required’ => true),
'color’ => array(’type’ => self::TYPE_STRING, 'validate’ => 'isColor’),
'position’ => array(’type’ => self::TYPE_INT, 'validate’ => 'isInt’),
'tooltip’ => array(’type’ => self::TYPE_HTML, 'lang’ => false, 'validate’ => 'isCleanHtml’,’required’ => false),
'name’ => array(’type’ => self::TYPE_STRING, 'lang’ => true, 'validate’ => 'isGenericName’, 'required’ => true, 'size’ => 64),
)
);
———————-
public static function getAttributes($id_lang, $not_null = false)
{
if (!Combination::isFeatureActive())
return array();
return Db::getInstance()->executeS(’
SELECT DISTINCT ag.*, agl.*, a.`id_attribute`, a.`tooltip`, 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` = ’.(int)$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` = ’.(int)$id_lang.’)
’.Shop::addSqlAssociation(’attribute_group’, 'ag’).’
’.Shop::addSqlAssociation(’attribute’, 'a’).’
’.($not_null ? 'WHERE a.`id_attribute` IS NOT NULL AND al.`name` IS NOT NULL AND agl.`id_attribute_group` IS NOT NULL’ : ”).’
ORDER BY agl.`name` ASC, a.`position` ASC
’);
}
—————————–
Zmiany w pliku AdminAttributeGroupsController.php
public function renderFormAttributes()
{
$attributes_groups = AttributeGroup::getAttributesGroups($this->context->language->id);
$this->table = 'attribute’;
$this->identifier = 'id_attribute’;
$this->fields_form = array(
'legend’ => array(
'title’ => $this->l(’Values’),
'image’ => ’../img/admin/asterisk.gif’,
),
'input’ => array(
array(
'type’ => 'select’,
'label’ => $this->l(’Attribute group:’),
'name’ => 'id_attribute_group’,
'required’ => true,
'options’ => array(
'query’ => $attributes_groups,
'id’ => 'id_attribute_group’,
'name’ => 'name’
),
'desc’ => $this->l(’Choose the group of the attribute’)
),
array(
'type’ => 'text’,
'label’ => $this->l(’Value:’),
'name’ => 'name’,
'lang’ => true,
'size’ => 33,
'required’ => true,
'hint’ => $this->l(’Invalid characters:’).’ ;=#{}’
),
array(
'type’ => 'textarea’,
'label’ => $this->l(’Dodatkowy tekst’),
'name’ => 'tooltip’,
'lang’ => false,
'cols’ => 100,
'rows’ => 15,
'class’ => 'rte’,
'autoload_rte’ => true,
'required’ => false
)
)
);
————–
Utworzona kolumna w ps_attribute tooltip -> varchar.
To wszystko co dodałem i próbowałem wywołać to w product.tpl poprzez {$tooltip} ale nie działa.
Witam, i jest jakieś rozwiązanie do wywołania tego w product.tpl?
Do końca nie znam kodu presty i nie wiem jak to wywołać np: w jednym atrybucie w tabeli jest tekst w postaci html przekazany z textarea jak widać w kodzie powyżej „dodatkowy tekst”. I chciałbym to wyświetlić jako tooltip na stronie produktu, pisałeś coś o smarty assign, czyli rozumiem że trzeba dodać $tooltip gdzieś do kontrollera tak? Dziękuję za pomoc.
Witam, dalej nie znalazłem rozwiązania na powyższe rozwiązanie, można prosić o pomoc z dodaniem tego do product.tpl? Próbowałem dodać to do wiersza z $groups, tam gdzie pobiera dane typu nazwa z tej samej tabeli i nic. Prawdopodobnie trezba to dodać gdzie indziej za pomocą smarty->assign ale nie bardzo wiem gdzie :/. Pozdrawiam
Czy problem udało się naprawić? Rozumiem, że nie działa pokazywanie tych zmiennych zaciąganych z atrybutów w pliku product.tpl a co za tym idzie na karcie produktu ? Napisz w jaki sposób przekazujesz dane (i jakie dane przekazujesz) w pliku controllers/front/ProductController.php. Jakbyś jeszcze zdradził którą wersję Presta Shop masz to też będzie nam łatwiej udzielić Ci wskazówki 🙂
Witam
Czy jest za pomocą tej modyfikacji możliwość dodania do opisu produktu Cech produktu z konkretnego atrybutu żeby po zmianie atrybutu zmieniał sie także opis na Karcie produktu?
TZN: Zmieniamy atrybut np: długość węża, czy jego przekrój jeden z atrybutów a w opisie produktu zmienia się jego opis czyli szczegołowe dane w Prestashop 1.6 standardowy motyw