This reproduce the domain_prefix behavior, on the first page hit of the domain :)

/**
 * Implements hook_domain_bootstrap_full().
 */
function mymodule_domain_bootstrap_full($domain) {
  global $databases;

  // Define the prefix
  $prefix = 'domain_' . $domain['domain_id'] . '_';

  // Define tables to (copy and) load dynamically, modify at your ease
  $tables = array('block', 'block_custom', 'menu_links', 'cache_menu');

  foreach ($tables as $table) {
    $new_table = $prefix . $table;
    // If the table for the domain does not exists, duplicate the normal one
    if (!db_table_exists($new_table)) {
      // Copy structure
      db_query("CREATE TABLE $new_table LIKE $table");
      // Copy data
      db_query("INSERT $new_table SELECT * from $table"); // Comment this line if you don't want data to be copied
    }
    $databases['default']['default']['prefix'][$table] = $prefix;
  }

  // This resets our current database connection with prefixes
  Database::closeConnection();
  Database::parseConnectionInfo();
}

/**
 * Implements hook_enable().
 */
function mymodule_enable() {
  domain_bootstrap_register();
}

Comments

agentrickard’s picture

Title: Domain Prefix-like lightweight behavior, in a few line of codes » Shortcut: Domain Prefix-like lightweight behavior, in a few line of codes
Priority: Normal » Major

Nice. Part of the fun of Domain Prefix was trying to abstract this behavior to a module. Problem is, I never actually used it in production.

Matt B’s picture

Thanks for the shortcut - works fine for my needs!

Matt B’s picture

Issue summary: View changes

Updated issue summary.

hanksterr7’s picture

Hi

I took the above code, and dropped it in a file called domainPrefix.module. I changed "mymodule" to "domainPrefix" (x2).

I made a file called domainPrefix.info and put this in it:
name = Domain Prefix
description = Allow DA and Forums to work nicely together (from https://drupal.org/node/1953292)
package = Domain Prefix
core = 7.x

; Information added by drupal.org packaging script on 2013-06-02
version = "7.x-3.10"
core = "7.x"
project = "domainPrefix"
datestamp = "1370207153"

I put the two files in a new folder (sites/all/modules/domainPrefix)

I assume this is what you intended.

I found Domain Prefix available as a new module and enabled it. I got this error:
PDOException: SQLSTATE[42S02]: Base table or view not found: 1146 Table 'resilie4_dru1.block' doesn't exist: CREATE TABLE domain_1_block LIKE block; Array ( ) in domainPrefix_domain_bootstrap_full() (line 19 of /home4/resilie4/public_html/drupal7root/drupal7/sites/all/modules/domainPrefix/domainPrefix.module).

I checked my db and I have a prefix already on all the tables, so I guess the code needs to check for the prefix for my db from settings.php.

I can hardcode the prefix in the above code (using this instead: $prefix = 'xup_domain_' . $domain['domain_id'] . '_';)

I assume there is a way to have this inserted via a variable.

Am I getting close? (scary if I'm actually starting to understand this :) )

Thanks
-- hanksterr7

hanksterr7’s picture

Well I thought I was getting close.

Here's my code:

/**
 * Implements hook_domain_bootstrap_full().
 */
function domainPrefix_domain_bootstrap_full($domain) {
  global $databases;

  // Define the prefix
  $prefix = 'domain_' . $domain['domain_id'] . '_';
  $dbPrefix = 'xup_';

  // Define tables to (copy and) load dynamically, modify at you ease
  $tables = array('block', 'block_custom', 'menu_links', 'cache_menu');

  foreach ($tables as $table) {
    $new_table = $dbPrefix . $prefix . $table;
    // If the table for the domain does not exists, duplicate the normal one
    if (!db_table_exists($new_table)) {
      // Copy structure
      $tableWPre = $dbPrefix . $table;
      db_query("CREATE TABLE $new_table LIKE $tableWPre");
      // Copy data
      db_query("INSERT $new_table SELECT * from $tableWPre"); // Comment this line if you don't want data to be copied
    }
    $databases['default']['default']['prefix'][$table] = $dbPrefix . $prefix;
  }

  // This resets our current database connection with prefixes
  Database::closeConnection();
  Database::parseConnectionInfo();
}

/**
 * Implements hook_enable().
 */
function domainPrefix_enable() {
  domain_bootstrap_register();
}

If this ends with
$databases['default']['default']['prefix'][$table] = $dbPrefix . $prefix;
then the site will open. But if I change pages, I get

PDOException: SQLSTATE[42S01]: Base table or view already exists: 1050 Table 'xup_domain_1_block' already exists: CREATE TABLE xup_domain_1_block LIKE xup_block; Array ( ) in domainPrefix_domain_bootstrap_full() (line 21 of /home4/resilie4/public_html/drupal7root/drupal7/sites/all/modules/domainPrefix/domainPrefix.module).

Don't understand why the line
if (!db_table_exists($new_table)) {
isn't catching the existence of the recently created table.

If I say
$databases['default']['default']['prefix'][$table] = $prefix;
then I get this error from Domain Access on the first attempt to open the site:

PDOException: SQLSTATE[42S02]: Base table or view not found: 1146 Table 'resilie4_dru1.dup_domain_conf' doesn't exist: SELECT settings FROM {domain_conf} WHERE domain_id = :domain_id; Array ( [:domain_id] => 1 ) in domain_conf_domain_bootstrap_full() (line 31 of /home4/resilie4/public_html/drupal7root/drupal7/sites/all/modules/domain/domain_conf/domain_conf.module).

Help?

Also, I think I may be wasting my time. My desire was to get Domain-specific forum behavior (forums, topics and containers that are specific to subdomains, as managed by Domain Access). The code is doing nothing with Forums, so even if it works, I don't expect it will meet my need (unless adding some more table to the $tables array will bring forums into the new behavior)

Thanks

SebCorbin’s picture

Chances are db_table_exists($new_table) adds the prefix you entered in your settings.php, resulting in checking the existence of a table named xup_xup_domain_1_block

Try this:

/**
 * Implements hook_domain_bootstrap_full().
 */
function domainPrefix_domain_bootstrap_full($domain) {
  global $databases;

  // Define the prefix
  $prefix = 'domain_' . $domain['domain_id'] . '_';
  $dbPrefix = 'xup_';

  // Define tables to (copy and) load dynamically, modify at you ease
  $tables = array('block', 'block_custom', 'menu_links', 'cache_menu');

  foreach ($tables as $table) {
    $new_table = $prefix . $table;
    // If the table for the domain does not exists, duplicate the normal one
    if (!db_table_exists($new_table)) {
      $new_table = $dbPrefix . $new_table;
      // Copy structure
      $tableWPre = $dbPrefix . $table;
      db_query("CREATE TABLE $new_table LIKE $tableWPre");
      // Copy data
      db_query("INSERT $new_table SELECT * from $tableWPre"); // Comment this line if you don't want data to be copied
    }
    $databases['default']['default']['prefix'][$table] = $dbPrefix . $prefix;
  }

  // This resets our current database connection with prefixes
  Database::closeConnection();
  Database::parseConnectionInfo();
}

/**
 * Implements hook_enable().
 */
function domainPrefix_enable() {
  domain_bootstrap_register();
}
hanksterr7’s picture

Yep, that was it! Thanks!

Now to try to get this to work for Forums (and the associated taxonomy). I added the forum, taxonomy_index, taxonomy_term_data, taxonomy_term_hierarchy, and taxonomy_vocabulary tables to the list.

I did get this error when deleting a term from the Forum taxonomy in my primary domain, which didn't seem to cause a problem:
Notice: Undefined index: vid in location_taxonomy_form_alter() (line 42 of /home4/resilie4/public_html/drupal7root/drupal7/sites/all/modules/location/contrib/location_taxonomy/location_taxonomy.module).

I then added a term to the Forum taxonomy in my second domain. The term got added to the taxonomy_term_data table instead of the domain_2_taxonomy_term_data table.

How do I ensure that the domain-specific tables get used instead of the regular ones? Isn't that what the
$databases['default']['default']['prefix'][$table] = $dbPrefix . $prefix;
line should be doing?

Thanks!

hanksterr7’s picture

Issue summary: View changes

Updated issue summary.

hanksterr7’s picture

I'm thinking I need to add field stuff.

When I'm on admin/structure/taxonomy/forums and I add terms, they get added to the regular taxonomy_term_data table, not the domain-specific one.

I added field_data_taxonomy_forums and field_revision_taxonomy_forums but that didn't help.

I see there is field_config and field_config_instance. In field_config there is this value of the data field for the row with field_name taxonomy_forums:
a:6:{s:8:"settings";a:1:{s:14:"allowed_values";a:1:{i:0;a:2:{s:10:"vocabulary";s:6:"forums";s:6:"parent";i:0;}}}s:12:"entity_types";a:0:{}s:12:"translatable";b:0;s:7:"storage";a:4:{s:4:"type";s:17:"field_sql_storage";s:8:"settings";a:0:{}s:6:"module";s:17:"field_sql_storage";s:6:"active";i:1;}s:12:"foreign keys";a:1:{s:3:"tid";a:2:{s:5:"table";s:18:"taxonomy_term_data";s:7:"columns";a:1:{s:3:"tid";s:3:"tid";}}}s:7:"indexes";a:1:{s:3:"tid";a:1:{i:0;s:3:"tid";}}}

Note that this specifies the taxonomy_term_data table.

I'm thinking I need to add the field_config and field_config_instance tables to the set of tables that are domain prefixed, and edit the value of data to specify the domain prefixed table name.

This seems rather kludgy

Thoughts on a better way to do this?

Thanks

hanksterr7’s picture

Issue summary: View changes

Updated issue summary.