192 lines
5.8 KiB
PHP
192 lines
5.8 KiB
PHP
|
|
<?php
|
||
|
|
|
||
|
|
declare(strict_types=1);
|
||
|
|
|
||
|
|
namespace App\Lib\Helpers;
|
||
|
|
|
||
|
|
use App\Exceptions\Helpers\UnsupportedStructureConversionException;
|
||
|
|
use Illuminate\Support\Facades\File;
|
||
|
|
use Illuminate\Support\Facades\Storage;
|
||
|
|
|
||
|
|
abstract class ToolboxHelperCore
|
||
|
|
{
|
||
|
|
/**
|
||
|
|
* Multibyte-safe str_replace with unified dispatch.
|
||
|
|
*
|
||
|
|
* Returns false when $replace is an array but $search is a scalar string.
|
||
|
|
*
|
||
|
|
* @param array<string>|string $search
|
||
|
|
* @param array<string>|string $replace
|
||
|
|
* @param array<int|string, mixed>|string $subject
|
||
|
|
* @return array<int|string, mixed>|string|false
|
||
|
|
*/
|
||
|
|
public static function mbReplace(
|
||
|
|
array | string $search,
|
||
|
|
array | string $replace,
|
||
|
|
array | string $subject,
|
||
|
|
int &$count = 0,
|
||
|
|
): array | string | false {
|
||
|
|
if (is_array($subject)) {
|
||
|
|
return self::mbReplaceInArraySubject($search, $replace, $subject, $count);
|
||
|
|
}
|
||
|
|
|
||
|
|
return self::mbReplaceScalar($search, $replace, $subject, $count);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Dispatch for scalar subject.
|
||
|
|
* Returns false when $replace is array but $search is a scalar string.
|
||
|
|
*
|
||
|
|
* @param array<string>|string $search
|
||
|
|
* @param array<string>|string $replace
|
||
|
|
*/
|
||
|
|
private static function mbReplaceScalar(
|
||
|
|
array | string $search,
|
||
|
|
array | string $replace,
|
||
|
|
string $subject,
|
||
|
|
int &$count = 0,
|
||
|
|
): string | false {
|
||
|
|
if (! is_array($search) && is_array($replace)) {
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (is_array($search)) {
|
||
|
|
return self::mbReplaceWithSearchArray($search, $replace, $subject, $count);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (! is_string($replace)) {
|
||
|
|
throw new \InvalidArgumentException('Replace must be a string when search is a string.');
|
||
|
|
}
|
||
|
|
|
||
|
|
return self::mbReplaceSingle($search, $replace, $subject, $count);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @param string[]|string $search
|
||
|
|
* @param string[]|string $replace
|
||
|
|
* @param array<int|string, mixed> $subject
|
||
|
|
* @return array<int|string, mixed>
|
||
|
|
*/
|
||
|
|
public static function mbReplaceInArraySubject(array | string $search, array | string $replace, array $subject, int &$count = 0): array
|
||
|
|
{
|
||
|
|
foreach ($subject as &$value) {
|
||
|
|
if (is_array($value)) {
|
||
|
|
$value = self::mbReplaceInArraySubject($search, $replace, $value, $count);
|
||
|
|
} elseif (is_array($search) && is_string($value)) {
|
||
|
|
$value = self::mbReplaceWithSearchArray($search, $replace, $value, $count);
|
||
|
|
} elseif (! is_array($replace) && is_string($value)) {
|
||
|
|
$value = self::mbReplaceSingle($search, $replace, $value, $count);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
unset($value);
|
||
|
|
|
||
|
|
return $subject;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @param string[] $search
|
||
|
|
* @param array<string>|string $replace
|
||
|
|
*/
|
||
|
|
public static function mbReplaceWithSearchArray(array $search, array | string $replace, string $subject, int &$count = 0): string
|
||
|
|
{
|
||
|
|
if (! is_array($replace)) {
|
||
|
|
foreach ($search as $searchItem) {
|
||
|
|
$subject = (string) self::mbReplaceSingle($searchItem, $replace, $subject, $count);
|
||
|
|
}
|
||
|
|
|
||
|
|
return $subject;
|
||
|
|
}
|
||
|
|
|
||
|
|
$iterations = max(count($search), count($replace));
|
||
|
|
$searchItem = reset($search);
|
||
|
|
$replaceItem = reset($replace);
|
||
|
|
|
||
|
|
while ($iterations--) {
|
||
|
|
$subject = (string) self::mbReplaceSingle((string) $searchItem, (string) $replaceItem, $subject, $count);
|
||
|
|
$searchItem = next($search);
|
||
|
|
$replaceItem = next($replace);
|
||
|
|
}
|
||
|
|
|
||
|
|
return $subject;
|
||
|
|
}
|
||
|
|
|
||
|
|
public static function mbReplaceSingle(string $search, string $replace, string $subject, int &$count = 0): string
|
||
|
|
{
|
||
|
|
$parts = mb_split(preg_quote($search), $subject) ?: [];
|
||
|
|
$count = count($parts) - 1;
|
||
|
|
|
||
|
|
return implode($replace, $parts);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Convert deeply an object to array
|
||
|
|
*
|
||
|
|
* @return array<int|string,mixed>
|
||
|
|
*
|
||
|
|
* @throws \App\Exceptions\Helpers\UnsupportedStructureConversionException If $input var is a scalar value.
|
||
|
|
*/
|
||
|
|
public static function objectToArray(mixed $input): array
|
||
|
|
{
|
||
|
|
if (! (is_object($input) || is_array($input))) {
|
||
|
|
throw UnsupportedStructureConversionException::fromType($input);
|
||
|
|
}
|
||
|
|
|
||
|
|
$ret = (array) $input;
|
||
|
|
foreach ($ret as &$item) {
|
||
|
|
$item = (is_object($item) || is_array($item)) ? self::objectToArray($item) : $item;
|
||
|
|
}
|
||
|
|
|
||
|
|
return $ret;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Convert deeply an array to object
|
||
|
|
*
|
||
|
|
* @throws \App\Exceptions\Helpers\UnsupportedStructureConversionException If $input var is a scalar value.
|
||
|
|
*/
|
||
|
|
public static function arrayToObject(mixed $input): object
|
||
|
|
{
|
||
|
|
if (! (is_object($input) || is_array($input))) {
|
||
|
|
throw UnsupportedStructureConversionException::fromType($input);
|
||
|
|
}
|
||
|
|
|
||
|
|
$ret = (object) $input;
|
||
|
|
$retArray = (array) $ret;
|
||
|
|
foreach ($retArray as &$item) {
|
||
|
|
$item = (is_object($item) || is_array($item)) ? self::arrayToObject($item) : $item;
|
||
|
|
}
|
||
|
|
unset($item);
|
||
|
|
|
||
|
|
return (object) $retArray;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get the file full path
|
||
|
|
*/
|
||
|
|
protected static function getUploadedFileFullPath(string $value, bool $useStorage): string
|
||
|
|
{
|
||
|
|
/** @var \Illuminate\Filesystem\FilesystemAdapter */
|
||
|
|
$disk = Storage::disk();
|
||
|
|
|
||
|
|
if ($useStorage) {
|
||
|
|
return $disk->path($value);
|
||
|
|
}
|
||
|
|
|
||
|
|
return realpath($value) ?: $value;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get the file mimetype
|
||
|
|
*
|
||
|
|
* @return string|false
|
||
|
|
*/
|
||
|
|
protected static function getUploadedFileMimeType(string $value, bool $useStorage)
|
||
|
|
{
|
||
|
|
if ($useStorage) {
|
||
|
|
return Storage::mimeType($value);
|
||
|
|
}
|
||
|
|
|
||
|
|
return File::mimeType($value);
|
||
|
|
}
|
||
|
|
}
|