38 oeffentliche Firmen tragen eine URL im Namen ("Firma - https://..."),
laufend ueber die API. Nicht ablehnen (traefe die Meldung), sondern
normalisieren: URL raus, Rest bleibt Name, URL ins leere Website-Feld;
besteht der Name nur aus der URL, wird der Host zum Namen. Am API-Eingang
vor der Zuordnung; im Bestand per companies:strip-links-from-names mit
Dry-Run, Slugs bleiben.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
80 lines
2.6 KiB
PHP
80 lines
2.6 KiB
PHP
<?php
|
|
|
|
namespace App\Services\Company;
|
|
|
|
use Illuminate\Support\Str;
|
|
|
|
/**
|
|
* Zieht Links aus einem Firmennamen (17.09.2026).
|
|
*
|
|
* Über die API kommen Namen wie „Steinreinigung - https://www.bgn.at/…"
|
|
* oder nur „www.beispiel.de" — SEO-Gewohnheit der Einlieferer, auf der
|
|
* Newsroom-Seite aber ein Link im Namen. Ablehnen träfe die Meldung des
|
|
* Einlieferers, deshalb normalisieren: URL raus, Rest bleibt Name, die
|
|
* URL wandert ins Website-Feld, falls das leer ist. Bleibt vom Namen nichts
|
|
* übrig, wird der Host der URL zum Namen („ak-autos.de") — eine nackte
|
|
* Domain ist Marke, kein Link.
|
|
*/
|
|
class CompanyNameNormalizer
|
|
{
|
|
private const URL_PATTERN = '~(?:https?://|www\.)[^\s,;|()<>"\']+|\b[a-z0-9-]+(?:\.[a-z0-9-]+)*\.[a-z]{2,}/[^\s,;|()<>"\']*~iu';
|
|
|
|
/**
|
|
* @return array{name: string, website: ?string, removed: list<string>}
|
|
*/
|
|
public static function normalize(string $name, ?string $website = null): array
|
|
{
|
|
$removed = [];
|
|
$stripped = (string) preg_replace_callback(self::URL_PATTERN, static function (array $match) use (&$removed): string {
|
|
$removed[] = rtrim($match[0], '.,:;');
|
|
|
|
return ' ';
|
|
}, $name);
|
|
|
|
$clean = self::tidy($stripped);
|
|
|
|
if ($clean === '' && $removed !== []) {
|
|
$clean = self::host($removed[0]) ?? Str::squish($name);
|
|
}
|
|
|
|
if (blank($website) && $removed !== []) {
|
|
$website = $removed[0];
|
|
}
|
|
|
|
return [
|
|
'name' => $clean !== '' ? $clean : Str::squish($name),
|
|
'website' => filled($website) ? trim((string) $website) : null,
|
|
'removed' => $removed,
|
|
];
|
|
}
|
|
|
|
public static function containsUrl(string $name): bool
|
|
{
|
|
return preg_match(self::URL_PATTERN, $name) === 1;
|
|
}
|
|
|
|
/**
|
|
* Verwaiste Trenner nach dem Herausziehen der URL aufräumen:
|
|
* „Firma - “, „ - Firma", „Firma ( )", „Firma /".
|
|
*/
|
|
private static function tidy(string $value): string
|
|
{
|
|
$value = (string) preg_replace('~\(\s*\)|\[\s*\]~u', ' ', $value);
|
|
$value = Str::squish($value);
|
|
$value = (string) preg_replace('~(?:\s*[-–—|/,:]+\s*){2,}~u', ' - ', $value);
|
|
|
|
return trim($value, " \t\n\r\0\x0B-–—|/,:");
|
|
}
|
|
|
|
private static function host(string $url): ?string
|
|
{
|
|
$candidate = Str::startsWith(mb_strtolower($url), ['http://', 'https://']) ? $url : 'https://'.$url;
|
|
$host = parse_url($candidate, PHP_URL_HOST);
|
|
|
|
if (! is_string($host) || $host === '') {
|
|
return null;
|
|
}
|
|
|
|
return (string) preg_replace('~^www\.~i', '', mb_strtolower($host));
|
|
}
|
|
}
|