Nowoczesny sposób przepisywania plików lib

21

Problem jest dobrze znany: libklasy ładowane są wyłącznie przez autoloader i nie możemy ich zmienić inaczej niż:

  • Skopiowanie ich w całości do codePool, który jest sprawdzany wcześniej niż lib.
  • Instalowanie autoloadera PSR-0 , określenie mapy klas autoload, a następnie skopiowanie pliku w całości do tej struktury folderów. [moje obecne rozwiązanie]

Jestem w trudnym miejscu, ponieważ potencjalnie chcę dotknąć wielu z tych plików - ale ze względu na moje zdrowie psychiczne oraz stabilność / możliwość aktualizacji sklepu nie chcę kopiować całych klas bibliotek.

Teraz oczywiście istnieją potencjalne rozwiązania tego problemu, ale wszystkie mają swoje własne problemy:

  • Przejdź na trasę AOP i skorzystaj z biblioteki opartej na PHP, takiej jak Go! AOP : Ostatnio sprawdziłem, że będzie wymagać załadowania klas Magento przez autoloader kompozytora, a nie tylko jedna dostępna. Flyingmana wykonał już pewne prace w tym obszarze, ale zdecydowanie nie jest gotowy do użycia w produkcji, a moje potrzeby są bardziej bezpośrednie. Chcę również wysłać jako rozszerzenie, a to wymagałoby większej konfiguracji kompozytora.
  • Przejdź na trasę AOP i użyj natywnego rozszerzenia PHP : Prawdopodobnie najbardziej korzystne w tym momencie, ale wymagałoby to zainstalowania osobnego rozszerzenia, nie wspominając już o tym, że nie będzie działać z HHVM.
  • Użyj PHP classkit i / lub runkit : to kolejne natywne rozszerzenie PHP, więc ma taki sam problem jak powyżej.
  • Patchuj strony wywoławcze, aby używać mojej własnej \Danslo\Varien_Xwersji namespaced ( ), a następnie rozszerz oryginalną ( \Varien_X): Jest po prostu zbyt wiele stron wywoławczych do łatania i wymagałoby to niemałej ilości przepisywania. Brak opcji.
  • Rzuć własnym: Powinno być możliwe:

    1. Napisz własny autoloader.
    2. Skopiuj oryginalną klasę do osobnego folderu ( {root_dir}/var/tmp), zawiń ją namespace \Magento { < original contents > }.
    3. Dołącz ten plik.
    4. Uwzględnij moją zmodyfikowaną klasę OriginalClass extends Magento\OriginalClass {}

Wada tego jest oczywista: dynamiczne generowanie kodu, regex, trochę narzutu na ładowanie przerobionych klas. Ale jestem prawie pewien, że w tym momencie byłoby lepiej skopiować ~ 5000 wierszy kodu, gdy chcę tylko dotknąć / dodać ~ 100 wierszy.

Wiem, że dużo pytam, ale czy jest coś nowoczesnego i stosunkowo czystego, co pomaga rozwiązać ten problem?

Daniel Sloof
źródło
1
Znalazłeś już rozwiązanie obserwatora Alans? stackoverflow.com/a/4636662/158325
B00MER

Odpowiedzi:

9

Zdecydowałem się na wdrożenie Go! Struktura AOP w Magento.

Zobacz Danslo_Aop na github.

Daniel Sloof
źródło
2

Przejdź na trasę AOP i skorzystaj z biblioteki opartej na PHP, takiej jak Go! AOP: Ostatnio sprawdziłem, że będzie wymagać załadowania klas Magento przez autoloader kompozytora, a nie tylko jedna dostępna. Flyingmana wykonał już pewne prace w tym obszarze, ale zdecydowanie nie jest gotowy do użycia w produkcji, a moje potrzeby są bardziej bezpośrednie. Chcę również wysłać jako rozszerzenie, a to wymagałoby większej konfiguracji kompozytora.

Chcę dodać, że Go! Framework AOP może działać bez kompozytora, mogę pomóc w konfiguracji (po prostu stwórz w tym celu problem na github). Kompozytor jest potrzebny tylko do przejrzystej integracji z nowoczesnymi aplikacjami.

Po prostu zamień include $filenamelub require $filenamew swoim bootstrapie include FilterInjectorTransformer::rewrite($filename)i skonfiguruj autoloader dla Go! Sam AOP.

lisachenko
źródło
1
O, nieźle. Na pewno spróbuję tego.
Daniel Sloof
0

Idź z podejściem autoloadera. Zmień nazwę / all / klas w lib z prefiksem:

find lib -name '*.php' -exec sed -e 's,^class ,class Oldlib_,' {} +

Uruchom następujący „override fixer” za każdym razem, gdy dodasz plik do mylib:

find lib -name '*.php' -print | while read FILE
do
    classname=$(echo ${FILE}|sed -e 's,^lib/,,' -e 's,\.php$,,' -e 's,/,_,g')
    if [ ! -f mylib/${FILE#lib/} ]; then
        # ensure is_a works by providing a stub with correct classname
        echo "class ${classname} extends Oldlib_${classname} {}" > mylib/${classname}.php
    elif [ -f mylib/${classname}.php ]; then
        # we have a new override, but the old file still exists
        rm mylib/${classname}.php
    fi
done

Naucz autoloader, aby zwracał, mylib/${classname}.phpjeśli istnieje, a mylib/full/path/to/class.phpjeśli nie istnieje i nie mylib/full/path/to/class.phpdziała.

Umieść swoje przesłonięcia mylib/full/path/to/class.phpi rozszerz wersję Oldlib_.

Uaktualnienia po prostu wycofaj prefiks w lib / upgrade, ponownie zastosuj prefiks, uruchom ponownie narzędzie do nadpisywania. Pozostały rzeczy, które zostały przeniesione lib/i zostały wcześniej zastąpione, ale nie jest to związane z problemem. Twoim problemem może być liczba plików w katalogu mylib /, ale ufam, że możesz to rozwiązać :).

Melvyn
źródło
Takie podejście wprowadza wiele zagrożeń i rzeczy, które należy zachować, szczególnie w odniesieniu do aktualizacji. Łamie także zasadę „nie dotykaj rdzenia”. Ponadto nie jest to opłacalna opcja dla programistów rozszerzeń.
beeplogic,
Z całym szacunkiem ~ choć twoje rozwiązanie działa ... nie można tego traktować jako a modernprzepisywania plików lib. Programowanie imperatywne to stara szkoła;)
Eddie B,
0

Możesz także zdefiniować niestandardowy strumień i dodać go na górze ścieżki automatycznego ładowania. Działa z każdym autoloaderem i wymaga minimalnej adaptacji. Patrz przykład

KAndy
źródło