Jak napisać niestandardowe rozszerzenie?

143

Ponieważ ostatnio miałem wiele problemów z darmowym i komercyjnym rozszerzeniem, postanowiłem zadać to pytanie i odpowiedzieć na nie, wykonując czynności, które zwykle wykonuję, pisząc rozszerzenie. Edytuj odpowiedź lub dodaj nową.
W większości przypadków podczas instalowania rozszerzenia lub motywu muszę poświęcić kilka godzin (czasem więcej, a czasem mniej), aby działał we wszystkich potrzebnych środowiskach:

  • dev: zwykle localhosttam, gdzie projekt znajduje się w podfolderze
  • przedprodukcja i życie

Stało się tak nawet w przypadku rozszerzeń od dużych dostawców rozszerzeń (które powinny pozostać bezimienne, przynajmniej dopóki naprawdę nie oszaleję i nie dodam tutaj ich nazw).
Zatem głównym pytaniem jest ... jakie kroki powinienem wziąć pod uwagę, pisząc rozszerzenie, aby zapewnić jakość kodu i ułatwić korzystanie z niego przez osobę techniczną i nietechniczną oraz zmianę przez osobę techniczną?

Marius
źródło
11
Wygląda na to, że jeden z dużych dostawców wewnętrznych nie spodobał się temu pytaniu i głosował za nim. :)
Marius
1
Osobiście absolutnie nie ma problemu z Wyomindem, ale szyfrują swój kod i nadal są „partnerami premium” :( (na przykład)
sv3n

Odpowiedzi:

185

Oto, co zwykle robię:

  1. Zawsze rozwijaj się z error_reportingwłączonym.
  2. Zawsze rozwijaj z isDeveloperModeustawionym na true. Po prostu dodaj SetEnv MAGE_IS_DEVELOPER_MODE 1do swojego httpd.confpliku (lub odpowiedniego pliku dla Nginx lub czegoś innego)
  3. Jeśli rozszerzenie jest powiązane z podstawową funkcjonalnością, dodaj zależność w pliku deklaracji <depends><Mage_Catalog /></depend>
  4. Jeśli moduł jest przeznaczony do użytku społeczności, użyj go communityjako puli kodów, aby dać programistom szansę na zastąpienie niektórych klas bez bezpośredniej modyfikacji kodu
  5. Umieść pliki projektu interfejsu użytkownika, app/design/frontend/base/default aby były dostępne dla wszystkich motywów.
  6. Umieść pliki projektu administratora app/design/adminhtml/default/defaulti nie zmieniaj motywu administratora. Mogę chcieć to zmienić w jednym z moich modułów.
  7. Poprzedź nazwy plików układów i folderów szablonów nazwami firm, aby ułatwić ich izolowanie. easylife_articles.xmliapp/design/.../easylife_articles
  8. Umieść swoje zasoby statyczne (JavaScript, CSS i obrazy) w podobnym folderze jak pliki szablonów easylife_articles/images/doh.png
  9. Załącz prosty plik tekstowy ze sposobem odinstalowania rozszerzenia: Jakie pliki należy usunąć, jakie tabele należy usunąć, jakie ustawienia konfiguracji należy usunąć z core_config_datatabeli.
  10. Nie pisz zapytań bezpośrednio w modelach, blokach lub pomocnikach, użyj do tego modelu zasobów.
  11. Nie pisz zapytań, używając bezpośrednio nazw tabel Select * from sales_flat_order where .... Użyj a Zend_Selecti przekształć nazwy tabel za pomocą ->getTable('sales/order').
  12. Użyj podstawowego adresu URL, aby dołączyć jspliki do szablonu. Źle <script type="text/javascript" src="../js/some.js"></script> . Dobrze <script type="text/javascript" src="<?php echo Mage::getBaseUrl('js').'some.js'?>"></script>
  13. Nie przepisuj klas, chyba że jest to konieczne. Użyj obserwatorów, a jeśli nie jest możliwe użycie metod pomocniczych, które otrzymują jako parametr i instancję klasy, którą chcesz przesłonić. Źle : Zastąp, Mage_Catalog_Model_Productaby dodać metodę getProductArticles(). Racja . W swoim pomocniku dodaj getProductArticles(Mage_Catalog_Model_Product $product)
  14. Jeśli przesłonisz klasy, umieść ich listę w readme.txtpliku
  15. Użyj domyślnej ścieżki administratora dla sekcji administratora swojego modułu. Błędny adres URL administratora articles/adminhtml_articles/index . Właściwy adres URL administratora admin/articles/index
  16. Dodaj listę ACL dla swoich sekcji administracyjnych. Może chcę ograniczyć dostęp do niektórych administratorów.
  17. Nie dodawaj innej struktury JavaScript (jQuery, MooTools itp.), Jeśli nie jest to konieczne. Napisz kod w prototypie.
  18. Spraw, by szablon HTML W3C był prawidłowy (dotyczy to programistów OCD, takich jak ja).
  19. Nie umieszczaj zdjęć w mediafolderze. Użyj skin. media Folder zazwyczaj nie posiada oznaczenia wersji, a to sprawia, że coraz trudniej jest przejść na stronę z różnymi środowiskami.
  20. Przetestuj swoje rozszerzenie z włączonym i wyłączonym płaskim katalogiem. Aby nie podwoić czasu rozwoju, użyj Małpy Chaosu .
  21. Przetestuj swoje rozszerzenie za pomocą pamięci podręcznej oni pamięci podręcznej off.
  22. Unikaj używania wielkich liter w nazwach modułów i klas. Jeśli nie zostanie odpowiednio przetestowany, może to powodować problemy w różnych systemach operacyjnych. To raczej zalecenie, a nie „konieczność”.
  23. Wysyłaj zdarzenia w kodzie, aby ułatwić programistom zmianę funkcji.
  24. Postępuj zgodnie z tymi samymi standardami kodowania, których używa Magento, i komentuj swój kod.
  25. Nie używaj krótkich tagów PHP ( <? $this->doSomething() ?>). Użyj pełnych tagów ( <?php $this->doSomething()?>). Nie używaj jeszcze krótkich znaczników echa. ( <?="D'oh";?>). Użyj ( <?php echo "D'oh";?>)
  26. Przetłumacz swoje teksty za pomocą $this->__i dodaj plik tłumaczenia ustawień regionalnych z tekstami ( app/local/en_US/Easylife_Articles.csv) przynajmniej dla en_USjęzyka. Nie wszystkie strony internetowe są zbudowane w języku angielskim, a identyfikacja tekstów do przetłumaczenia jest czasochłonna.
  27. Jeśli sprzedajesz ofertę rozszerzenia, przynajmniej podstawowe wsparcie. Lub przynajmniej odpowiedz na otrzymane wiadomości e-mail dotyczące pomocy technicznej.
  28. Nie wykonuj stałych połączeń z serwerami przez rozszerzenie w celu sprawdzenia licencji. Kiedyś, podczas instalacji jest więcej niż wystarczające (nie podoba mi się to podejście, ale lepiej niż cały czas dzwonić). (Zainspirowany tym pytaniem )
  29. Rozwijaj z aktywowanym logiem i od czasu do czasu spójrz na var/log/system.logplik. Wymienione tutaj błędy nie są wyświetlane nawet przy włączonym trybie programisty. Jeśli występuje co najmniej jeden błąd, po kilku miesiącach uruchamiania rozszerzenia pojawia się duży plik dziennika.
  30. Jeśli Twoje rozszerzenie w jakiś sposób wpływa na proces realizacji transakcji lub zamówienia, upewnij się, że działa z wieloma wysyłkami lub jeśli nie powinno działać z wieloma wysyłkami, upewnij się, że nie ma na to wpływu.
  31. Nie zastępuj domyślnego paska powiadomień administratora (lub adresu URL kanału). Jeśli jestem zainteresowany tym, co masz do zaoferowania, subskrybuję Twój biuletyn. Zobaczę, co ma do powiedzenia Magento. To dla mnie ważniejsze.
  32. Jeśli szyfrujesz pliki kodu za pomocą Ioncube (lub czegoś innego) ... cóż ... Po prostu cię nienawidzę i mam nadzieję, że Twoja firma zbankrutuje

Jak dotąd. Dodam więcej, gdy tylko wymyślę coś innego.

Marius
źródło
Zgadzam się z tobą, to zdecydowanie dobry początek. Z pewnością zrozumiesz również, że nie zawsze jest możliwe pokrycie wszystkich różnych rodzajów konfiguracji i problemów, przynajmniej zmniejszy to możliwe. Większość problemów, które spotykam z innymi rozszerzeniami lub ludzie spotykają się z moim, są spowodowane konfliktem z nadpisywaniem.
Sylvain Rayé,
2
@ Marius, na pewno 1+ ode mnie. Obejmuje większość przypadków i scenariuszy, przed którymi stoimy w fazie rozwoju.
liyakat
4
@ColinM. Po pierwsze, to zaszczyt mieć tutaj swój komentarz. :) Zgadzam się, że jest różnica, zmodyfikuję odpowiedź, ale nadal uważam, że należy ich unikać, przynajmniej dopóki PHP 5.3 nie stanie się „nowym PHP 4”. Mam na myśli, że wciąż jest używany na dużą skalę.
Marius
4
@Marius, twoje punkty są bardzo pomocne. Do nr 31 poważnie skupiałem się na każdym punkcie, ale na nr 32 wybuchnąłem głośnym śmiechem. +1 specjalnie dla punktu # 32
MTM
1
If you encrypt your code files with Ioncube (or something else)...well...I just hate you and I hope your business goes bankruptCzuję to samo. Są firmy, które nie oferują zaktualizowanej wersji, trzeba będzie za nie zapłacić, to dla mnie naprawdę frustrujące i nie rozumiem, dlaczego chcą ciągle sprzedawać ten sam produkt (oczywiście, aby zarabiać pieniądze?). Po prostu nie kupuję już ich produktu. Wiesz o kim mówię.
Adarsh ​​Khatri,
31

Jestem wielkim fanem używania modmana, dzięki czemu mogę rozwijać i kontrolować źródła tylko mojego rozszerzenia i pozostawić podstawowe pliki i strukturę folderów bez zmian. Sprawia również, że testy w różnych instalacjach przebiegają płynniej.

Aha, i jedna ogromna wskazówka zawsze próbuje lokalnie zainstalować paczkowane rozszerzenie na czystej instalacji magento przed przesłaniem go do Magento Connect, tyle razy brakowało mi plików w menedżerze pakietów.

David Manners
źródło
3
Dobra rozmowa na temat „instaluj rozszerzenie pakietu lokalnie”. Myślę, że należy to do kategorii: „Przetestuj swoje cholerne rozszerzenie od góry do dołu”.
Marius
Już wcześniej mnie to złapało. Upewnij się, że przetestowałeś pakiet na czystej instalacji, która nie jest tą samą, na której go spakowałeś!
Joseph Leedy,
22

Andreas von Studnitz i Dr. Nikolai Krambrock dobrze przedstawili jakość kodu na Meet Magento DE 2014. Rozróżniają między ogólną jakością kodu a jakością kodu specyficzną dla Magento. Krótko mówiąc, obowiązują następujące ogólne zasady:

  • Zastosowanie elementów konstrukcji - podobnie jak klas i metod - powinno być rozmieszczone w klasach o średnich rozmiarach. Te elementy struktury mają sens tylko wtedy, gdy są używane do strukturyzacji. Dlatego muszą być średniej wielkości. Uważa się, że używa 100-200 linii kodu dla klas i 3-20 linii kodu dla metod.
  • Ze względu na użycie „if” lub „while” kod jest wcięty. Jeśli są więcej niż 3 wcięcia, lepiej je poprawić. Zbyt wiele wcięć świadczy o złożoności kodu i dlatego należy go unikać.
  • Martwego kodu należy unikać i usuwać. Analizy statyczne pomagają je znaleźć, jeśli takie istnieją.

Jeszcze ważniejsze są reguły specyficzne dla Magento:

  • Moduły powinny działać niezależnie. Powinny mieć jedynie niewielką zależność od innych modułów i brak zależności od szablonów. Rozwiązaniem jest użycie aktualizacji układu (podstawowa / domyślna) zamiast adaptacji do plików szablonów i modułu obejmującego dodatkowe funkcje szablonu.
  • Aby zachować możliwość aktualizacji w Magento, należy unikać włamań i włamań do modułów zewnętrznych. Lepszym sposobem jest użycie zamiast tego przepisywania lub obserwatora.
  • W przypadku zmian lepiej jest używać skryptów instalacyjnych zamiast bezpośrednich zmian bazy danych lub administratora. Dzięki nim zmiany należy wprowadzać tylko jednorazowo.

Oto kilka dodatkowych szczegółów i wideo z prezentacji: http://www.code4business.de/code-quality-magento/

użytkownik3743859
źródło
1
Ale gdybyś miał angielską wersję linku, który zamieściłeś, byłoby jeszcze lepiej.
Marius
Angielska wersja tej prezentacji zostanie wkrótce napisana. Będę Cię informować na bieżąco i udostępnię nowy link, jak tylko opublikowana zostanie wersja angielska.
user3743859,
Angielska wersja prezentacji jest już dostępna online. Oto link do niego: code4business.de/code-quality-magento
użytkownik3743859
co? Nadal jest po niemiecku. Ale przypadkiem uczestniczyłem w tej prezentacji w języku angielskim na MeetMagentRo około 2 tygodnie temu. Świetna sprawa.
Marius
18

Jeśli sprzedajesz swoje rozszerzenie lub udostępniasz je innym, pomyśl o pisaniu kodu, który będzie czytelny dla człowieka.

  1. nie rób zbyt skomplikowanej metody
  2. dodaj bloki DOC do swoich metod *
  3. użyj prawidłowych nazw zmiennych, takich jak $productIdszamiast$ids
  4. to samo dotyczy metod, public function myOnProductSaveMethod() {...}mówi ... nic, ale tryDisableInternetOnProductSave()da wskazówkę, że chcesz zaplanować
  5. używaj podpowiedzi typu tam, gdzie ma to sens someMethod(Varien_Data_Db_Collection $collection)
  6. unikaj magicznych liczb i łańcuchów **
  7. jeśli używasz modeli ustaw $_eventPrefixwłaściwość (i $_eventObject), aby były lepiej dostępne dla obserwatorów
  8. jeśli dodasz pola konfiguracji systemu
    • ustaw wartości domyślne w config.xml
    • dodaj <validate>węzły do ​​pól wsystem.xml
    • dodaj zasoby ACL do adminhtml.xml
  9. nie dodawaj bezużytecznych / reklamowych pozycji menu pierwszego poziomu w zapleczu administratora - ani w pasku górnym, ani w sekcjach konfiguracji
  10. dodaj zasoby ACL dla wszystkich akcji kontrolera (również masowania!)
  11. upewnij się, że twoje zapytania działają z prefiksami tabeli DB
  12. pomyśl o (nie) kompatybilności wstecznej (tak naprawdę opiera się ona na opiniach)
    • nie obsługują Mysql4klas
    • nie używaj przestarzałych metod
  13. upewnij się, że twoje rozszerzenie działa zgodnie z oczekiwaniami w każdym przypadku - dodaj UnitTests (na przykład PhpUnit)
  14. oprócz Davida Mannera ... dodaj composer.jsonteż, aby ułatwić wdrożenie
  15. ponieważ PHP5.6 to EOL, napisz kod dla PHP7. Użyj declare(strict_types=1);i zdefiniuj typy wejścia i wyjścia
  16. Magento2: sprawdź swój kod za pomocą narzędzi do analizy kodu statycznego, takich jak phpstan . Wsparcie dla magicznych metod tutaj . (najnowsze zatwierdzenie działa z 2.3, wcześniej dla 2.1 / 2.2 - taht wymaga phpstan 0.8.5)

* Bloki DOC:

Jeśli sprawdzisz kod Magento-1 za pomocą PHP_CodeSniffer dla standardu PSR2 lub PHPMD , być może zechcesz dodać te linie (tam, gdzie ma to sens) ...

  • na zajęcia
    • @phpcs:disable PSR1.Classes.ClassDeclaration.MissingNamespace
    • @phpcs:disable PSR2.Classes.PropertyDeclaration.Underscore - odziedziczone właściwości
    • @phpcs:disable Squiz.Classes.ValidClassName.NotCamelCaps
    • @SuppressWarnings(PHPMD.CamelCaseClassName)
    • @SuppressWarnings(PHPMD.CamelCasePropertyName) - odziedziczone właściwości
  • do metod
    • @SuppressWarnings(PHPMD.CamelCaseMethodName) - metody odziedziczone
    • @SuppressWarnings(PHPMD.StaticAccess)- jeśli używasz Mage::lub innych połączeń statycznych

** Często używany:

  • identyfikator sklepu administratora
    • 0 > Mage_Core_Model_App::ADMIN_STORE_ID
  • produkt status
    • 1 > Mage_Catalog_Model_Product_Status::STATUS_ENABLED
    • 2> Mage_Catalog_Model_Product_Status::STATUS_DISABLED (nie 0jak można się spodziewać)
  • produkt type
    • simple > Mage_Catalog_Model_Product_Type::TYPE_SIMPLE
    • bundle > Mage_Catalog_Model_Product_Type::TYPE_BUNDLE
    • configurable > Mage_Catalog_Model_Product_Type::TYPE_CONFIGURABLE
    • grouped > Mage_Catalog_Model_Product_Type::TYPE_GROUPED
    • virtual > Mage_Catalog_Model_Product_Type::TYPE_VIRTUAL
  • produkt visibity
    • 1 > Mage_Catalog_Model_Product_Visibility::VISIBILITY_NOT_VISIBLE
    • 2 > Mage_Catalog_Model_Product_Visibility::VISIBILITY_IN_CATALOG
    • 3 > Mage_Catalog_Model_Product_Visibility::VISIBILITY_IN_SEARCH
    • 4 > Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH

To samo dla zamówienia SQL ASCvs Zend_Db_Select::SQL_ASC (na przykład) .

Mówiąc „to nie jest niepotrzebne, bo nigdy się nie zmieni” ? Na przykład identyfikator jednostki dla catalog_productatrybutów zmienił się gdzieś pomiędzy Magento 1.5 a 1.9 z 10na 4, więc może to spowodować uszkodzenie twojego rozszerzenia:

$collection->addFieldToFilter('entity_type_id', 10)

Użycie tego zamiast tego dodaje jedno zapytanie, ale będziesz bezpieczny ...

$entityTypeId = Mage::getModel('eav/config')
    ->getEntityType(Mage_Catalog_Model_Product::ENTITY)
    ->getEntityTypeId();

$collection->addFieldToFilter('entity_type_id', $entityTypeId)
sv3n
źródło
8

@marius, dotyczący standardów kodowania (punkt 24 na liście).

Lubię używać PHP_CodeSniffer wraz z EQP i EKG CS automatycznie egzekwować te normy.

Korzystanie PHP_CodeSniffer nie trzeba się martwić o zapominając rzeczy jak zastąpienie array()ze []unikać używania is_nullpozostawić nieużywane zmienne lokalne lub nawet metodę bez bloku PHPDoc.

PHP_CodeSniffer zawsze ci o tym powie.

diazwatson
źródło
Myślę, że nie ma możliwości skonfigurowania obu CS w PHPStorm (dla tych, którzy używają PHPStorm), ale zawsze możesz użyć terminala, aby sprawdzić CS w kodzie. Istnieją również narzędzia, takie jak grumphp github.com/phpro/grumphp, które trochę pomagają.
diazwatson
To może ci pomóc magento.stackexchange.com/questions/200022/…
Pramod Kharade