Add IBAN and BIC validation with custom hooks; update localization messages and cache timestamps
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
<?php
|
||||
|
||||
namespace Espo\Custom\Hooks\CBankverbindungen;
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
use Espo\Core\Exceptions\BadRequest;
|
||||
use Espo\Core\Utils\Language;
|
||||
|
||||
class BankdatenValidation
|
||||
{
|
||||
private $language;
|
||||
|
||||
public function __construct(Language $language)
|
||||
{
|
||||
$this->language = $language;
|
||||
}
|
||||
|
||||
public function beforeSave(Entity $entity, array $options): void
|
||||
{
|
||||
// IBAN-Normalisierung und Validierung
|
||||
$iban = $entity->get('iban');
|
||||
if ($iban !== null && $iban !== '') {
|
||||
// IBAN normalisieren: Leerzeichen entfernen und Großbuchstaben
|
||||
$ibanClean = strtoupper(str_replace(' ', '', $iban));
|
||||
$entity->set('iban', $ibanClean);
|
||||
|
||||
// Mathematische IBAN-Prüfung mit Modulo-97
|
||||
if (!$this->validateIban($ibanClean)) {
|
||||
$message = $this->language->translateLabel('invalidIbanChecksum', 'messages', 'CBankverbindungen');
|
||||
throw new BadRequest($message);
|
||||
}
|
||||
}
|
||||
|
||||
// BIC-Normalisierung und Validierung
|
||||
$bic = $entity->get('bic');
|
||||
if ($bic !== null && $bic !== '') {
|
||||
// BIC normalisieren: Leerzeichen entfernen und Großbuchstaben
|
||||
$bicClean = strtoupper(str_replace(' ', '', $bic));
|
||||
$entity->set('bic', $bicClean);
|
||||
|
||||
// BIC-Format prüfen: 8 oder 11 Zeichen
|
||||
$bicLength = strlen($bicClean);
|
||||
if ($bicLength !== 8 && $bicLength !== 11) {
|
||||
$message = $this->language->translateLabel('invalidBicLength', 'messages', 'CBankverbindungen');
|
||||
throw new BadRequest($message);
|
||||
}
|
||||
|
||||
// BIC-Format prüfen: Regex
|
||||
if (!preg_match('/^[A-Z]{6}[A-Z0-9]{2}([A-Z0-9]{3})?$/', $bicClean)) {
|
||||
$message = $this->language->translateLabel('invalidBicFormat', 'messages', 'CBankverbindungen');
|
||||
throw new BadRequest($message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function validateIban(string $iban): bool
|
||||
{
|
||||
// IBAN-Länge prüfen (mindestens 15 Zeichen)
|
||||
if (strlen($iban) < 15) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// IBAN umstellen: erste 4 Zeichen ans Ende
|
||||
$rearranged = substr($iban, 4) . substr($iban, 0, 4);
|
||||
|
||||
// Buchstaben in Zahlen umwandeln (A=10, B=11, ..., Z=35)
|
||||
$numeric = '';
|
||||
for ($i = 0; $i < strlen($rearranged); $i++) {
|
||||
$char = $rearranged[$i];
|
||||
if (ctype_alpha($char)) {
|
||||
$numeric .= (string)(ord($char) - ord('A') + 10);
|
||||
} else {
|
||||
$numeric .= $char;
|
||||
}
|
||||
}
|
||||
|
||||
// Modulo-97-Prüfung
|
||||
return $this->bcmod($numeric, '97') === '1';
|
||||
}
|
||||
|
||||
private function bcmod(string $number, string $modulus): string
|
||||
{
|
||||
// Für große Zahlen: Modulo in Schritten berechnen
|
||||
$take = 9;
|
||||
$mod = '';
|
||||
|
||||
do {
|
||||
$a = (int)($mod . substr($number, 0, $take));
|
||||
$number = substr($number, $take);
|
||||
$mod = (string)($a % (int)$modulus);
|
||||
} while (strlen($number) > 0);
|
||||
|
||||
return $mod;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user