Zawartość artykułu
Jak są deklarowane okładki kategorii w PrestaShop?
Okładki kategorii w PrestaShop są ustawiane po prostu przez wgranie pliku JPEG w folder:
img/c
Pod nazwą:
{ID-KATEGORII}.jpg {ID-KATEGORII}-category_default.jpg
Mogą być jeszcze inne wymiary okładek – są one zdeklarowane w wygląd -> zdjęcia (PrestaShop 1.7) lub Preferencje -> zdjęcia (PrestaShop 1.6)
Czyli np.
img/c/12.jpg img/c/12-category_default.jpg
Dla kategorii o ID = 12.
Jest to o tyle problematyczne że ciężko jest ustawić np. tą samą okładkę dla np. 300 podkategorii. No chyba, że masz czas kopiować 300 x 2 plików JPEG (jak kategorie mają więcej wymiarów to jeszcze więcej…).
Dla przykładu (wycinek drzewa ze sklepu www.wetkarma.pl):
ID = 12 (Kategoria podstawowa: PIES) 286 Żywienie 31 Karma sucha 32 Karma mokra 13 Karma weterynaryjna 29 Karma bezzbożowa 188 Mleko dla szczeniąt 33 Przysmaki 293 Karma według wieku psa 294 Karma według wagi psa 295 Karma według rasy psa 296 Karma według producentów 35 Przeciw pasożytom 189 Preparaty 190 Obroże 191 Akcesoria 34 Zdrowie (itd...)
Tutaj dla kategorii podstawowej „Pies” wszystkie potomne kategorie musza mieć taką samą okładkę jak ta kategoria podstawowa. Zatem trzeba by było utworzyć pliki:
img/c/286.jpg img/c/286-category_default.jpg img/c/31.jpg img/c/31-category_default.jpg img/c/32.jpg img/c/32-category_default.jpg ....
Zatem około weekend kopiowania plików 🙂
Gdyby to było zdeklarowane w bazie danych – wystarczyło by zapytanie. Tutaj niestety nic nam to nie da.
Idea skryptu który zrobi to za nas.
Aby obejść to ograniczenie opracowaliśmy sprytną metodę na ustawienie tego w parę sekund. Idea jest taka:
- Skrypt pobiera ID kategorii podstawowej – czyli tej która ma podkategorie. Ilość podkategorii nie ma znaczenia. Może być ich 50 a może być 1500. Mogą być podzielone na jeszcze kolejne podkategorie i liczba zagłębień – nie ma znaczenia.
- Skrypt tworzy listę wszystkich potomnych kategorii
- Skrypt kopiuje zdjęcie kategorii podstawowej (musi być ono ustawione) i powiela je dla wszystkich kategorii wgłąb
- Skrypt de facto – po prostu kopiuje pliki JPEG na serwerze.
Jeśli interesuje Cię taka zmiana – wykonaj poniższe czynności ! 🙂
Uwaga! Prezentowane tutaj rozwiązanie zadziała zarówno w wersji PrestaShop 1.7 jak i w nieco starszej – PrestaShop 1.6. Zostało to przez nas sprawdzone 😉
Ustawienie okładki kategorii podstawowej.
Aby skrypt zadziałał – musi on mieć skąd skopiować okładkę do kategorii potomnych. W innym wypadku – skrypt zostanie przerwany.
Włącz zatem edycję kategorii głównej (w powyższym przykładzie będzie to kategoria „Pies”).
Nastepnie wgraj okładkę w polu „Zdjęcie kategorii”:
I zapisz edycję tej kategorii.
Zmiany w plikach
UWAGA! Przed modyfikacjami wykonaj kopie plików PHP z przed zmiany!
UWAGA #2! Nasza modyfikacja permanentnie i nieodwracalnie nadpisze pliki w folderze img/c. Rozważ wykonanie kopii bezpieczeństwa tego folderu w razie potrzeby
Dla szybkości posłużymy się stroną CMS. Tam wkleimy kod który wykona zadanie i po ukończeniu procesu kopiowania – usuniemy go 🙂
Otwórz plik:
controllers/front/CmsController.php
Znajdź fragment kodu:
public function initContent()
Wklej nad nim kod:
public function allSubcategoriesIds($catID) { $subcatObj = new Category($catID); $subcatObj2 = $subcatObj->getSubCategories($this->context->language->id); if (!empty($subcatObj2)) { foreach ($subcatObj2 as $value) { $output .= $value['id_category'].","; $subcatObjNext = new Category($value['id_category']); $subcatObjNext2 = $subcatObj->getSubCategories($this->context->language->id); if (!empty($subcatObjNext2)) { $output .= $this->allSubcategoriesIds($value['id_category']); } } } if ($output!=='') { return $output; } } public function copyAllSubCatImages($catId) { $strIds = $this->allSubcategoriesIds($catId); $curr = _PS_IMG_DIR_.'c/'.$catId.'.jpg'; $curr2 = _PS_IMG_DIR_.'c/'.$catId.'-category_default.jpg'; // jeśli kategorie posiadają więcej wymiarów w dziale "zdjęcia" dopisz je tutaj if (file_exists($curr) && file_exists($curr2)) { $ii=0; foreach (explode(',',$strIds) as $subCatId) { if (is_numeric($subCatId)) { if (copy($curr, _PS_IMG_DIR_.'c/'.$subCatId.'.jpg')) { echo '<br>skopiowałem zdjęcie '.$subCatId.'.jpg'; $ii++; } if (copy($curr, _PS_IMG_DIR_.'c/'.$subCatId.'-category_default.jpg')) { echo '<br>skopiowałem zdjęcie '.$subCatId.'-category_default.jpg'; $ii++; } // jeśli kategorie posiadają więcej wymiarów w dziale "zdjęcia" dopisz je tutaj } } echo "Skopiowano {$ii} plików"; } else { // die('brak pliku'); } }
W wcześniej wspomnianej metodzie initContent() po kodzie:
public function initContent() {
Wklej kod:
if (isset($_GET['subcatcopy'])) { echo "<pre>"; print_r($this->copyAllSubCatImages($_GET['subcatcopy'])); echo "</pre>"; die; }
Gotowe!
W tym momencie musisz uruchomić wklejony skrypt. W tym celu wejdź na dowolną stronę statyczną-CMS (fraza „content” w adresie) na Twoim sklepie internetowym.
Np. na stronę regulaminu:
http://{adres-twojego-sklepu}/content/3-regulamin
ID strony którą wywołasz nie ma znaczenia.
Jednak po w/w adresie – doklej w pasku przegladarki:
?subcatcopy={ID-kategorii-podstawowej}
Czyli docelowy adres będzie to np.
http://{adres-twojego-sklepu}/content/3-regulamin?subcatcopy=12
Gotowe! Skrypt nast. rozpocznie kopiowania i zobaczysz listing typu:
skopiowałem zdjęcie 286.jpg skopiowałem zdjęcie 286-category_default.jpg skopiowałem zdjęcie 31.jpg skopiowałem zdjęcie 31-category_default.jpg skopiowałem zdjęcie 32.jpg skopiowałem zdjęcie 32-category_default.jpg skopiowałem zdjęcie 13.jpg skopiowałem zdjęcie 13-category_default.jpg .....
Gdy strona się w całości załaduje – możesz sprawdzić czy wszystkie okładki zostały skopiowane 🙂
Jak wszystko się zgadza – usuń wklejony kod w pliku:
controllers/front/CmsController.php
Regeneracja miniatur
Aby było w pełni po bożemu możesz w dziale „Zdjęcia” wywołać regenerację miniatur dla wybranych rozmiarów zdjęć kategorii. W naszym skrypcie nie skalujemy zdjęć tylko po prostu dla każdego wymiaru – kopiujemy zdjęcie oryginalne.
grafika:wallpaperflare.com
Czy nie uważasz, że edycja bezpośrednio w kontrolerach potem będzie problematyczna przy aktualizacji? Zabezpieczasz się jakoś przed tym?