Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Drupal - How can I make an array globally accessible?

I'm using this code in a views field template (in this case views-view-field--all-members--uid.tpl.php):

<?php

$users_friends = flag_friend_get_friends($user->uid);

$users_friends_ids = array();

foreach ($users_friends as $id => $value) {     
 $users_friends_ids[] = $id;    
}


?>

It basically gets the user ids of friends and puts them in an array so I can check if the field matches any of the user ids.

So my problem is that I don't want to have this within this template (for a few reasons), but if I don't I can't access the array. How can I make this array globally accessible?

like image 981
james6848 Avatar asked Apr 17 '11 22:04

james6848


2 Answers

Without knowing your "few reasons", I can't say if this is the answer for sure. My own reasons would probably be that I don't want the same code executing a bunch of times, and I'd rather not have the same exact code in multiple places.

I would then create a function with a static variable to hold the friends array.

function mymodule_get_friends_ids() {
  // pull in the current global user variable
  global $user;

  // call up the static variable
  static $users_friends_ids;
  // return if this static var has already been set
  if (is_array($users_friends_ids)) {
    return $users_friends_ids;
  }

  // if we hit here, then this function has not been
  // run yet for this page load.

  // init array
  $users_friends_ids = array();

  // if user is anon, no need to go on
  if (user_is_anonymous()) {
    return $users_friends_ids;
  }

  // get friends array
  $users_friends = flag_friend_get_friends($user->uid);

  // build ids array
  foreach ($users_friends as $id => $value) {     
    $users_friends_ids[] = $id;    
  }

  return $users_friends_ids;
}

Now in your templates, you can call mymodule_get_friends_ids() in as many places as you want, and the working code below the first return will only get executed the first time it is called.

like image 85
Coder1 Avatar answered Sep 18 '22 17:09

Coder1


Coder1's advice is very good - it keeps you from populating your global variable namespace with a lot of junk. It's probably the most "elegant." It might not be the easiest to use if you are rather new to PHP (which I'm guessing might be the case if it's hard to get your head around returning arrays, but that's ok).

However, if this is really a priority, you probably don't care about having one extra global variable.

I suppose I may be stating the obvious here - but you can, at pretty much any point in execution (provided the information you need has already been generated - e.g., the $user variable has been populated), do this:

$GLOBALS['users_friends_ids'] = /* your code goes here */

Then in your template, you access this by ...

$friendsArray = $GLOBALS['users_friends_ids'];

Or you can simply use the construct

global $user_friends_ids;

when you want to initialize the variable, or access it inside a function or class (which is the case for your template files - they are called inside functions, so you need to globalize or use the $GLOBALS array, which is "automagically" all of the variables active in the global namespace).

The most "logical" place to do this would be inside a module using one of the many hooks available, to execute this code only once. hook_init() might do it for you, if the user object is already loaded at this point (not sure, you'll have to test). But you might not want to figure out making Drupal modules (it's not that difficult).

If you are doing this inside a template (and though it's not good practice, many Drupal site owners with a beginning knowledge of PHP put everything in templates), you'll want to know which template code is being executed when. Node template code tends to be executed before page template code - which is logical, since otherwise the variables for node content in the page template wouldn't be populated.

If you have listings of nodes, they'll be calling this code multiple times, so you'll end up doing something similar to what Coder1 is describing. If you don't want to create your own small module, you could put the function declaration he's written in your theme's template.php file, since it's called only once. You don't want to put function declarations in the tpl.php files, since they are sometimes called more than once (and you aren't allowed to declare functions more than once).

If you have a hard time understanding the function and the return, you can always do something like this in your code (which is very, very inelegant - but it's better to have inelegant code that you do understand, than elegant code that's you don't).

if(!isset($GLOBALS['users_friends_ids'])) {
   $GLOBALS['users_friends_ids'] = /* your code here */
}
like image 34
James Avatar answered Sep 19 '22 17:09

James