When you have a calendar view created from template. When you use the pagination, the tabs no longer work.
E.g. you go to your calendar/day page and go to the next day. The URL shift to /calendar/day/20170409. This means the tabs are also formed similarly. E.g. /calendar/month/20170409 for the month tab. This URL doesn't work, because the month expects something like /calendar/month/201704
Changing the contextual filters so e.g. the month display uses the full date, makes sure not the entire month is shown.

This seems related to behaviour in core where arguments are added to the tabs when using them, so unsure on how to fix this.

Issue fork calendar-2867991

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

daften created an issue. See original summary.

sleepingmonk’s picture

Calendar View Date Arguments cause Page not found when argument string is longer than format expects:

i.e.
argument = 20170523 (Ymd)
validation_format = 'Ym'

Either in link generation (view tabs) or in argument validation, we need to alter the argument value to match the expected validation format.

YW format already tries to do something like this:

FROM DateArgumentWrapper.php

  protected function createFromFormat($value) {
    $format = $this->getArgFormat();
    if ($format == 'YW') {
      $date = new \DateTime();
      $year = (int)substr($value, 0, 4);
      $month = (int)substr($value, 4, 2);
      $date->setISODate($year, $month);
    }
    else {
      // Adds a ! character to the format so that the date is reset instead of
      // using the current day info, which can lead to issues for months with
      // 31 days.
      $format = '!' . $this->getArgFormat();
      $date =  \DateTime::createFromFormat($format, $value);
    }
    return $date;
  }

I will continue to work on this and provide a patch as soon as I can.

jeremylichtman’s picture

Just started tracing the issue.

I put some kint statements in createFromFormat to see what it is doing.

It appears to take the date format from the current view display, rather than trying to determine the type of display that the tab would be for.

This is an obvious statement, but it may be tricky to try to obtain the correct formats out of the view, since the tabs at that point consist only of a path and a string (i.e. "Month" - which could be translated as well).

jeremylichtman’s picture

The following is a work-around, since it is overriding the tabs instead of re-architecting how the calendar module creates them in the first place. The code deals with url params (i.e. form options) as well. In a production environment, this should probably be refactored into a set of helper functions.

/**
 * Implements hook_menu_local_tasks_alter().
 * Ensure that the date portion of the tab url is in the correct format.
 */
function YOUR_MODULE_menu_local_tasks_alter(&$data, $route_name) {
  // Needs to be set to the specific calendar view's machine id.
  $view_name = 'view.VIEW_NAME';

  // Needs to be set to the default type of display (i.e. day / week / month / year)
  $default_display = 'month';

  if (strpos($route_name, $view_name) !== FALSE) {
    // Work out what display we're currently on.
    $route_name_find = $view_name . '.page_';
    $route_name_temp = str_replace($route_name_find, '', $route_name);
    
    // If default, we still need to parse out the dates.
    if ($route_name_temp == '') {
      $route_name_temp = $default_display; 
    }
    
    // Check to see if a query string exists
    $current_uri = \Drupal::request()->getRequestUri();
    $uri_parts = explode('?', $current_uri);
    
    // If a query string exists, set it as an option on the pager links.
    if (isset($uri_parts[1])) {
      // Get the query into an array.
      $query = urldecode($uri_parts[1]);
      parse_str($query, $query_parts);

      // Clean up array params.
      foreach ($query_parts as $index => $query_part) {
        // If we are dealing with a "multiple" option.
        if (is_array($query_part)) {
          // Save it temporarily.
          $temp_key = $index;
          $temp_part = $query_part;

          // Remove it from the index of query items.
          unset($query_parts[$index]);

          // Create separate keyed items in our param array for each
          // of the "multiple" options.
          $key_parts = explode('[', $temp_key);
          foreach ($temp_part as $temp_index => $temp_item) {
            $new_key = $key_parts[0] . '[' . $temp_index . ']';
            $query_parts[$new_key] = $temp_item;
          }
        }
      }

      $query_keys = array_keys($query_parts);
      $query_values = array_values($query_parts);
    }
  
 
    // Process the tabs.
    $tabs = $data['tabs'][0];
    foreach ($tabs as $tab_name => $tab) {
      // Try to figure out what type of tab it is.
      $tab_name_find = 'views_view:' . $view_name . '.page_';
      $tab_name_temp = str_replace($tab_name_find, '', $tab_name);
      $link = $tab['#link'];
      $url = $link['url'];
      $params = $url->getRouteParameters();
      $date_param = $params['arg_0'];

      if (!is_null($date_param)) {
        // Try to turn the param into an actual date.
        $new_date = 0;
        if ($route_name_temp == 'day') {
          // format is yyyymmdd
          $year = substr($date_param, 0, 4);
          $month = substr($date_param, 4, 2);
          $day = substr($date_param, 6, 2);
          $new_date = mktime(0, 0, 0, $month, $day, $year);
        }
        else if ($route_name_temp == 'week') {
          // format is yyyyww
          $year = substr($date_param, 0, 4);
          $week = substr($date_param, 4, 2);
          $new_date = strtotime("01 Jan " . $year . " 00:00:00 GMT + " . $week . " weeks");
        }
        else if ($route_name_temp == 'month') {
          // format is yyyymm
          $year = substr($date_param, 0, 4);
          $month = substr($date_param, 4, 2);
          $day = 1;
          $new_date = mktime(0, 0, 0, $month, $day, $year);
        }      
        else if ($route_name_temp == 'year') {
          // format is yyyy 
          $year = substr($date_param, 0, 4);
          $month = 1;
          $day = 1;
          $new_date = mktime(0, 0, 0, $month, $day, $year);
        }

        // Now figure out what sort of date format we need for the tab.
        if ($new_date != 0) {
          if ($tab_name_temp == 'day') {
            $new_date = date('Ymd', $new_date);
          }
          else if ($tab_name_temp == 'week') {
            $new_date = date('YW', $new_date);
          }
          else if ($tab_name_temp == 'month') {
            $new_date = date('Ym', $new_date);
          }
          else if ($tab_name_temp == 'year') {
            $new_date = date('Y', $new_date);
          }
          
          // Push the param back in.
          $data['tabs'][0][$tab_name]['#link']['url']->setRouteParameter('arg_0', $new_date);
          
          // Put any query params back in as well.
          if (!empty($query_parts)) {
            $data['tabs'][0][$tab_name]['#link']['url']->setOption('query', $query_parts);
          }
        }
      }
    }
  }
}
pslcbs’s picture

Hi,
I think this issue is fixed with attached patch.
Inactive tabs now have clean paths without incorrect dates after using pagers.
I don't know if is the best approach but it works for me.

Neslee Canil Pinto’s picture

Status: Needs review » Needs work
Issue tags: +Needs reroll
jedsaet’s picture

Status: Needs work » Needs review
Issue tags: -Needs reroll
FileSize
886 bytes

Straight re-roll of #5.

Status: Needs review » Needs work

The last submitted patch, 7: tab_navigation_not_working_after_using_pager-2867991-7.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

rokzabukovec’s picture

Status: Needs work » Needs review
FileSize
2.41 KB
2.45 KB

The patch from #7 applied cleanly and works but it has some problems with coding standards. I applied the patch and fix coding standard errors and created a new patch. See interdiff for details. Marking this as "Needs review".

Status: Needs review » Needs work

The last submitted patch, 9: 2867991-9.patch, failed testing. View results

nikitagupta’s picture

Status: Needs work » Needs review
FileSize
2.67 KB

fixed coding standard errors.

Status: Needs review » Needs work

The last submitted patch, 11: 2867991-11.patch, failed testing. View results

nikitagupta’s picture

Status: Needs work » Needs review
Neslee Canil Pinto’s picture

Status: Needs review » Needs work
Issue tags: +Needs reroll

Patch needs reroll

Suresh Prabhu Parkala’s picture

Assigned: Unassigned » Suresh Prabhu Parkala
Suresh Prabhu Parkala’s picture

Status: Needs work » Needs review
FileSize
1.67 KB

Re-rolled patch please review.

Status: Needs review » Needs work

The last submitted patch, 16: 2867991-16.patch, failed testing. View results

kyoder’s picture

Here's an updated patch.

manishsaharan’s picture

Version: 8.x-1.x-dev » 8.x-1.0-alpha4
Assigned: Suresh Prabhu Parkala » Unassigned
Status: Needs work » Needs review
Issue tags: -Needs reroll +Needs tests
FileSize
2.95 KB

After applying #18 patch, tabs were working fine, but there are some another issues for Year Calendar.
To reproduce that apply #18 patch and click on Year tab

  1. 1. First issue you will see is "Website Encountered Error."
  2. 2. Once you fix first issue then you will see theme is completely broken for Year calendar

This patch fixes all of these issues.
Test with Drupal 9.4 and Calendar 8.x-1.0-alpha4 version

igork96’s picture

I reroled the patch from #19, it was breaking the style and it had warning error when you visit the year view of the calendar. Test with Drupal 9.4 and Calendar 8.x-1.0-alpha4 version.

solideogloria’s picture

Version: 8.x-1.0-alpha4 » 8.x-1.x-dev

Issues should target dev. Test the patch with dev, not just alpha

igork96’s picture

Here is a patch against 8.x-1.x-dev for testing.

mortona2k’s picture

Status: Needs review » Reviewed & tested by the community

Patch #23 fixed it for me. It works by altering the local tasks and removing extra arguments from the path. Maybe we should check in the css changes separately if those aren't necessary for this.