Don't hack core and don't hack contrib (unless you have to)

If you spend much time in the Drupal community you'll hear the refrain don't hack core. But no matter how many times it might be said the temptation to hack core seems great. We've recently helped with several sites and there seems to be a common thread of problems caused by hacking core. These hacks are then costly to the client in the long run, often resulting in several hours (at best) of additional work to sort out what has been done and set things right.

My contractor says they need to hack core

So you've heard you shouldn't hack core and now you have a developer that is telling you they must do it to accomplish your goals. Please, Please, Please when you hear this do yourself a big favor and say no. If the contractor you're working with still says it's necessary then by all means get a second opinion. There are many, many, many, manyThis is the firm I started and own., reputable Drupal consulting firms who will help you figure out whether the hacks to core are really necessary.In addition to consulting firms there are a number of outlets like forums and local Drupal groups who would also likely have people willing to give you some suggestions The money you spend hiring one of these groups for a couple of hours will be well worth it in the long run.

There are, perhaps, a few cases in which hacking the core of Drupal may be necessary but they are pretty special cases and I'll discuss them at the end of this post.

Let's take a look at a recent example. A site we've worked with wanted to setup user profiles to allow the site users to choose whether to display their birthdate as the actual date or as their age in years. The site in question uses Bio Module for its user profiles. In this case the contractor's decision was to modify drupal's user.module.

Here's a brief list of the problems with modifying the user.module this way:

  1. Security releases made to Drupal that affect the user.module will overwrite the hacks
  2. Because the contractor may not be following proper coding practices they may be introducing security holes into an otherwise secure systemThe lack of regard for proper coding practices is evident in this abuse of the community practices.
  3. A future consultant won't be so likely to look immediately for changes to Drupal core and will instead spend time looking in the places these changes should be made.
  4. This sort of change would affect all of the sites in this installation, which could be unintended if it is a multi-site installation.
  5. In most cases there is no need to hack core

When I pointed out to the site owner that this change could, and should, be made in a custom module or as a part of the theme the consultant replied that there was an easy work-around. The work-around proposed was to copy the hacked user module into a site-specific module directory so it would be used by that site while other sites in their multi-site installation would have access to the standard core user.module. Because of the way Drupal loads modules this will work as it is smart enough to load only one version of the module so there aren't PHP errors caused by what would otherwise be duplicate function names. While this will technically work, just as hacking core will technically work, it suffers from at least all of the same problems. In addition to the problems above now there's the challenge of keeping track of which sites have which hacks in them. None of this leads to happiness or high-functioning Drupal sites down the road.

So what is the right way? Well as in so many things in Drupal there are several methods that would work. Off hand there's the option of adding a checkbox or select field to the bio content type and using that to flag the theming of the birthdate element on output. There's also the way I'd possibly do it with a call to hook_form_alter() and adding an additional field to the form storing the results in the database. And then there are combinations of this sort of practice that would work. The point being there are nearly always better ways.

While the contributions or module repository is a bit different one would be wise to consider most of these same principles as rules in that domain as well. Especially if you don't have an in-house developer type to support your changes there is almost certainly a big ugly train wreck around the corner.

I said back in the beginning I'd mention a couple of possible exceptions. The first thing one should do if you're considering one of these exceptions is reconsider whether there isn't a better way to do what you need to do. Once you are convinced there is no better way consider posting a support requestPosting a support request in the issue queue presumes you have searched the issue queue already to see if somebody has already raised the issue. Chances are good with the thousands of Drupal installations around the globe somebody else might have seen the same issue. or asking in an IRC channel to see if somebody else sees another way.

So once you reach the conclusion that there is no other way and you've found one of those magical issues for which there is no fix and you have to find a way to work around it. The first step is to go back to the issue queue and see what others have said. What sort of thing might this be? One example that comes to mind is that in Drupal 5 and Drupal 6 there is hard-coded HTML in the comment_render() function. This is one of the last places there is any hard-coded HTML in Drupal and can make changing comments to suit a site difficult or impossible depending on the site's needs. As you should expect when an issue reaches this level you can expect to find an issue in the Drupal.org issue queue. And low and behold there is http://drupal.org/node/162747. It may be possible to use one of the patches presented in just such an issue to solve your site's problem even if the issue is not completely resolved it should guide your solution.

So here's a cheat sheet if you run into one of these issues:

  1. The issue should be documented on drupal.org
  2. If you're the first to document the issue ask around in IRC and the community to see if there's another solution lurking somewhere
  3. Create a patch with what you eventually change. This won't solve all your problems but will make that next critical upgrade a lot smoother.
  4. Keep a site-log where you document especially these changes. Anybody coming in to work on the project should have access and be expected to update the log
  5. Follow up on the issue in the queue, provide feedback on what worked and what didn't and update as changes come out

Category: 

3 Comments

Don't hack core; I don't hack core; but if I did... but I don't!

Good discursive post, especially showing that there are other ways of accomplishing functionality than hacking core. I should start by saying we don't hack core. But if someone asked me how to do it safely... I think your patch suggestion is the start, but you'd need to go further to make it safe: how would another developer on your team know that a particular site needed a particular patch?

I think you need a robust versioning system of your own, independent of the d.o repository. You would keep local copies of all the Drupal versions in e.g. a svn repository as tags, and when you want to upgrade your patched Drupal, you should have a scripted way of bringing in a new Drupal core version and patching it on the way in, maybe with svn hooks. That way other devs could just upgrade by bringing in a new version, running the standard merges, then switching it on the staging/production server(s).

Still... hacking core is just... daft. It misses the point of Drupal, the community advantage that an open-source project has. It means you suddenly have to start worrying about core, whereas you were probably sold Drupal on the basis that volunteers gladly worried about core for you, and they would still do that if you hadn't hacked core.

User integration is the point at which it's been most tempting to hack core, I think. Often external systems will really test the user hooks to breaking point, with tortuous back-and-forth workflows, asynchronous calling, data mapping into external databases etc. But there's almost always a way without hacking core: it's just usually a nasty way. The point is: it's a maintainable nastiness. That's the least worst kind!

I think the article is so

I think the article is so power packed that it can salvage you from the dilemma between to hack core or not to hack. I hope the article can dispel much of your confusion regarding the uses hacking the core under pressure. It is indeed very useful post.