0

I'm making a module that lets users manage database records for various organizations. I'm using Drupal 7 and an very new at it. I'm logged in as the admin user. I have a menu item 'cb' that checks args and returns content generated by various functions, here it is in the menu:

function org_menu() {
  $items['org'] = array(
    'title' => 'My Orgs',
    'page callback' => 'org_show_orgs',
    'access callback' => TRUE,
  );
  $items['org/create_org'] = array(
    'title' => 'Create New Org',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('org_create_form'),
    'access callback' => TRUE,
  );
  $items['org/search_orgs'] = array(
    'title' => 'Find Orgs',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('org_search'),
    'access callback' => TRUE,
  );
  $items['org/cb'] = array(
    'type' => MENU_CALLBACK,
    'page callback' => 'custom_callback',
  );
  return $items;
}

And this is the cb function that determines what I am trying to do, and calls the appropriate content function:

function custom_callback () {
  if ( arg(2)=="edit" )
    return org_edit_org();
  if ( arg(2)=="view" ) {
    return org_show_orgs();
  }
  return "<H3>Invalid callback function: '".arg(2)."'";
}

and the actual org_get_orgs function:

function org_show_orgs() {
  global $user;
  $acctid=arg(3);
  if ( !$acctid && $user->uid==0 )
    return array('my_content' => '<H3>My Orgs</H3>Please log in to view your orgs.'.
                    '<BR><H3>Find Orgs</H3>', drupal_get_form('org_search'));

  if ( $acctid ) {
    //return "case1 arg0=".arg(0)."<BR>arg1=".arg(1)."<BR>arg2=".arg(2)."<BR>arg3="
    //              .arg(3)."<BR>arg4=".arg(5)."<BR>acctid=$acctid<BR><BR>";
    $account=user_load($acctid);
    //return "case2 arg0=".arg(0)."<BR>arg1=".arg(1)."<BR>arg2=".arg(2)."<BR>arg3="
    //              .arg(3)."<BR>arg4=".arg(5)."<BR>acctid=$acctid<BR><BR>";
    if ( $account===FALSE )
      return "<H3>Invalid acctid "+$acctid+"</H3>";
    else
      return "<H3>account was not FALSE</H3>";
  }
}

cb() gets called correctly and the org_show_orgs() function gets called as expected. arg(3) is the user id, so I can allow a user to view another user's orgs.

I hit the url http://example.com/?q=org/cb/view/1 and it works - I see admin's orgs. If I pick a userid for another user, it works - I see their orgs as well. The problem is when I tinker with the url and pass in an id of a user that doesnt exist - then I get all kinds of weirdness. For example, if I hit

http://example.com/?q=org/cb/view/4

If I uncomment that case2 line, I clearly see all my variables are correct:

case2 arg0=org
arg1=cb
arg2=view
arg3=4
arg4=
acctid=4

but if I try to test if $account===FALSE, I get the maintenance page. If I change the id to 3, I get an 'access denied' page. If I change the id to 2, I see a 'page not found' page. If I try return print_r($account,TRUE); I get the menus and a completely blank content cell. No error, which I'd get it it was a non-array object. If I try get_class($account) after I retrieve it, I get the menus but no css, and everything is just listed down the left side, no regions, themes, nothing.

Besides the $account issue, is there a better way to be doing this than that callback menu, or is that the drupal way?

1
  • 2
    user_load() is documented to return FALSE if it fails. Can you verify that it doesn't work outside of your complex workflow? If you simply run $account = user_load(4); in a standard Drupal page callback does it return FALSE?
    – Clive
    May 29, 2013 at 15:37

3 Answers 3

1

The account test probably is working, but this is wrong:

return "<H3>Invalid acctid "+$acctid+"</H3>";

If the $acctid is an integer, it's evaluating that and returning an integer. The proper php concatenation operator is '.' (without the quotes), change your return statement to

return "<H3>Invalid acctid ".$acctid."</H3>";

It'll evaluate to the string you're presumably expecting.

-1

Actually, the value returned by user_load() is an array. If the $id is not valid, it will return an empty array.

Try changing your test to if (empty($account)).

4
  • 1
    It returns FALSE for me when I run it with an invalid user ID, and a stdClass object on success (Drupal 7). I've never seen it return an array before, is that documented somewhere?
    – Clive
    May 29, 2013 at 16:04
  • @Clive - If you trace the function through the Drupal API, the actual return value comes from entity_load().
    – Triskelion
    May 29, 2013 at 16:08
  • 1
    user_load() takes the return value from user_load_multiple() (which uses entity_load()). That return val is an array, but user_load() runs reset() on it. Running reset() on an empty array results in FALSE.
    – Clive
    May 29, 2013 at 16:10
  • @Clive - Good catch. I missed it. However, empty() is a more generic method of testing for a FALSE value, and drupalnewbie for some reason is tryng to compare handles, not values. At least the comparison should be '==' and not '==='.
    – Triskelion
    May 29, 2013 at 16:17
-1

These tests will not work in recent PHP, because account is an object array. Use the following condition: if (count($account) > 0)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.