You are here

function recipe_ingredient_quantity_from_decimal in Recipe 7.2

Same name and namespace in other branches
  1. 5 recipe.module \recipe_ingredient_quantity_from_decimal()
  2. 6 recipe.module \recipe_ingredient_quantity_from_decimal()
  3. 7 recipe.module \recipe_ingredient_quantity_from_decimal()

Converts an ingredient's quantity from decimal to fraction.

6 calls to recipe_ingredient_quantity_from_decimal()
decimal_to_fraction_callback in modules/recipe_plaintext.module
merge_template in modules/recipe_mastercook4.module
RecipeUnitTest::testIngredientQuantityConversion in src/Tests/RecipeUnitTest.php
Test ingredient quantity conversion functions.
recipe_field_formatter_view in ./recipe.module
Implements hook_field_formatter_view().
recipe_field_widget_form in ./recipe.module
Implements hook_field_widget_form().

... See full list

File

./recipe.module, line 1029
Contains functions for Recipe node CRUD and display.

Code

function recipe_ingredient_quantity_from_decimal($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 = array(
      '3333' => array(
        1,
        3,
      ),
      '6666' => array(
        2,
        3,
      ),
      '9999' => array(
        3,
        3,
      ),
      // thirds
      '1666' => array(
        1,
        6,
      ),
      '8333' => array(
        5,
        6,
      ),
      // sixths
      '1111' => array(
        1,
        9,
      ),
      '2222' => array(
        2,
        9,
      ),
      '4444' => array(
        4,
        9,
      ),
      '5555' => array(
        5,
        9,
      ),
      '7777' => array(
        7,
        9,
      ),
      '8888' => array(
        8,
        9,
      ),
      // ninths
      '0833' => array(
        1,
        12,
      ),
      '4166' => array(
        5,
        12,
      ),
      '5833' => array(
        7,
        12,
      ),
      '9166' => array(
        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 = greatest_common_divisor($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 filter_xss_admin(trim($ingredient_quantity));
}