I have been searching for the answers to this question with no luck at all. From what I observe in the database structure, the location to the modules are specified in the 'system' table. The only solution I have is to write an SQL query to update the 'filename' column.

Is there a better/cleaner solution in solving this, for eg., a contrib module?

14 Answers 14

up vote 26 down vote accepted

You only need to move your modules to the your new location and rebuild the regisry. When the registry rebuilds the path to the modules will be updated. Check registry_rebuild().

Rescans all code in modules or includes directories, storing the location of each interface or class in the database.

Although, I would recommend you to backup you database before testing this.

If you are using drush you could also rebuild the registry using the following command:

drush cc registry

You can also install the registry_rebuild command for drush:

// install registry_rebuild
drush dl registry_rebuild
// rebuild the registry
drush rr
  • If I understand It correctly, you could also truncate your registry_file table, wich will force drupal to rescan all files and rebuild the table. – Cyclonecode Dec 16 '11 at 16:01
  • 3
    Truncating the table sounds like a bad idea and will most likely result in a totally broken site. – Berdir Dec 18 '11 at 12:02
  • @Berdir - Agree that it sounds like a bad idea. But, just tried it and seems to work. First I took a backup and truncated the entire table using DELETE FROM registry_file; and added a call to rebuild_registry() in my page.tpl.php. – Cyclonecode Dec 18 '11 at 14:42
  • This is over complicated, just do what John Laine said, it's always worked for me. – Jim Kirkpatrick Dec 21 '11 at 17:44
  • 1
    @JimKirkpatrick - You're right there's no need to disable the modules. – Cyclonecode Jan 12 '12 at 6:18

I restored a backup from production locally and tried to just move things and hit admin/modules or to run registry_rebuild() but it didn't stop fatal errors from being thrown. This makes sense to me since some modules may use includes or whatever in their hook_init(), or you may have a menu router path set that depends on a module or include that Drupal can't find on bootstrap. Ultimately, this is what I did (your paths may be different):

Step 1: Replace sites/all/modules with sites/all/modules/contrib

UPDATE system SET filename = REPLACE(filename, 'sites/all/modules', 'sites/all/modules/contrib');
UPDATE registry SET filename = REPLACE(filename, 'sites/all/modules', 'sites/all/modules/contrib');
UPDATE registry_file SET filename = REPLACE(filename, 'sites/all/modules', 'sites/all/modules/contrib');

Step 2: Replace sites/all/modules/contrib with sites/all/modules/custom for custom namespaced modules

UPDATE system SET filename = REPLACE(filename, 'sites/all/modules/contrib', 'sites/all/modules/custom') WHERE name LIKE 'my_custom_namespace_%';
UPDATE registry SET filename = REPLACE(filename, 'sites/all/modules/contrib', 'sites/all/modules/custom') WHERE name LIKE 'my_custom_namespace_%';
UPDATE registry_file SET filename = REPLACE(filename, 'sites/all/modules/contrib', 'sites/all/modules/custom') WHERE filename LIKE '%my_custom_namespace_%';

Step 3: Move dev modules into sites/all/modules/dev

UPDATE system SET filename = REPLACE(filename, 'sites/all/modules/contrib', 'sites/all/modules/dev') WHERE name LIKE 'devel%';
UPDATE registry SET filename = REPLACE(filename, 'sites/all/modules/contrib', 'sites/all/modules/dev') WHERE name LIKE 'devel%';
UPDATE registry_file SET filename = REPLACE(filename, 'sites/all/modules/contrib', 'sites/all/modules/dev') WHERE filename LIKE '%devel%';

Step 4: Clear caches so that things will bootstrap properly

TRUNCATE TABLE cache
TRUNCATE TABLE cache_bootstrap
TRUNCATE TABLE cache_menu
TRUNCATE TABLE cache_page
TRUNCATE TABLE cache_path

Note: If you use a custom module or a contrib like LoginToboggan to handle 403 (access denied) and you've gotten logged out during this process, you may need to update the include_file column in the menu_roter table to use the new path for the include file. This is probably a rare occurrence.

UPDATE menu_router SET include_file = 'sites/all/modules/custom/my_custom_namespace/includes/foo.inc' WHERE path = 'access-denied'

Once these queries have run – which will only take a split second – hit up admin/config/development/performance and clear the cache so that menu paths rebuild.

  • Thanks for this! I tried the steps mentioned in the top answers, but that didn't help in my case. I suspect anyone on a Pantheon-hosted site needs to perform these db statements in your answer and then do the "drush registry-rebuild" and "drush cc registry" – Anne Bonham Jan 13 '17 at 23:11
  • Oh and on Pantheon, I could not get site up with the Redis module anywhere but sites/all/modules - so I just gave up and left this one module in the root modules folder. Ah well - at least my other modules are nicely organized. – Anne Bonham Jan 13 '17 at 23:15
  • For those using LoginToboggan, here are the 3 MySQL commands you'll need: update menu_router set include_file = 'sites/all/modules/contrib/logintoboggan/logintoboggan.admin.inc' WHERE path = 'admin/config/system/logintoboggan'; update menu_router set include_file = 'sites/all/modules/contrib/logintoboggan/logintoboggan.validation.inc' WHERE path = 'toboggan/revalidate/%'; update menu_router set include_file = 'sites/all/modules/contrib/logintoboggan/logintoboggan.validation.inc' WHERE path = 'user/validate/%/%/%'; – tyler.frankenstein Apr 30 at 21:25

Try the cool tool from Mark Sonnabaum: Drush Rebuild Project Paths. It automates the process; worked great for me. Uses Drush, of course.

I will second the suggestion that you try this on a copy of your site database, though.

For the record, there's a great drush command to rebuild the registry: http://drupal.org/project/registry_rebuild

There's plenty of information in the project's page.

  • This is my most preferred method of moving modules around. I had some modules that were enabled in sites/all/modules which had to be moved to contrib subdirectory. All I had to was drush dl registry_rebuild; mv OLD_PATH/module NEW_PATH/module; drush rr – Sumeet Pareek Jul 22 '14 at 7:13
  • This worked for me. I moved all my modules first then did the registry_rebuild – gerl Dec 4 '14 at 17:20
  • Interestingly, drush rr --fire-bazooka leads to errors, but drush rr is fine. – Alex.Designworks May 12 '16 at 12:15

Firstly, always backup your database, so simple to do you'll kick yourself if something goes wrong and you didn't backup.

I'm not sure if it matters if you disable the modules or not; you might want to do it, just in case. Then do this:

  1. Put your site in maintenance mode at (sitename)/admin/config/development/maintenance
  2. Physically move your modules in the file system.
  3. Clear your caches at (sitename)/admin/config/development/performance, or just re-save your modules page.

All done! Drupal will re-search for all installed modules.

  • +1 for maintaince mode, always nice to do this prior to something like this – Cyclonecode Jan 28 '12 at 20:20
  • 1
    This causes fatal errors 100% of the time for me. Maybe it works if you move modules that don't have dependencies or something. – ergophobe Mar 1 '14 at 4:26

Why don't you try the Registry Rebuild module. It worked every time for me.

Here is a quote about it (from the module's project page):

There are times in Drupal 7 when the registry gets hopelessly hosed and you need to rebuild the registry (a list of PHP classes and the files they go with). Sometimes, though, you can't do this regular cache-clear activity because some class is required when the system is trying to bootstrap.

  • Whilst this may theoretically answer the question, it would be preferable to include the essential parts of the answer here, and provide the link for reference. If there is a procedure for moving modules that includes using module you linked, please describe it. – Mołot Apr 30 '14 at 7:26
  • No theory... it works. Follow the instructions on the page. I used the drush method and it just worked. – iLLin Sep 16 '15 at 12:22

You can use the Registry Rebuild module, which integrates with Drush via the Drush RR command.

Basically what you do are these steps:

  1. Move your modules to another directory, and
  2. Registry Rebuild will then rebuild the system table to get the modules in the right place.

I first learned/discovered it via DrupalEasy Podcast #133, which further explains how this module / drush cmd can be used.

PS: Of course, first perform a backup of your site ...

  • 3
    I second this. Back up site. Move all modules into new folders. Run registry rebuild in drush, or just follow the instructions and navigate to the included php file to run it. Simple. – Collins Sep 18 '15 at 20:56

Visit /admin/build/modules it will rebuild the paths in the system table. Sometimes drupal can't bootstrap anymore so this solution does not work in this case. If it does not work you can use Drush Rebuild Project Paths as said in a previous answer. You have to add the new drush command before breaking bootstrap though. To add the new command check out the readme's COMMANDS section

I had some trouble with drush dl not working because of the module directory issues. Generally I like stack answers that I can simply paste in to get things working. Here you find a couple of lines that will install Drush Rebuild Registry and run it on your site if you're already in the proper site directory.

pushd ~  # good if drush on your site is broken because of moved modules
drush dl -y registry_rebuild
popd 
drush rr

I'm not 100% sure on a true drupal-esk answer but in my experience:

I accidentally moved one of my custom module folders into another custom module folder when FTPing to the server. They both still worked. Drupal seemed to have recognized it as a separate module even while it was in another module's folder. I did not have to disable the module.

**This module that I moved did NOT have an .install file so I'm not sure if that matters.

  • The install file is only for procedures called during module installation and is not a requirement. It worked because you can have any folder structure under /sites/all/modules, drupal will be looking for the .info files recursively. – gbyte.co Sep 18 '15 at 14:53
  • @gbyte.co thanks for the clarification on that! I knew about the install file but did not know drupal's recursive process of searching for .info files. I figured it didn't matter which subfolder they were in but it's good to have a solid answer! – Exziled Sep 18 '15 at 15:48

Drupal distributions don't handle this well, so recently after accidentally ending up with a copy of Entity API in sites/all/ on a Panopoly site, none of this worked. Registry rebuild, loading the modules page and everything else caused a fatal error.

Disabling the module isn't simple either if you have to move something like Entity API which is required by tons of other modules in Panopoly.

To solve this, for Entity API you would do something like this:

  1. Update the path in the system table:

    UPDATE `system` 
      SET `filename` = REPLACE(
        `filename`, 
        'sites/all/modules/entity', 
        'profiles/panopoly/modules/contrib/entity'
      );
    
  2. Then rebuild the registry:

    drush rr
    

Drupal 7

First of all try drush rr.

If it won't work, after moving the files, try the following Drush commands in your Drupal root dir:

drush sqlq "TRUNCATE cache; TRUNCATE cache_bootstrap;"
php -r "define('DRUPAL_ROOT', getcwd()); require_once DRUPAL_ROOT . '/includes/bootstrap.inc'; drupal_bootstrap(DRUPAL_BOOTSTRAP_SESSION); registry_rebuild(); registry_update(); cache_clear_all();"
drush -y cc all

If above doesn't work, find the table which still have the old information about the path by:

drush --ordered-dump sql-dump | grep "sites/all/modules" # Change the path to the old one.

If none is found, that means it's your external cache.

If so, don't forget to restart them, e.g.:

killall -HUP memcached
drush eval "function_exists('xcache_clear_cache') && xcache_clear_cache();"

See more: What method is used to clear caches in the Drupal?


Alternatively you may try the following MySQL queries after moving the files:

UPDATE system SET filename = REPLACE(filename, "sites/all/modules", "sites/newplace/modules") WHERE
       filename LIKE "sites/all/modules/%" AND type = "module"
       AND name IN ("my", "module", "whose", "path", "changed");

UPDATE registry SET filename = REPLACE(filename, "sites/all/modules", "sites/newplace/modules") WHERE
       filename LIKE "sites/all/modules/%"
       AND module IN  ("my", "module", "whose", "path", "changed");

Moving your modules into contrib/dev/patched/custom subfolders is recommended. There are no performance gains however, this is done for practical and aesthetic reasons. This will make the lives of future developers easier.

You can move most of the contrib modules to subfolders without a problem on a live site. You should clear the caches afterwards. If you don't use drush and find you cannot access the cache clearing page anymore, you will have to visit /update.php or manually truncate the cache tables. I only ever had to do the last bit when moving the entity API module.

Moving core modules is technically possible, but I would not recommend it nor do I see any valid reason for doing this.

Update: Moving modules like entity API may require rebuilding of the registry. Check out the registry_rebuild page.

You could just add a sym link in the sites/all/modules diretory pointing to sites/all/contrib. I'm not sure if it solves your problem. There are other solutions too, including the installation profile, or a drush make file. I don't know enough to provide details on them but at least it's a direction you can look at.

  • 5
    It's a maintenance headache in the longer run – AgA Dec 17 '11 at 16:23
  • this is a hack and goes around the fix... not a good solution. – iLLin Sep 16 '15 at 12:18
  • yep far better to use drush registry_rebuild now that it's available. – lexicant Sep 24 '15 at 15:01

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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