You are here

class CalendarHelper in Calendar 8.2

Same name and namespace in other branches
  1. 8 src/CalendarHelper.php \Drupal\calendar\CalendarHelper

Class CalendarHelper.

@package Drupal\calendar

Hierarchy

Expanded class hierarchy of CalendarHelper

4 files declare their use of CalendarHelper
CalendarHeader.php in src/Plugin/views/area/CalendarHeader.php
CalendarPager.php in src/Plugin/views/pager/CalendarPager.php
CalendarYearMonthDate.php in src/Plugin/views/argument/CalendarYearMonthDate.php
CalendarYearWeekDate.php in src/Plugin/views/argument/CalendarYearWeekDate.php
1 string reference to 'CalendarHelper'
calendar.services.yml in ./calendar.services.yml
calendar.services.yml
1 service uses CalendarHelper
calendar.helper in ./calendar.services.yml
Drupal\calendar\CalendarHelper

File

src/CalendarHelper.php, line 18

Namespace

Drupal\calendar
View source
class CalendarHelper extends DateHelper {

  /**
   * Returns an array for day.
   *
   * @param \Drupal\views\ViewExecutable $view
   *  The view.
   *
   * @return array
   *   Empty array for day.
   *
   * @throws \Exception
   */
  public static function day(ViewExecutable $view) {
    $week_header = self::buildWeekHeader($view->styleInfo
      ->getDayNameSize());
    $calendar_arguments = self::getCalendarArguments($view);
    foreach ($calendar_arguments as $date_argument) {
      $date = new DrupalDateTime($date_argument['argument']);
    }
    $week_counter = self::weekInfoDate($date)['weekno'];
    $caldays[$week_counter]['weekdays'][$date
      ->format('Ymd')] = [
      'header' => $week_header[(int) $date
        ->format('w')],
      'date' => $date
        ->format('d'),
      'multiday' => [],
      'allday' => [],
      'other' => [],
    ];

    // Add start- and enddate since we need this for offset calculations and linkdata.
    $info = self::weekInfoDate($date);
    $caldays[$info['weekno']]['startweekdate'] = $info['startweekdate'];
    $caldays[$info['weekno']]['endweekdate'] = $info['endweekdate'];
    return $caldays;
  }

  /**
   * Returns an array for week.
   *
   * @param \Drupal\views\ViewExecutable $view
   *  The view.
   *
   * @return array
   *   Empty array for week.
   *
   * @throws \Exception
   */
  public static function week(ViewExecutable $view) {
    $week_header = self::buildWeekHeader($view->styleInfo
      ->getDayNameSize());
    $calendar_arguments = self::getCalendarArguments($view);
    foreach ($calendar_arguments as $date_argument) {
      $week_info = self::weekInfo($date_argument['argument']);

      // Week_header is already ordered so use that.
      $week_header_keys = array_keys($week_header);
      $week_header_day = array_shift($week_header_keys);
      $date = clone $week_info['startweekdate'];
      $end_date = clone $week_info['endweekdate'];
      do {
        $caldays[$week_info['weekno']]['weekdays'][$date
          ->format('Ymd')] = [
          'header' => $week_header[$week_header_day],
          'date' => $date
            ->format('d'),
          'multiday' => [],
          'allday' => [],
          'other' => [],
        ];
        $date
          ->add(new DateInterval('P1D'));
        if ($week_header_day < 6) {
          $week_header_day++;
        }
        else {
          $week_header_day = 0;
        }
      } while ($date <= $end_date);

      // Add start- and enddate since we need this for offset calculations and linkdata.
      $caldays[$week_info['weekno']]['startweekdate'] = $week_info['startweekdate'];
      $caldays[$week_info['weekno']]['endweekdate'] = $week_info['endweekdate'];
    }
    return $caldays;
  }

  /**
   * Returns an array for month.
   *
   * @param ViewExecutable $view
   *   The view.
   *
   * @return array
   *   Empty array for month.
   *
   * @throws \Exception
   */
  public static function month(ViewExecutable $view) {
    $week_header = self::buildWeekHeader($view->styleInfo
      ->getDayNameSize());
    $calendar_arguments = self::getCalendarArguments($view);
    foreach ($calendar_arguments as $date_argument) {

      // Get first and last day from month in argument.
      $start_date = new DrupalDateTime($date_argument['argument'] . '01');
      $first_week_info = self::weekInfo($start_date
        ->format('Y') . $start_date
        ->format('W'));
      $end_date = clone $start_date;
      $end_date
        ->modify("last day of this month");
      $year = $end_date
        ->format('Y');
      if ($end_date
        ->format('W') < $start_date
        ->format('W')) {
        $year++;
      }
      $last_week_info = self::weekInfo($year . $end_date
        ->format('W'));

      // Build array with days per week with prefixes and suffixes.
      $caldays = [];
      $week_counter = $first_week_info['weekno'];
      $week_counter_max = $last_week_info['weekno'];

      // Correct for new year by calculating number of weeks in diff.
      if ($end_date
        ->format('W') < $start_date
        ->format('W')) {
        $week_counter_max = $week_counter + (int) floor($first_week_info['startweekdate']
          ->diff($last_week_info['startweekdate'])->days / 7);
      }
      do {
        $week_date = $first_week_info['startweekdate'];
        $week_end_date = clone $week_date;
        $week_end_date
          ->add(new DateInterval('P6D'));
        $calweek = [];

        // $week_header is already ordered so use first key.
        foreach ($week_header as $key => $value) {
          $week_header_day = $key;
          break;
        }

        // Inner loop to construct days for each week, some of which may be prefix or suffix.
        do {
          $calweek[$week_date
            ->format('Ymd')] = [
            'header' => $week_header[$week_header_day],
            'date' => $first_week_info['startweekdate']
              ->format('d'),
            'multiday' => [],
            'allday' => [],
            'other' => [],
          ];
          if ($week_date < $start_date) {
            $calweek[$week_date
              ->format('Ymd')]['class'] = 'prefix';
          }
          elseif ($week_date > $end_date) {
            $calweek[$week_date
              ->format('Ymd')]['class'] = 'suffix';
          }
          $week_date
            ->add(new DateInterval('P1D'));
          if ($week_header_day < 6) {
            $week_header_day++;
          }
          else {
            $week_header_day = 0;
          }
        } while ($week_date <= $week_end_date);

        // Add start- and enddate since we need this for offset calculations.
        $calweek_keys = array_keys($calweek);
        $startweekdate = new DateTime(array_shift($calweek_keys));
        $endweekdate = new DateTime(array_pop($calweek_keys));
        $caldays[$week_counter] = [
          'startweekdate' => $startweekdate,
          'endweekdate' => $endweekdate,
          'weekdays' => $calweek,
        ];
        $week_counter++;
      } while ($week_counter <= $week_counter_max);
    }
    return $caldays;
  }

  /**
   * Helper function to build header with days for a week.
   *
   * @param int $day_name_size
   *   An int configuring the presentation of the day name.
   *
   * @return array
   *   Complete header for week days.
   */
  public static function buildWeekHeader($day_name_size) {
    switch ($day_name_size) {
      case '1':
        $weekdays = DateHelper::weekDaysAbbr1(TRUE);
        $week_header = DateHelper::weekDaysOrdered($weekdays);
        break;
      case '2':
        $weekdays = DateHelper::weekDaysAbbr2(TRUE);
        $week_header = DateHelper::weekDaysOrdered($weekdays);
        break;
      case '3':
        $weekdays = DateHelper::weekDaysAbbr(TRUE);
        $week_header = DateHelper::weekDaysOrdered($weekdays);
        break;
      default:
        $weekdays = DateHelper::weekDays(TRUE);
        $week_header = DateHelper::weekDaysOrdered($weekdays);
    }
    return $week_header;
  }

  /**
   * Helper function to find the calendar date argument handlers for a view.
   *
   * @param \Drupal\views\ViewExecutable $view
   *  The view.
   *
   * @return array|false
   *   Returns the argument handler if one is found, or FALSE otherwise.
   */
  public static function getCalendarArguments(ViewExecutable $view) {
    $calendar_arguments = [];
    foreach ($view->argument as $argument) {
      if (substr($argument
        ->getPluginId(), 0, 9) === 'calendar_') {
        $date = new DrupalDateTime($argument->argument);
        if ($date
          ->hasErrors()) {
          $now = new DrupalDateTime();
          switch ($argument
            ->getPluginId()) {
            case 'calendar_year_month':
              $argument->argument = $now
                ->format('Ym');
              break;
            case 'calendar_year_week':
              $argument->argument = $now
                ->format('YW');
              break;
            case 'calendar_day':
              $argument->argument = $now
                ->format('Ymd');
              break;
          }
        }
        $calendar_arguments[] = [
          'field' => str_replace('_value', '', $argument->realField),
          'argument' => $argument->argument,
          //          'plugin' => $argument->getPlugin(),
          'id' => $argument
            ->getPluginId(),
        ];
      }
    }
    if ($calendar_arguments) {
      return $calendar_arguments;
    }
    else {
      return FALSE;
    }
  }

  /**
   * Helper function to return start- and enddate for week
   *
   * @param string $date_argument
   *   The date argument string
   * @param string $id
   *   The optional calendar argument plugin
   *
   * @return array
   *   An array containing startweekdate and endweekdate
   *
   * @throws \Exception
   */
  public static function weekInfo($date_argument) {
    $week = NULL;
    $startweekdate = new DrupalDateTime();
    $year = (int) substr($date_argument, 0, 4);
    $week = (int) substr($date_argument, 4);
    $startweekdate
      ->setISOdate($year, $week);

    // Get first day of week from Drupal config and move day by diff
    $first_day_week = Drupal::config('system.date')
      ->get('first_day');
    if ($first_day_week === 0) {
      $week_start_day = self::WeekDays()[$first_day_week]
        ->getUntranslatedString();
      $startweekdate
        ->modify($week_start_day . ' previous week');
    }
    else {
      $week_start_day = self::WeekDays()[$first_day_week]
        ->getUntranslatedString();
      $startweekdate
        ->modify($week_start_day . ' this week');
    }
    $endweekdate = clone $startweekdate;
    $endweekdate
      ->add(new \DateInterval('P6DT23H59M59S'));
    return [
      'startweekdate' => $startweekdate,
      'endweekdate' => $endweekdate,
      'weekno' => $week,
    ];
  }
  public static function weekInfoDate($date) {
    $startweekdate = new DrupalDateTime($date);

    // Get first day of week from Drupal config and move day by diff
    $first_day_week = Drupal::config('system.date')
      ->get('first_day');
    $week_start_day = self::WeekDays()[$first_day_week]
      ->getUntranslatedString();
    if ($first_day_week === 0) {

      //} && $date->format('w') === '0') {
      if ($startweekdate
        ->format('w') === '0') {

        // do nothing
        // $startweekdate->modify($week_start_day . ' this week');
      }
      else {
        $startweekdate
          ->modify($week_start_day . ' previous week');
      }
    }
    else {
      if ($startweekdate
        ->format('w') < $first_day_week) {
        $startweekdate
          ->modify('previous ' . $week_start_day);
      }
      else {
        $startweekdate
          ->modify($week_start_day . ' this week');
      }
    }
    $week = $startweekdate
      ->format('W');

    // Add time because this function is used in arguments
    $endweekdate = clone $startweekdate;
    $endweekdate
      ->add(new \DateInterval('P6DT23H59M59S'));
    return [
      'startweekdate' => $startweekdate,
      'endweekdate' => $endweekdate,
      'weekno' => $week,
    ];
  }

  /**
   * Helper function to build array with hours.
   *
   * @TODO make this configurable as 24hr or AM/PM.
   *
   * @return array
   *   Array with hours formatted as h:i.
   */
  public static function buildDayHours() {
    $day_hours = [];
    $i = 0;
    do {
      $day_hours[sprintf("%05.2f", $i)] = NULL;
      $i++;
    } while ($i < 24);
    return $day_hours;
  }

  /**
   * Get views that (may) act as Calendar Display.
   * Used to select views with other granularity to link to.
   *
   * @param \Drupal\views\ViewExecutable|NULL $view
   *  The view.
   *
   * @return array
   *   Array with view displays that have Calendar arguments.
   *
   * @throws \Exception
   */
  public static function getCalendarDisplays(ViewExecutable $view = NULL) {
    $displays = $views = [];
    if (!$view) {
      $views_all = Drupal::entityTypeManager()
        ->getStorage('view')
        ->loadMultiple();
    }
    else {
      $views_all[$view->storage
        ->id()] = Drupal::entityTypeManager()
        ->getStorage('view')
        ->load($view->storage
        ->id());
    }
    foreach ($views_all as $view_id => $all_view) {
      foreach ($all_view
        ->get('display') as $key => $display) {
        if (isset($display['display_options']['style']['type']) && $display['display_options']['style']['type'] === 'calendar') {
          $view = View::load($view_id)
            ->getExecutable()
            ->executeDisplay($key);
          $views[] = $view['#view'];
        }
      }
    }
    foreach ($views as $view) {
      $arguments = self::getCalendarArguments($view);
      if ($arguments) {
        $plugin = explode('_', $arguments[0]['id']);
        $displays[array_pop($plugin)] = [
          'route' => 'view' . '.' . $view->storage
            ->id() . '.' . $view->current_display,
          'title' => $view->storage
            ->label() . ' : ' . $view->displayHandlers
            ->get($view->current_display)->display['display_title'],
          'view' => $view,
        ];
      }
    }
    return $displays;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
CalendarHelper::buildDayHours public static function Helper function to build array with hours.
CalendarHelper::buildWeekHeader public static function Helper function to build header with days for a week.
CalendarHelper::day public static function Returns an array for day.
CalendarHelper::getCalendarArguments public static function Helper function to find the calendar date argument handlers for a view.
CalendarHelper::getCalendarDisplays public static function Get views that (may) act as Calendar Display. Used to select views with other granularity to link to.
CalendarHelper::month public static function Returns an array for month.
CalendarHelper::week public static function Returns an array for week.
CalendarHelper::weekInfo public static function Helper function to return start- and enddate for week
CalendarHelper::weekInfoDate public static function
DateHelper::ampm public static function Constructs an array of AM and PM options.
DateHelper::dayOfWeek public static function Returns day of week for a given date (0 = Sunday).
DateHelper::dayOfWeekName public static function Returns translated name of the day of week for a given date.
DateHelper::days public static function Constructs an array of days in a month.
DateHelper::daysInMonth public static function Identifies the number of days in a month for a date.
DateHelper::daysInYear public static function Identifies the number of days in a year for a date.
DateHelper::hours public static function Constructs an array of hours.
DateHelper::minutes public static function Constructs an array of minutes.
DateHelper::monthNames public static function Returns a translated array of month names.
DateHelper::monthNamesAbbr public static function Constructs a translated array of month name abbreviations
DateHelper::monthNamesAbbrUntranslated public static function Constructs an untranslated array of abbreviated month names.
DateHelper::monthNamesUntranslated public static function Constructs an untranslated array of month names.
DateHelper::seconds public static function Constructs an array of seconds.
DateHelper::weekDays public static function Returns a translated array of week names.
DateHelper::weekDaysAbbr public static function Constructs a translated array of week day abbreviations.
DateHelper::weekDaysAbbr1 public static function Constructs a translated array of 1-letter week day abbreviations.
DateHelper::weekDaysAbbr2 public static function Constructs a translated array of 2-letter week day abbreviations.
DateHelper::weekDaysOrdered public static function Reorders weekdays to match the first day of the week.
DateHelper::weekDaysUntranslated public static function Constructs an untranslated array of week days.
DateHelper::years public static function Constructs an array of years in a specified range.