You are here

public function HMSService::formatted_to_seconds in HMS Field 8

Returns number of seconds from a formatted string.

Parameters

$str:

string $format:

Return value

mixed

Overrides HMSServiceInterface::formatted_to_seconds

1 call to HMSService::formatted_to_seconds()
HMSService::isValid in src/HMSService.php
Validate hms field input.

File

src/HMSService.php, line 116

Class

HMSService
Provides a service to handle various hms related functionality.

Namespace

Drupal\hms_field

Code

public function formatted_to_seconds($str, $format = 'h:m:s', $element = [], $form_state = []) {
  if (!strlen($str)) {
    return NULL;
  }
  elseif ($str == '0') {
    return 0;
  }
  $value = 0;
  $error = FALSE;

  // Input validation for space separated format.
  if ($format == 'hms') {
    $preg = [];
    if (is_numeric($str) || preg_match('/^(?P<H>[-]{0,1}[0-9]{1,5}(\\.[0-9]{1,3})?)$|^(?P<negative>[-]{0,1})(((?P<w>[0-9.]{1,5})w)?((?P<d>[0-9.]{1,5})d)?((?P<h>[0-9.]{1,5})h)?([ ]{0,1})((?P<m>[0-9.]{1,05})m)?([ ]{0,1})((?P<s>[0-9.]{1,5})s)?)/', $str, $preg)) {
      $error = TRUE;
      foreach ($preg as $code => $val) {
        if (!is_numeric($val)) {
          continue;
        }
        switch ($code) {
          case 'w':
            $error = FALSE;
            $value += $val * 604800;
            break;
          case 'd':
            $error = FALSE;
            $value += $val * 86400;
            break;
          case 'h':
          case 'H':
            $error = FALSE;
            $value += $val * 3600;
            break;
          case 'm':
            $error = FALSE;
            $value += $val * 60;
            break;
          case 's':
            $error = FALSE;
            $value += $val;
            break;
          default:
            break;
        }
      }
      if (!empty($preg['negative'])) {
        $value = $value * -1;
      }
      if ($error == 0) {
        return $value;
      }
    }
    else {
      $error = TRUE;
    }
  }

  // Input validation ISO 8601 based.
  $preg_string = preg_replace([
    '/[h]{1,6}/',
    '/[m]{1,2}|[s]{1,2}/',
  ], [
    '([0-9]{1,6})',
    '([0-9]{1,2})',
  ], $format);
  if (!preg_match("@^" . $preg_string . "\$@", $str) && !preg_match('/^[0-9]{1,6}([,.][0-9]{1,6})?$/', $str)) {
    $error = TRUE;
  }

  // Does not follow space separated format.
  if ($error) {
    if (!empty($form_state)) {
      $form_state
        ->setErrorByName('field_name', t('The %name value is in wrong format, check in field settings.', [
        '%name' => t($element['#title']),
      ]));
    }
    return FALSE;
  }

  // is the value negative?
  $negative = FALSE;
  if (substr($str, 0, 1) == '-') {
    $negative = TRUE;
    $str = substr($str, 1);
  }
  $factor_map = $this
    ->factor_map();
  $search = $this
    ->normalize_format($format);
  for ($i = 0; $i < strlen($search); $i++) {

    // Is this char in the factor map?
    if (isset($factor_map[$search[$i]])) {
      $factor = $factor_map[$search[$i]];

      // What is the next seperator to search for?
      $bumper = '$';
      if (isset($search[$i + 1])) {
        $bumper = '(' . preg_quote($search[$i + 1], '/') . '|$)';
      }
      if (preg_match_all('/^(.*)' . $bumper . '/U', $str, $matches)) {

        // Replace , with .
        $num = str_replace(',', '.', $matches[1][0]);

        // Return error when found string is not numeric
        if (!is_numeric($num)) {
          return FALSE;
        }

        // Shorten $str
        $str = substr($str, strlen($matches[1][0]));

        // Calculate value
        $value += $num * $factor;
      }
    }
    elseif (substr($str, 0, 1) == $search[$i]) {

      // Expected this value, cut off and go ahead.
      $str = substr($str, 1);
    }
    else {

      // Does not follow format.
      return FALSE;
    }
    if (!strlen($str)) {

      // No more $str to investigate.
      break;
    }
  }
  if ($negative) {
    $value = 0 - $value;
  }
  return $value;
}