foldershare-8.x-1.2/src/Utilities/FormatUtilities.php
src/Utilities/FormatUtilities.php
<?php
namespace Drupal\foldershare\Utilities;
use Drupal\Core\Render\Markup;
use Drupal\Component\Render\FormattableMarkup;
/**
* Defines utility functions to help with formatting.
*
* The functions in this class help format error messages and number values
* indicating the number of bytes used by something.
*
* <B>Warning:</B> This class is strictly internal to the FolderShare
* module. The class's existance, name, and content may change from
* release to release without any promise of backwards compatability.
*
* @ingroup foldershare
*/
final class FormatUtilities {
/*---------------------------------------------------------------------
*
* Functions.
*
*---------------------------------------------------------------------*/
/**
* Formats a number with a bytes suffix.
*
* The given number is formatted and returned as markup that may include
* a suffix like 'K' for kilobytes, 'M' for megabytes, or 'G' for
* gigabytes.
*
* An optional argument selects whether the unit of 'k' should
* be the current standard 1000, or the older convention of 1024.
*
* Optionally, suffixes may be full words instead of abbreviations.
*
* @param mixed $number
* The number to format.
* @param int $kunit
* (optional, default = 1000) Either 1000 (ISO standard kilobyte) or
* 1024 (legacy kibibyte).
* @param bool $fullWord
* (optional, default = FALSE) When FALSE, use an abbreviation suffix,
* like "KB". When TRUE, use a full word suffix, like "Kilobytes".
* @param int $decimalDigits
* (optional, default = 2) The number of decimal digits for the resulting
* number.
*
* @return \Drupal\Core\StringTranslation\TranslatableMarkup
* Returns a representation of the number, along with a suffix
* that summarizes the value using the selected 'k' units.
*
* @internal
* Drupal's format_size() function is widely used to format values in
* units of kilobytes, megabytes, etc. Unfortunately, it considers a
* "kilobyte" equal to 1024 bytes, which is not compliant with the
* 1998 International Electrotechnical Commission (IEC) and
* International System of Quantities (ISO) standards. By those standards,
* a "kilobyte" equals 1000 bytes. This definition retains the SI units
* convention that "k" is for 1000 (e.g. kilometer, kilogram).
*
* The following code is loosely based upon format_size(). It corrects
* the math for the selected "k" units (kilo or kibi) and uses the
* corresponding correct suffixes. It also supports a requested number
* of decimal digits.
*
* The following code also ignores the $langcode, which format_size()
* incorrectly uses to make the output translatable - even though it is
* NOT subject to translation since it is numeric and the suffixes are
* defined by international standards.
* @endinternal
*/
public static function formatBytes(
$number,
int $kunit = 1000,
bool $fullWord = FALSE,
int $decimalDigits = 2) {
// Validate.
switch ($kunit) {
case 1000:
case 1024:
$kunit = (float) $kunit;
break;
default:
$kunit = 1000.0;
break;
}
if ($decimalDigits < 0) {
$decimalDigits = 0;
}
if ($number < $kunit) {
// The quantity is smaller than the 'k' unit. Report it as-is.
return \Drupal::translation()->formatPlural(
$number,
'1 byte',
'@count bytes');
}
// Find the proper 'k'. Values larger than the largest 'k' unit
// will just be large numbers ahead of the largest prefix (e.g.
// "879 YB").
$value = (((float) $number) / $kunit);
foreach (['K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y'] as $unit) {
if ($value < $kunit) {
// The value is now less than the next unit, stop reducing.
break;
}
$value /= $kunit;
}
// Simplify the remainder with the proper number of decimal digits.
$fmt = '%1.' . $decimalDigits . 'f';
$formattedValue = sprintf($fmt, $value);
// If using abbrevations, return the formatted value and suffix.
if ($fullWord === FALSE) {
// Use abbreviations for suffixes.
switch ($kunit) {
default:
case 1000:
$suffix = $unit . 'B';
break;
case 1024:
$suffix = $unit . 'iB';
break;
}
return new FormattableMarkup(
'@value @suffix',
[
'@value' => $formattedValue,
'@suffix' => $suffix,
]);
}
// When using full words, return the formatted value and word,
// using singular and plural forms as appropriate.
$singular = [];
$plural = [];
switch ($kunit) {
default:
case 1000:
$singular = [
'K' => 'Kilobyte',
'M' => 'Megabyte',
'G' => 'Gigabyte',
'T' => 'Terabyte',
'P' => 'Petabyte',
'E' => 'Exabyte',
'Z' => 'Zettabyte',
'Y' => 'Yottabyte',
];
$plural = [
'K' => 'Kilobytes',
'M' => 'Megabytes',
'G' => 'Gigabytes',
'T' => 'Terabytes',
'P' => 'Petabytes',
'E' => 'Exabytes',
'Z' => 'Zettabytes',
'Y' => 'Yottabytes',
];
break;
case 1024:
$singular = [
'K' => 'Kibibyte',
'M' => 'Mibibyte',
'G' => 'Gibibyte',
'T' => 'Tebibyte',
'P' => 'Pebibyte',
'E' => 'Exbibyte',
'Z' => 'Zebibyte',
'Y' => 'Yobibyte',
];
$plural = [
'K' => 'Kibibytes',
'M' => 'Mibibytes',
'G' => 'Gibibytes',
'T' => 'Tebibytes',
'P' => 'Pebibytes',
'E' => 'Exbibytes',
'Z' => 'Zebibytes',
'Y' => 'Yobibytes',
];
break;
}
return new FormattableMarkup(
'@value @suffix',
[
'@value' => $formattedValue,
'@suffix' => ($value < 1) ? $singular[$unit] : $plural[$unit],
]);
}
/**
* Returns standardized markup for a summary, body, & details message.
*
* Formatted messages are intended for use in exceptions or as
* messages posted on a page via Drupal's messenger. They follow
* a three-part convention:
*
* - Summary - a short statement of the essential issue.
*
* - Body - a longer multi-sentence description of the problem and how
* a user might solve it.
*
* - Details summary - a brief summary of the details section.
*
* - Details - a much longer detailed explanation.
*
* The summary is required, but the body and details are optional.
*
* @param string|\Drupal\Component\Render\MarkupInterface $summary
* The short summary of the issue.
* @param string|\Drupal\Component\Render\MarkupInterface $body
* (optional, default = NULL = none) The longer description of the issue
* and how to resolve it.
* @param string|\Drupal\Component\Render\MarkupInterface $detailsSummary
* (optional, default = NULL = none) A brief summary of the details
* section. This could be "Details:", for instance.
* @param string|\Drupal\Component\Render\MarkupInterface $details
* (optional, default = NULL = none) The much longer detailed information.
*
* @return \Drupal\Core\Render\Markup
* Returns a Markup object suitable for use in messages. Casting the
* object to a (string) creates a conventional string message.
*/
public static function createFormattedMessage(
$summary,
$body = NULL,
$detailsSummary = NULL,
$details = NULL) {
$markup = '<span class="foldershare-message-summary">' .
(string) $summary . "</span> \n";
if ($body !== NULL) {
$markup .= '<p class="foldershare-message-body">' .
(string) $body . "</p> \n";
}
if ($details !== NULL) {
$markup .= '<details class="foldershare-message-details">';
if ($detailsSummary !== NULL) {
$markup .= '<summary>' . (string) $detailsSummary . "</summary> \n";
}
$markup .= '<p>' . (string) $details . '</p></details>';
}
return Markup::create($markup);
}
}
