public function IngredientQuantityUtility::getQuantityFromDecimal in Recipe 8.2
Converts an ingredient's quantity from decimal to fraction.
Parameters
float $ingredient_quantity: The ingredient quantity formatted as a decimal.
string $fraction_format: A string representing the fraction format, used by sprintf().
bool $edit_mode: Whether or not the ingredient is being edited.
Return value
string The ingredient quantity formatted as a fraction.
File
- modules/
ingredient/ src/ Utility/ IngredientQuantityUtility.php, line 25
Class
- IngredientQuantityUtility
- Provides the ingredient.quantity service.
Namespace
Drupal\ingredient\UtilityCode
public function getQuantityFromDecimal($ingredient_quantity, $fraction_format = '{%d} %d⁄%d', $edit_mode = FALSE) {
if (strpos($ingredient_quantity, '.')) {
$decimal = abs($ingredient_quantity);
$whole = floor($decimal);
$numerator = 0;
$denominator = 1;
$top_heavy = 0;
$power = 1;
$flag = 0;
while ($flag == 0) {
$argument = $decimal * $power;
if ($argument == floor($argument)) {
$flag = 1;
}
else {
$power = $power * 10;
}
}
// We have to workaround for repeating, non-exact decimals for thirds,
// sixths, ninths, twelfths.
$overrides = [
// Thirds.
'3333' => [
1,
3,
],
'6666' => [
2,
3,
],
'9999' => [
3,
3,
],
'1666' => [
1,
6,
],
// Sixths.
'8333' => [
5,
6,
],
// Ninths.
'1111' => [
1,
9,
],
'2222' => [
2,
9,
],
'4444' => [
4,
9,
],
'5555' => [
5,
9,
],
'7777' => [
7,
9,
],
'8888' => [
8,
9,
],
'0833' => [
1,
12,
],
'4166' => [
5,
12,
],
'5833' => [
7,
12,
],
// twelfths.
'9166' => [
11,
12,
],
];
// Truncate the whole part to get just the fractional part.
$conversionstr = substr((string) ($decimal - floor($decimal)), 2, 4);
if (array_key_exists($conversionstr, $overrides)) {
if ($overrides[$conversionstr][0] == $overrides[$conversionstr][1]) {
return $whole + 1;
}
$denominator = $overrides[$conversionstr][1];
$numerator = floor($decimal) * $denominator + $overrides[$conversionstr][0];
}
else {
$numerator = $decimal * $power;
$denominator = $power;
}
// Repeating decimals have been corrected.
$gcd = $this
->getGcd($numerator, $denominator);
$numerator = $numerator / $gcd;
$denominator = $denominator / $gcd;
$top_heavy = $numerator;
$numerator = abs($top_heavy) - abs($whole) * $denominator;
$ingredient_quantity = sprintf($fraction_format, $whole, $numerator, $denominator);
if ($whole == 0 && strpos($ingredient_quantity, '{') >= 0) {
// Remove anything in curly braces.
$ingredient_quantity = preg_replace('/{.*}/', '', $ingredient_quantity);
}
else {
// Remove just the curly braces, but keep everything between them.
$ingredient_quantity = preg_replace('/{|}/', '', $ingredient_quantity);
}
// In edit mode we don't want to show html tags like <sup> and <sub>.
if ($edit_mode) {
$ingredient_quantity = strip_tags($ingredient_quantity);
}
}
return Xss::filterAdmin(trim($ingredient_quantity));
}