Efficiently Shutting Off Default Functionality in Drupal 7
There are good reasons to use a heavyweight, popular framework like Drupal even when setting up a trivial server, such as one that serves a single simple API. For example:
- The assurance of security.
- Someone has probably already written a module that provides much of the functionality you want.
- Later addition of new features will be much less costly.
The best case scenario is that you spend perhaps an hour setting up Drupal, adding a single existing module for your simple API, and then you're done, with a reasonable expectation that your new server works well and is secure. A more common outcome is a day or two spent coding to modify and glue together a few existing modules - but that is still probably much faster than doing it all yourself.
Being a heavyweight framework, Drupal arrives out of the box with a lot of default functionality turned on. You probably want next to none of this stuff running on your simple API server. The formal way to deal with this issue is to write a custom installation profile that results in the features, modules, and data you want in place on a newly installed server - and nothing more. This can chew up time even for very simple servers, however, as all too few module authors pay attention to the important differences in behavior between a profile installation and an ordinary module installation on a running Drupal server. This tends to lead to cursing and patches. Further, if you haven't written an installation profile in the past, you will need some time to come up to speed on the API, examine the existing profiles, read the documentation, and find the pitfalls by trial and error.
You should nonetheless learn how to write installation profiles at some point. But if you are in a hurry, there are other valid, fast ways to cut down the exposed functionality in a standard Drupal installation. A few of these follow.
No Outgoing Email, Ever
So your application will never need to send email: you will never be creating users in a way that needs registration mails, there are no features that send mail, and in short you don't care about the existence of email. Chasing down all the default functionality that might be sending mail can be a pain, however. So why not just cut it all short at the neck? Create a custom module, include a suitable hook_mail_alter() implementation and there will be no more mail.
In suppress.info:
name = Suppress description = Custom module to shut down unwanted functionality. core = 7.x
In suppress.module:
/** * Implements hook_mail_alter(). * * Suppress all outgoing mail - easier this way than individually finding * every place that mail is sent, some of which offer no options to turn * off sending. */ function suppress_mail_alter(&$message) { // Don't send. Works as of core 7.12. $message['send'] = FALSE; }
No User Registration
A simple API server may have no need for user registration, password reminders, or the like. Administrative users will be created by the master admin account when needed. If this is the case, you can (and should) turn off user registration in the administration interface, but why not simply remove the pages? It stops drive-by bots from submitting forms, and helps to keep exposed functionality to a minimum.
Implementing hook_menu_alter() is the way to go here. Removing items from the menu removes menu-based links to the pages in question, and gives assurance that no-one can even access this functionality:
/** * Implements hook_menu_alter(). */ function suppress_menu_alter(&$menu) { // Get rid the registration form. unset($menu['user/register']); // Get rid of the password reset form. unset($menu['user/password']); unset($menu['user/reset/%/%/%']); }
Restrict the Front-End to Administrative Use Only
If your server only exists to serve APIs, then it probably doesn't need a home page. In fact, the home page should be the administrative interface. One easy way to put this in place is to set the default homepage to "admin" and the 403 page to "user" - in other words when a user turns up at the site, they will see a login prompt and after logging in successfully will be presented with the administrative interface.
You can set this up in the administration under Configuration->System->Site Information, but you could also put it into suppress.install:
/** * Implements hook_install(). */ function suppress_install() { variable_set('site_frontpage', 'admin'); variable_set('site_403', 'user'); }
Liberally Remove Other Menu Items
An implementation of hook_menu_alter() allows removal of the pages that host all sorts of standard Drupal functionality that you might not need for - or want to expose on - a simple API server. Since third party modules often depend on the modules that provide these pages, removing them from the menu is easier than most other options.
Some examples follow:
/** * Implements hook_menu_alter(). */ function suppress_menu_alter(&$menu) { // Get rid the registration form. unset($menu['user/register']); // Get rid of the password reset form. unset($menu['user/password']); unset($menu['user/reset/%/%/%']); // Remove everything to do with taxonomies. foreach ($menu as $path => $item) { if (preg_match("/^taxonomy//", $path)) { unset($menu[$path]); } } // Remove all comment-related menu items. foreach ($menu as $path => $item) { if (preg_match("/^comment//", $path)) { unset($menu[$path]); } } // Remove all node viewing, editing, etc. foreach ($menu as $path => $item) { if (preg_match("/^node($|/)/", $path)) { unset($menu[$path]); } } // Remove all search-related menu items. foreach ($menu as $path => $item) { if (preg_match("/^search($|/)/", $path)) { unset($menu[$path]); } } // Remove the feed. unset($menu['rss.xml']); }
You get the idea, I'm sure. If you have installed third party modules, there may be other menu items to trim as well.