If you have a grouped field (such as a date, for example), the unformatted preprocessor makes an incorrect assumption.

In the ForEach, it's assumed $id correlates to the $id in $view->result (eg, a "row counter"). However this is not the case. The $id actually corresponds to the row number for the group. This means if you have lots of groups, all with single grouped values, this $id will always be 0 (zero).

Comments

Anonymous’s picture

Status: Active » Needs review
StatusFileSize
new1.49 KB

Does this patch fix the problem?

nicholasthompson’s picture

StatusFileSize
new1.87 KB

No, however that row_index is handy to know as I fixed it using a static counter ;-)

Attached is an alternative patch which includes the above patch + a fix for this issue (using the $id and the $row_index together).

pascalduez’s picture

StatusFileSize
new1.43 KB

Hi,

I'm experiencing the same issue, token replacement on row classes getting messed when grouping fields.
Patch in #1 did no resolved the issue.
Patch in #2 did no resolved the issue and thrown an error
"Invalid argument supplied for foreach() in [...]/semanticviews.module at line 36."

Using $view->row_index is indeed a good idea, but as it refers to the last rendered row index, then the incrementation overpass the result rows number.

The following patch create a static var initialized at 0, and increment it at the end of the preprocess fonctions.

Review welcome :-)

pascalduez’s picture

StatusFileSize
new1.54 KB

Okay, previous patch in #3 logically fails on pages with several views...
The following address it using a keyed array by view vid.

pascalduez’s picture

StatusFileSize
new1.58 KB

view vid doesn't work with views exported in code, thus not stored in DB.
Switched to view name...

bladwin’s picture

Does this [comment #5] patch work ... can anyone else confirm?

----- EDIT: Confirmed Working -----

bladwin’s picture

Status: Needs review » Reviewed & tested by the community

The patch in comment #5, I can confirm that it works.
I upgraded my semanticviews module to the latest 1.x-dev release before applying the patch though. Can someone else confirm that the patch also works as intended with the stable 1.1 release?

----- EDIT -----
So a few hours went by, no error messages and everything was working -- the error that appeared was an error in semanticviews.module, Line 36: (invalid argument supplied)

<?php
function semanticviews_get_token_replacements($row, $tokens) {
  $replacements = array(); 
  foreach ($row as $alias => $value) { //This is line 36
    if (!empty($tokens[$alias])) {
      $replacements[$tokens[$alias]] = $value;
    }
  }
  return $replacements;
}
?>

I changed the two "$row" args to "$row_id", which is what the patch is changing in semanticviews.theme.inc. the error moved down a line to 37 and was still an invalid argument supplied. The other strange issue is that if the error appears 8 times, it was only the last 8 rows whose tokens were not processed, the preceding rows, in multiple groups, had their tokens processed w/o any issue. I'm hoping that I will get this resolved soon, as I really need my $row $tokens to be processed in a group.

MrMaksimize’s picture

So I don't know much about semanticviews, or views coding in general, but here's how I ended up modifying a code to get this to work.

function semanticviews_get_token_replacements($row, $tokens) {
  $replacements = array();
  if (empty($row)){
    return;
  }
  if (is_object($row)){
    $row = get_object_vars($row);
  }
  foreach ($row as $alias => $value) {
    if (!empty($tokens[$alias])) {
      $replacements[$tokens[$alias]] = $value;
    }
  }
  return $replacements;
}

What was interesting is that some rows that run through this function are empty variables, therefore the warning in the foreach loop.

The second thing, I'm not sure about this, but as far as I know you can't run a foreach loop on a stdClass object. So I added the conversion to an array before the loop runs.

MrMaksimize’s picture

yay! got it working. after looking at it more it turns out that quicktabs pre-loading the views in the background was the culprit of the empty rows being passed. But the really good question is why?!? :)

djschoone’s picture

#1002714-5: Bug with Token Replacements when grouping works for me. I did not patch the semanticviews module, but made de changes in the function and placed it in template.php

/**
 * Display the simple view of rows one after another
 * patched version http://drupal.org/files/issues/grouping_field_tokens-1002714-5.patch
 */
function [yourtheme]_preprocess_semanticviews_view_unformatted(&$vars) {
  $view = $vars['view'];
  // Initialize the row index.
  static $row_index = array();
  if (!isset($row_index[$view->name])) {
    $row_index[$view->name] = 0;
  }


  $vars['group_element'] = check_plain($vars['options']['group']['element_type']);
  $vars['group_attributes'] = array();
  if ($vars['options']['group']['class']) {
    $vars['group_attributes']['class'] = $vars['options']['group']['class'];
  }

  $vars['list_element'] = check_plain($vars['options']['list']['element_type']);
  $vars['list_attributes'] = array();
  if ($vars['options']['list']['class']) {
    $vars['list_attributes']['class'] = $vars['options']['list']['class'];
  }

  // TODO: set a default or handle empty value.
  $vars['row_element'] = check_plain($vars['options']['row']['element_type']);
  $last_every_nth = $vars['options']['row']['last_every_nth'];

  $vars['row_attributes'] = array();

  // Set up striping class array.
  $stripes = array();
  if (trim($vars['options']['row']['striping_classes'])) {
    $stripes = explode(' ', trim($vars['options']['row']['striping_classes']));
  }
  $striping = count($stripes);

  // Get alias tokens.
  $tokens = semanticviews_get_alias_tokens($view);

  foreach ($vars['rows'] as $id => $row) {
    // Get the right view result row id, needed for grouped fields.
    $row_id = $row_index[$view->name] + $id;

    // Get token replacements.
    $replacements = semanticviews_get_token_replacements($view->result[$row_id], $tokens);
    // Add replacement for the row number.
    $replacements['#'] = $row_id;

    $vars['row_attributes'][$id] = array();
    $classes = array();
    if ($vars['options']['row']['class']) {
      $classes[] = strtr($vars['options']['row']['class'], $replacements);
    }
    if ($vars['options']['row']['first_class']) {
      // The FIRST class attribute can be used in two ways. When the "last every
      // nth" option is specified, the FIRST attribute is added to the class in
      // those intervals. This could be useful for grid designs where the first
      // unit in a row needs a zero width margin.
      if (($last_every_nth && $id % $last_every_nth == 0) ||
         // Otherwise when last every nth is not set, the FIRST class is added
         // to the first row in the pager set.
         (!$last_every_nth && $id == 0)) {
        $classes[] = strtr($vars['options']['row']['first_class'], $replacements);
      }
    }
    if ($vars['options']['row']['last_class']) {
      // The LAST class attribute can be used in two ways. When the "last every
      // nth" option is specified, the LAST attribute is added to the class in
      // those intervals. This could be useful for grid designs where the last
      // unit in a row needs a zero width margin.
      if (($last_every_nth && ($id + 1) % $last_every_nth == 0) ||
         // Otherwise when last every nth is not set, the LAST class is added
         // to the last row in the pager set.
         (!$last_every_nth && ($id + 1) == count($vars['rows']))) {
        $classes[] = strtr($vars['options']['row']['last_class'], $replacements);
      }
    }

    if ($striping) {
      $classes[] = strtr($stripes[$id % $striping], $replacements);
    }

    if (!empty($classes)) {
      $vars['row_attributes'][$id]['class'] = implode(' ', $classes);
    }
  }
  // Increment the row index for next call.
  $row_index[$view->name] = $view->row_index + 1;
}
Scyther’s picture

Issue summary: View changes
Status: Reviewed & tested by the community » Closed (won't fix)

D6 no longer supported. It will not be fixed.