Cyfroteka.pl

klikaj i czytaj online

Cyfro
Czytomierz
00613 009816 10450029 na godz. na dobę w sumie
Magento. Przewodnik dla programistów PHP - książka
Magento. Przewodnik dla programistów PHP - książka
Autor: Liczba stron: 224
Wydawca: Helion Język publikacji: polski
ISBN: 978-83-246-8940-8 Data wydania:
Lektor:
Kategoria: ebooki >> komputery i informatyka >> webmasterstwo >> php - programowanie
Porównaj ceny (książka, ebook, audiobook).

Poznaj i rozbuduj możliwości Magento!

Magento to platforma pozwalająca na prowadzenie handlu w sieci. Jej pierwsza wersja ukazała się w 2008 roku i od tego czasu platforma jest ciągle rozwijana. Magento powstało w oparciu o Zend Framework, a fakt ten cieszy wielu programistów PHP. Jeżeli chcesz poznać możliwości tej platformy, jeżeli chcesz wdrożyć ją, dostosować do własnych potrzeb lub napisać nowy moduł, to masz w rękach doskonałą książkę.

Ten przewodnik pozwoli Ci zgłębić tajniki Magento. W pierwszej kolejności poznasz architekturę platformy, niezbędne narzędzia oraz techniki — to pomoże Ci sprawnie poruszać się w środowisku Magento. Po tym wstępie przejdziesz do bardziej zaawansowanych zagadnień. Poznasz model EAV oraz nauczysz się rozszerzać interfejs użytkownika. Ponadto przekonasz się, że stworzenie nowego modułu w panelu administracyjnym wcale nie musi być takie trudne. W tej książce znajdziesz również dokładny opis API platformy oraz dowiesz się, jak testować stworzony kod. Na sam koniec zobaczysz, w jaki sposób przygotować Twój produkt do wdrażania i dystrybucji. Książka ta jest obowiązkową lekturą dla wszystkich programistów PHP pracujących w środowisku Magento.

Dzięki tej książce:

Wykorzystaj potencjał platformy Magento!

Znajdź podobne książki Ostatnio czytane w tej kategorii

Darmowy fragment publikacji:

Tytuł oryginału: Magento PHP Developer s Guide Tłumaczenie: Daniel Kaczmarek ISBN: 978-83-246-8940-8 Copyright © 2013 Packt Publishing. First published in the English language under the title „Magento PHP Developer s Guide”. Polish edition copyright © 2014 by Helion S.A. All rights reserved. All rights reserved. No part of this book may be reproduced or transmitted in any form or by any means, electronic or mechanical, including photocopying, recording or by any information storage retrieval system, without permission from the Publisher. Wszelkie prawa zastrzeżone. Nieautoryzowane rozpowszechnianie całości lub fragmentu niniejszej publikacji w jakiejkolwiek postaci jest zabronione. Wykonywanie kopii metodą kserograficzną, fotograficzną, a także kopiowanie książki na nośniku filmowym, magnetycznym lub innym powoduje naruszenie praw autorskich niniejszej publikacji. Wszystkie znaki występujące w tekście są zastrzeżonymi znakami firmowymi bądź towarowymi ich właścicieli. Autor oraz Wydawnictwo HELION dołożyli wszelkich starań, by zawarte w tej książce informacje były kompletne i rzetelne. Nie biorą jednak żadnej odpowiedzialności ani za ich wykorzystanie, ani za związane z tym ewentualne naruszenie praw patentowych lub autorskich. Autor oraz Wydawnictwo HELION nie ponoszą również żadnej odpowiedzialności za ewentualne szkody wynikłe z wykorzystania informacji zawartych w książce. Wydawnictwo HELION ul. Kościuszki 1c, 44-100 GLIWICE tel. 32 231 22 19, 32 230 98 63 e-mail: helion@helion.pl WWW: http://helion.pl (księgarnia internetowa, katalog książek) Drogi Czytelniku! Jeżeli chcesz ocenić tę książkę, zajrzyj pod adres http://helion.pl/user/opinie/magphp Możesz tam wpisać swoje uwagi, spostrzeżenia, recenzję. Printed in Poland. • Kup książkę • Poleć książkę • Oceń książkę • Księgarnia internetowa • Lubię to! » Nasza społeczność Spis tre(cid:258)ci O autorze O redaktorach Przedmowa O czym jest ta ksi(cid:200)(cid:285)ka? Wymagania pocz(cid:200)tkowe Dla kogo jest ta ksi(cid:200)(cid:285)ka? Konwencje zastosowane w ksi(cid:200)(cid:285)ce Przyk(cid:239)adowe kody (cid:283)ród(cid:239)owe Rozdzia(cid:239) 1. Rozpoznanie i instalacja (cid:258)rodowiska rozwojowego Podstawowe informacje na temat LAMP Uruchamianie VirtualBox Uruchomienie maszyny wirtualnej Instalacja serwera Apache2 Instalacja PHP Instalacja serwera MySQL Konfiguracja (cid:258)rodowiska docelowego Konfiguracja i uruchamianie (cid:258)rodowiska przy u(cid:285)yciu Vagrant Instalacja narz(cid:218)dzia Vagrant Wybór zintegrowanego (cid:258)rodowiska programistycznego Korzystanie z systemu kontroli wersji Podsumowanie Rozdzia(cid:239) 2. Podstawy Magento dla programistów Zend Framework — podstawa Magento Struktura folderów Magento Architektura modu(cid:239)owa Modu(cid:239) automatycznego (cid:239)adowania Pule kodu 7 9 11 11 12 12 13 13 15 15 16 19 23 24 25 25 28 29 31 31 32 33 33 35 36 37 38 Kup książkęPoleć książkę Spis tre(cid:286)ci Obiekty (cid:258)cie(cid:285)ek i przep(cid:239)yw (cid:285)(cid:200)da(cid:241) MVC w wersji Magento Modele Widoki Analiza pliku uk(cid:239)adu Kontrolery Witryny WWW i zasi(cid:218)gi sklepów Nazwy i funkcje wytwórcze Zdarzenia i obserwatory Generator zdarzenia Wi(cid:200)zania obserwatorów Podsumowanie Rozdzia(cid:239) 3. ORM i kolekcje danych Struktura modelu Magento Metody magiczne Model EAV Czym jest model EAV? Odczytywanie danych Korzystanie z kolekcji Magento Uzyskanie kolekcji produktów, które nale(cid:285)(cid:200) do okre(cid:258)lonej kategorii Uzyskanie nowych produktów, które pojawi(cid:239)y si(cid:218) w dniu x lub pó(cid:283)niej Uzyskanie produktów, które najlepiej si(cid:218) sprzedaj(cid:200) Filtrowanie kolekcji produktów wzgl(cid:218)dem widoczno(cid:258)ci produktów Filtrowanie produktów, którym nie przypisano obrazka Dodanie wielu kryteriów porz(cid:200)dkowania Wykonywanie bezpo(cid:258)rednich zapyta(cid:241) j(cid:218)zyka SQL Odczyt Zapisywanie Podsumowanie Rozdzia(cid:239) 4. Programowanie interfejsu u(cid:285)ytkownika Rozszerzenie Magento Scenariusz Funkcje Dalszy rozwój Witaj, Magento Konfiguracja XML modu(cid:239)u Modele i zapisywanie danych Tworzenie modeli Zasoby konfiguracyjne Czego si(cid:218) dowiedzieli(cid:258)my? Definiowanie (cid:258)cie(cid:285)ek Kontroler indeksu Kontroler wyszukiwania Kontroler widoku 4 39 43 47 47 48 50 51 52 55 56 58 59 61 62 64 68 68 73 76 78 79 80 80 81 81 82 83 84 84 85 85 85 86 86 87 90 92 93 98 106 107 108 113 115 Kup książkęPoleć książkę Spis tre(cid:286)ci Bloki i uk(cid:239)ady Bloki i widoki kontrolera IndexController Bloki i widoki kontrolera SearchController Bloki i widoki kontrolera ViewController Dodawanie produktów do listy prezentów Podsumowanie Rozdzia(cid:239) 5. Programowanie modu(cid:239)u administracyjnego Rozbudowa modu(cid:239)u Adminhtml Powrót do konfiguracji Wid(cid:285)et siatki Zarz(cid:200)dzanie listami prezentów Uprawnienia i lista kontroli dost(cid:218)pu Zbiorcza zmiana danych za pomoc(cid:200) akcji masowych Wid(cid:285)et formularza (cid:146)adowanie danych Zapisywanie danych Podsumowanie Rozdzia(cid:239) 6. API Magento Core API XML-RPC SOAP API REST Korzystanie z API Definiowanie danych logowania dla protoko(cid:239)ów XML-RPC i SOAP Definiowanie danych logowania dla protoko(cid:239)u REST API (cid:146)adowanie i odczytywanie danych Zmienianie danych Usuwanie produktu Rozszerzanie API Rozszerzanie API REST Zabezpieczanie API Podsumowanie Rozdzia(cid:239) 7. Testowanie i zapewnienie jako(cid:258)ci Testowanie Magento Testy jednostkowe Testy regresyjne Testy funkcjonalne Programowanie sterowane przez testy (TDD) Platformy i narz(cid:218)dzia do testowania Testy jednostkowe z wykorzystaniem PHPUnit Testy funkcjonalne z wykorzystaniem biblioteki Mink Pierwszy test Podsumowanie 116 117 123 127 128 128 129 130 132 136 140 141 145 147 151 152 153 155 155 156 157 159 160 160 162 164 165 166 167 175 177 178 179 180 180 180 181 181 182 182 195 196 199 5 Kup książkęPoleć książkę Spis tre(cid:286)ci Rozdzia(cid:239) 8. Wdra(cid:285)anie i dystrybucja Minimalizacja czasu wdro(cid:285)enia Od pocz(cid:200)tku stosuj zalecane praktyki Upewnij si(cid:218), (cid:285)e na ró(cid:285)nych (cid:258)rodowiskach uzyskasz identyczne wyniki Jak gotowe, to gotowe Rola systemów kontroli wersji w procesie wdro(cid:285)enia SVN Git Dystrybucja Umieszczanie rozszerzenia w pakiecie Publikowanie rozszerzenia Podsumowanie Dodatek A. Witaj, Magento Konfiguracja Kontroler Test dzia(cid:239)ania (cid:258)cie(cid:285)ki Skorowidz 201 201 202 202 203 204 204 204 206 207 212 214 215 215 216 217 219 6 Kup książkęPoleć książkę O autorze Allan McGregor posiada certyfikat Magento Certified Developer Plus i od czterech lat pracuje z Magento. Uzyska(cid:239) tak(cid:285)e certyfikat Linux System Administration wydany przez firm(cid:218) IBM. Swoj(cid:200) przygod(cid:218) z Magento rozpocz(cid:200)(cid:239) jako samodzielny programista, który szuka(cid:239) najlepszego narz(cid:218)dzia do tworzenia rozwi(cid:200)za(cid:241) e-commerce’owych. Obecnie pracuje jako g(cid:239)ówny progra- mista Magento w firmie Demac Media (www.demacmedia.com). Allan jest te(cid:285) pasjonatem pro- gramowania, stale poszukuj(cid:200)cym nowych, lepszych technologii i narz(cid:218)dzi programistycznych. W Demac Media Allan wspó(cid:239)tworzy(cid:239) rozwi(cid:200)zania dla ró(cid:285)norodnych klientów. Dzi(cid:218)ki temu zdoby(cid:239) do(cid:258)wiadczenie oraz wiedz(cid:218), która pozwala mu stawia(cid:202) czo(cid:239)a nawet najtrudniejszym wyzwaniom zwi(cid:200)zanym z wykorzystaniem Magento. W ramach jednego z projektów wewn(cid:218)trznych prowadzonych w Demac Media Allan tworzy(cid:239) narz(cid:218)dzie Triplecheck.io (http://triplecheck.io) — pioniersk(cid:200) us(cid:239)ug(cid:218), która monitoruje i audy- tuje poprawno(cid:258)(cid:202) kodu (cid:283)ród(cid:239)owego sklepu stworzonego w Magento. Wpisy McGregora mo(cid:285)na (cid:258)ledzi(cid:202) na Twitterze pod adresem: http://www.twitter.com/allanmcgregor. Praca nad t(cid:200) ksi(cid:200)(cid:285)k(cid:200) by(cid:239)a dla mnie ogromnym wyzwaniem, które jednak w pe(cid:239)ni si(cid:218) op(cid:239)aci(cid:239)o. W trakcie pisania dowiedzia(cid:239)em si(cid:218) wielu nowych rzeczy na temat Magento, a tak(cid:285)e kilku o samym sobie — za- równo o cz(cid:239)owieku, jak i o programi(cid:258)cie. W pierwszej kolejno(cid:258)ci chc(cid:218) podzi(cid:218)kowa(cid:202) mojej wspania(cid:239)ej (cid:285)onie za jej bezwarunkowe wsparcie i zro- zumienie, które okazuje mi, gdy pracuj(cid:218) nad coraz to nowymi projektami. Dzi(cid:218)kuj(cid:218) te(cid:285) Matthew Bertulliemu i Dimitriemu Colomvakosowi, wspó(cid:239)za(cid:239)o(cid:285)ycielom Demac Media, za wsparcie, które mi okazywali. Michael Krietzer i Corey Slavnik, moi przyjaciele i wspó(cid:239)pracownicy, z wielk(cid:200) ochot(cid:200) po(cid:258)wi(cid:218)cali swój wolny czas, aby zredagowa(cid:202) t(cid:218) ksi(cid:200)(cid:285)k(cid:218). Specjalne podzi(cid:218)kowania kieruj(cid:218) do ca(cid:239)ej rodziny Demac Media. To, co uda(cid:239)o mi si(cid:218) zdoby(cid:202), osi(cid:200)gn(cid:200)(cid:239)em dzi(cid:218)ki Wam. Kup książkęPoleć książkę Magento. Przewodnik dla programistów PHP 8 Kup książkęPoleć książkę 3 ORM i kolekcje danych Kolekcje i modele to chleb powszedni dla wszystkich programistów, którzy pracuj(cid:200) z Magento. W tym rozdziale opisany zostanie system ORM obecny w Magento. Poka(cid:285)(cid:218) tak(cid:285)e, jak nale(cid:285)y prawid(cid:239)owo korzysta(cid:202) z kolekcji danych oraz z systemu EAV. Magento, podobnie jak wi(cid:218)kszo(cid:258)(cid:202) wspó(cid:239)czesnych systemów, implementuje system mapowania obiektowo-relacyjnego (ang. object-relational mapping — ORM). Mapowanie obiektowo-relacyjne (ORM, O/RM lub mapowanie O/R) w technologiach informatycznych to technika programowania, w której dane wyst(cid:218)puj(cid:200)ce w ró(cid:285)nych, niezgodnych formatach przekszta(cid:239)cane s(cid:200) na j(cid:218)zyki programowania zorientowanego obiektowo. W ten sposób tworzy si(cid:218) „baz(cid:218) danych wirtualnych obiektów”, której mo(cid:285)na u(cid:285)ywa(cid:202) w konstrukcjach j(cid:218)zyka programowania. W tym rozdziale przedstawione zostan(cid:200) nast(cid:218)puj(cid:200)ce zagadnienia: (cid:81) modele Magento; (cid:81) struktura modelu danych Magento; (cid:81) EAV i modele EAV; (cid:81) wykorzystanie bezpo(cid:258)rednich zapyta(cid:241) j(cid:218)zyka SQL. W rozdziale wykorzystane zostan(cid:200) równie(cid:285) liczne fragmenty przyk(cid:239)adowego kodu (cid:283)ród(cid:239)owego, na podstawie których (cid:239)atwiej b(cid:218)dzie zrozumie(cid:202) sposób dzia(cid:239)ania Magento. Uruchomienie przyk(cid:239)adowych kodów prezentowanych w tym rozdziale wymaga domy(cid:258)lnej instalacji Magento na maszynie VagrantBox lub instalacji Magento z danymi przyk(cid:239)adowymi. Kup książkęPoleć książkę Magento. Przewodnik dla programistów PHP Dla celów tego rozdzia(cid:239)u stworzy(cid:239)em interaktywn(cid:200) konsol(cid:218) Magento (ang. Interactive Magento Console — IMC), która jest skryptem pow(cid:239)oki zaimplementowanym specjalnie na potrzeby tej ksi(cid:200)(cid:285)ki. Inspiracj(cid:200) dla niej jest przeznaczona dla Ruby interaktywna konsola Ruby (ang. Interactive Ruby Console — IRC). W celu uruchomienia IMC nale(cid:285)y wykona(cid:202) nast(cid:218)puj(cid:200)ce czynno(cid:258)ci. 1. Zainstalowa(cid:202) IMC. W tym celu trzeba pobra(cid:202) pliki (cid:283)ród(cid:239)owe ze strony: https://github.com/amacgregor/mdg_imc i rozpakowa(cid:202) je w testowej instalacji Magento. IMC jest prostym skryptem pow(cid:239)oki Magento, który pozwoli nam testowa(cid:202) kod w czasie rzeczywistym. 2. Po rozpakowaniu skryptu nale(cid:285)y zalogowa(cid:202) si(cid:218) w pow(cid:239)oce maszyny wirtualnej. 3. W kolejnym kroku trzeba przej(cid:258)(cid:202) do g(cid:239)ównego folderu Magento. Je(cid:285)eli korzysta si(cid:218) z domy(cid:258)lnej maszyny Vagrant, instalacja jest ju(cid:285) w niej obecna. Folderem g(cid:239)ównym jest /srv/www/ce1720/public_html/, a aby do niego przej(cid:258)(cid:202), nale(cid:285)y wpisa(cid:202) w wierszu polece(cid:241) nast(cid:218)puj(cid:200)ce polecenie: $ cd /srv/www/ce1720/public_html 4. Na koniec mo(cid:285)na uruchomi(cid:202) IMC nast(cid:218)puj(cid:200)cym poleceniem: $ php shell/imc.php 5. Je(cid:285)eli instalacja przebieg(cid:239)a poprawnie, nowy wiersz w wierszu polece(cid:241) powinien zaczyna(cid:202) si(cid:218) symbolem magento . Struktura modelu Magento Jak powiedziano w poprzednim rozdziale, modele danych Magento s(cid:239)u(cid:285)(cid:200) do manipulowania danymi i ich odczytywania. Warstwa modeli podzielona jest na dwa podstawowe typy: modele proste i modele EAV. (cid:81) Modele proste. Tego typu implementacje modeli s(cid:200) zwyk(cid:239)ymi odwzorowaniami jednego obiektu na jedn(cid:200) tabel(cid:218), co oznacza, (cid:285)e atrybuty obiektu odpowiadaj(cid:200) ka(cid:285)demu polu oraz strukturze tabeli. (cid:81) Modele encja – atrybut – warto(cid:258)(cid:202) (EAV). W modelach tego rodzaju encje opisuje si(cid:218) atrybutami o zmiennej liczbie. Nale(cid:285)y podkre(cid:258)li(cid:202), (cid:285)e nie wszystkie modele Magento u(cid:285)ywaj(cid:200) systemu ORM lub rozszerzaj(cid:200) jego mo(cid:285)li- wo(cid:258)ci. Obserwatory s(cid:200) doskona(cid:239)ym przyk(cid:239)adem prostych klas modeli, które to modele nie s(cid:200) odwzoro- wane na konkretn(cid:200) tabel(cid:218) lub encj(cid:218) bazy danych. Dodatkowo ka(cid:285)dy typ modelu jest kszta(cid:239)towany przez nast(cid:218)puj(cid:200)ce warstwy. (cid:81) Klasa modelu. W niej implementuje si(cid:218) logik(cid:218) biznesow(cid:200). Modele s(cid:239)u(cid:285)(cid:200) do manipulowania danymi, lecz nie maj(cid:200) bezpo(cid:258)redniego dost(cid:218)pu do tych danych. 62 Kup książkęPoleć książkę Rozdzia(cid:225) 3. • ORM i kolekcje danych (cid:81) Klasa modelu zasobów. Modele zasobów komunikuj(cid:200) si(cid:218) z baz(cid:200) danych w imieniu modeli. Modele zasobów wykonuj(cid:200) wszelkie operacje typu CRUD. (cid:81) Klasa modelu kolekcji. Ka(cid:285)dy model danych zawiera klas(cid:218) kolekcji. Kolekcje s(cid:200) obiektami, które przechowuj(cid:200) jedn(cid:200) lub wi(cid:218)cej instancji modelu Magento. CRUD oznacza cztery podstawowe operacje na danych w bazie danych: Create (tworzenie), Read (odczyt), Update (zmiana), Delete (usuwanie). Modele Magento nie zawieraj(cid:200) (cid:285)adnej logiki komunikacji z baz(cid:200) danych — wr(cid:218)cz s(cid:200) one nie- zale(cid:285)ne od bazy danych. Odpowiedni kod implementuje si(cid:218) w warstwie modelu zasobów. Dzi(cid:218)ki opisanej konstrukcji Magento mo(cid:285)e obs(cid:239)ugiwa(cid:202) ró(cid:285)ne rodzaje baz danych i platform. Wprawdzie na chwil(cid:218) obecn(cid:200) oficjalnie obs(cid:239)ugiwany jest jedynie serwer MySQL, bez trudu mo(cid:285)na jednak napisa(cid:202) now(cid:200) klas(cid:218) zasobu przeznaczon(cid:200) dla nowej bazy danych, która to klasa nie b(cid:218)dzie w (cid:285)aden sposób wp(cid:239)ywa(cid:202) na logik(cid:218) modeli. Schemat struktury modeli Magento przedstawiono na rysunku 3.1. Rysunek 3.1. Schemat struktury modeli Magento Wykonajmy zatem pewien eksperyment, który b(cid:218)dzie polega(cid:239) na stworzeniu instancji obiektu pro- duktu i ustawieniu jego wybranych atrybutów. Nale(cid:285)y w tym celu wykona(cid:202) nast(cid:218)puj(cid:200)ce czynno(cid:258)ci. 1. Uruchomi(cid:202) interaktywn(cid:200) konsol(cid:218) Magento w g(cid:239)ównym folderze rozwojowej instalacji narz(cid:218)dzia: php shell/imc.php 2. Pierwszy krok polega na stworzeniu nowej instancji obiektu produktu, do czego s(cid:239)u(cid:285)y nast(cid:218)puj(cid:200)ce polecenie: magento $product = Mage::getModel( catalog/product ); 63 Kup książkęPoleć książkę Magento. Przewodnik dla programistów PHP 3. Poni(cid:285)szym poleceniem potwierdzimy, (cid:285)e jest to pusta instancja klasy produktu: magento echo get_class($product); 4. Je(cid:285)eli wszystko pójdzie dobrze, w konsoli powinien pojawi(cid:202) si(cid:218) nast(cid:218)puj(cid:200)cy komunikat: magento Magento_Catalog_Model_Product 5. Aby dowiedzie(cid:202) si(cid:218) wi(cid:218)cej na temat metod klasy, mo(cid:285)na wykona(cid:202) polecenie o poni(cid:285)szej tre(cid:258)ci: magento print_r(get_class_methods($product)); W efekcie zwrócona zostanie tablica, w której widnie(cid:202) b(cid:218)d(cid:200) wszystkie metody udost(cid:218)pniane przez klas(cid:218). Spróbujmy zatem wykona(cid:202) poni(cid:285)szy fragment kodu (cid:283)ród(cid:239)owego, aby zmodyfikowa(cid:202) cen(cid:218) i nazw(cid:218) produktu: $product = Mage::getModel( catalog/product )- load(2); $name = $product- getName() . -TEST ; $price = $product- getPrice(); $product- setPrice($price + 15); $product- setName($name); $product- save(); W pierwszym wierszu przyk(cid:239)adowego kodu (cid:283)ród(cid:239)owego tworzona jest instancja wskazanego obiektu, po czym odczytywana jest warto(cid:258)(cid:202) atrybutu obiektu, w którym zapisana jest nazwa produktu. Nast(cid:218)pnie ustawiana jest cena i nazwa, po czym obiekt zostaje zapisany. Analiza implementacji klasy produktu Magento Mage_Catalog_Model_Product szybko wyka(cid:285)e, (cid:285)e o ile funkcje getName() i getPrice() s(cid:200) w niej zaimplementowane, o tyle ju(cid:285) definicji funkcji setPrice() i setName() w niej nie ma. Powstaje zatem kluczowe pytanie: w jaki(cid:285) to magiczny sposób Magento definiuje okre(cid:258)lone meto- dy ustawiania i odczytywania danych w obiekcie produktu? Wprawdzie getPrice() i getName() s(cid:200) jawnie zaimplementowane, jednak nigdzie nie ma definicji metod ustawiaj(cid:200)cych i odczy- tuj(cid:200)cych inne atrybuty produktu, takie jak kolor albo nazwa producenta. Metody magiczne Có(cid:285), rzeczywi(cid:258)cie zdarza si(cid:218), (cid:285)e dzia(cid:239)anie systemu ORM Magento ociera si(cid:218) o magi(cid:218). Mówi(cid:200)c bardziej precyzyjnie: w systemie ORM wykorzystuje si(cid:218) jeden z najciekawszych mechanizmów dost(cid:218)pnych w PHP, który umo(cid:285)liwia definiowanie metod ustawiaj(cid:200)cych i odczytuj(cid:200)cych dane — mechanizm ten opiera si(cid:218) na magicznej metodzie __call(). Dzi(cid:218)ki niej metod Magento mo(cid:285)na u(cid:285)ywa(cid:202) do ustawiania, usuwania, sprawdzania i odczytywania danych. Gdy podj(cid:218)ta zostanie próba wywo(cid:239)ania metody, która nie jest zaimplementowana w klasie, PHP zacznie szuka(cid:202) w klasach rodziców deklaracji tej metody. Je(cid:285)eli odpowiednia funkcja nie zostanie znaleziona w (cid:285)adnej z klas rodziców, podj(cid:218)ta zostanie ostatnia próba, która polega na wywo(cid:239)aniu metody __call(). Je(cid:285)eli funkcja zostanie znaleziona, Magento (a w(cid:239)a(cid:258)ciwie PHP) wywo(cid:239)a ma- giczn(cid:200) metod(cid:218) i przeka(cid:285)e do niej nazw(cid:218) pierwotnie wywo(cid:239)ywanej metody oraz jej argumenty. 64 Kup książkęPoleć książkę Rozdzia(cid:225) 3. • ORM i kolekcje danych Model Product nie ma zdefiniowanej metody __call(), lecz dziedziczy j(cid:200) z klasy Varien_Object, która jest klas(cid:200) podstawow(cid:200) dla wszystkich modeli Magento. Drzewo dziedziczenia dla klasy Mage_Catalog_Model_Product znajduje si(cid:218) na schemacie przedstawionym na rysunku 3.2. Rysunek 3.2. Drzewo dziedziczenia dla klasy Mage_Catalog_Model_Product Ka(cid:285)dy model Magento dziedziczy po klasie Varien_Object. Przyjrzyjmy si(cid:218) bli(cid:285)ej klasie Varien_Object. W tym celu nale(cid:285)y wykona(cid:202) nast(cid:218)puj(cid:200)ce czynno(cid:258)ci. 1. Otworzy(cid:202) plik folder_g(cid:239)ówny_magento/lib/Varien/Object.php. 2. Klasa Varien_Object ma zdefiniowan(cid:200) metod(cid:218) __call(), a tak(cid:285)e implementuje dwie przestarza(cid:239)e metody: __set() i __get(). Te dwie ostatnie metody s(cid:200) zast(cid:200)pione metod(cid:200) __call() i dlatego ju(cid:285) si(cid:218) ich nie u(cid:285)ywa. public function __call($method, $args) { switch (substr($method, 0, 3)) { case get : //Varien_Profiler::start( GETTER: .get_class($this). :: .$method); $key = $this- _underscore(substr($method,3)); $data = $this- getData($key, isset($args[0]) ? $args[0] : null); //Varien_Profiler::stop( GETTER: .get_class($this). :: .$method); return $data; case set : //Varien_Profiler::start( SETTER: .get_class($this). :: .$method); $key = $this- _underscore(substr($method,3)); $result = $this- setData($key, isset($args[0]) ? $args[0] : null); //Varien_Profiler::stop( SETTER: .get_class($this). :: .$method); return $result; case uns : //Varien_Profiler::start( UNS: .get_class($this). :: .$method); $key = $this- _underscore(substr($method,3)); $result = $this- unsetData($key); //Varien_Profiler::stop( UNS: .get_class($this). :: .$method); return $result; case has : 65 Kup książkęPoleć książkę Magento. Przewodnik dla programistów PHP //Varien_Profiler::start( HAS: .get_class($this). :: .$method); $key = $this- _underscore(substr($method,3)); //Varien_Profiler::stop( HAS: .get_class($this). :: .$method); return isset($this- _data[$key]); } throw new Varien_Exception( Invalid method . get_class($this). :: .$method. ( .print_r($args,1). ) ); } W metodzie __call() znajduje si(cid:218) instrukcja switch, która obs(cid:239)uguje nie tylko funkcje usta- wiania (set) i odczytywania (get) danych, ale równie(cid:285) funkcje unset i has. Po uruchomieniu debuggera i prze(cid:258)ledzeniu wywo(cid:239)a(cid:241) metody __call() w przyk(cid:239)adowym fragmencie kodu oka(cid:285)e si(cid:218), (cid:285)e przyjmuje ona dwa argumenty: nazw(cid:218) metody (na przyk(cid:239)ad setName()) oraz argumenty pochodz(cid:200)ce z wywo(cid:239)ania oryginalnego. Co ciekawe, Magento próbuje zidentyfikowa(cid:202) typ metody na podstawie pierwszych trzech liter nazwy metody wywo(cid:239)ywanej. Operacja ta zachodzi w momencie, gdy instrukcja switch wykonuje funkcj(cid:218) substr(): substr($method, 0, 3) Pierwsz(cid:200) czynno(cid:258)ci(cid:200) wykonywan(cid:200) w ka(cid:285)dym przypadku analizowanym przez instrukcj(cid:218) switch jest wykonanie funkcji _underscore(), która przyjmuje parametr w postaci reszty znaków nazwy metody oprócz trzech pierwszych liter. W naszym przyk(cid:239)adzie argumentem dla _underscore() b(cid:218)dzie Name. Funkcja _underscore() zwraca klucz danych. Klucz ten jest wykorzystywany w ka(cid:285)dym przy- padku analizowanym przez instrukcj(cid:218), aby wykona(cid:202) odpowiednie operacje na danych. Istniej(cid:200) cztery podstawowe operacje na danych i ka(cid:285)da z nich jest wywo(cid:239)ywana w odpowiadaj(cid:200)cym jej przypadku instrukcji switch: (cid:81) setData($parameters), (cid:81) getData($parameters), (cid:81) unsetData($parameters), (cid:81) isset($parameters). Ka(cid:285)da z wymienionych funkcji wykonuje odpowiednie dla niej operacje na tablicy danych klasy Varien_Object. W wi(cid:218)kszo(cid:258)ci przypadków wywo(cid:239)ywana jest magiczna metoda set/get, która wykonuje odpowiednie czynno(cid:258)ci na atrybutach obiektu. Istnieje tylko kilka wyj(cid:200)tków od tej regu(cid:239)y — na przyk(cid:239)ad gdy wymagana jest dodatkowa logika biznesowa, metody usta- wiania i odczytywania danych s(cid:200) definiowane jawnie. W naszym przyk(cid:239)adzie takimi metodami s(cid:200) getName() i getPrice(): public function getPrice() { if ($this- _calculatePrice || !$this- getData( price )) { return $this- getPriceModel()- getPrice($this); 66 Kup książkęPoleć książkę Rozdzia(cid:225) 3. • ORM i kolekcje danych } else { return $this- getData( price ); } } Nie b(cid:218)dziemy si(cid:218) na razie wg(cid:239)(cid:218)bia(cid:202) w szczegó(cid:239)y dzia(cid:239)ania funkcji getPrice(). Na jej podstawie wida(cid:202) jednak wyra(cid:283)nie, (cid:285)e dla niektórych cz(cid:218)(cid:258)ci modelu konieczne mo(cid:285)e by(cid:202) zaimplemento- wanie dodatkowej logiki: public function getName() { return $this- _getData( name ); } Natomiast metoda getName() nie zosta(cid:239)a jawnie zaimplementowana po to, by realizowa(cid:202) dodat- kow(cid:200) logik(cid:218) biznesow(cid:200), ale po to, by zoptymalizowa(cid:202) dzia(cid:239)anie kluczowego elementu Magento. Funkcja getName() klasy Mage_Catalog_Model_Product mo(cid:285)e by(cid:202) teoretycznie wykonywana setki razy przy ka(cid:285)dym (cid:239)adowaniu strony i jest jedn(cid:200) z najcz(cid:218)(cid:258)ciej u(cid:285)ywanych w ca(cid:239)ym Magento. W ko(cid:241)cu czym by(cid:239)aby platforma e-commerce’owa, gdyby nie skupia(cid:239)a si(cid:218) na produktach? Zarówno w interfejsie u(cid:285)ytkownika, jak i w modu(cid:239)ach wewn(cid:218)trznych funkcja getName() zostanie pr(cid:218)dzej czy pó(cid:283)niej wywo(cid:239)ana. Na przyk(cid:239)ad je(cid:285)eli (cid:239)adujemy stron(cid:218) kategorii z 24 produktami, oznacza to konieczno(cid:258)(cid:202) wykonania 24 niezale(cid:285)nych wywo(cid:239)a(cid:241) funkcji getName() i w ka(cid:285)dym z tych wywo(cid:239)a(cid:241) poszukiwana b(cid:218)dzie metoda getName() na ka(cid:285)dej klasie rodzica; nast(cid:218)pnie podj(cid:218)ta zostanie próba wykonania magicznej metody __call(). Ostatecznie ca(cid:239)y proces mo(cid:285)e zaj(cid:200)(cid:202) d(cid:239)ugie milisekundy. Modele zasobów zawieraj(cid:200) kompletn(cid:200) logik(cid:218) komunikacji z baz(cid:200) danych i tworz(cid:200) instancje wymaganych adapterów odczytywania danych i zapisywania ich do odpowiadaj(cid:200)cych im (cid:283)róde(cid:239) danych. Wró(cid:202)my do przyk(cid:239)adu z produktami i spójrzmy na model zasobów produktów z ry- sunku 3.3, zlokalizowany w klasie Mage_Catalog_Model_Resource_Product. Rysunek 3.3. Model zasobów produktów Modele zasobów wyst(cid:218)puj(cid:200) w dwóch odmianach: Entity oraz MySQL4. Drugi z nich jest standardow(cid:200) implementacj(cid:200) relacji jedna tabela – jeden model, natomiast pierwszy jest zde- cydowanie bardziej skomplikowany. 67 Kup książkęPoleć książkę Magento. Przewodnik dla programistów PHP Model EAV EAV jest skrótowcem s(cid:239)ów entity (encja), attribute (atrybut) i value (warto(cid:258)(cid:202)) i oznacza kon- cepcj(cid:218), z której zrozumieniem pocz(cid:200)tkuj(cid:200)cy programi(cid:258)ci Magento maj(cid:200) zwykle najwi(cid:218)ksze trudno(cid:258)ci. Koncepcja EAV jest w Magento do(cid:258)(cid:202) powszechnie wykorzystywana, jednak w innych wspó(cid:239)czesnych systemach informatycznych spotyka si(cid:218) j(cid:200) stosunkowo rzadko. Poza tym im- plementacja modelu w Magento sama w sobie jest do(cid:258)(cid:202) z(cid:239)o(cid:285)ona. Schemat modelu EAV przedstawiono na rysunku 3.4. Rysunek 3.4. Schemat modelu EAV Czym jest model EAV? Aby zrozumie(cid:202), czym w ogóle jest model EAV oraz jak(cid:200) funkcj(cid:218) pe(cid:239)ni w Magento, trzeba naj- pierw opisa(cid:202) jego cz(cid:218)(cid:258)ci sk(cid:239)adowe. (cid:81) Encja. Encja reprezentuje pojedyncze dane w obiektach Magento — produktach, klientach, kategoriach i zamówieniach. Ka(cid:285)da encja jest przechowywana w bazie danych i ma unikatowy identyfikator. (cid:81) Atrybut. Atrybut reprezentuje w(cid:239)a(cid:258)ciwo(cid:258)ci obiektów. Poszczególne atrybuty nie s(cid:200) umieszczane w oddzielnych kolumnach tabeli produktów — wszystkie atrybuty s(cid:200) przechowywane w odr(cid:218)bnych zbiorach tabel. (cid:81) Warto(cid:258)(cid:202). Jak wskazuje nazwa, jest to zwyk(cid:239)a warto(cid:258)(cid:202) skojarzona z okre(cid:258)lonym atrybutem. To w(cid:239)a(cid:258)nie ten wzorzec projektowy stoi za niespotykan(cid:200) elastyczno(cid:258)ci(cid:200) i niemal nieograniczonymi mo(cid:285)liwo(cid:258)ciami Magento, poniewa(cid:285) dzi(cid:218)ki niemu mo(cid:285)na dodawa(cid:202) i usuwa(cid:202) nowe w(cid:239)a(cid:258)ciwo(cid:258)ci bez konieczno(cid:258)ci wprowadzania jakichkolwiek zmian w kodzie (cid:283)ród(cid:239)owym czy szablonach. Podczas gdy model w uj(cid:218)ciu Magento mo(cid:285)na postrzega(cid:202) jako mechanizm rozrostu bazy da- nych w pionie (nowe atrybuty dodawane s(cid:200) w postaci nowych wierszy), model tradycyjny po- wi(cid:218)ksza baz(cid:218) danych w poziomie (nowe atrybuty oznaczaj(cid:200) nowe kolumny), poniewa(cid:285) wi(cid:200)(cid:285)e si(cid:218) z konieczno(cid:258)ci(cid:200) ka(cid:285)dorazowej zmiany w schemacie bazy danych, gdy zachodzi potrzeba dodania nowego atrybutu. 68 Kup książkęPoleć książkę Rozdzia(cid:225) 3. • ORM i kolekcje danych Oprócz tego, (cid:285)e model EAV umo(cid:285)liwia dokonywanie coraz to nowych zmian w bazie danych, to równie(cid:285) dzia(cid:239)a bardziej wydajnie, poniewa(cid:285) przetwarzane s(cid:200) tylko atrybuty niepuste. Nie trzeba wi(cid:218)c rezerwowa(cid:202) dodatkowego miejsca w bazie danych na atrybuty null. Wi(cid:218)cej szczegó(cid:239)owych informacji na temat struktury bazy danych Magento mo(cid:285)na znale(cid:283)(cid:202) na stronie: www.magereverse.com. Dodawanie nowego atrybutu produktu jest bardzo proste i sprowadza si(cid:218) do okre(cid:258)lenia w Magento jego typu — mo(cid:285)e to by(cid:202) kolor, rozmiar, marka i tym podobne. Równie prosta jest czynno(cid:258)(cid:202) odwrotna, gdy trzeba pozby(cid:202) si(cid:218) nieu(cid:285)ywanych atrybutów w modelach produktów albo klientów. Wi(cid:218)cej informacji na temat zarz(cid:200)dzania atrybutami mo(cid:285)na znale(cid:283)(cid:202) na stronie: http://www.magentocommerce. com/knowledge-base/entry/how-do-attributes-work-in-magento. Magento w wersji Community Edition obecnie obs(cid:239)uguje osiem ró(cid:285)nych typów obiektów EAV. S(cid:200) to: (cid:81) klient, (cid:81) adres klienta, (cid:81) produkty, (cid:81) kategorie produktów, (cid:81) zamówienia, (cid:81) faktury, (cid:81) noty kredytowe, (cid:81) wysy(cid:239)ki. W Magento Enterprise Edition obs(cid:239)ugiwany jest jeszcze jeden typ — obiekt RMA symbolizuj(cid:200)cy zlecenie odbioru stosowane w przypadku zwrotu towarów. Jest on cz(cid:218)(cid:258)ci(cid:200) systemu Return Merchandise Authori- zation (RMA). Elastyczno(cid:258)(cid:202) i szerokie mo(cid:285)liwo(cid:258)ci maj(cid:200) niestety swoj(cid:200) cen(cid:218) — implementacja modelu EAV sprawia, (cid:285)e dane na temat encji ulegaj(cid:200) rozproszeniu w wielu tabelach. Na przyk(cid:239)ad dane na temat samego modelu produktu s(cid:200) przechowywane w oko(cid:239)o 40 ró(cid:285)nych tabelach. Diagram widoczny na rysunku 3.5 prezentuje zaledwie kilka tabel, w których przechowywane s(cid:200) dane na temat produktów przetwarzanych w Magento. 69 Kup książkęPoleć książkę Magento. Przewodnik dla programistów PHP Rysunek 3.5. Schemat kilku wybranych tabel, w których przechowywane s(cid:200) dane na temat produktów Kolejn(cid:200) wad(cid:200) stosowania modelu EAV jest to, (cid:285)e odczytywanie du(cid:285)ych kolekcji obiektów EAV znacz(cid:200)co wp(cid:239)ywa na wydajno(cid:258)(cid:202) systemu, a jednocze(cid:258)nie wymaga tworzenia bardzo skompli- kowanych zapyta(cid:241) do bazy danych. Dane s(cid:200) w tym modelu bardziej pofragmentowane (znaj- duj(cid:200) si(cid:218) w wielu tabelach), zatem odczytanie pojedynczego rekordu wymaga wykonania co najmniej kilku z(cid:239)(cid:200)cze(cid:241). Kontynuuj(cid:200)c nasz przyk(cid:239)ad oparty na produktach przechowywanych w Magento, stworzymy teraz r(cid:218)cznie zapytanie, które b(cid:218)dzie zwraca(cid:202) rekord pojedynczego produktu. Prezentowane w dalszej cz(cid:218)(cid:258)ci punktu zapytania mo(cid:285)na wykonywa(cid:202) i zmienia(cid:202) w narz(cid:218)dziu PHPMyAdmin lub MySQL Workbench. PHPMyAdmin mo(cid:285)na pobra(cid:202) ze strony: http://www.phpmyadmin.net/, za(cid:258) MySQL Workbench jest dost(cid:218)pne na witrynie: http://www.mysql.com/products/workbench/. Pierwsz(cid:200) tabel(cid:200), z jakiej b(cid:218)dziemy musieli skorzysta(cid:202), jest catalog_product_entity. Mo(cid:285)na j(cid:200) traktowa(cid:202) jako g(cid:239)ówn(cid:200) tabel(cid:218) produktów w modelu EAV, poniewa(cid:285) znajduj(cid:200) si(cid:218) w niej naj- wa(cid:285)niejsze atrybuty encji produktów. Zawarto(cid:258)(cid:202) tabeli catalog_product_entity przedstawiono na rysunku 3.6. Zawarto(cid:258)(cid:202) tabeli catalog_product_entity zostanie zwrócona po wykonaniu nast(cid:218)puj(cid:200)cego zapytania j(cid:218)zyka SQL: SELECT * FROM catalog_product_entity ; 70 Kup książkęPoleć książkę Rozdzia(cid:225) 3. • ORM i kolekcje danych Rysunek 3.6. Fragment zawarto(cid:258)ci tabeli catalog_product_entity W tabeli znajduj(cid:200) si(cid:218) opisane ni(cid:285)ej pola. (cid:81) entity_id — unikatowy identyfikator produktu, u(cid:285)ywany wewn(cid:218)trznie przez Magento. (cid:81) entity_type_id — Magento u(cid:285)ywa w systemie EAV kilku ró(cid:285)nych typów, mi(cid:218)dzy innymi modeli, produktów, klientów i zamówie(cid:241). Dzi(cid:218)ki temu, (cid:285)e ka(cid:285)dy z tych typów ma unikatowy identyfikator, Magento mo(cid:285)e odczyta(cid:202) ich atrybuty i warto(cid:258)ci z odpowiednich tabel. (cid:81) attribute_set_id — atrybuty produktów mo(cid:285)na lokalnie grupowa(cid:202) w zbiory atrybutów. Zbiory atrybutów zapewniaj(cid:200) jeszcze dalej id(cid:200)c(cid:200) elastyczno(cid:258)(cid:202) struktury produktów, poniewa(cid:285) dzi(cid:218)ki nim produkty mog(cid:200) mie(cid:202) tylko niektóre spo(cid:258)ród wszystkich dost(cid:218)pnych atrybutów. (cid:81) type_id — w Magento wyst(cid:218)puje kilka ró(cid:285)nych typów produktów: proste, konfigurowalne, (cid:239)(cid:200)czone, dost(cid:218)pne do pobrania i grupowane. Ka(cid:285)dy typ produktu ma unikatowe ustawienia i funkcje. (cid:81) sku — jednostka magazynowa (ang. Stock Keeping Unit — SKU) to liczba lub kod, który identyfikuje unikatowy produkt lub artyku(cid:239) dost(cid:218)pny w sklepie do sprzeda(cid:285)y. Warto(cid:258)(cid:202) SKU jest definiowana przez u(cid:285)ytkownika. (cid:81) has_options — wskazuje, czy produkt ma dodatkowe opcje. (cid:81) required_options — wskazuje, czy wymagane s(cid:200) jakie(cid:258) dodatkowe opcje. (cid:81) created_at — data utworzenia wiersza. (cid:81) updated_at — data ostatniej modyfikacji wiersza. 71 Kup książkęPoleć książkę Magento. Przewodnik dla programistów PHP Znamy ju(cid:285) struktur(cid:218) tabeli, która przechowuje encje produktów, a tak(cid:285)e wiemy, (cid:285)e ka(cid:285)dy re- kord tej tabeli reprezentuje pojedynczy produkt w sklepie Magento. Nie mamy natomiast jeszcze wystarczaj(cid:200)cych informacji na temat samego produktu, oprócz kodu jednostki maga- zynowej SKU oraz typu produktu. Gdzie zatem znajduj(cid:200) si(cid:218) pozosta(cid:239)e atrybuty produktów? I sk(cid:200)d Magento wie, który atrybut dotyczy produktu, a który klienta? Brakuj(cid:200)ce informacje mo(cid:285)na uzyska(cid:202) z tabeli eav_attribute — w tym celu nale(cid:285)y wykona(cid:202) nast(cid:218)puj(cid:200)ce zapytanie SQL: SELECT * FROM eav_attribute ; Wynik zapytania b(cid:218)dzie zawiera(cid:239) nie tylko atrybuty produktów, ale równie(cid:285) atrybuty charak- terystyczne dla modelu klienta, modelu zamówienia i im podobnych. Na szcz(cid:218)(cid:258)cie znamy ju(cid:285) klucz, na podstawie którego mo(cid:285)na wyizolowa(cid:202) atrybuty, jakie nas interesuj(cid:200). Nale(cid:285)y w tym celu wykona(cid:202) zapytanie w nast(cid:218)puj(cid:200)cej postaci: SELECT * FROM eav_attribute WHERE entity_type_id = 4; Zapytanie o takiej tre(cid:258)ci nakazuje bazie danych zwrócenie tylko tych atrybutów, dla których warto(cid:258)(cid:202) w polu entity_type_id odpowiada analogicznemu identyfikatorowi entity_type_id produktu, czyli ma warto(cid:258)(cid:202) 4. Zanim przejdziemy dalej, warto zapozna(cid:202) si(cid:218) z najwa(cid:285)niejszymi polami tabeli eav_attribute. (cid:81) attribute_id — unikatowy identyfikator ka(cid:285)dego atrybutu; stanowi jednocze(cid:258)nie klucz g(cid:239)ówny tabeli. (cid:81) entity_type_id — to pole kojarzy ka(cid:285)dy atrybut z odpowiednim typem modelu EAV. (cid:81) attribute_code — nazwa lub klucz atrybutu; na podstawie tej warto(cid:258)ci magiczne metody generuj(cid:200) metody do odczytywania i ustawiania warto(cid:258)ci. (cid:81) backend_model — model wewn(cid:218)trzny, który zarz(cid:200)dza (cid:239)adowaniem danych z bazy danych i zapisywaniem ich do niej. (cid:81) backend_type — wskazuje typ warto(cid:258)ci zapisywanej w magazynie danych (bazie danych). (cid:81) backend_table — warto(cid:258)(cid:202) w tym polu wskazuje, czy atrybut powinien by(cid:202) przechowywany w tabeli specjalnej zamiast w domy(cid:258)lnych tabelach systemu EAV. (cid:81) frontend_model — model interfejsu u(cid:285)ytkownika, odpowiada za generowanie elementu atrybutu na potrzeby przegl(cid:200)darki internetowej. (cid:81) frontend_input — analogicznie do modelu interfejsu u(cid:285)ytkownika warto(cid:258)(cid:202) w tym polu wskazuje typ pola wej(cid:258)ciowego, jakie powinno zosta(cid:202) wy(cid:258)wietlone przez przegl(cid:200)dark(cid:218). (cid:81) frontend_label — w tym polu znajduje si(cid:218) etykieta (nazwa) atrybutu, która zostanie wy(cid:258)wietlona w przegl(cid:200)darce. (cid:81) source_model — na podstawie modeli (cid:283)ród(cid:239)owych atrybuty s(cid:200) wype(cid:239)niane dozwolonymi warto(cid:258)ciami. Magento zawiera kilka predefiniowanych modeli (cid:283)ród(cid:239)owych, mi(cid:218)dzy innymi dla krajów, warto(cid:258)ci typu „tak” lub „nie” i im podobnych. 72 Kup książkęPoleć książkę Rozdzia(cid:225) 3. • ORM i kolekcje danych Odczytywanie danych Na tym etapie wiemy ju(cid:285), jak pozyskuje si(cid:218) encje produktów oraz ich atrybuty, które dotycz(cid:200) ca(cid:239)ej encji. Czas wi(cid:218)c odczyta(cid:202) rzeczywiste dane. Aby nie komplikowa(cid:202) zbytnio przyk(cid:239)adu (i zapytania), skupimy si(cid:218) na odczytaniu atrybutu, który zawiera nazw(cid:218) produktu. Sk(cid:200)d wiadomo, w której tabeli przechowywane s(cid:200) warto(cid:258)ci atrybutów? Có(cid:285), na szcz(cid:218)(cid:258)cie w Magento konsekwentnie u(cid:285)ywa si(cid:218) jasno okre(cid:258)lonej konwencji nazewniczej, zgodnie z któr(cid:200) nadaje si(cid:218) odpowiednie nazwy tabelom. Rzut oka na struktur(cid:218) bazy danych wyka(cid:285)e, (cid:285)e w bazie wyst(cid:218)puje kilka tabel, których nazwa zaczyna si(cid:218) od przedrostka catalog_product_entity: (cid:81) catalog_product_entity, (cid:81) catalog_product_entity_datetime, (cid:81) catalog_product_entity_decimal, (cid:81) catalog_product_entity_int, (cid:81) catalog_product_entity_text, (cid:81) catalog_product_entity_varchar, (cid:81) catalog_product_entity_gallery, (cid:81) catalog_product_entity_media_gallery, (cid:81) catalog_product_entity_tier_price. No dobrze, ale sk(cid:200)d mamy wiedzie(cid:202), z której tabeli nale(cid:285)y uzyska(cid:202) warto(cid:258)(cid:202) atrybutu wskazu- j(cid:200)cego nazw(cid:218) produktu? Uwa(cid:285)ny czytelnik na pewno zna ju(cid:285) odpowied(cid:283) — wystarczy sobie przypomnie(cid:202), (cid:285)e w tabeli eav_attribute znajduje si(cid:218) kolumna o nazwie backend_type. W systemie EAV Magento ka(cid:285)dy atrybut jest przechowywany w oddzielnej tabeli, zgodnie z typem warto(cid:258)ci backend_type tego atrybutu. Aby upewni(cid:202) si(cid:218) co do typu warto(cid:258)ci nazwy produktu, wystarczy wykona(cid:202) zapytanie SQL o nast(cid:218)puj(cid:200)cej postaci: SELECT * FROM eav_attribute WHERE entity_type_id =4 AND attribute_code = name ; W wyniku wykonania zapytania oka(cid:285)e si(cid:218), (cid:285)e typem warto(cid:258)ci jest varchar oraz (cid:285)e warto(cid:258)ci dla tego atrybutu s(cid:200) przechowywane w tabeli catalog_product_entity_varchar. Spójrzmy na za- warto(cid:258)(cid:202) tabeli widoczn(cid:200) na rysunku 3.7. Tabela catalog_product_entity_varchar zawiera sze(cid:258)(cid:202) nast(cid:218)puj(cid:200)cych kolumn. (cid:81) value_id — unikatowy identyfikator warto(cid:258)ci, który jest jednocze(cid:258)nie kluczem g(cid:239)ównym tabeli. (cid:81) entity_type_id — identyfikator typu encji dla tej warto(cid:258)ci. (cid:81) attribute_id — klucz obcy, którego warto(cid:258)(cid:202) odnosi si(cid:218) do zawarto(cid:258)ci tabeli eav_entity. 73 Kup książkęPoleć książkę Magento. Przewodnik dla programistów PHP Rysunek 3.7. Zawarto(cid:258)(cid:202) tabeli catalog_product_entity_varchar (cid:81) store_id — klucz obcy, który kojarzy warto(cid:258)(cid:202) atrybutu z widokiem sklepu. (cid:81) entity_id — klucz obcy do odpowiedniej tabeli encji. W naszym przyk(cid:239)adzie tak(cid:200) tabel(cid:200) jest catalog_product_entity. (cid:81) value — rzeczywista warto(cid:258)(cid:202) atrybutu, któr(cid:200) chcemy uzyska(cid:202). Atrybut mo(cid:285)na skonfigurowa(cid:202) w taki sposób, aby jego warto(cid:258)(cid:202) by(cid:239)a warto(cid:258)ci(cid:200) globaln(cid:200), czyli dost(cid:218)pn(cid:200) we wszystkich widokach sklepów, lub te(cid:285) by w ka(cid:285)dym widoku sklepu atrybut mia(cid:239) inn(cid:200) warto(cid:258)(cid:202). Znamy ju(cid:285) wszystkie tabele, w których znajduj(cid:200) si(cid:218) interesuj(cid:200)ce nas informacje na temat pro- duktów. Mo(cid:285)emy wi(cid:218)c napisa(cid:202) docelowe zapytanie: SELECT p.entity_id AS product_id, var.value AS product_name, p.sku AS product_sku FROM catalog_product_entity p, eav_attribute eav, catalog_product_entity_varchar var WHERE p.entity_type_id = eav.entity_type_id AND var.entity_id = p.entity_id AND eav.attribute_code = name AND eav.attribute_id = var.attribute_id Wynik wykonania zapytania znajduje si(cid:218) na rysunku 3.8. 74 Kup książkęPoleć książkę Rozdzia(cid:225) 3. • ORM i kolekcje danych Rysunek 3.8. Wynik wykonania zapytania o dane na temat produktów W wyniku wykonania zapytania zwrócone zosta(cid:239)y trzy kolumny: product_id, product_name oraz product_sku. Cofnijmy si(cid:218) zatem o krok, aby zobaczy(cid:202), jak uzyska(cid:202) jedynie nazwy produktów na podstawie SKU. Otó(cid:285) odpowiednie zapytanie j(cid:218)zyka SQL musia(cid:239)oby si(cid:218) sk(cid:239)ada(cid:202) z pi(cid:218)ciu wierszy i zwraca(cid:239)oby wy(cid:239)(cid:200)cznie jedn(cid:200) z dwóch danych na temat produktu: warto(cid:258)(cid:202) pola nu- merycznego (na przyk(cid:239)ad cen(cid:218)) z jednej tabeli warto(cid:258)ci EAV albo warto(cid:258)(cid:202) tekstow(cid:200) (na przyk(cid:239)ad nazw(cid:218) produktu) z innej tabeli warto(cid:258)ci EAV. Gdyby nie ORM zaimplementowany w Magento, utrzymywanie danych w systemie by(cid:239)oby w zasadzie niemo(cid:285)liwe. Na szcz(cid:218)(cid:258)cie dzi(cid:218)ki ORM prawdopodobnie nigdy nie trzeba b(cid:218)dzie pisa(cid:202) standardowego kodu SQL, aby odczytywa(cid:202) potrzebne informacje. Spójrzmy zatem, jak ten sam zestaw danych na temat produktów mo(cid:285)na uzyska(cid:202) dzi(cid:218)ki ORM Magento. 1. W pierwszym kroku trzeba stworzy(cid:202) instancj(cid:218) kolekcji produktów: $collection = Mage::getModel( catalog/product )- getCollection(); 2. Nast(cid:218)pnie konieczne b(cid:218)dzie jawne nakazanie Magento, (cid:285)e wybrany ma zosta(cid:202) atrybut, który wskazuje nazw(cid:218) produktu: $collection- addAttributeToSelect( name ); 75 Kup książkęPoleć książkę Magento. Przewodnik dla programistów PHP 3. Teraz trzeba posortowa(cid:202) kolekcj(cid:218) wzgl(cid:218)dem nazw produktów: $collection- setOrder( name , asc ); 4. Ko(cid:241)cowy krok polega na za(cid:239)adowaniu przez Magento ca(cid:239)ej kolekcji: $collection- load(); 5. Wynikiem wykonania opisanych czynno(cid:258)ci jest kolekcja wszystkich produktów przechowywanych w sklepie, uporz(cid:200)dkowana wzgl(cid:218)dem nazwy. Pe(cid:239)n(cid:200) tre(cid:258)(cid:202) zapytania j(cid:218)zyka SQL mo(cid:285)na uzyska(cid:202) po wykonaniu nast(cid:218)puj(cid:200)cej instrukcji: echo $collection- getSelect()- __toString(); Ostatecznie w zaledwie trzech wierszach kodu (cid:283)ród(cid:239)owego nakazali(cid:258)my Magento, aby system odczyta(cid:239) wszystkie produkty przechowywane w sklepie, wyizolowa(cid:239) z nich nazwy produktów i na koniec uporz(cid:200)dkowa(cid:239) je alfabetycznie. Ostatni wiersz przyk(cid:239)adowego kodu, $collection- getSelect()- __toString(), pozwala progra- mi(cid:258)cie podejrze(cid:202) rzeczywiste zapytanie j(cid:218)zyka SQL przetwarzane przez Magento na podstawie wykona- nego kodu (cid:283)ród(cid:239)owego. Rzeczywiste zapytanie j(cid:218)zyka SQL, które wykona Magento na podstawie przyk(cid:239)adowego kodu, ma nast(cid:218)puj(cid:200)c(cid:200) tre(cid:258)(cid:202): SELECT e .*. IF( at_name.value_id 0, at_name.value, at_name_default.value ) AS name FROM catalog_product_entity AS e LEFT JOIN catalog_product_entity_varchar AS at_name_default ON ( at_name_default . (cid:180) entity_id = e . entity_id ) AND ( at_name_default . attribute_id = 65 ) AND at_name_default . store_id =0 LEFT JOIN catalog_product_entity_varchar AS at_name ON ( at_name . entity_id = (cid:180) e . entity_id ) AND ( at_name . attribute_id = 65 ) AND ( at_name . store_id =1) ORDER BY name ASC Wida(cid:202) wi(cid:218)c wyra(cid:283)nie, (cid:285)e ORM i modele EAV s(cid:200) doskona(cid:239)ymi narz(cid:218)dziami, które nie tylko daj(cid:200) programistom wiele mo(cid:285)liwo(cid:258)ci i warunkuj(cid:200) elastyczno(cid:258)(cid:202), ale równie(cid:285) pozwalaj(cid:200) tworzy(cid:202) rozwi(cid:200)zania zwi(cid:218)z(cid:239)e i czytelne. Korzystanie z kolekcji Magento Gdy przyjrzymy si(cid:218) jeszcze raz kodowi (cid:283)ród(cid:239)owemu z poprzedniego przyk(cid:239)adu, warto zwróci(cid:202) uwag(cid:218), (cid:285)e oprócz stworzenia instancji modelu produktu wywo(cid:239)ana równie(cid:285) zosta(cid:239)a metoda getCollection(). Metoda getCollection() nale(cid:285)y do klasy Mage_Core_Model_Abstract, co oznacza, (cid:285)e mo(cid:285)e j(cid:200) wywo(cid:239)ywa(cid:202) ka(cid:285)dy model w Magento. 76 Kup książkęPoleć książkę Rozdzia(cid:225) 3. • ORM i kolekcje danych Wszystkie kolekcje s(cid:200) dziedziczone po klasie Varien_Data_Collection. Kolekcja Magento jest w zasadzie modelem, który zawiera inne modele. Dlatego zamiast prze- chowywa(cid:202) list(cid:218) produktów w tablicy, mo(cid:285)na u(cid:285)y(cid:202) do tego celu kolekcji produktów. Struktura danych obecna w kolekcji sprzyja grupowaniu modeli, a ponadto kolekcje udost(cid:218)pniaj(cid:200) spe- cjalne metody, za pomoc(cid:200) których mo(cid:285)na przetwarza(cid:202) encje przechowywane w kolekcji. Oto najbardziej przydatne metody udost(cid:218)pniane przez kolekcje. (cid:81) addAttributeToSelect — dodaje atrybut do encji w kolekcji. W szczególno(cid:258)ci w wywo(cid:239)aniu metody mo(cid:285)na u(cid:285)y(cid:202) symbolu wieloznacznego *, aby doda(cid:202) do encji wszystkie dost(cid:218)pne atrybuty. (cid:81) addFieldToFilter — dodaje pole filtrowania do kolekcji. Wywo(cid:239)uje si(cid:218) j(cid:200) na zwyk(cid:239)ych modelach, które nie s(cid:200) modelami EAV. (cid:81) addAttributeToFilter — s(cid:239)u(cid:285)y do filtrowania kolekcji encji EAV. (cid:81) addAttributeToSort — s(cid:239)u(cid:285)y do dodawania atrybutu do definicji porz(cid:200)dku sortowania. (cid:81) addStoreFilter — pozwala na filtrowanie wzgl(cid:218)dem sklepu; uwzgl(cid:218)dnia dost(cid:218)pno(cid:258)(cid:202) produktu w sklepie. (cid:81) addWebsiteFilter — dodaje do kolekcji filtr strony WWW. (cid:81) addCategoryFilter — wskazuje filtr kategorii dla kolekcji produktów. (cid:81) addUrlRewrite — s(cid:239)u(cid:285)y do dodawania przepisanych adresów URL dla produktu. (cid:81) setOrder — ustawia porz(cid:200)dek sortowania kolekcji. S(cid:200) to tylko niektóre spo(cid:258)ród wszystkich dost(cid:218)pnych metod przetwarzania kolekcji. Ka(cid:285)da kolekcja implementuje unikatowe metody, których charakter zale(cid:285)y od rodzaju encji przechowywanych w kolekcji. Na przyk(cid:239)ad kolekcja klientów Mage_Customer_Model_Resource_Customer_Collection ma zaimplementowan(cid:200) unikatow(cid:200) metod(cid:218) groupByEmail(), która — zgodnie z nazw(cid:200) — grupuje encje w kolekcji wzgl(cid:218)dem adresu poczty elektronicznej. Podobnie jak w poprzednich przyk(cid:239)adach, nadal b(cid:218)dziemy opiera(cid:202) si(cid:218) na modelach produktów. Tym razem skupimy si(cid:218) na kolekcji produktów. Dla przypomnienia na rysunku 3.9 przedsta- wiono ponownie model dziedziczenia dla klasy Mage_Catalog_Model_Product. Rysunek 3.9. Drzewo dziedziczenia dla klasy Mage_Catalog_Model_Product 77 Kup książkęPoleć książkę Magento. Przewodnik dla programistów PHP W celu lepszego zilustrowania sposobu, w jaki mo(cid:285)na u(cid:285)ywa(cid:202) kolekcji, we(cid:283)miemy pod uwag(cid:218) nast(cid:218)puj(cid:200)ce standardowe scenariusze dzia(cid:239)a(cid:241) na produktach. 1. Uzyskanie kolekcji produktów, które nale(cid:285)(cid:200) do okre(cid:258)lonej kategorii. 2. Uzyskanie nowych produktów, które pojawi(cid:239)y si(cid:218) w dniu x lub pó(cid:283)niej. 3. Uzyskanie produktów, które najlepiej si(cid:218) sprzedaj(cid:200). 4. Filtrowanie kolekcji produktów wzgl(cid:218)dem widoczno(cid:258)ci produktów. 5. Filtrowanie produktów, którym nie przypisano obrazka. 6. Dodanie wielu kryteriów porz(cid:200)dkowania. Uzyskanie kolekcji produktów, które nale(cid:285)(cid:200) do okre(cid:258)lonej kategorii Pierwszym zadaniem, z jakim próbuje si(cid:218) upora(cid:202) wi(cid:218)kszo(cid:258)(cid:202) programistów rozpoczynaj(cid:200)cych swoj(cid:200) przygod(cid:218) z Magento, jest za(cid:239)adowanie kolekcji produktów, które nale(cid:285)(cid:200) do okre(cid:258)lonej kategorii. Najcz(cid:218)(cid:258)ciej spotka(cid:202) mo(cid:285)na rozwi(cid:200)zania oparte na wykorzystaniu metod addCategoryFilter() lub addAttributeToFilter(). Jednak w wi(cid:218)kszo(cid:258)ci przypadków u(cid:285)ywanych w praktyce zdecy- dowanie (cid:239)atwiej jest zastosowa(cid:202) rozwi(cid:200)zanie znacznie prostsze, ale równie(cid:285) nie do ko(cid:241)ca in- tuicyjne w kontek(cid:258)cie informacji przedstawionych wcze(cid:258)niej w tej ksi(cid:200)(cid:285)ce. Najprostszy sposób realizacji zadania nie polega wcale na uzyskaniu kolekcji produktów i jej pó(cid:283)niejszemu filtrowaniu wzgl(cid:218)dem kategorii, lecz na stworzeniu najpierw instancji interesuj(cid:200)- cej nas kategorii, a nast(cid:218)pnie pobraniu z niej kolekcji produktów. Aby przekona(cid:202) si(cid:218) o sku- teczno(cid:258)ci takiego podej(cid:258)cia, w IMC nale(cid:285)y wykona(cid:202) nast(cid:218)puj(cid:200)cy fragment kodu: $category = Mage::getModel( catalog/category )- load(5); $productCollection = $category- getProductCollection(); W klasie Mage_Catalog_Model_Category zaimplementowana jest metoda getProductCollection(). Warto przeanalizowa(cid:202) kod (cid:283)ród(cid:239)owy tej metody: public function getProductCollection() { $collection = Mage::getResourceModel( catalog/product_collection ) - setStoreId($this- getStoreId()) - addCategoryFilter($this); return $collection; } Jak wida(cid:202), funkcja tworzy jedynie instancj(cid:218) modelu zasobów dla kolekcji produktów, to zna- czy jako sklep aktywny ustawia sklep o podanym identyfikatorze, a nast(cid:218)pnie przekazuje do metody addCategoryFilter() bie(cid:285)(cid:200)c(cid:200) kategori(cid:218). Opisane rozwi(cid:200)zanie jest bezpo(cid:258)rednim nast(cid:218)pstwem decyzji, które mia(cid:239)y na celu optymali- zacj(cid:218) wydajno(cid:258)ci Magento i u(cid:239)atwienie (cid:285)ycia programistom korzystaj(cid:200)cym z tego narz(cid:218)dzia. Dzi(cid:218)ki tym decyzjom bowiem kategoria b(cid:218)dzie w znakomitej wi(cid:218)kszo(cid:258)ci przypadków dost(cid:218)pna zawsze — w taki lub inny sposób. 78 Kup książkęPoleć książkę Rozdzia(cid:225) 3. • ORM i kolekcje danych Uzyskanie nowych produktów, które pojawi(cid:239)y si(cid:218) w dniu x lub pó(cid:283)niej Skoro wiadomo ju(cid:285), jak uzyska(cid:202) kolekcj(cid:218) produktów z danej kategorii, warto sprawdzi(cid:202), czy mo(cid:285)liwe jest zastosowanie filtrów na wynikowym zbiorze produktów, aby ostatecznie otrzyma(cid:202) tylko te, które pasuj(cid:200) do za(cid:239)o(cid:285)onych warunków. W tym konkretnym przyk(cid:239)adzie zadanie b(cid:218)dzie polega(cid:202) na uzyskaniu wszystkich produktów, które zosta(cid:239)y dodane nie wcze(cid:258)niej ni(cid:285) w grudniu 2012 roku. Analogicznie do poprzedniego przyk(cid:239)adu kolekcj(cid:218) produktów mo(cid:285)na przefiltrowa(cid:202) na podstawie daty ich stworzenia — w tym celu w IMC nale(cid:285)y wykona(cid:202) nast(cid:218)puj(cid:200)cy kod: // kolekcja produktów z poprzedniego przyk(cid:225)adu $productCollection- addFieldToFilter( created_at , array( from = 2012-12-01)); Proste, prawda? Mo(cid:285)na by nawet doda(cid:202) kolejny warunek i uzyska(cid:202) produkty, które zosta(cid:239)y dodane w okresie mi(cid:218)dzy dwiema podanymi datami. Powiedzmy, (cid:285)e konieczne jest odczytanie rekordów produktów dodanych w grudniu: $productCollection- addFieldToFilter( created_at , array( from = 2012-12-01)); $productCollection- addFieldToFilter( created_at , array( to = 2012-12-30)); Metoda addFieldToFilter Magento obs(cid:239)uguje warunki opisane w tabeli 3.1. Tabela 3.1. Warunki obs(cid:239)ugiwane przez metod(cid:218) addFieldToFilter Kod atrybutu Warunek SQL eq neq like nlike in nin is notnull null moreq gt lt gteq lteq = != LIKE NOT LIKE IN () NOT IN () IS NOT NULL NULL = = = Mo(cid:285)na te(cid:285) stosowa(cid:202) inne rodzaje filtrów. Na przyk(cid:239)ad wykonanie poni(cid:285)szego kodu w IMC po na(cid:239)o- (cid:285)eniu filtra na dat(cid:218) utworzenia produktu spowoduje, (cid:285)e zwrócone zostan(cid:200) tylko produkty widoczne: $productCollection- addAttributeToFilter( visibility , 4); 79 Kup książkęPoleć książkę Magento. Przewodnik dla programistów PHP visibility jest specjalnym atrybutem, za pomoc(cid:200) którego wskazuje si(cid:218), gdzie produkty maj(cid:200) by(cid:202) widoczne. Atrybut ten mo(cid:285)e mie(cid:202) nast(cid:218)puj(cid:200)ce warto(cid:258)ci: (cid:81) 1 — produkty nie s(cid:200) widoczne pojedynczo. (cid:81) 2 — produkty s(cid:200) widoczne w katalogu. (cid:81) 3 — produkty s(cid:200) widoczne w wynikach wyszukiwania. (cid:81) 4 — produkty s(cid:200) widoczne w katalogach i w wynikach wyszukiwania. Uzyskanie produktów, które najlepiej si(cid:218) sprzedaj(cid:200) Aby uzyska(cid:202) list(cid:218) produktów, które najlepiej sprzedaj(cid:200) si(cid:218) w danej kategorii, nale(cid:285)y wykona(cid:202) po(cid:239)(cid:200)czenie z tabel(cid:200) sales_order. Mechanizm odczytywania rekordów bestsellerowych pro- duktów przyda si(cid:218) pó(cid:283)niej do stworzenia specjalnej kategorii produktów albo umieszczenia takich danych w raportach. W IMC trzeba wykona(cid:202) nast(cid:218)puj(cid:200)cy kod: $category = Mage::getModel( catalog/category )- load(5); $productCollection = $category- getProductCollection(); $productCollection- getSelect()- join(array( o = sales_flat_order_item ), (cid:180) main_table.entity_id = o.product_id , array( o.row_total , o.product_id )) (cid:180)- group(array( sku )); Warto przeanalizowa(cid:202) zw(cid:239)aszcza operacje wykonywane w trzecim wierszu kodu. Metoda getSelect() jest dziedziczona bezpo(cid:258)rednio z klasy Varien_Data_Collection_Db i zwraca zmienn(cid:200), w której znajduje si(cid:218) instrukcja Select. Zmienna ta zawiera równie(cid:285) kolekcje, które udost(cid:218)pniaj(cid:200) metody odpowiedzialne za definiowanie z(cid:239)(cid:200)cze(cid:241) oraz za wykonywanie grupo- wania bez konieczno(cid:258)ci pisania kodu j(cid:218)zyka SQL. Nie jest to jedyny mo(cid:285)liwy sposób dodawania z(cid:239)(cid:200)czenia do kolekcji. Tak naprawd(cid:218) istnieje równie(cid:285) inne rozwi(cid:200)zanie, o wiele prostsze. Polega ono na wykorzystaniu funkcji joinField(). Nowa wersja kodu, w której wykorzystana zostanie ta funkcja, b(cid:218)dzie mie(cid:202) nast(cid:218)puj(cid:200)c(cid:200) posta(cid:202): $category = Mage::getModel( catalog/category )- load(5); $productCollection = $category- getProductCollection(); $productCollection- joinField( o , sales_flat_order_item , array( o.row_total , (cid:180) o.product_id ), main_table.entity_id = o.product_id )- group(array( sku )); Filtrowanie kolekcji produktów wzgl(cid:218)dem widoczno(cid:258)ci produktów To zadanie mo(cid:285)na wykona(cid:202) bardzo (cid:239)atwo za pomoc(cid:200) metody addAttributeToFilter(). Produkty w Magento s(cid:200) wyposa(cid:285)one w systemowy atrybut visibility, który okre(cid:258)la ich widoczno(cid:258)(cid:202). Atrybut visibility mo(cid:285)e mie(cid:202) jedn(cid:200) z czterech warto(cid:258)ci liczbowych z przedzia(cid:239)u od 1 do 4. W naszym przyk(cid:239)adzie interesuje nas wy(cid:239)(cid:200)cznie pokazywanie produktów, dla których atrybut widoczno(cid:258)ci ma warto(cid:258)(cid:202) 4, co oznacza, (cid:285)e produkty te s(cid:200) widoczne zarówno w wynikach wy- szukiwania, jak i w katalogu. W IMC nale(cid:285)y wykona(cid:202) nast(cid:218)puj(cid:200)cy kod (cid:283)ród(cid:239)owy: 80 Kup książkęPoleć książkę Rozdzia(cid:225) 3. • ORM i kolekcje danych $category = Mage::getModel( catalog/category )- load(5); $productCollection = $category- getProductCollection(); $productCollection- addAttributeToFilter( visibility , 4); Gdy widoczno(cid:258)(cid:202) produktu zostanie zmieniona, b(cid:218)dzie mo(cid:285)na porówna(cid:202) wynik wykonania kodu na ró(cid:285)nych kolekcjach. Filtrowanie produktów, którym nie przypisano obrazka Filtrowanie produktów bez przypisanego obrazka przydatne jest mi(cid:218)dzy innymi wówczas, gdy im- portuje si(cid:218) dane z zewn(cid:218)trznego systemu, który czasami zawodzi. Podobnie jak we wszystkich wcze- (cid:258)niejszych przyk(cid:239)adach, równie(cid:285) dla obrazka skojarzonego z produktem istnieje odpowiedni atrybut: $category = Mage::getModel( catalog/category )- load(5); $productCollection = $category- getProductCollection(); $productCollection- addAttributeToFilter( small_image ,array( notnull = , neq = (cid:180) no_selection )); Dzi(cid:218)ki zdefiniowaniu dodatkowego filtra produkty zwrócone w kolekcji wynikowej b(cid:218)d(cid:200) mie(cid:202) skojarzony z nimi ma(cid:239)y obrazek. Domy(cid:258)lnie w Magento wyst(cid:218)puj(cid:200) trzy typy obrazków dla produktów: miniatury, ma(cid:239)e obrazki small_image oraz obrazki w(cid:239)a(cid:258)ciwe. Ka(cid:285)dy z tych trzech typów obrazków jest wykorzystywany w ró(cid:285)nych cz(cid:218)(cid:258)ciach aplikacji. Zatem regu(cid:239)(cid:218) wyszuki- wania produktów mo(cid:285)na by jeszcze bardziej zaw(cid:218)zi(cid:202): $productCollection- addAttributeToFilter( small_image , (cid:180)array( notnull = , neq = no_selection ))- addAttributeToFilter( thumbnail, (cid:180)array( notnull = , neq = no_selection ))- addAttributeToFilter( image , (cid:180)array( notnull = , neq = no_selection )); Tak skonstruowany kod spowoduje, (cid:285)e zwrócona zostanie kolekcja produktów, dla których wskazano wszystkie trzy typy obrazków. Mo(cid:285)na poeksperymentowa(cid:202) na w(cid:239)asn(cid:200) r(cid:218)k(cid:218) i filtrowa(cid:202) produkty wzgl(cid:218)dem ró(cid:285)nych typów obrazków. Dodanie wielu kryteriów porz(cid:200)dkowania W ostatnim zadaniu uporz(cid:200)dkujemy zawarto(cid:258)(cid:202) kolekcji najpierw wzgl(cid:218)dem stanu magazynowego, a nast(cid:218)pnie wzgl(cid:218)dem ceny — od najwy(cid:285)szej do najni(cid:285)szej. Informacj(cid:218) o stanie magazynowym zwróci metoda addStockStatusToSelect(), która jest dost(cid:218)pna tylko w modelu zasobów repre- zentuj(cid:200)cym w(cid:239)a(cid:258)nie stan magazynowy. Metoda addStockStatusToSelect() sama wygeneruje odpowiednie zapytanie j(cid:218)zyka SQL, które zwróci kolekcj(cid:218): $category = Mage::getModel( catalog/category )- load(5); $productCollection = $category- getProductCollection(); $select = $productCollection- getSelect(); Mage::getResourceModel( cataloginventory/stock_status )- addStockStatusToSelect (cid:180)($select, Mage::app()- getWebsite()); $select- order( salable desc ); $select- order( price asc ); 81 Kup książkęPoleć książkę Magento. Przewodnik dla programistów PHP Zapytanie to spowoduje, (cid:285)e Magento uporz(cid:200)dkuje produkty wzgl(cid:218)dem ich dost(cid:218)pno(cid:258)ci do sprzeda(cid:285)y (b(cid:218)d(cid:200)cej warto(cid:258)ci(cid:200) logiczn(cid:200) — produkt mo(cid:285)e by(cid:202) dost(cid:218)pny w sprzeda(cid:285)y lub nie) oraz wzgl(cid:218)dem ceny. Jako efekt ko(cid:241)cowy zwrócona zostanie kolekcja produktów uporz(cid:200)dkowa- nych w ten sposób, (cid:285)e na pocz(cid:200)tku wyst(cid:218)powa(cid:202) b(cid:218)d(cid:200) produkty dost(cid:218)pne w sprzeda(cid:285)y u(cid:239)o(cid:285)one wzgl(cid:218)dem ceny od najwy(cid:285)szej do najni(cid:285)szej, a w dalszej kolejno(cid:258)ci widnie(cid:202) b(cid:218)d(cid:200) produkty niedost(cid:218)pne w sprzeda(cid:285)y, tak(cid:285)e uporz(cid:200)dkowane od najdro(cid:285)szego do najta(cid:241)szego. Warto poeksperymentowa(cid:202) z ró(cid:285)nymi kombinacjami kryteriów sortowania, aby zobaczy(cid:202), jak Magento organizuje i porz(cid:200)dkuje kolekcje produktów. Wykonywanie bezpo(cid:258)rednich zapyta(cid:241) j(cid:218)zyka SQL Wiemy ju(cid:285), w jaki sposób modele danych Magento oraz system ORM u(cid:239)atwiaj(cid:200) odczytywanie i zapisywanie danych oraz manipulowanie nimi. Zanim zajmiemy si(cid:218) g(cid:239)ównymi tematami tego punktu, czyli adapterami baz danych w Magento oraz wykonywaniem bezpo(cid:258)rednich zapyta(cid:241) j(cid:218)zyka SQL, najpierw koniecznie trzeba powiedzie(cid:202), dlaczego zasadniczo powinno si(cid:218) unika(cid:202) stosowania tych technik. Magento jest systemem niezwykle z(cid:239)o(cid:285)onym, przynajmniej cz(cid:218)(cid:258)ciowo sterowanym zdarzeniami, o czym by(cid:239)a ju(cid:285) mowa w poprzednim rozdziale. Samo zapisanie produktu wyzwala ró(cid:285)nego rodzaju zdarzenia, z których ka(cid:285)de wykonuje inne zadanie. Zdarzenia nie zajd(cid:200) jednak wówczas, gdy zmiana danych na temat produktu zostanie wprowadzona bezpo(cid:258)rednio przez zapytanie SQL. Dlatego programi(cid:258)ci musz(cid:200) pracowa(cid:202) z Magento z niezwyk(cid:239)(cid:200) ostro(cid:285)no(cid:258)ci(cid:200) i zawsze si(cid:218) upewnia(cid:202), czy istnieje wystarczaj(cid:200)cy powód, by nie korzysta(cid:202) z ORM. Istniej(cid:200) rzecz jasna okoliczno(cid:258)ci, w których mo(cid:285)liwo(cid:258)(cid:202) bezpo(cid:258)redniego operowania na bazie danych jest bardzo przydatna i okazuje si(cid:218) (cid:239)atwiejszym sposobem wykonania niektórych zada(cid:241) ni(cid:285) wykorzystywanie modeli Magento. Na przyk(cid:239)ad aby zmieni(cid:202) globalnie okre(cid:258)lony atrybut produktu albo zmodyfikowa(cid:202) status produktów w kolekcji, mo(cid:285)na by za(cid:239)adowa(cid:202) kolekcj(cid:218) pro- duktów i w p(cid:218)tli przej(cid:258)(cid:202) przez ka(cid:285)dy z nich, wprowadzaj(cid:200)c w nich wymagane zmiany i za- pisuj(cid:200)c je jedn(cid:200) po drugim. W przypadku niewielkiej kolekcji podej(cid:258)cie takie jeszcze by si(cid:218) sprawdzi(cid:239)o, jednak im wi(cid:218)kszy b(cid:218)dzie rozmiar zbioru danych, tym ni(cid:285)sza stanie si(cid:218) wydajno(cid:258)(cid:202) p(cid:218)tli przetwarzaj(cid:200)cej kolekcj(cid:218). W przypadku wi(cid:218)kszyc
Pobierz darmowy fragment (pdf)

Gdzie kupić całą publikację:

Magento. Przewodnik dla programistów PHP
Autor:

Opinie na temat publikacji:


Inne popularne pozycje z tej kategorii:


Czytaj również:


Prowadzisz stronę lub blog? Wstaw link do fragmentu tej książki i współpracuj z Cyfroteką: