I'm using Drupal 7.4 and I've enabled the 'Popular content' view of Views 3 (latest dev version). There, I've restricted the access to administrators only.

If an anonymous user accesses /popular of the 'Popular content' view, he gets the following warning:

Warning: array_shift() expects parameter 1 to be array, string given in views_page_title_pattern_alter() (Line 18 /home/staging/public_html/d7/sites/all/modules/page_title/modules/views.page_title.inc).

Warning: array_shift() expects parameter 1 to be array, string given in views_page_title_pattern_alter() (Line 19 /home/staging/public_html/d7/sites/all/modules/page_title/modules/views.page_title.inc).
CommentFileSizeAuthor
#4 1228006-4-pagetitle-views_args.patch970 bytesjeffschuler

Comments

jg314’s picture

I am getting this same error using Drupal 7.7 with Views 7.x-3.0-rc1. Any suggestions?

carl.brown’s picture

I've been encourntering the same thing... It seems that in some cases, $args is not an array, hence the warning ( array_shift() can only operate on an array ).

To get around the warning, I just checked if it's an array first, however, it doubt that this is the greatest idea as the rest of the views_page_title_pattern_alter() could still potentially run I think.

Not submitting a patch, as I don't think this is the right solution!

Here's the revisted function from views.page_title.inc

/**
 * @file
 * Views implementations of the page title hooks
 */


/**
 * Implementation of hook_page_title_alter().
 */
function views_page_title_pattern_alter(&$pattern, &$types) {
  $menu = menu_get_item();

  if ($menu['page_callback'] == 'views_page') {
    // Get the args, name and display_id
    $args = $menu['page_arguments'];

    if (is_array($args)) {
      // In some cases, this isn't an array, it's a BLOB or something.
      // As a result, array_shift throws a warning.
      // AFAIK, the assigned variables are never used,
      // They're just stripped out of the way so that what's left can be tested against later
      // See this bug: http://drupal.org/node/1228006
      $name = array_shift($args);
      $display_id = array_shift($args);
    }

    // Get the active page view
    $view = views_get_page_view();

    // If there is no view - then return - this helps protect from errors below
    if (!$view) return;

    // If there are args for this view, process to see if this argument has a SPECIFIC page title pattern
    if (!empty($args) && !empty($view->argument)) {
      // Grab the argument handlers
      $h = $view->argument;

      // Splice the arguments and get the key for the current arg.
      $h = array_shift(array_splice($h, count($args)-1, 1));

      // Get the Page Title Pattern from the options array for this handler
      $pattern = isset($h->options['page_title_pattern']) ? $h->options['page_title_pattern'] : $pattern;

      // If a page title pattern was found AND it contains a "%", assume there are placeholders and apply the %1, %2 type placeholder replacement.
      if (strpos($pattern, '%') !== FALSE) {
        // Grab the pre-built substitutions
        $subs = $view->build_info['substitutions'];

        // Apply any subs to the pattern
        $pattern = str_replace(array_keys($subs), $subs, $pattern);
      }
    }
    // This is a view with no args provided, or the specific arg has no title - lets use the base display title
    elseif ($view->display_handler->display->display_plugin == 'page_with_page_title') {
      $pattern = $view->display_handler->get_option('page_title_pattern');
    }
  }
}
nagiek’s picture

Are the maintainers looking into this problem? I also have this issue.

jeffschuler’s picture

Version: 7.x-2.5 » 7.x-2.x-dev
Status: Active » Needs review
StatusFileSize
new970 bytes

Well, it may not be the right solution, but maybe more likely to get reviewed if we make a patch and mark as such. :)

marcoka’s picture

i can confirm this. anonymous user, message from logfile

Warning: array_shift() expects parameter 1 to be array, string given in views_page_title_pattern_alter() (Zeile 19 von /var/www/test/sites/all/modules/contrib/page_title/modules/views.page_title.inc).

marcoka’s picture

any opinions of the maintainers on this patch? i mean its a small one and seems to work.

nicholasthompson’s picture

Status: Needs review » Fixed

It looks like $args remains serialized on a 403... How odd!

I have applied a different patch, one that just return FALSE; as I personally wouldn't want Page Title to be messing about with SEO on a 403 page where Drupal hasn't even finished unserializing the menu page arguments - it looks like very uncertain waters to be treading in. There might even be chunks of the Views API which aren't loaded.

Nice catch - Patch committed to dev. Tagged release soon.

(FYI)


[nthompson@localhost page_title]$ git diff
diff --git a/modules/views.page_title.inc b/modules/views.page_title.inc
index b48ce16..6f8ac32 100644
--- a/modules/views.page_title.inc
+++ b/modules/views.page_title.inc
@@ -13,8 +13,16 @@ function views_page_title_pattern_alter(&$pattern, &$types) {
   $menu = menu_get_item();

   if ($menu['page_callback'] == 'views_page') {
-    // Get the args, name and display_id
+    // Get the args from the menu router
     $args = $menu['page_arguments'];
+
+    // On a 403, the $args remain unserialized. In the event of this happening
+    // I think we would rather abort here than tread in uncerain waters.
+    if (!is_array($args)) {
+      return FALSE;
+    }
+
+    // Strip the name and display_id out so we're left with Views Args
     $name = array_shift($args);
     $display_id = array_shift($args);
nicholasthompson’s picture

Actually... I just realised D6 had the error fixed in it anyway just adding an is_array() check at the beginning. This is a far more simple fix + it keeps it consistent with D6...

-  if ($menu['page_callback'] == 'views_page') {
+  if ($menu['page_callback'] == 'views_page' && is_array($menu['page_arguments'])) {

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

summit’s picture

Hi, Is this fix (#8) committed please?

Edit: Somehow I also needed to add a end-bracket (}) to the end to get this working, complete file:

/**
 * Implementation of hook_page_title_alter().
 */
function views_page_title_pattern_alter(&$pattern, &$types) {
  $menu = menu_get_item();

  if ($menu['page_callback'] == 'views_page' && is_array($menu['page_arguments'])) {
    // Get the args, name and display_id
    $args = $menu['page_arguments'];
    $name = array_shift($args);
    $display_id = array_shift($args);

    // Get the active page view
    $view = views_get_page_view();

    // If there is no view - then return - this helps protect from errors below
    if (!$view) return;

    // If there are args for this view, process to see if this argument has a SPECIFIC page title pattern
    if (!empty($args) && !empty($view->argument)) {
      // Grab the argument handlers
      $h = $view->argument;

      // Splice the arguments and get the key for the current arg.
      $h = array_shift(array_splice($h, count($args)-1, 1));

      // Get the Page Title Pattern from the options array for this handler
      $pattern = isset($h->options['page_title_pattern']) ? $h->options['page_title_pattern'] : $pattern;

      // If a page title pattern was found AND it contains a "%", assume there are placeholders and apply the %1, %2 type placeholder replacement.
      if (strpos($pattern, '%') !== FALSE) {
        // Grab the pre-built substitutions
        $subs = $view->build_info['substitutions'];

        // Apply any subs to the pattern
        $pattern = str_replace(array_keys($subs), $subs, $pattern);
      }
    }
    // This is a view with no args provided, or the specific arg has no title - lets use the base display title
    elseif ($view->display_handler->display->display_plugin == 'page_with_page_title') {
      $pattern = $view->display_handler->get_option('page_title_pattern');
    }
  }
}

Thanks in advance if so!
Greetings, Martijn

summit’s picture

Issue summary: View changes

added Drupal version