Skip to Navigation

Controlling pane visibility in Drupal Panels2

Printer-friendly version

We're working on a social networking site, and one requirement is that only a user's buddies can see certain profile information by default. The site uses buddylist and I'd installed Private nodes to allow users to designate who can see nodes they contribute. But for their profile, limiting visibility to a user's buddies was a final requirement. We spent a good bit of time this morning reading the Panels2 API to figure out if we could programatically control the visibility of panes within a mini-panel or panel page. By using Panels' hook_panels_pane_content_alter() hook, we were able to implement this easily.

We already had a module to customize the site, and we added the hook and a helper function to it. First we needed a way to test if the logged in user was the buddy of the profile being viewed.

   1:<?php
   2:/**
   3: * Tests is the logged in user is a buddy of the specified uid
   4: * @param integer user id
   5: */
   6:function user_is_buddy($uid)
   7:{
   8:    static $is_buddy;
   9:    static $user_buddies;
  10:    global $user; // logged in user
  11:
  12:
  13:    if (!isset($is_buddy[$uid]))
  14:    {
  15:        if (!isset($user_buddies))
  16:        {
  17:            $user_buddies = array_keys(buddylist_get_buddies($user->uid, 'uid'));
  18:        }
  19:
  20:        // users are their own buddies
  21:        if ($uid == $user->uid)
  22:        {
  23:            $is_buddy[$uid] = true;
  24:        }
  25:        else if (!empty($uid))
  26:        {
  27:            $is_buddy[$uid]= in_array($uid, $user_buddies);
  28:        }
  29:        else
  30:        {
  31:            $is_buddy[$uid] = false;
  32:        }
  33:    }
  34:
  35:    return $is_buddy[$uid];
  36:}
  37:
  38:

In our implementation of the alter content hook, we simply remove the content we do not want to display if our is_buddy test fails by setting it to null. If content is empty, then the pane does not display at all. For most panes, the delta attribute should be sufficient to identify it, but some panes, like node fields and node field groups, have different deltas per user, so we had to rely on the subject property instead.

   1:<?php
   2:// implementation of hook_panels_pane_content_alter
   3:// http://groups.drupal.org/node/7678
   4:function my_module_panels_pane_content_alter($content, $pane, $args, $context)
   5:{
   6:    // user profile customizations
   7:    if ('user' == arg(0) && $profile_uid = (int) arg(1))
   8:    {
   9:        // don't display profile about stuff to non buddies, EVER
  10:        // delta is diff for every user
  11:        $is_buddy = user_is_buddy($profile_uid);
  12:        if ('About You' == $content->subject && false == $is_buddy)
  13:        {
  14:            $content->content = null;
  15:        }
  16:
  17:        // don't display blog posts to non-buddies
  18:        if ('blogs_user_id'== $content->delta && false == $is_buddy)
  19:        {
  20:            $content->content = '';
  21:        }
  22:    }
  23:
  24:    return $content;
  25:}