Fuer alle die das Thema noch interessiert. Ich (muss) ja kein Code hier veroeffentlichen, aber einen kleinen Hinweis andeuten. Updatesicher koennt ihr eure eigene Validierungen durch Ueberladen oder (in Gambiosprache) Overload der Klasse "CustomerInputValidator" loesen. Will man zum Beispiel auf valide PLZ hin pruefen. Dann koennt ihr das unter PHP: /*** Checks if the entered postcode is valid.** @param string $p_postcode Customer's post code.** @return bool Is valid?*/// TODO: Diesen Witz durch RegEx in einer Overload-Klasse ersetzen// Hinweis: getPostcodeMaxLength() ist auf 10 Zeichen hart codiert in der Klasse "CustomerInputValidatorSettings".// Hinweis: getPostcodeMinLength() ist auf 4 Zeichen hart codiert in der Datenbank hinterlegt.public function validatePostcode($p_postcode){ if (strlen_wrapper(trim((string)$p_postcode)) > $this->settings->getPostcodeMaxLength()) { $this->errorStatus = true; $this->errorMessageCollection->setValue('error_post_code', $this->settings->getInvalidInputErrorMessage()); return false; } if (strlen_wrapper((string)$p_postcode) < $this->settings->getPostcodeMinLength()) { $this->errorStatus = true; $this->errorMessageCollection->setValue('error_post_code', $this->settings->getPostcodeErrorMessage()); return false; } return true;} Dann wuensche ich euch viel Erfolg und gutes gelingen. Fuer Tipps stehe ich euch, wie immer gerne zur Verfuegung! Entschuldigt bitte den Text ohne Umlaute - Habe auf der mobilen Workstation englische Tastatur.
Keine schöne aber auf die schnelle eine Lösung bzgl. Straße und Postleitzahl erstellt, wo auch mein Vorgesetzter nichts sagen dürfte (da kein 1:1 Code) Unter "user_classes/overloads/CustomerRegistrationInputValidatorService/" zum Beispiel eine Datei "CheckoutFormValidation.php" erstellen und mit: PHP: class CheckoutFormValidation extends CheckoutFormValidation_parent{ /** * Checks if the entered data is valid. * * Expects an array with the following keys: * - gender * - firstname * - lastname * - dob (date of birth) * - company * - email_address * - suburb * - email_address_confirm * - postcode * - city * - country * - state (ID or name) * - telephone * - fax * - vat * * @param array $inputArray Customer Input array. * * @return bool Is customer data valid? */ protected function _validateDataByArray(array $inputArray) { $this->validateGender($inputArray['gender']); $this->validateFirstname($inputArray['firstname']); $this->validateLastname($inputArray['lastname']); $this->validateDateOfBirth($inputArray['dob']); $this->validateCompany($inputArray['company']); $this->validateEmailAndConfirmation($inputArray['email_address'], $inputArray['email_address_confirm']); $this->validateSuburb($inputArray['suburb']); /* * RegEx für Straße/Nr. */ if (!preg_match("/^([\wüäö\s*?(\-\.)?]{2,})\s*?(\d)+?\w*?$/i", $inputArray['street_address'])) { $this->errorStatus = true; $this->errorMessageCollection->setValue('error_street', 'Straßeneingabe ist ungültig.'); } /* * RegEx für Postleitzahl * * @country->getId() * 150 = Niederlande * 222 = Großbritannien */ $country = $this->customerCountryRepository->findById(new IdType($inputArray['country'])); if ($country->getId() === 150 && !preg_match("/^([0-9]{4}\s?[a-z]{2})$/i", $inputArray['postcode']) ) { $this->errorStatus = true; $this->errorMessageCollection->setValue('error_post_code', 'Postcode is ongeldig.'); } elseif ($country->getId() === 222 && !preg_match("/^([a-z0-9]{2,4}\s?[a-z0-9]{3})$/i", $inputArray['postcode']) ) { $this->errorStatus = true; $this->errorMessageCollection->setValue('error_post_code', 'Zip code is invalid.'); } if (!preg_match("/^([0-9]{4,10})$/i", $inputArray['postcode'])) { $this->errorStatus = true; $this->errorMessageCollection->setValue('error_post_code', 'Postleitzahl ist ungültig.'); } $this->validateCity($inputArray['city']); $this->validateCountry($inputArray['country']); $this->validateCountryZone($inputArray['state'], $inputArray['country']); $this->validateTelephoneNumber($inputArray['telephone']); $this->validateFaxNumber($inputArray['fax']); return !$this->getErrorStatus(); }} befüllen... Eventuell die Fehlerausgaben durch den Translator jagen Danach die Cache leeren und gut ist. Getestet wurde an einem Gastkonto... von daher vor der Nutzung erst an einem Testshop testen!
Danke, das sieht schon ganz gut aus. Leider Funktioniert die Prüfung der Straße nur dort, wo die Hausnummer HINTER der Straße steht. In Frankreich steht die immer davor. Deshalb habe ich einfach nur geprüft ob eine Zahl im String vorhanden ist, dann ist es egal ob vorne oder hinten. Funktioniert bei "Strasse des 17. Juni" dann natürlich auch ohne Hausnummer, aber so viele Strassennamen mit Zahlen drinn gibt es nicht.
Vielen Dank für den Hinweis wegen Frankreich... Vielleicht könnte man eine Auflistung der EU Länder erstellen, die von unseren bekannten Standard für Adressen abweichen und diese per Reguläre Ausdrücke abfangen. Damit hätten wir schon mal die EU Länder abgedeckt. Weiter hinaus glaube ich verkauft eh niemand seine Waren.
Für die PLZ habe ich diese Liste regulärer Ausdrücke bereits erstellt und in Tabelle countries eingetragen. Da ist dann auch die Art der Adresse definiert. Man sollte aber nicht zu genau prüfen, dann gibt es wieder neue Probleme. Die Autofill-Problematik kann man auch so gut abfangen. Wenn man noch die Länge der PLZ prüft, hilft es falsche Länderangaben auszufiltern. Ein reine Dezimalangabe im Feld Ort sollte auch nicht erlaubt sein.
Ich schaue es mir später mal an, deine SQL-Datei. Du hast schon recht... Man sollte nicht all zu streng sein... Aber die Standards sollten gegeben sein. Zum Beispiel: Tippe so viele Leerzeichen ein, wie du lustig bist, solange du auch z.B eine Zahl eintippst und keine Sonderzeichen.
Stimmt. Man könnte damit auch Zeilenschaltungen und nicht unterstützte Sonderzeichen filtern, die gerne im Feld Strasse eingegeben werden und später, z.B. beim Import in die Warenwirtschaft, Probleme machen.
Hallo Christian, habe mir deine SQL-Datei angeschaut. Die Postleitzahlen hätten wir ja mit der oben gezeigten Lösung schon mal alle EU-Länder abgedeckt. Für Straßen die RegEx für Straßen/Nr. mit diesem ersetzen PHP: /** RegEx für Straße/Nr.*/if (!preg_match("/^(\d+?\w*?\s*?([\wàâæçèéêëîïôœùûÿ\s*?(\-\.)?]{2,})|([\wüäö\s*?(\-\.)?]{2,})\s*?(\d)+?\w*?)$/i", $inputArray['street_address'])) { $this->errorStatus = true; $this->errorMessageCollection->setValue('error_street', 'Straßeneingabe ist ungültig.');} Also PHP: class CheckoutFormValidation extends CheckoutFormValidation_parent{ /** * Checks if the entered data is valid. * * Expects an array with the following keys: * - gender * - firstname * - lastname * - dob (date of birth) * - company * - email_address * - suburb * - email_address_confirm * - postcode * - city * - country * - state (ID or name) * - telephone * - fax * - vat * * @param array $inputArray Customer Input array. * * @return bool Is customer data valid? */ protected function _validateDataByArray(array $inputArray) { $this->validateGender($inputArray['gender']); $this->validateFirstname($inputArray['firstname']); $this->validateLastname($inputArray['lastname']); $this->validateDateOfBirth($inputArray['dob']); $this->validateCompany($inputArray['company']); $this->validateEmailAndConfirmation($inputArray['email_address'], $inputArray['email_address_confirm']); $this->validateSuburb($inputArray['suburb']); /* * RegEx für Straße/Nr. */ if (!preg_match("/^(\d+?\w*?\s*?([\wàâæçèéêëîïôœùûÿ\s*?(\-\.)?]{2,})|([\wüäö\s*?(\-\.)?]{2,})\s*?(\d)+?\w*?)$/i", $inputArray['street_address'])) { $this->errorStatus = true; $this->errorMessageCollection->setValue('error_street', 'Straßeneingabe ist ungültig.'); } /* * RegEx für Niederlande und Großbritannien * * @country * 150 = Niederlande * 222 = Großbritannien */ $country = $this->customerCountryRepository->findById(new IdType($inputArray['country'])); if ($country->getId() === 150 && !preg_match("/^([0-9]{4}\s?[a-z]{2})$/i", $inputArray['postcode']) ) { $this->errorStatus = true; $this->errorMessageCollection->setValue('error_post_code', 'Postcode is ongeldig.'); } elseif ($country->getId() === 222 && !preg_match("/^([a-z0-9]{2,4}\s?[a-z0-9]{3})$/i", $inputArray['postcode']) ) { $this->errorStatus = true; $this->errorMessageCollection->setValue('error_post_code', 'Zip code is invalid.'); } if (!preg_match("/^([0-9]{4,10})$/i", $inputArray['postcode'])) { $this->errorStatus = true; $this->errorMessageCollection->setValue('error_post_code', 'Postleitzahl ist ungültig.'); } $this->validateCity($inputArray['city']); $this->validateCountry($inputArray['country']); $this->validateCountryZone($inputArray['state'], $inputArray['country']); $this->validateTelephoneNumber($inputArray['telephone']); $this->validateFaxNumber($inputArray['fax']); return !$this->getErrorStatus(); }} Weiß nur nicht wie die RegEx mit franz. Zeichen umgeht... Müsste man vorab gucken. Haben wir hier im Forum zufällig einen französischen Experten der alle Sonderzeichen der Franzosen auflisten kann? Und dann haben wir da noch die Spanier, Polen usw. mit ihren Sonderzeichen
Habe mir deine SQL nun genauer angeschaut und da gibt es doch noch die eine oder die andere Abweichung der Postleitzahlen in den EU-Ländern. Zum Beispiel: Polen - Die PLZ besteht auch wie in DE nur aus Ziffern, jedoch kann auch ein Bindestrich vorkommen, usw. Wie aktuell sind diese Angaben in deiner SQL? Kann mir gut vorstellen, dass wir dann unsere Lösung über RegEx von oben in Verbindung zum gewählten Land über eine Datenbankabfrage steuern können. Somit wäre der Quellcode etwas sauberer und leichter lesbar Was die Sonderzeichen in der jeweiligen Sprache betrifft, könnte man evtl. vorerst über eine Konstante PHP: const VALID_CHARACTERS = " "; // Alle möglichen Vorkommen von exotischen Wortzeichen. fest definieren und peu à peu das ganze (aus Performancegründen) nach Land optimieren und diese ebenfalls in der DB ablegen. Die fertige Lösung dann noch zusätzlich über eine Art "Autofill" ergänzen und perfekt ist das Disaster
Da muss ich schon wieder aufzeigen ;-) Guckst Du hier: https://www.hs-hannover.de/fileadmi...h2_online/f2_index/f2_index_sonderzeichen.pdf Der Einfachheit würde ich sagen, alle Zeichen von ASCII 000 bis 032 und von 168 bis 255 sperren oder nur Zeichen von 033 bis 167 erlauben.
Na ja, ich weiß nicht wie der Code reagieren wird, wenn wir auf ASCII-Werte prüfen, aber UTF-8 Code eingeleitet wird und wir wollen ja eine performante Lösung haben Danke für den Wiki-Link... Mit den jeweiligen Links zu den einzelnen Ländern kann man deine Vorlagen zu Postleitzahlen aus der SQL etwas besser tunen
Sorry für die lange Wartezeit.. hatte beruflich viel um die Ohren Auf dieser Grundlage kannst du deine Datenbank ins Spiel bringen. Das Anpassen wegen RegEx und den ASCII-Werten überlasse ich dir. PHP: class CustomizedFormValidation extends CustomizedFormValidation_parent{ protected $settings; protected $loader; protected $db; protected $errorfields = [ 'firstname' => 'first_name', 'lastname' => 'last_name', 'street_address' => 'street', 'postcode' => 'post_code', 'city' => 'city', ]; public function __construct( CustomerServiceInterface $customerServiceInterface, CountryServiceInterface $countryServiceInterface, CustomerInputValidatorSettingsInterface $customerInputValidatorSettingsInterface, CustomerCountryRepositoryInterface $customerCountryRepositoryInterface, CustomerCountryZoneRepositoryInterface $customerCountryZoneRepositoryInterface, VatNumberValidatorInterface $vatNumberValidatorInterface ) { $this->loader = MainFactory::create('GXCoreLoader', MainFactory::create('GXCoreLoaderSettings')); $this->db = $this->loader->getDatabaseQueryBuilder(); parent::__construct( $customerServiceInterface, $countryServiceInterface, $customerInputValidatorSettingsInterface, $customerCountryRepositoryInterface, $customerCountryZoneRepositoryInterface, $vatNumberValidatorInterface ); } protected function _validateDataByArray(array $inputArray) { foreach ($inputArray as $item => $value) { for ($i = 0; $i < strlen($value); $i++) { if (ord($value[$i]) <= 32 || ord($value[$i]) >= 168 && array_key_exists($item, $this->errorfields)) { $this->errorStatus = true; $this->errorMessageCollection->setValue('error_'.$this->errorfields[$item], 'Sonderzeichen sind nicht erlaubt.'); } } } $this->validateGender($inputArray['gender']); $this->validateFirstname($inputArray['firstname']); $this->validateLastname($inputArray['lastname']); $this->validateDateOfBirth($inputArray['dob']); $this->validateCompany($inputArray['company']); $this->validateEmailAndConfirmation($inputArray['email_address'], $inputArray['email_address_confirm']); $this->customValidateStreet($inputArray['street_address'], $inputArray['country']); $this->validateSuburb($inputArray['suburb']); $this->customValidatePostcode($inputArray['postcode'], $inputArray['country']); $this->validateCity($inputArray['city']); $this->validateCountry($inputArray['country']); $this->validateCountryZone($inputArray['state'], $inputArray['country']); $this->validateTelephoneNumber($inputArray['telephone']); $this->validateFaxNumber($inputArray['fax']); return !$this->getErrorStatus(); } private function customValidatePostcode($format, $country) { // Holt sich das Format und ein Beispiel aus der Datenbank $regEx = $this->db->select('zip_format, zip_sample')->from('countries')->where('countries_id', $country)->get()->result_array(); if (!preg_match("/".$regEx[0]['zip_format']."/i", $format)) { $this->errorStatus = true; $this->errorMessageCollection->setValue('error_post_code', '(Format: '.$regEx[0]['zip_sample'].')'); } } private function customValidateStreet($format, $country) { // Holt sich das Format und ein Beispiel aus der Datenbank $regEx = $this->db->select('street_format, street_sample')->from('countries')->where('countries_id', $country)->get()->result_array(); if (!preg_match("/".$regEx[0]['street_format']."/i", $format)) { $this->errorStatus = true; $this->errorMessageCollection->setValue('error_street', '(Format: '.$regEx[0]['street_sample'].')'); } } In "user_classes/overloads/CustomerRegistrationInputValidatorService" Datei erstellen und einfügen.... Ist Updatesicher solange Gambio nichts schwerwiegendes verändert. Viel Spaß damit!
Nachdem es in letzer Zeit häufiger Bestellungen ohne Hausnummer gab, hab ich auch nach einer Lösung gesucht. Die Überprüfung klappt soweit, allerdings nur bei neu angelegten Adressen, allerdings nicht bei Adressänderungen oder abweichender Lieferadresse. Gibt es eine einfache Möglichkeit die Überprüfung auch dort durchzuführen? Außerdem habe ich das Problem, dass die Sonderzeichen nur als Viereck dargestellt werden. Die Datenbank und der Shop sind, aber auf UTF8 eingestellt, wo könnte das Problem liegen?
Habe das jetzt mal getestet (ohne die Sonderzeichen-SQL-Datenbank): Straße "XY-strasse 7/8/93" ist für Österreich damit nicht mehr möglich scheinbar. Ich dachte, der Regex prüft nur ob die Straße sowohl Buchstaben als auch Zahlen enthält? Das ist hier ja der Fall eigentlich... Ich dachte, ich könnte Code: if (!preg_match("/^(\d+?\w*?\s*?([\wàâæçèéêëîïôœùûÿ\s*?(\-\.)?]{2,})|([\wüäö\s*?(\-\.)?]{2,})\s*?(\d)+?\w*?)$/i", $inputArray['street_address'])) { ersetzen durch: Code: if (!preg_match("/([A-Za-z]+(\d+[A-Za-z]*)+|[A-Za-z]*\d+[A-Za-z]+)[A-Za-z0-9]*/", $inputArray['street_address'])) { Da wird aber nicht einmal eine "normale" Adresse ohne Slashes akzeptiert. Kann mir jemand auf die Sprünge helfen? Oder @Christian Mueller kann man auf deine Datenbankerweiterung nicht verzichten?
Die Datenbank enthält Regex für die PLZ-Überprüfung für alle Länder. Nicht für die Straßenüberprüfung. Ich habe die Straßen-Hausnummer-Überprüfung einfacher gestaltet. Code: public function _validateDataByArray(array $inputArray) { /* * Straße/Nr. auf Hausnummer prüfen */ if (reset(array_filter(str_split($inputArray['street_address']), 'ctype_digit')) == '') { $this->errorStatus = true; $this->errorMessageCollection->setValue('error_street', ENTRY_HOUSE_NUMBER_ERROR); }