Beliebige Methoden überschreiben

Einklappen
X
 
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge
  • bubblez
    Contao-Nutzer
    • 24.11.2009
    • 248

    #1

    Beliebige Methoden überschreiben

    Hallo zusammen
    Schon mehrfach habe ich kleine Änderungen vorgenommen, wenn das Verhalten gewisser Extensions nicht genau meinen Bedürfnissen entsprach. Allerdings habe ich dies immer in den "original" PHP-Dateien der Extension gemacht. Gibt es auch eine Möglichkeit die Methoden in einer separaten PHP zu überschreiben? Das wäre dann updatesicher und der Code ist sauber getrennt.
    Das Tutorial auf typolight (https://contao.org/methoden-ueberschreiben.html) habe ich bereits gelesen und auch so verwenden können. Allerdings wird mir dabei nicht klar, wie ich damit zum Beispiel eine Methode z.B. der Klasse HelpdeskController in meinem eigenen Modul (CustomHelpdesk) überschreiben kann.
    http://www.ideadapt.net - where ideas become code
  • andreas.schempp
    Contao Core-Team
    Association Vorstand
    • 15.06.2009
    • 5701

    #2
    Du kannst in PHP keine bestehenden Methoden einer Klasse überschreiben. Das können gewisse Programmiersprachen (z.B. Obj-C auf Mac), aber PHP nicht.

    In den meisten Fällen ist das aber auch nicht nötig, weil du den Aufruf dieser Funktion überschreiben kannst. Wenn du z.B. ein Frontend-Modul hast, in dem du etwas ändern willst, dann kannst du ein neues Frontend-Modul machen, welches das besagt erweitert (class ModuleXXX extends ModuleYYY) und dort die Funktion ändern.
    terminal42 gmbh
    Wir sind Contao Premium-Partner! Für Modulwünsche oder Programmierungen kannst du uns gerne kontaktieren.
    Hilfe für Isotope eCommerce kann man auch kaufen: Isotope Circle

    Kommentar

    • bubblez
      Contao-Nutzer
      • 24.11.2009
      • 248

      #3
      Ok danke für eure Antworten. Für mich kommt eigentlich nur die zweite Variante mit dem Überschreiben in Frage.
      Hab dazu die zu überschreibende Methode im existierenden Modul (HelpdeskController->prepareForm) von private auf protected geändert, damit ich diese überschreiben kann. Diese kleine Änderung könnte man als .patch realisieren oder einfach manuell ausführen nach einem Update.
      Dann habe ich einen Ordner system/modules/XCustom angelegt. Darin die Dateien: config/config.php und XHelpdeskController.php. In XHelpdeskController.php möcht ich die Methode wie folgt überschreiben:

      Code:
      class XHelpdeskController extends HelpdeskController {
      	public function prepareForm($mode, &$link, $submitText){
      Die Methode wird aber nie ausgeführt. Muss ich in config.php noch etwas angeben damit die Klasse richtig geladen wird, damit das Überschreiben überhaupt stattfindet?
      http://www.ideadapt.net - where ideas become code

      Kommentar

      • FloB
        Contao-Urgestein
        • 19.06.2009
        • 1618

        #4
        Helpdesk ist da etwas speziell. Wenn du eine alternative Klasse beschreibst, musst du alle aufrufenden Stellen im Code ändern. Somit kommst du nicht drumherum, das ganze kräftig zu überarbeiten. Ab 2.8 kannst du auch einfach die Klasse über die initconfig.php einbinden (mit gleichem Namen wie die zu ersetzende Klasse) – das funktioniert, da noch nicht deklarierte Klassen per Autoloader eingebunden werden (also bereits deklarierte Klassen werden nicht erneut gesucht)*.

        * Es kann sein, dass es trotzdem nicht ganz klappt, z. B. wenn die Datei der HelpdeskController-Klasse explizit eingebunden wird. Dann kommts zu einem Parse Error.
        So long,
        FloB since Nov. 2007 +706P +115P and counting

        Kommentar

        • fonkadelic
          Contao-Nutzer
          • 21.02.2010
          • 3

          #5
          Zitat von FloB Beitrag anzeigen
          Ab 2.8 kannst du auch einfach die Klasse über die initconfig.php einbinden (mit gleichem Namen wie die zu ersetzende Klasse) – das funktioniert, da noch nicht deklarierte Klassen per Autoloader eingebunden werden (also bereits deklarierte Klassen werden nicht erneut gesucht)*.

          * Es kann sein, dass es trotzdem nicht ganz klappt, z. B. wenn die Datei der HelpdeskController-Klasse explizit eingebunden wird. Dann kommts zu einem Parse Error.
          Ist das dann praktisch eine Alternative zu der Methode die im o.g. Tutorial (https://contao.org/methoden-ueberschreiben.html) erklärt wird? Oder gibt es da Unterschiede?

          Viele Grüsse

          Kommentar

          • FloB
            Contao-Urgestein
            • 19.06.2009
            • 1618

            #6
            Nope, da gibt es einen Unterschied.

            Technisch läuft das in etwa bei dem von dir verlinkten Tutorial in etwa so ab: Du vererbst die vorhandene Klasse (diese Klasse hat einen neuen Namen) und änderst eine oder mehrere Methoden ab. Dann überschreibst du die Registrierung der Klasse in TYPOlight, sodass statt der bisherigen Klasse die neue verwendet wird.

            Damit man die Methode per initconfig.php versteht, muss man wissen, dass TL noch nicht definierte Klassen sucht, sobald sie aufgerufen werden (Autoloading). Genau das wird bei dieser Methode ausgenutzt: Es wird eine Kopie der bisherigen Klasse (der Name der Klasse bleibt gleich) angelegt und verändert, und dann explizit über die initconfig.php eingebunden. Somit muss TL gar nicht mehr nach der entsprechenden Klasse suchen, wenn diese aufgerufen wird, da sie schon definiert wurde.
            Das ist keine super saubere Lösung, aber sie funktioniert in den meisten Fällen!
            So long,
            FloB since Nov. 2007 +706P +115P and counting

            Kommentar

            • bubblez
              Contao-Nutzer
              • 24.11.2009
              • 248

              #7
              Zur Methode im Tutorial:
              TYPOlight wird über die Konfiguration mitgeteilt, es soll für eine bestimmte Sache die selbstgeschriebene Klasse laden. Beim Laden der selbstgeschriebenen Klasse wird PHP aber die Eltern Klasse suchen, von der die selbstgeschriebene erbt. Dadurch wird die TYPOlight standart Klasse implizit geladen.

              Mit der initconfig ist es doch eigentlich ganz einfach:
              Man kann in dieser Datei einfach Sachen machen die zur Initialisierungszeit ausgeführt werden müssen. Da wird meines Erachtens nichts kopiert/verändert. Der Punkt ist einfach, dass wenn eine Klasse oder Funktion bereits definiert ist, diese kein zweites mal geladen wird, sondern die bestehende Definition verwendet wird. Somit kann man in initconfig eigene Klassen laden, die sonst von TYPOlight gegeben wären.

              Die __autoload Funktion wird aufgerufen, sobald PHP eine bestimmte Klasse nicht findet und deshalb laden muss. In der TYPOlight Implementation wird der zu ladende Klassenname als PHP-Datei in den system/libraries und den system/modules Unterordnern gesucht. Das ist mitunter ein Grund weshalb die PHP Datei immer auch dem darin definierten Klassennamen entsprechen sollte.

              Stimmt das, denn dann hab ich es jetzt verstanden ?
              Zuletzt geändert von bubblez; 24.02.2010, 14:37.
              http://www.ideadapt.net - where ideas become code

              Kommentar

              • FloB
                Contao-Urgestein
                • 19.06.2009
                • 1618

                #8
                Ja, ist korrekt.

                Allerdings sollte man, wenn man Klassen per initconfig ersetzen möchte, mindestens mit der Originalklasse beim Programmieren beginnen (ergo: kopieren), damit man nicht von irgendwelchen Fehlermeldungen überrascht wird.
                So long,
                FloB since Nov. 2007 +706P +115P and counting

                Kommentar

                Lädt...