2020-12-11 02:43:58 +00:00
|
|
|
<?php
|
|
|
|
|
2021-07-19 05:53:45 +00:00
|
|
|
declare(strict_types=1);
|
|
|
|
|
2020-12-11 02:43:58 +00:00
|
|
|
namespace App\Utilities;
|
|
|
|
|
2022-06-16 10:56:33 +00:00
|
|
|
use RuntimeException;
|
2022-11-20 04:16:03 +00:00
|
|
|
use voku\helper\UTF8;
|
2022-06-16 10:56:33 +00:00
|
|
|
|
2022-07-01 07:41:04 +00:00
|
|
|
final class Strings
|
2020-12-11 02:43:58 +00:00
|
|
|
{
|
2023-01-16 08:09:16 +00:00
|
|
|
/**
|
|
|
|
* Given a nullable string value, return null if the string is null or otherwise
|
|
|
|
* is considered "empty", or the trimmed value otherwise.
|
|
|
|
*/
|
|
|
|
public static function nonEmptyOrNull(?string $input): ?string
|
|
|
|
{
|
|
|
|
if (null === $input || '' === $input) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
$input = trim($input);
|
|
|
|
return (!empty($input))
|
|
|
|
? $input
|
|
|
|
: null;
|
|
|
|
}
|
|
|
|
|
2020-12-11 02:43:58 +00:00
|
|
|
/**
|
|
|
|
* Truncate text (adding "..." if needed)
|
|
|
|
*/
|
2022-05-18 01:54:44 +00:00
|
|
|
public static function truncateText(string $text, int $limit = 80, string $pad = '...'): string
|
2020-12-11 02:43:58 +00:00
|
|
|
{
|
|
|
|
mb_internal_encoding('UTF-8');
|
|
|
|
|
|
|
|
if (mb_strlen($text) <= $limit) {
|
|
|
|
return $text;
|
|
|
|
}
|
|
|
|
|
|
|
|
$wrapped_text = self::mbWordwrap($text, $limit, '{N}', true);
|
2021-07-19 05:53:45 +00:00
|
|
|
$shortened_text = mb_substr(
|
|
|
|
$wrapped_text,
|
|
|
|
0,
|
|
|
|
strpos($wrapped_text, '{N}') ?: null
|
|
|
|
);
|
2020-12-11 02:43:58 +00:00
|
|
|
|
|
|
|
// Prevent the padding string from bumping up against punctuation.
|
|
|
|
$punctuation = ['.', ',', ';', '?', '!'];
|
|
|
|
if (in_array(mb_substr($shortened_text, -1), $punctuation, true)) {
|
|
|
|
$shortened_text = mb_substr($shortened_text, 0, -1);
|
|
|
|
}
|
|
|
|
|
|
|
|
return $shortened_text . $pad;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Generate a randomized password of specified length.
|
|
|
|
*
|
2021-07-19 05:53:45 +00:00
|
|
|
* @param int $length
|
2020-12-11 02:43:58 +00:00
|
|
|
*/
|
2021-07-19 05:53:45 +00:00
|
|
|
public static function generatePassword(int $length = 8): string
|
2020-12-11 02:43:58 +00:00
|
|
|
{
|
|
|
|
// String of all possible characters. Avoids using certain letters and numbers that closely resemble others.
|
2021-07-19 05:53:45 +00:00
|
|
|
$keyspace = '234679ACDEFGHJKLMNPQRTWXYZacdefghjkmnpqrtwxyz';
|
2020-12-11 02:43:58 +00:00
|
|
|
|
2021-07-19 05:53:45 +00:00
|
|
|
$str = '';
|
|
|
|
$max = mb_strlen($keyspace, '8bit') - 1;
|
2020-12-11 02:43:58 +00:00
|
|
|
|
2021-07-19 05:53:45 +00:00
|
|
|
for ($i = 0; $i < $length; ++$i) {
|
2022-03-17 00:04:40 +00:00
|
|
|
/** @noinspection RandomApiMigrationInspection */
|
|
|
|
$str .= $keyspace[rand(0, $max)];
|
2020-12-11 02:43:58 +00:00
|
|
|
}
|
2021-07-19 05:53:45 +00:00
|
|
|
return $str;
|
2020-12-11 02:43:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* UTF-8 capable replacement for wordwrap function.
|
|
|
|
*
|
|
|
|
* @param string $str
|
|
|
|
* @param int $width
|
2021-08-23 02:08:52 +00:00
|
|
|
* @param non-empty-string $break
|
2020-12-11 02:43:58 +00:00
|
|
|
* @param bool $cut
|
|
|
|
*/
|
2021-08-23 02:08:52 +00:00
|
|
|
public static function mbWordwrap(string $str, int $width = 75, string $break = "\n", bool $cut = false): string
|
2020-12-11 02:43:58 +00:00
|
|
|
{
|
|
|
|
$lines = explode($break, $str);
|
|
|
|
foreach ($lines as &$line) {
|
|
|
|
$line = rtrim($line);
|
|
|
|
if (mb_strlen($line) <= $width) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
$words = explode(' ', $line);
|
|
|
|
$line = '';
|
|
|
|
$actual = '';
|
|
|
|
foreach ($words as $word) {
|
|
|
|
if (mb_strlen($actual . $word) <= $width) {
|
|
|
|
$actual .= $word . ' ';
|
|
|
|
} else {
|
|
|
|
if ($actual != '') {
|
|
|
|
$line .= rtrim($actual) . $break;
|
|
|
|
}
|
|
|
|
$actual = $word;
|
|
|
|
if ($cut) {
|
|
|
|
while (mb_strlen($actual) > $width) {
|
|
|
|
$line .= mb_substr($actual, 0, $width) . $break;
|
|
|
|
$actual = mb_substr($actual, $width);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
$actual .= ' ';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
$line .= trim($actual);
|
|
|
|
}
|
|
|
|
|
|
|
|
return implode($break, $lines);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Truncate URL in text-presentable format (i.e. "http://www.example.com" becomes "example.com")
|
|
|
|
*
|
2021-06-13 03:57:10 +00:00
|
|
|
* @param string|null $url
|
2020-12-11 02:43:58 +00:00
|
|
|
* @param int $length
|
|
|
|
*/
|
2022-06-20 00:27:59 +00:00
|
|
|
public static function truncateUrl(?string $url, int $length = 40): string
|
2020-12-11 02:43:58 +00:00
|
|
|
{
|
2021-06-13 03:57:10 +00:00
|
|
|
if (null === $url) {
|
|
|
|
return '';
|
|
|
|
}
|
|
|
|
|
2021-06-10 03:22:13 +00:00
|
|
|
/** @noinspection HttpUrlsUsage */
|
2020-12-11 02:43:58 +00:00
|
|
|
$url = str_replace(['http://', 'https://', 'www.'], '', $url);
|
|
|
|
|
|
|
|
return self::truncateText(rtrim($url, '/'), $length);
|
|
|
|
}
|
2022-06-02 22:27:33 +00:00
|
|
|
|
|
|
|
public static function getProgrammaticString(string $str): string
|
|
|
|
{
|
|
|
|
$result = mb_ereg_replace("([^\w\s\d\-_~,;\[\]\(\).])", '', $str);
|
|
|
|
if (null === $result || false === $result) {
|
2022-06-16 10:56:33 +00:00
|
|
|
throw new RuntimeException('Cannot parse input string.');
|
2022-06-02 22:27:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
$result = mb_ereg_replace("([\.]{2,})", '.', $result);
|
|
|
|
if (null === $result || false === $result) {
|
2022-06-16 10:56:33 +00:00
|
|
|
throw new RuntimeException('Cannot parse input string.');
|
2022-06-02 22:27:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
$result = str_replace(' ', '_', $result);
|
|
|
|
return mb_strtolower($result);
|
|
|
|
}
|
2022-11-20 04:16:03 +00:00
|
|
|
|
|
|
|
public static function stringToUtf8(?string $original): string
|
|
|
|
{
|
|
|
|
$original ??= '';
|
|
|
|
|
|
|
|
$string = UTF8::encode('UTF-8', $original);
|
|
|
|
$string = UTF8::fix_simple_utf8($string);
|
|
|
|
return UTF8::clean(
|
|
|
|
$string,
|
|
|
|
true,
|
|
|
|
true,
|
|
|
|
true,
|
|
|
|
true,
|
|
|
|
true
|
|
|
|
);
|
|
|
|
}
|
2020-12-11 02:43:58 +00:00
|
|
|
}
|