335 lines
11 KiB
PHP
335 lines
11 KiB
PHP
<?php
|
|
|
|
namespace Leantime\Core\Support;
|
|
|
|
use Carbon\CarbonImmutable;
|
|
use Carbon\CarbonInterface;
|
|
use Illuminate\Support\Facades\Date;
|
|
use Leantime\Core\Language;
|
|
use PHPUnit\Exception;
|
|
|
|
/**
|
|
* Class Format
|
|
*
|
|
* This class provides various formatting methods for simple data types (strings, ints, floats)
|
|
*/
|
|
class Format
|
|
{
|
|
private mixed $value = '';
|
|
|
|
private mixed $value2 = '';
|
|
|
|
private DateTimeHelper $dateTimeHelper;
|
|
|
|
private Language $language;
|
|
|
|
/**
|
|
* Creates a new instance of the class.
|
|
*
|
|
* PSA: This class will NOT throw exceptions or error messages since it is a user facing string formatting class.
|
|
* If you need to evaluate correct parsing of datetimes use the datetime helper and not this format class.
|
|
*
|
|
* @param string|int|float $value The value to be assigned. If empty, the constructor will return early.
|
|
* @param null|string|int|float $value2 The second value to be assigned. It can be null. Used for certain cases
|
|
* as specified by $fromFormat.
|
|
* @param FromFormat|null $fromFormat The format of the values. Can be one of the constants defined in the
|
|
* FromFormat class.
|
|
* @return void
|
|
*/
|
|
public function __construct(
|
|
string|int|float|null|\DateTimeInterface|CarbonInterface $value,
|
|
string|int|float|null|\DateTimeInterface|CarbonInterface $value2,
|
|
?FromFormat $fromFormat = FromFormat::DbDate
|
|
) {
|
|
|
|
$this->dateTimeHelper = app()->make(DateTimeHelper::class);
|
|
$this->language = app()->make(Language::class);
|
|
|
|
if (empty($value)) {
|
|
return;
|
|
}
|
|
|
|
if ($value instanceof \DateTime) {
|
|
$value = CarbonImmutable::create($value);
|
|
$this->value = CarbonImmutable::create($value);
|
|
}
|
|
|
|
if ($value2 instanceof \DateTime) {
|
|
$value2 = CarbonImmutable::create($value2);
|
|
$this->value = CarbonImmutable::create($value2);
|
|
}
|
|
|
|
try {
|
|
switch ($fromFormat) {
|
|
case FromFormat::DbDate:
|
|
$this->value = $this->dateTimeHelper->parseDbDateTime($value);
|
|
break;
|
|
case FromFormat::UserDateTime:
|
|
$this->value = $this->dateTimeHelper->parseUserDateTime($value, $value2);
|
|
break;
|
|
case FromFormat::User24hTime:
|
|
$this->value = $this->dateTimeHelper->parseUser24hTime($value);
|
|
break;
|
|
case FromFormat::Db24hTime:
|
|
$this->value = $this->dateTimeHelper->parseDb24hTime($value);
|
|
break;
|
|
case FromFormat::UserDateStartOfDay:
|
|
$this->value = $this->dateTimeHelper->parseUserDateTime($value, 'start');
|
|
break;
|
|
case FromFormat::UserDateEndOfDay:
|
|
$this->value = $this->dateTimeHelper->parseUserDateTime($value, 'end');
|
|
break;
|
|
default:
|
|
$this->value = $value;
|
|
break;
|
|
}
|
|
} catch (\Throwable $e) {
|
|
// Several things can throw exceptions in the date parsing scripts.
|
|
// Most common is an invalid date format. This could also be an empty string or a 0000-00... date.
|
|
// Since this format class is purely for user facing purposes we will not show an error message
|
|
// but return an empty string.
|
|
$this->value = $value;
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns the user formatted date string based on the 'value' property.
|
|
*
|
|
* @param string $emptyOutput The output to be returned when the 'value' property is empty.
|
|
* Defaults to an empty string.
|
|
* @return string The formatted date string or the $emptyOutput if the 'value' property is empty or
|
|
* the formatted date string is empty.
|
|
*/
|
|
public function date(string $emptyOutput = ''): string
|
|
{
|
|
|
|
if (empty($this->value) || ! $this->value instanceof CarbonImmutable) {
|
|
return $emptyOutput;
|
|
}
|
|
|
|
$formattedDate = $this->value->formatDateForUser();
|
|
|
|
return $formattedDate !== '' ? $formattedDate : $emptyOutput;
|
|
}
|
|
|
|
/**
|
|
* Retrieve the formatted time string from the ISO value.
|
|
* Returns an empty string if 'value' is null.
|
|
*
|
|
* @return string The formatted time string.
|
|
*/
|
|
public function time(): string
|
|
{
|
|
if (empty($this->value) || ! $this->value instanceof CarbonImmutable) {
|
|
return '';
|
|
}
|
|
|
|
return $this->value->formatTimeForUser();
|
|
}
|
|
|
|
/**
|
|
* Generates an ISO 8601 formatted date and time string in user timezone
|
|
*
|
|
* @return string The ISO 8601 formatted date and time string. Returns an empty string if the value is null.
|
|
*/
|
|
public function isoDateTime(): string
|
|
{
|
|
if (empty($this->value) || ! $this->value instanceof CarbonImmutable) {
|
|
return '';
|
|
}
|
|
|
|
return $this->value->setToUserTimezone()->format('Y-m-d H:i:s');
|
|
}
|
|
|
|
/**
|
|
* Generates an ISO 8601 formatted date and time string in UTC timezone
|
|
*
|
|
* @return string The ISO 8601 formatted date and time string. Returns an empty string if the value is null.
|
|
*/
|
|
public function isoDateTimeUTC(): string
|
|
{
|
|
if (empty($this->value) || ! $this->value instanceof CarbonImmutable) {
|
|
return '';
|
|
}
|
|
|
|
return $this->value->formatDateTimeForDb();
|
|
}
|
|
|
|
/**
|
|
* @deprecated
|
|
*
|
|
* This method is deprecated and only included because of plugin backwards compatibility.
|
|
* Once all plugins are updated this will be removed.
|
|
*
|
|
* @return string The ISO 8601 formatted date string. Returns an empty string if the value is null.
|
|
*/
|
|
public function isoDate(): string
|
|
{
|
|
|
|
if (empty($this->value)) {
|
|
return '';
|
|
}
|
|
|
|
// This method should not be used anymore however we have plugins that are still using it and they will not have
|
|
// the new enum values. So they are still calling format($var)->isoDate() without a enum modifier that would
|
|
// indicate that this is a user date (which it was historically).
|
|
// So now we have to shuffle things around and since the format was probably not correct anyways, let's reparse
|
|
|
|
if (! $this->value instanceof CarbonImmutable) {
|
|
|
|
try {
|
|
$this->value = $this->dateTimeHelper->parseUserDateTime($this->value, 'start');
|
|
} catch (Exception $e) {
|
|
report($e);
|
|
|
|
return '';
|
|
}
|
|
|
|
} else {
|
|
|
|
// If for some reason Carbon was able to parse the date we'll need to make sure the timezone is set to the
|
|
// users timezone.
|
|
|
|
// Date was falsly parsed as UTC but is actually user date. Shift timezone.
|
|
$userTimezone = session('usersettings.timezone');
|
|
// Carbon shift timezone will change timezone without actually changing the numbers
|
|
$this->value->shiftTimezone($userTimezone);
|
|
}
|
|
|
|
return $this->value->formatDateTimeForDb();
|
|
}
|
|
|
|
/**
|
|
* Generate unix timestamp from date.
|
|
*/
|
|
public function timestamp(): int|bool
|
|
{
|
|
if (empty($this->value) || ! $this->value instanceof CarbonImmutable) {
|
|
return false;
|
|
}
|
|
|
|
return $this->value->getTimestamp();
|
|
}
|
|
|
|
/**
|
|
* Generate unix timestamp from date in miliseconds for javascript usage
|
|
*/
|
|
public function jsTimestamp(): int|bool
|
|
{
|
|
if (empty($this->value) || ! $this->value instanceof CarbonImmutable) {
|
|
return false;
|
|
}
|
|
|
|
return $this->value->getTimestampMs();
|
|
}
|
|
|
|
/**
|
|
* Retrieves the 24-hour time string from the ISO formatted value property.
|
|
*
|
|
* @return string The 24-hour time string. If the value property is null, an empty string is returned.
|
|
*/
|
|
public function time24(): string
|
|
{
|
|
if (empty($this->value) || ! $this->value instanceof CarbonImmutable) {
|
|
return '';
|
|
}
|
|
|
|
return $this->value->format24HTimeForUser();
|
|
}
|
|
|
|
/**
|
|
* Converts a 24-hour formatted time string to a user-friendly time string.
|
|
*
|
|
* @return string The user-friendly time string in the format "H:i A". Returns an empty string if the value is null.
|
|
*/
|
|
public function userTime24toUserTime(): string
|
|
{
|
|
if (empty($this->value) || ! $this->value instanceof CarbonImmutable) {
|
|
return '';
|
|
}
|
|
|
|
return $this->value->formatTimeForUser();
|
|
|
|
}
|
|
|
|
/**
|
|
* Generates a string representation of currency.
|
|
*
|
|
* @return string The string representation of currency.
|
|
*/
|
|
public function currency(): string
|
|
{
|
|
if ($this->value == null) {
|
|
return '';
|
|
}
|
|
|
|
return $this->language->__('language.currency').''.number_format($this->value, 2);
|
|
}
|
|
|
|
/**
|
|
* Generates a string representation of a percentage.
|
|
*
|
|
* @return string The percentage string. Returns an empty string if the value is null.
|
|
* If the second value is empty, the first value is returned with a "%" sign appended.
|
|
* If both values are set, the percentage is calculated and formatted to two decimal places, followed by a "%" sign.
|
|
*/
|
|
public function percent(): string
|
|
{
|
|
// First value empty, just return empty string
|
|
if ($this->value == null) {
|
|
return '';
|
|
}
|
|
|
|
// Second value empty return first value with % sign
|
|
if (empty($this->value2)) {
|
|
return number_format($this->value, 2).'%';
|
|
}
|
|
|
|
// Both values set. Return percent calculation
|
|
$percent = ($this->value / $this->value2) * 100;
|
|
|
|
return number_format($percent, 2).'%';
|
|
}
|
|
|
|
/**
|
|
* Formats a decimal number with two decimal places.
|
|
*
|
|
* @return string The decimal number formatted with two decimal places.
|
|
*/
|
|
public function decimal(): string
|
|
{
|
|
return number_format((float) $this->value, 2);
|
|
}
|
|
|
|
public function diffForHumans(): string
|
|
{
|
|
if ($this->value->isToday()) {
|
|
return $this->language->__('dates.today');
|
|
} elseif ($this->value->isYesterday()) {
|
|
return $this->language->__('dates.yesterday');
|
|
} elseif ($this->value->isTomorrow()) {
|
|
return $this->language->__('dates.tomorrow');
|
|
} else {
|
|
return $this->value->endOfDay()->diffForHumans();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Format bytes to human readable format
|
|
*
|
|
* @return string The formatted size
|
|
*/
|
|
public function formatBytes(): string
|
|
{
|
|
$units = ['B', 'KB', 'MB', 'GB', 'TB'];
|
|
|
|
$bytes = max($this->value, 0);
|
|
$pow = floor(($bytes ? log($bytes) : 0) / log(1024));
|
|
$pow = min($pow, count($units) - 1);
|
|
|
|
return round($bytes / (1024 ** $pow), 2).' '.$units[$pow];
|
|
}
|
|
}
|