Files

40 lines
1.3 KiB
PHP

<?php
declare(strict_types=1);
namespace MonetaPhpShop\receipt;
/**
* Òåêñòîâûå ïîëÿ ÷åêà (íàçâàíèÿ ïîçèöèé, ÔÈÎ), ñòðîêè â UTF-8: «çíà÷åíèÿ íå äîëæíû ñîäåðæàòü
* êàâû÷åê, çíàêîâ &, $, #, îáðàòíûõ è ïðÿìûõ ñëýøåé» (`cmsspecification.pdf`); êîíòðàêò ìîäóëåé
* äîáàâëÿåò `%` è `;`. Îñòàâëÿåì áåëûé ñïèñîê: áóêâû, öèôðû, ïðîáåë è `.,()_¹+-`.
*
* Òîëüêî ASCII â øàáëîíàõ (`¹` — `\x{2116}`): ïîñëå ñáîðêè ôàéë â cp1251, à øàáëîí ñ `/u`
* îáÿçàí áûòü UTF-8. Áåç `mbstring` — ÿäðî PHPShop åãî íå òðåáóåò.
*/
final class ReceiptText
{
private const ELLIPSIS = '...';
private function __construct() {}
public static function clean(string $value, int $maxLength): string
{
$value = self::sanitize($value);
if ((int) preg_match_all('/./su', $value) <= $maxLength) {
return $value;
}
preg_match('/\A.{0,' . ($maxLength - strlen(self::ELLIPSIS)) . '}/su', $value, $matches);
return rtrim($matches[0] ?? '') . self::ELLIPSIS;
}
private static function sanitize(string $value): string
{
$decoded = html_entity_decode(strip_tags($value), ENT_QUOTES | ENT_HTML5, 'UTF-8');
$allowed = preg_replace('/[^\p{L}\p{N}\s.,()_\x{2116}+\-]/u', ' ', $decoded) ?? '';
return trim(preg_replace('/\s+/u', ' ', $allowed) ?? '');
}
}