[Shopware52] Alternative zu ...ValidateStep1_FilterStart und ValidateStep2_FilterStart

Hi Zusammen,

ich habe ein Plugin entwickelt welches innerhalb der Registrierung einige Validierungen vornimmt. Nun funktioniert das ganze in Shopware52 nicht mehr; da ich dazu immer die folgenden EVENT’s genutzt habe:

Shopware_Modules_Admin_ValidateStep1_FilterStart
Shopware_Modules_Admin_ValidateStep2_FilterStart

Was ist die Alternative? Ich habe gesehen, dass es diese EVENT’s (Filter) nicht mehr gibt. Wie kann ich nun eigene Filter schreiben? Hat Jemand einen Tipp für mich? Ich benötige dies für die Registrierung und für die Persönlichen Daten.

Viele Grüße
AvL

Scheinbar ab 5.2 mit dem shopware_account.customer_validator  Wearing-Sunglasses

Morgen gleich mal ausprobieren…Alternativen sind aber herzlich willkommen :wink:

  

 

Hat jemand noch einen Tipp wie ich in der Registrierung zum Beispiel Vorname, Nachname, Strasse, PLZ und Ort nach einen bestimmten Muster validieren kann? Es geht hier dabei um eine maximale Längen Begrenzung. Validator-Service bin ich noch nicht wirklich weit gekommen…

Ich bin mir zwar nicht so sicher, ob das Folgende “Best Practice” ist. Aber es gibt ein Form Event namens “Shopware_Form_Builder”. Hier hast du Zugriff auf den Form Builder und kannst neue Constraints hinzufügen.

Die Event-Listener Methode könnte in etwa so ausehen:

subscribeEvent(
    'Shopware_Form_Builder',
    'onPreSetData'
);
/* ... */
public function onPreSetData(Enlight_Event_EventArgs $arguments) 
{
    $reference = $arguments->getReference();
    $builder = $arguments->getBuilder();
    
    // prüfen, ob es sich um das Adress-Formular handelt
    if ($reference != "Shopware\Bundle\AccountBundle\Form\Account\AddressFormType")
        return;
    
    // neue Constraint für die PLZ
    $builder->add('zipcode', TextType::class, [
        'constraints' => [/* hier Constrains einfügen */])]
    ]);
}
/* ... */

Der Code ist nicht getestet! Weitere Infos zum Symfony Form Component gibts in der der Dokumentation http://symfony.com/doc/current/components/form.html#form-validation
( dort steht auch wie man mit Constraints umgeht)

Viele Grüße

edit:  Ugh. Nachdem ich ein paar Kommentare hinzugefügt hat, hat der Editor alle > durch > ersetzt   . Also einfach statt “>” ein “>” denken. 

1 „Gefällt mir“

HI Simkli,

so ähnlich habe ich es heute ausprobiert. So wie hier:

Address Management Guide

Ist zwar nicht das gleiche; aber ich probiere Deinen Ansatz gleich mal aus :wink: Ich hatte immer das Problem, dass zwar eine Fehlermeldung angezeigt wird; das Feld Vorname aber nicht rot markiert wird. Ich gebe gleich nochmal Feedback…

Danke :wink:

Hi Simkli,

sauber…Dann habe ich heute echt etwas auf den Augen gehabt. Das hilft mir nun aber mal richtig weiter. Danke Dir  Thumb-Up

Sieht bei mir nun so aus:

 

public function onFormBuild(\Enlight_Event_EventArgs $event) {

    if ($event->getReference() !== \Shopware\Bundle\AccountBundle\Form\Account\PersonalFormType::class) {
        return;
    }

    $builder = $event->getBuilder();

    $builder->add('firstname', \Symfony\Component\Form\Extension\Core\Type\TextType::class, [
        'constraints' => [
            new \Symfony\Component\Validator\Constraints\Length(['max'=>5])
        ]
    ]);
}

Nur beim Geburtstag habe ich noch ein Problem. Aber dafür brauche ich ein eigenes Constraint (Die sind mir aus täglicher Arbeit bekannt)

Viele Grüße und nochmals Danke!
 

 

Anbei nochmal Feedback. Bei der Registrierung funktioniert die Sache sehr gut; meine Fehlermeldungen werden angezeigt. Bei den Funktionen Liefer/Rechnungsadresse kommt zwar eine Fehlermeldung und das Feld wird auch rot angezeigt; aber mein Fehlermeldungstext erscheint nicht. Hast Du hier evtl. auch eine Lösung?

@AvL schrieb:

https://developers.shopware.com/developers-guide/address-management-guide/

Oh man die Seite habe ich übersehen  Gasp.

 Bei den Funktionen Liefer/Rechnungsadresse kommt zwar eine Fehlermeldung und das Feld wird auch rot angezeigt; aber mein Fehlermeldungstext erscheint nicht.

Zeig doch mal deinen Code. Dann können wir dir da evtl. konkret weiterhelfen.
 

Was mir auffällt ist, dass Shopware die Fehlermeldungen beim Editieren einer Adresse anders handhabt als bei der Registrierung:

Register-Controller:

getErrors(true) as $error) {
            $errors[$error->getOrigin()->getName()] = $this->View()->fetch('string:' . $error->getMessage());
        }
/* ... */

Address-Controller

getErrors(true) as $error) {
    $errorFlags[$error->getOrigin()->getName()] = true;
    if ($error->getMessage()) {
        $errorMessages[] = $error->getMessage();
    }
}
$errorMessages = array_unique($errorMessages);
/* ... */

Beim Register-Controller wird die Fehlermeldung sogar noch durch die Smarty-Engine geschleust. Beim Address-Controller werden die Fehlermeldung nicht mehr direkt dem Feld zugeordnet und global für das Formular gesammelt (gleiche Fehlermeldungen werden zusammengefasst array_unique) . ¯_(ツ)_/¯

Hier mal mein komplett abgespeckter Code…Zum testen tuhe ich einfach so als müsste der Vorname eine E-Mailadresse sein.

 

registerEvents();
        return true;
    }

    private function registerEvents() {
        $this->subscribeEvent('Shopware_Form_Builder', 'onFormBuild');
        return true;
    }


    public function onFormBuild(\Enlight_Event_EventArgs $event) {

        if ($event->getReference() !== \Shopware\Bundle\AccountBundle\Form\Account\AddressFormType::class) {
            return;
        }

        $builder = $event->getBuilder();

        $builder->add('firstname', Symfony\Component\Form\Extension\Core\Type\TextType::class, [
            'constraints' => [
                new \Symfony\Component\Validator\Constraints\Email(['message' => 'bla'])
            ]
        ]);
    }
}

Hätte nicht gedacht, dass es in Shopware52 soviele Änderungen bzgl. der Validierung gibt. Wäre natürlich toll, wenn die Fehlermeldungen überall durchgeschleust würden. Entweder ist es ein Denkfehler seitens Shopware52 oder ich habe einen Denkfehler :wink:

Grüße

Stand der Dinge ist nun, dass ich mir die Fehlermeldung auch im Account/AdressEdit ausgeben lassen kann…

Code etwas erweitert; allerdings bin ich mir noch nicht 100% sicher, ob das nun so alles schön richtig ist…Vlt meldet sich ja noch ein Entwickler von Shopware. Die haben sich ja sicherlich etwas dabei gedacht 

 

registerEvents();
        return true;
    }

    private function registerEvents() {
        $this->subscribeEvent('Shopware_Form_Builder', 'onFormBuild');
        $this->subscribeEvent('Enlight_Controller_Action_PostDispatch_Frontend_Address', 'onAdressEdit');
        return true;
    }

    public function onAdressEdit(Enlight_Event_EventArgs $arguments) {

        $controller = $arguments->getSubject();
        $request = $arguments->getRequest();
        $view = $controller->View();

        $userId = Shopware()->Session()->get('sUserId');
        $addressId = $request->getParam('id', null);

        if ($request->getControllerName() == 'address' && $request->getActionName() == 'edit' && $request->isPost()) {

            $addressRepository = $this->get('models')->getRepository(Address::class);
            $address = $addressRepository->getOneByUser(
                $addressId,
                $userId
            );

            $form = $this->get('shopware.form.factory')->create(AddressFormType::class, $address);
            $form->handleRequest($request);

            $view->assign(
                $this->getFormViewData($form)
            );
        }
    }

    private function getFormViewData(FormInterface $form, $view)
    {
        $errorFlags = [];
        $errorMessages = [];
        $viewData = [];

        $errorMessages[] =
            $this
                ->get('snippets')
                ->getNamespace('frontend/account/internalMessages')
                ->get('ErrorFillIn', 'Please fill in all red fields');

        foreach ($form->getErrors(true) as $error) {

            $errorFlags[
                $error->getOrigin()->getName()
            ] = true;

            $errorMessages[] = $error->getMessage();
        }

        $errorMessages = array_unique($errorMessages);

        $viewData['error_flags'] = $errorFlags;
        $viewData['error_messages'] = $errorMessages;

        return $viewData;
    }


    public function onFormBuild(\Enlight_Event_EventArgs $event) {

        if ($event->getReference() !== \Shopware\Bundle\AccountBundle\Form\Account\AddressFormType::class) {
            return;
        }

        $builder = $event->getBuilder();

        $builder->add('firstname', Symfony\Component\Form\Extension\Core\Type\TextType::class, [
            'constraints' => [
                new \Symfony\Component\Validator\Constraints\Email(['message' => 'Ihr Vorname muss eine E-Mailadresse sein'])
            ]
        ]);
    }
}

 

Habe jetzt noch folgendes Problem wenn ich die Session auslaufen lassen:

 

The provided X-CSRF-Token is invalid. Please go back, reload the page and try again. in engine/Shopware/Components/CSRFTokenValidator.php on line 161

Wenn ich nun das Plugin deaktiviere, oder den Cache lösche usw. tritt weiterhin dieser Fehler auf. (Cache leeren unter var/cache nutzt auch nichts) Das kann es ja eigentlich nicht sein. Lösche ich das Plugin über den Plugin-Manager erscheint die Fehlermeldung weiterhin. Erst wenn ich das Plugin komplett vom Server lösche erscheint diese Fehlermeldung nicht mehr. Was mache ich falsch, oder wie kann man das beheben oder handelt es sich hierbei um einen Bug in SW52? Nachtrag: ich werde heute Abend mal folgende Anleitung ausprobieren: CSRF Protection

Dann gibt es noch ein Problem in dem “Bare/frontend/account/profile.tpl”
 

{* Error messages *}
                                {block name="frontend_account_profile_profile_errors"}
                                    {if $section == 'profile' && $errorMessages}
                                        {include file="frontend/register/error_message.tpl" error_messages=["{s name="ErrorFillIn" namespace="frontend/account/internalMessages"}{/s}"]}
                                    {/if}
                                {/block}

Ich kann die Error-Messages nicht überschreiben. 

@shopware‍ könnte man dies bitte in einem nächsten Update in dem Standard-Template korrigieren? Wenn ich die Profildaten mit eigenen Methoden validieren möchte und Fehlerausgeben möchte, behindert mich dieser Block. Es ist ja nicht im Sinne der Plugin-Entwickler, dass die nun einen extra Block in Ihrem Template hinterlegen; nur weil SW das nicht durchgehend gleich hält. Wäre schön, wenn man in diesem Template auch eigene Fehlermeldungen ausgeben könnte.

Grüße
AvL

Kann es sein, dass der CSRF-Fehler nur dann Zustande kommt, sobald man sich im gleichen Browser im Admin-Bereich bewegt und später die Session des Kunden ausläuft (Also ich bin ja im gleichen Browser 1 x als Admin eingeloggt und 1 x als Kunde)?

The provided X-CSRF-Token is invalid. Please go back, reload the page and try again. in engine/Shopware/Components/CSRFTokenValidator.php on line 161

Stack trace:

#0 [internal function]: Shopware\Components\CSRFTokenValidator->checkFrontendTokenValidation(Object(Enlight_Controller_ActionEventArgs))
#1 engine/Library/Enlight/Event/Handler/Default.php(91): call_user_func(Array, Object(Enlight_Controller_ActionEventArgs))
#2 engine/Library/Enlight/Event/EventManager.php(214): Enlight_Event_Handler_Default->execute(Object(Enlight_Controller_ActionEventArgs))
#3 engine/Library/Enlight/Controller/Action.php(143): Enlight_Event_EventManager->notify('Enlight_Control...', Object(Enlight_Controller_ActionEventArgs))
#4 engine/Library/Enlight/Controller/Dispatcher/Default.php(523): Enlight_Controller_Action->dispatch('saveProfileActi...')
#5 engine/Library/Enlight/Controller/Front.php(226): Enlight_Controller_Dispatcher_Default->dispatch(Object(Enlight_Controller_Request_RequestHttp), Object(Enlight_Controller_Response_ResponseHttp))
#6 engine/Shopware/Kernel.php(176): Enlight_Controller_Front->dispatch()
#7 vendor/symfony/http-kernel/HttpCache/HttpCache.php(487): Shopware\Kernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#8 engine/Shopware/Components/HttpCache/AppCache.php(255): Symfony\Component\HttpKernel\HttpCache\HttpCache->forward(Object(Symfony\Component\HttpFoundation\Request), true, NULL)
#9 vendor/symfony/http-kernel/HttpCache/HttpCache.php(258): Shopware\Components\HttpCache\AppCache->forward(Object(Symfony\Component\HttpFoundation\Request), true)
#10 vendor/symfony/http-kernel/HttpCache/HttpCache.php(275): Symfony\Component\HttpKernel\HttpCache\HttpCache->pass(Object(Symfony\Component\HttpFoundation\Request), true)
#11 engine/Shopware/Components/HttpCache/AppCache.php(133): Symfony\Component\HttpKernel\HttpCache\HttpCache->invalidate(Object(Symfony\Component\HttpFoundation\Request), true)
#12 vendor/symfony/http-kernel/HttpCache/HttpCache.php(206): Shopware\Components\HttpCache\AppCache->invalidate(Object(Symfony\Component\HttpFoundation\Request), true)
#13 engine/Shopware/Components/HttpCache/AppCache.php(114): Symfony\Component\HttpKernel\HttpCache\HttpCache->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#14 shopware.php(101): Shopware\Components\HttpCache\AppCache->handle(Object(Symfony\Component\HttpFoundation\Request))
#15 {main}

Grüße
AvL

Ich habe anhand der Anleitung für das Address Management (https://developers.shopware.com/developers-guide/address-management-guide/) neue Felder als Attributfelder hinzugefügt. Da dieses Pflichtfelder sein sollen, habe ich entsprechend über das Event Shopware_Form_Builder die Validierungen hinzugefügt.

Dies führt nun jedoch dazu, dass das Adressformular im Backend nicht mehr speicherbar ist. Hat jemand auch bereits mit diesem Problem zu kämpfen gehabt?

Folgende Fehlermeldung ist dann zu sehen:

Validierung Fehler
bpaEmailGeneral:
bpaPhoneGeneral:

Alle Versuche, dies zu umgehen, scheiterten bislang. Hat hier jemand eine Idee?

 

Viele Grüße,
Alexander

Hallo zusammen,

dieser Beitrag hat mir bei meiner Adressprüfung sehr weitergeholfen.

Nun habe ich jedoch das Problem, dass die Felder nicht Rot markiert werden. Die Fehlermeldung aus der Variable $name wird ausgegeben sowie der Text „Bitte füllen Sie alle rot markierten Felder aus“.

Habe ich hier etwas vergessen zu setzen?

$name = Shopware()->Snippets()->getNamespace('frontend')->get('CustomerFieldValidationName',
                'Der Vorname darf max. 29 Zeichen lang sein.', true);

if ($args->getReference() == \Shopware\Bundle\AccountBundle\Form\Account\AddressFormType::class) {
            $builder = $args->getBuilder();

            $builder->add('name', \Symfony\Component\Form\Extension\Core\Type\TextType::class, [
                'constraints' => [
                    new \Symfony\Component\Validator\Constraints\Length(['max'=>29,
                        'maxMessage' => $name]),
                ]
            ]);
}

 

Viele Grüße

Michael