mirror of
https://github.com/Icinga/icingaweb2-module-director.git
synced 2025-07-31 01:34:12 +02:00
MySQL gives useless error messages for invalid UTF8 characters and confuses users with an 'Invalid datetime format' message. Once storing imported data fails, the original data will now be scanned for invalid UTF-8 characters. If such are found, a dedicated exception with more details is thrown. Otherwise the original exception will be forwarded fixes #2143
60 lines
1.6 KiB
PHP
60 lines
1.6 KiB
PHP
<?php
|
|
|
|
namespace Icinga\Module\Director\Data;
|
|
|
|
use InvalidArgumentException;
|
|
use ipl\Html\Error;
|
|
|
|
class RecursiveUtf8Validator
|
|
{
|
|
protected static $rowNum;
|
|
|
|
protected static $column;
|
|
|
|
/**
|
|
* @param array $rows Usually array of stdClass
|
|
* @return bool
|
|
*/
|
|
public static function validateRows($rows)
|
|
{
|
|
foreach ($rows as self::$rowNum => $row) {
|
|
foreach ($row as self::$column => $value) {
|
|
static::assertUtf8($value);
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
protected static function assertUtf8($value)
|
|
{
|
|
if (\is_string($value)) {
|
|
static::assertUtf8String($value);
|
|
} elseif (\is_array($value) || $value instanceof \stdClass) {
|
|
foreach ((array) $value as $k => $v) {
|
|
static::assertUtf8($k);
|
|
static::assertUtf8($v);
|
|
}
|
|
} elseif ($value !== null && !\is_scalar($value)) {
|
|
throw new InvalidArgumentException("Cannot validate " . Error::getPhpTypeName($value));
|
|
}
|
|
}
|
|
|
|
protected static function assertUtf8String($string)
|
|
{
|
|
if (@\iconv('UTF-8', 'UTF-8', $string) != $string) {
|
|
$row = self::$rowNum;
|
|
if (is_int($row)) {
|
|
$row++;
|
|
}
|
|
throw new InvalidArgumentException(\sprintf(
|
|
'Invalid UTF-8 on row %s, column %s: "%s" (%s)',
|
|
$row,
|
|
self::$column,
|
|
\iconv('UTF-8', 'UTF-8//IGNORE', $string),
|
|
'0x' . \bin2hex($string)
|
|
));
|
|
}
|
|
}
|
|
}
|