You are here

public function OfficeHoursFormatterTrait::getRows in Office Hours 8

Returns the items of a field.

Parameters

array $items: Result from FieldItemListInterface $items->getValue().

array $settings:

array $field_settings:

$time:

Return value

array The formatted list of slots.

5 calls to OfficeHoursFormatterTrait::getRows()
OfficeHoursFormatterBase::getStatusTimeLeft in src/Plugin/Field/FieldFormatter/OfficeHoursFormatterBase.php
OfficeHoursFormatterDefault::viewElements in src/Plugin/Field/FieldFormatter/OfficeHoursFormatterDefault.php
Builds a renderable array for a field value.
OfficeHoursFormatterSchema::viewElements in src/Plugin/Field/FieldFormatter/OfficeHoursFormatterSchema.php
Builds a renderable array for a field value.
OfficeHoursFormatterTable::viewElements in src/Plugin/Field/FieldFormatter/OfficeHoursFormatterTable.php
Builds a renderable array for a field value.
OfficeHoursItemList::getRows in src/Plugin/Field/FieldType/OfficeHoursItemList.php
Returns the items of a field.

File

src/OfficeHoursFormatterTrait.php, line 25

Class

OfficeHoursFormatterTrait
Factors out OfficeHoursItemList->getItems()->getRows().

Namespace

Drupal\office_hours

Code

public function getRows(array $items, array $settings, array $field_settings, $time = NULL) {
  $default_office_hours = [
    'startday' => NULL,
    'endday' => NULL,
    'closed' => $this
      ->t(Html::escape($settings['closed_format'])),
    'current' => FALSE,
    'next' => FALSE,
    'slots' => [],
    'formatted_slots' => [],
    'comments' => [],
  ];

  // Initialize days and times, using date_api as key (0=Sun, 6=Sat).
  // Empty days are not yet present in $items, and are now added in $days.
  $office_hours = [];
  for ($day = 0; $day < 7; $day++) {
    $office_hours[$day] = [
      'startday' => $day,
    ] + $default_office_hours;
  }

  // Loop through all lines.
  // Detect the current line and the open/closed status.
  // Convert the day number to (int) to get '0' for Sundays, not 'false'.
  $time = $time === NULL ? \Drupal::time()
    ->getRequestTime() : $time;
  $today = (int) idate('w', $time);

  // Get day_number: (0=Sun, 6=Sat).
  $now = date('Hi', $time);

  // 'Hi' format, with leading zero (0900).
  foreach ($items as $key => $item) {

    // Calculate start and end times.
    $day = (int) $item['day'];

    // Format to 'Hi' format, with leading zero (0900).
    $start = OfficeHoursDatetime::get($item['starthours'], 'Hi');
    $end = OfficeHoursDatetime::get($item['endhours'], 'Hi');
    $office_hours[$day] = $office_hours[$day] ?? [
      'startday' => $day,
    ] + $default_office_hours;
    $office_hours[$day]['slots'][] = [
      // Format to 'Hi' format, with leading zero (0900).
      'start' => $start,
      'end' => $end,
      'comment' => $item['comment'],
    ];
  }
  $next = NULL;
  foreach ($office_hours as $day => &$day_data) {
    foreach ($day_data['slots'] as $slot_id => $slot) {
      if ($day <= $today) {

        // Initialize to first day of (next) week, in case we're closed
        // the rest of the week.
        // @todo Use $settings['office_hours_first_day'] ?
        if ($next === NULL) {
          $next = $day;
        }
      }
      if ($day == $today) {
        $start = $slot['start'];
        $end = $slot['end'];
        if ($start > $now) {

          // We will open later today.
          $next = $day;
        }
        elseif ($start < $end && $end < $now) {

          // We were open today, but are already closed.
        }
        else {

          // We are still open.
          $day_data['current'] = TRUE;
          $next = $day;
        }
      }
      elseif ($day > $today) {
        if ($next === NULL) {
          $next = $day;
        }
        elseif ($next < $today) {
          $next = $day;
        }
        else {

          // Just for analysis.
        }
      }
      else {

        // Just for analysis.
      }
    }
  }
  if ($next !== NULL) {
    $office_hours[$next]['next'] = TRUE;
  }

  /*
   * We have a list of all possible rows, marking the next and current day.
   * Now, filter according to formatter settings.
   */

  // Reorder weekdays to match the first day of the week, using formatter settings.
  $office_hours = OfficeHoursDateHelper::weekDaysOrdered($office_hours, $settings['office_hours_first_day']);

  // Compress all slots of the same day into one item.
  if ($settings['compress']) {
    $office_hours = $this
      ->compressSlots($office_hours);
  }

  // Group identical, consecutive days into one item.
  if ($settings['grouped']) {
    $office_hours = $this
      ->groupDays($office_hours);
  }

  // From here, no more adding/removing, only formatting.
  // Format the day names.
  $office_hours = $this
    ->formatLabels($office_hours, $settings);

  // Format the start and end time into one slot.
  $office_hours = $this
    ->formatSlots($office_hours, $settings, $field_settings);

  // Return the filtered days/slots/items/rows.
  switch ($settings['show_closed']) {
    case 'open':
      $office_hours = $this
        ->keepOpenDays($office_hours);
      break;
    case 'next':
      $office_hours = $this
        ->keepNextDay($office_hours);
      break;
    case 'none':
      $office_hours = [];
      break;
    case 'current':
      $office_hours = $this
        ->keepCurrentDay($office_hours);
      break;
  }
  return $office_hours;
}