I have a use case where I am allowing users to create nodes (in particular, nodes called saved_search that store parameters for Apache Solr searches), and a block is created for each saved_search node via hook_block_info and hook_block view implementations. I want to have these blocks available in a custom homebox page, but using some complex custom access rules (each user can create saved_search nodes, but could have access to other search nodes, depending on whether or not they are made public in the users organic group or made public to all users, etc.). In other words, the blocks available to each user will be different for each user. I have a custom hook_homebox implementation written, and for the blocks array element, it returns a list of the available blocks after being run through the access checks:

/**
 * Helper function to get all source and saved search blocks available to the user.
 */
function mymodule_dashboard_get_blocks() {
  // Get all blocks generated by saved_search nodes.
  global $user;
  $data_access = mymodule_get_searches($user, 'saved_search');  
  // Create saved_search blocks.
  foreach ($data_access as $nid) {
    $blocks['apachesolr_saved_searches_saved_search_' . $nid] = array(
      'module' => 'apachesolr_saved_searches',
      'delta' => 'saved_search_' . $nid,
      'region' => 2,
      'movable' => 1,
      'status' => 0,
      'open' => 1,
      'closable' => 1,
      'title' => '',
      'weight' => -7, 
    ); 
  }
  
  return $blocks;
}

where mymodule_get_searches($user, 'saved_search') gets a list of the saved_search nodes the user should have access to.

However, the problem I'm running into is that I can't get the blocks to be available to the user once the search has been created. After looking through the code all day, I have a feeling there's an easier way to create a pages where the blocks avaiable vary by user. Since only hook_homebox is documented the api file, could someone point me in the right direction?

Thanks.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

wonder95’s picture

After a few hours of digging through code, I found that a few small code changes will allow blocks to be made available to a specific user. The main thing preventing this was the fact that the blocks are saved as part of the homebox page in the menu hook, which means they are only added to the page when the menu router is rebuilt.

  // Created Homebox pages
  $pages = homebox_pages();
  if (is_array($pages) && count($pages) > 0) {
    foreach ($pages as $page) {
      $items[$page->settings['path']] = array(
        'title' => $page->settings['title'],
        'page callback' => 'homebox_build',
        'page arguments' => array($page->name),
        'access callback' => '_homebox_user_access_view_homebox',
        'access arguments' => array($page),
        'type' => $page->settings['menu'] ? MENU_NORMAL_ITEM : MENU_CALLBACK,
      );
      $items[$page->settings['path'] . '/block/%'] = array(
        'title' => $page->settings['title'],
        'page callback' => 'homebox_build_block',
        'page arguments' => array($page, count(explode('/', $page->settings['path'])) + 1),
        'access callback' => '_homebox_user_access_view_homebox',
        'access arguments' => array($page),
        'type' => $page->settings['menu'] ? MENU_NORMAL_ITEM : MENU_CALLBACK,
      );
    }
  }

By changing the menu hook so that only the page name is passed to homebox_build() and homebox_pre_build_user() instead of the whole $page object, then the page is built dynamically based on hook_homebox implementations at load time. I'll work on adding some caching to make this a quicker process, but for now this greatly increases flexibility.

Patch is attached.

wonder95’s picture

Category: support » feature
drumm’s picture

I think using homebox's configurable blocks will make this a lot easier. See the tracker_user block in http://drupalcode.org/project/drupalorg.git/blob/refs/heads/7.x-3.x:/dru.... You want to only have one apachesolr_saved_searches_saved_search block, and the nid is configured.

wonder95’s picture

I've looked at the configurable block keys before, but I'm not seeing how the tracker_user block applies. In my case, I need to have multiple blocks that are unique to the user, not just one block where the content is distinct for each user. As I read it, the configurable block info controls the content of the specific block, not how many blocks are displayed on the homebox page. Am I missing something?

Thanks.

Anybody’s picture

Should be solvable by #1781796: Allow modules to alter available blocks. I guess. We'll introduce a similar hook in 2.x

Anybody’s picture

Status: Needs review » Closed (won't fix)

Please create a new Drupal 8+ (3.0.x) issue, referencing this one, if this is still relevant for Drupal 8+ (3.0.x).

As this issue was created for Drupal 7 which is close to EOL and won't receive any new features here anymore (unless someone implements them or sponsors development) I'm closing this issue for cleanup now.

If anyone works on this or has a solution, feel free to reopen! :)
Thank you.