Wo versteckt sich die Funktion registeruser()?

Hallo zusammen,

um den subscription-Status neben der OxidDB in einer weiteren Datenbank abzulegen, möchte ich u.a. die Funktion überladen, welche beim Registrieren eines neuen Users aufgerufen wird.

Ein Blick in den Block /source/Application/views/flow/tpl/page/form/register.tpl verrät:

<input type="hidden" name="fnc" value="registeruser">
<input type="hidden" name="cl" value="register">

Also muss die Funktion RegisterController::registeruser() von meinem Controller (den ich ebenfalls register nenne, um den Block nicht verändern zu müssen) überschrieben werden. Blöd nur, dass sich in der PHP-Datei zum RegisterController keine solche Funktion finden lässt.

Laut diesem Thread (die Person wollte damals genau das gleiche machen wie ich jetzt), war/ist die Funktion mal in der oxcmp_user.php zu finden. Aber auch da Fehlanzeige. Schlimmer noch: Habe mit Notepad++ sämtliche Files durchsucht und nirgends eine derartige Funktion entdeckt…?! Das kann sich Oxid doch nicht aus den Fingern saugen? Ändere ich der einfachheit halber dennoch den cl-value im Block, weigert sich Oxid sogar, die Funktion in meinem Controller zu nutzen.

Was übersehe ich nur?

// Edit: Verwendete Shopversion: 6.3

Ich habe in Visual Studio Code geschribe registeruser, und diese Function befinde sich in Application > views > dein oxid shop > tpl > form auf der Datei register.tpl.

ich kenne nicht viele über code, aber ich werde dir empfiehlt habe eine Ähnliche code editor, mit den sparen zeit…

Ab v6 gibts neben dem “source” Ordner auch noch den “vendor” Ordner rmit weiteren Dateien, bei den nachfolgenden Versionen gibts mehr und mehr Shopdateien nur noch in dem vendor Ordner und nicht mehr in soruce.

Bei mir in einer v6.1 ist diese Funktion z.b. in source/Application/Component/UserComponent.php

Danke für deine Antwort.
Das ist leider nur der oben beschriebene Aufruf der Funktion. Bin aber auf der Suche nach der Definition.

In sucht machine schreibe oxid function RegisterController und bekommt dieses Link.

Danke, habe sie auch in der 6.3 dort gefunden. Komisch, das meine Suche da nicht angeschlagen hat, hatte eigentlich ab Root gesucht. Wie auch immer, vielen Dank!

Was mich dennoch verwundert, ist, dass laut der register.tpl die Funktion registeruser() in dem Controller register, also der Datei RegisterController.php aufgerufen wird (&cl=register). In dieser müsste es also mindestens einen Verweis auf die UserComponent.php geben… :face_with_raised_eyebrow:

Das heißt ja, ich muss dann alternativ die Klasse UserComponent extenden statt den RegisterController

Die UserComponente ist überall verfügbar.

Kommt drauf an, was Du machen möchtest.

Die UserComponente ist überall verfügbar.

Okay, verstehe. Wozu ist denn dann die Angabe cl=register in dem Block, wenn die Funktion registeruser() sich gar nicht darin befindet?



Kommt drauf an, was Du machen möchtest.

Die Funktion überschreiben (bzw in PHP nennt sich das ja auch überladen, soweit ich weiß), die einen neuen User registriert, weil ich parallel zum Eintrag in der Shopdatenbank den User noch in einer anderen Datenbank eintragen muss. Gemäß den hidden fields des Registrier-Buttons (/form/register.tpl) handelt es sich dabei um RegisterController::registerUser().

Schau Dir einfach die render-Methode im RegisterController an. Hier spielt die Musik bei der Registrierung und bei einer Fehler oder Erfolgsmeldung.

1 Like

Danke für den Hinweis. Stehe aber wohl gerade auf dem Schlauch. In der RegisterController::render() wird ja nur gecheckt, welcher Block nach dem Registrierungsversuch angezeigt werden soll (success/confirm/register). Aber finde nirgends eine Verbindung zur Funktion registeruser(), die ja aber offensichtlich dennoch irgendwie, irgendwann, irgendwo aufgerufen werden muss.

Wir bleiben auf register, weil es nur hier die Anzeigen zur Bestätigung gibt.

1 Like

Achsoo, okay. Ergo muss ich einfach die UserComponent extenden und die Funktion registeruser() überschreiben, meine Zusätze einfügen und die parent::registeruser() aufrufen.
Also habe ich hier keinen Controller mehr sondern eine Component und muss meine Überladung in die extends-Liste der metadata-Eintragen.
Uff okay, die Logik ist echt speziell. Dann versuche ich das mal

So, hier die jüngste Implementation:

metadata.php (relevanter Ausschnitt)

//$sMetadataVersion = '2.0';

'extend'       => array(
  \OxidEsales\Eshop\Application\Component\UserComponent::class
      => \kcs\kcs_sendysync\Component\SendySyncUserComponent::class
),

'controllers'  => array(
    'sendysyncmain' => \kcs\kcs_sendysync\Controller\MainController::class
),



SendySyncUserComponent.php

<?php
namespace kcs\kcs_sendysync\Component;

/**
 * Class UserComponent
 * @package kcs\kcs_sendysync\Controller
 *
 * Überladet die Funktion für die Registrierung im Shop und integriert dabei die Eintragung in die Sendy-Datenbank.
 *
 */
class SendySyncUserComponent extends SendySyncUserComponent_parent
  {
  /** @Override
   * Ruft createUser() auf, welche die Registrierung validiert und den User ggf (seitens Oxid) anlegt.
   * Anschließend wird der User zusätzlich in die Sendy-Datenbank eingetragen (Sync-Funktion)
   * Abschließend wird noch das Ergebnis des Registrierungsvorgangs aus den Classmembers ausgelesen, damit das aufrufende Template
   * das korrekte Untertemplate (register/confirm/success) laden kann.
   *
   * @return string partial parameter string or null
   */
  public function registerUser()
    {
    // Zu Testzwecken.
    echo "<h1>Foo</h1>";

    // User in Oxid-Datenbank registrieren (createUser() validiert Eingaben und legt User an)
    if ($this->createUser() != false && $this->_blIsNewUser)
      {
      // Die Ergebnisse vom Registrierungsversuch in die Classmembers eintragen, damit der register-Block den korrekten Ergebnisblock laden kann
      if ($this->_blNewsSubscriptionStatus === null || $this->_blNewsSubscriptionStatus)
        { return 'register?success=1'; }
      else
        { return 'register?success=1&newslettererror=4'; }
      }
    else
      {
      // Wenn Registrierung fehlgeschlägt Session beenden
      $this->logout();
      }
    }
  }

}



Aufgerufen werden soll sie nach wie vor durch den folgenden HTTP-Reqest in der register.tpl:

<input type="hidden" name="fnc" value="registeruser">
<input type="hidden" name="cl" value="register">

Leider wird nach wie vor die ursprüngliche UserComponent::registeruser() verwendet, anstatt meiner SendySyncUserComponent::registeruser().
Kann den Fehler nicht ausfindig machen. Falls es einem pfiffigen Mitleser ins Auge springt, gerne raus mit der Sprache :slight_smile:
Aber eigentlich ist fast alles genauso wie an dem Klarna-Modul, an dem ich mich orientiert habe…

// Edit:
Ich vermute inzwischen “nur” ein Namespace-Problem, da mir PHPStorm folgendes in der metadata.php mit “undefined class” markiert, was aber im Klarna-Modul exakt so gemacht wird:

'extend' => array(
  UserComponent::class => SendySyncUserComponent::class
  ),

hast du in der composer.json hinterlegt, auf welchen Pfad dein namespace aufgelöst werden soll?

Guten Morgen,

Meinst du im “autoload”-Abschnitt? Ja. Ich gehe davon aus, das die composer.json soweit korrekt ist, da meine andere Klasse (ein Controller) funktioniert und das ja auch nur der gewöhnliche Aufbau wie sonst auch ist. Vorsichtshalber hier aber mein JSON-File, evtl. fällt dir ja etwas auf. Konnte dieses neue Problem nämlich leider immer noch nicht ausfindig machen.

{
  "name": "kcs/kcs_sendysync",
  "type": "oxideshop-module",
  "minimum-stability": "dev",
  "version": "1.0.4",
  "extra": {
    "oxideshop": {
      "target-directory": "kcs/kcs_sendysync"
    }
  },
  "require": {
    "php": ">=5.6"
  },
  "autoload": {
    "psr-4": {
      "kcs\\kcs_sendysync\\": "../../../source/modules/kcs/kcs_sendysync"
    }
  }
}

Heureka. Habe immerhin einen Workaround gefunden!

Nun wird meine überladene Version SendySyncUserComponent::registeruser() aufgerufen anstelle der UserComponent::registeruser().

Und zwar hat ein Eintrag für die Vererbung via xy_parent gefehlt.

__
Folgenden Eintrag habe ich in die /.phpstorm.meta.php/oxid.meta.php hinzugefügt, um das Problem zu umgehen:

    namespace kcs\kcs_sendysync\Component {
    class SendySyncUserComponent_parent extends \OxidEsales\Eshop\Application\Component\UserComponent
    {

    }
}




So wie ich das sehe, erzeugt dieser Eintrag einen Verweis auf die tatsächliche Parent-Klasse, wodurch das extenden per “xy_parent” überhaupt erst möglich wird. Ergo sollte dieser Eintrag höchstwahrscheinlich eigentlich automatisch von Oxid erzeugt werden.
→ Warum das in diesem Fall nicht geschehen ist? Keine Ahnung! Aber vorerst kann ich damit arbeiten, bis ich die Ursache für dieses Verhalten identifiziert habe.

Fun Fact am Rande:
Eigentlich hätte das ganze dann ja problemlos funktionieren müssen, wenn ich in meiner SendySyncUserComponent als Parent anstatt…

SendySyncUserComponent_parent

einfach direkt…
\OxidEsales\Eshop\Application\Component\UserComponent

angebe.
→ Während der Problemsuche habe ich u.a. genau das versucht, was jedoch auch nicht dazu geführt hatte, dass die überladene Funktion verwendet wird. Ziemlich unlogisch irgendwie. Nunja, da Computer für gewöhnlich nicht unlogisch agieren, scheint als wäre irgendwas ziemlich kaputt in meinem Developmemnt-Shopsystem. Werde das Ganze mal noch frisch aufsetzen und prüfen, ob der Eintrag in der oxid.meta.php dann automatisch generiert wird.

Nochmals vielen Dank an alle Mithelfer.
Wer noch Ideen hat, was hier schief läuft/lief, ist natürlich weiterhin herzlich dazu eingeladen, weitere Antworten zu posten.