How to Disable Whole Form from hook_form_alter? I've got a form I want to be disabled when certain criteria are met. According to the Form API I thought $form['#access'] = FALSE; would be sufficient. But no dice.

Instead, I'm doing this, which feels wrong, plus I get an error, "Warning: implode(): Invalid arguments passed in form_builder()"

foreach($form as $key =&gt; $element){
          unset($form[$key]);
}
$form['#prefix'] = 'Bad user. Don\'t access this form!';


Kind of a big stick approach. What's the right way to do this?
Drupal doesn't cope with the form being removed in such a way because it is expecting certain things in the form array after you have altered it.

That's why you are getting that error, because form_builder() does this:

if (!isset($element['#id'])) {
  $element['#id'] = drupal_html_id('edit-' . implode('-', $element['#parents']));
}


but you have removed $element['#parents'] when you looped through unsetting everything, including #parents.

If you want to loop through all form elements are remove them the correct way would be to use element_children(), which will loop through the keys of child elements but skip properties of the current element.

So to loop though child elements you would do this:

// Remove all elements from this form.
foreach (element_children($form) as $key) {
  unset($form[$key]);
}


Alternatively you could restrict access like this, which could cause you less side effects if other modules are expecting form elements that you have deleted.

// Restrict access to all elements in this form.
foreach (element_children($form) as $key) {
  $form[$key]['#access'] = FALSE;
}


If the form is a page though, not in a block or something, then it might be better to use hook_menu_alter() to block it as Shawn said in his answer.