Jak zastąpić podstawowe klasy?

20

Czasami istnieje potrzeba zastąpienia klas podstawowych, aby uzyskać większą funkcjonalność lub sprawić, aby niektóre podstawowe funkcje działały w inny sposób. Czy jest jakiś sposób na zastąpienie podstawowych klas? Jeśli to możliwe, jakie problemy mogę rozwiązać, zastępując je?

Dmitry Rekun
źródło
1
Byłoby wspaniale, gdybyś mógł uściślić swoje pytanie, aby uczynić je bardziej szczegółowym lub opisać wyraźny problem.
Valentin Despa
Dla użytkowników Joomla 3 - sprawdź te. To ci pomoże. joomla.stackexchange.com/questions/5449/… Wtyczka - github.com/ghazal/plg_mvcoverride Dzięki joomla.stackexchange.com/users/270/ghazal
cha

Odpowiedzi:

16

Tak to mozliwe.

Możesz użyć wtyczki systemowej do zastąpienia klas, przeczytaj ten link i to i to

Dwa problemy, które napotkasz:

  1. musisz przesłonić całą klasę (nie tylko jej części)

  2. jeśli rdzeń został zaktualizowany, a klasa również zaktualizowana / zmieniona, musisz zaktualizować swoje zastąpienie (w razie potrzeby).

jackJoe
źródło
4
Przydałoby się wkleić odpowiednie kroki z podanych linków lub przynajmniej podać opis linków, na wypadek gdyby się poruszyły lub zmieniły.
codinghands
10

Jakiś czas temu stworzyłem wtyczkę, która pozwala ci przesłonić podstawowe klasy, ale wciąż jest ofiarą problemów wskazanych przez @jackJoe w swojej odpowiedzi. Pozwala jednak na czyste zastępowanie.

https://gist.github.com/dongilbert/3237387

Don Gilbert
źródło
7
Chcę tylko powiedzieć, że to rozwiązanie działa pięknie i że Don jest prawdziwym pokrewnym duchem Open Source - czapki z głów dla niego i jego pracy !!!
PKB
Z twoim prostym skryptem jest poważny problem polegający na tym, że nie ładuje on wstępnie składników. Tak więc, jeśli zastąpisz komponenty, to tak naprawdę nie działa dla większości z nich (np. Komponent com_content). Działa dobrze, ale musi wstępnie załadować komponent, aby mógł je zastąpić (nie można zastąpić czegoś, co nie zostało jeszcze zadeklarowane). Aha, i musisz użyć onAfterRoute zamiast robić wszystko w konstruktorze. Jeśli chcesz wiedzieć, co mam na myśli przez ten komentarz, spróbuj zastąpić components/com_content/models/articles.php.
itoctopus,
4

Byłem na tym bardzo długo i obiecałem Donowi, że kiedy skończę, poda więcej szczegółów na ten temat.

Musiałem przesłonić Joomla MVC dla komponentów i powiedzieć Joomla, aby szukał zastąpień również w folderze HTML wtyczki, nie tylko w folderze HTML szablonu.

Nigdy nie podobało mi się, gdy programiści faktycznie wybrali domyślną klasę Joomla i zepsuli ją, więc raczej jeśli to możliwe, rozszerzam tę klasę, zamiast coś hamować.

Mój proces wykonuje następujące czynności.

  1. Zdobądź klasę, którą muszę zastąpić
  2. Przeczytaj, zamień nazwę klasy, utwórz nowy plik w moim folderze klasy tymczasowej
  3. Załaduj moją wersję klasy
  4. Załaduj klasę Joomla
  5. Zarejestruj moją metodę rozszerzania, która rozszerza funkcję loadTemplate, aby wyszukać zastąpienie w mojej wtyczce, niż szablon Joomla i ostatni składnik Joomla

oto obraz raczej http://prntscr.com/3d9syq

Pierwsze części poniższego fragmentu to sprawdzenie, gdzie jest użytkownik. Jeśli ma zamiar zaktualizować Joomla, usuwam pliki klasy tymczasowej, które zostały utworzone, aby upewnić się, że otrzymamy nowe po zakończeniu aktualizacji, a nie o numer JackJoe 2)

if (($this->Input('option') == 'com_joomlaupdate' && $this->Input('task') == 'update.install') || ($this->Input('option') == 'com_joomlaupdate' && $this->Input('layout') == 'complete')) {

    JFolder::delete(JPATH_SITE . '/plugins/system/yjsg/includes/yjsgcore/classes/extend/classes/');
    JFolder::create(JPATH_SITE . '/plugins/system/yjsg/includes/yjsgcore/classes/extend/classes/');
    $indexContent = '';
    JFile::write(JPATH_SITE . '/plugins/system/yjsg/includes/yjsgcore/classes/extend/classes/index.html', $indexContent);
}

$YjsgJViewDefaultRead         = JPATH_LIBRARIES . '/legacy/view/legacy.php';
$YjsgJViewDefaultFile         = YJSGEXTEND . "classes" . YJDS . "Yjsg" . $isView . "Default" . $IsJversion . ".php";



    //extend JView library class

    if (!JFile::exists($YjsgJViewDefaultFile)) {
        $YjsgJViewDefault = JFile::read($YjsgJViewDefaultRead);
        $YjsgJViewDefault = str_replace('class ' . $isView, 'class Yjsg' . $isView . 'Default', $YjsgJViewDefault);
        JFile::write($YjsgJViewDefaultFile, $YjsgJViewDefault);
    }

    require_once($YjsgJViewDefaultFile);
    jimport('joomla.application.component.view');
    JLoader::register($isView, YJSGEXTEND . $IsJversion . '/component/view.php', true);
Dan
źródło