View source
<?php
define('DOMAIN_PREFIX_IGNORE', 1);
define('DOMAIN_PREFIX_CREATE', 2);
define('DOMAIN_PREFIX_COPY', 4);
define('DOMAIN_PREFIX_DROP', 8);
define('DOMAIN_PREFIX_UPDATE', 16);
function domain_prefix_menu($may_cache) {
$items = array();
if ($may_cache) {
$items[] = array(
'title' => t('Table prefixing'),
'path' => 'admin/build/domain/prefix',
'access' => user_access('administer table prefixing'),
'type' => MENU_LOCAL_TASK,
'callback' => 'drupal_get_form',
'callback arguments' => array(
'domain_prefix_configure_form',
),
);
}
else {
$items[] = array(
'title' => t('Domain prefix settings'),
'path' => 'admin/build/domain/prefix/' . arg(4),
'access' => user_access('administer table prefixing'),
'type' => MENU_CALLBACK,
'callback' => 'drupal_get_form',
'callback arguments' => array(
'domain_prefix_form',
arg(4),
),
);
$items[] = array(
'title' => t('Domain prefix update'),
'path' => 'domain_prefix_update',
'access' => user_access('administer table prefixing'),
'type' => MENU_CALLBACK,
'callback' => 'domain_prefix_update',
);
}
return $items;
}
function domain_prefix_perm() {
return array(
'administer table prefixing',
);
}
function domain_prefix_get_prefix() {
global $db_prefix;
$prefix = NULL;
if (!empty($db_prefix)) {
if (is_array($db_prefix)) {
$prefix = $db_prefix['default'];
}
else {
$prefix = $db_prefix;
}
}
return $prefix;
}
function domain_prefix_get_tables($prefix = NULL) {
if (empty($prefix)) {
$prefix = domain_prefix_get_prefix();
}
switch ($GLOBALS['db_type']) {
case 'pgsql':
if (empty($prefix)) {
$result = db_query("SELECT table_name FROM information_schema.tables WHERE table_schema = 'public'");
}
else {
$result = db_query("SELECT table_name FROM information_schema.tables WHERE table_schema = 'public' AND table_name LIKE '{$prefix}%%'");
}
break;
default:
if (empty($prefix)) {
$result = db_query("SHOW TABLES");
}
else {
$result = db_query("SHOW TABLES LIKE '{$prefix}%%'");
}
break;
}
$tables = array();
$disallow = domain_prefix_disallow();
while ($data = db_fetch_array($result)) {
$str = current($data);
if (!empty($prefix)) {
$str = preg_replace('/' . $prefix . '/', '', $str, 1);
}
if (!in_array($str, $disallow) && substr($str, 0, 7) != 'domain_') {
$tables[$str]['tablename'] = $str;
$tables[$str]['module'] = domain_prefix_module_lookup($str);
}
}
uasort($tables, '_domain_prefix_sort');
return $tables;
}
function _domain_prefix_sort($a, $b) {
$_a = str_replace('_', '', $a['tablename']);
$_b = str_replace('_', '', $b['tablename']);
if ($a['module'] == $b['module']) {
return strcmp($_a, $_b);
}
return strcmp($a['module'], $b['module']);
}
function domain_prefix_configure_form() {
$default = domain_default();
domain_goto($default);
$tables = domain_prefix_get_tables($prefix);
$disallow = domain_prefix_disallow();
$info = unserialize(variable_get('domain_prefix', NULL));
$settings = $info['settings'];
$source_defaults = $info['sources'];
$form = array();
$form['domain'] = array(
'#type' => 'fieldset',
'#title' => t('Domain creation rules'),
'#collapsible' => TRUE,
'#collapsed' => FALSE,
);
$form['domain']['domain_prefix_options'] = array(
'#type' => 'radios',
'#title' => t('Domain creation options'),
'#description' => t('Determines what actions to take when creating new domain records.'),
'#options' => array(
1 => t('Generate tables as defined below'),
0 => t('Do not generate any tables'),
),
'#default_value' => variable_get('domain_prefix_options', 1),
'#required' => TRUE,
);
$last = '';
$root = domain_default();
foreach ($tables as $table => $info) {
if (!in_array($table, $disallow) && substr($table, 0, 7) != 'domain_') {
if (empty($settings[$table])) {
$settings[$table] = DOMAIN_PREFIX_IGNORE;
$source_defaults['_source_' . $table] = 0;
}
$module = $info['module'];
if ($last != $module) {
$last = $module;
}
else {
$module = '';
}
$options = array();
$options[DOMAIN_PREFIX_IGNORE] = t('ignore');
$options[DOMAIN_PREFIX_CREATE] = t('create');
$options[DOMAIN_PREFIX_COPY] = t('copy');
$form['domain_prefix'][$table] = array(
'#type' => 'radios',
'#title' => $table,
'#options' => $options,
'#default_value' => $settings[$table],
'#description' => $module,
);
$sources = array();
$sources[0] = $root['sitename'];
$result = db_query("SELECT dp.domain_id, d.sitename FROM {domain_prefix} dp INNER JOIN {domain} d ON dp.domain_id = d.domain_id WHERE dp.tablename = '%s' AND dp.status > 1", $table);
while ($data = db_fetch_array($result)) {
$sources[$data['domain_id']] = $data['sitename'];
}
$form['domain_source']['_source_' . $table] = array(
'#type' => 'select',
'#title' => '',
'#options' => $sources,
'#default_value' => $source_defaults['_source_' . $table],
);
}
}
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Save prefix settings'),
);
$form['restore'] = array(
'#type' => 'submit',
'#value' => t('Restore defaults'),
);
return $form;
}
function domain_prefix_domainlinks($domain) {
if (user_access('administer table prefixing')) {
$links[] = array(
'title' => t('tables'),
'path' => 'admin/build/domain/prefix/' . $domain['domain_id'],
);
return $links;
}
}
function domain_prefix_configure_form_submit($form_id, $form_values) {
$options = $form_values['domain_prefix_options'];
$unset = array(
'op',
'submit',
'restore',
'form_token',
'form_id',
'domain_prefix_options',
);
$data = $form_values;
foreach ($unset as $key) {
unset($data[$key]);
}
if ($form_values['op'] == $form_values['restore']) {
variable_del('domain_prefix');
drupal_set_message(t('Default prefix settings reset.'));
}
else {
foreach ($data as $key => $value) {
if (substr($key, 0, 8) == '_source_') {
$info['sources'][$key] = $value;
}
else {
$info['settings'][$key] = $value;
}
}
$settings = serialize($info);
variable_set('domain_prefix', $settings);
drupal_set_message(t('Default prefix settings changed.'));
}
variable_set('domain_prefix_options', $options);
}
function theme_domain_prefix_configure_form($form) {
$output = t('<p>These settings control advanced functions. Please read the documentation carefully.</p>');
$header = array(
t('Table'),
t('Source'),
t('Ignore'),
t('Create'),
t('Copy'),
);
if ($form['prefix_theme']['#value'] > 0) {
$header[] = t('Update');
$header[] = t('Drop');
unset($form['prefix_theme']);
}
$output = drupal_render($form['domain']);
foreach (element_children($form['domain_prefix']) as $key) {
if ($form['domain_prefix'][$key]['#description']) {
$rows[] = array(
'<b>' . $form['domain_prefix'][$key]['#description'] . '</b>',
array(
'',
'colspan' => 4,
),
);
}
$row = array();
$row[] = ' - ' . $form['domain_prefix'][$key]['#title'];
$row[] = drupal_render($form['domain_source']['_source_' . $key]);
foreach (element_children($form['domain_prefix'][$key]) as $option) {
$row[] = drupal_render($form['domain_prefix'][$key][$option]);
}
$render = drupal_render($form['domain_prefix'][$key]);
$rows[] = $row;
}
$output .= theme('table', $header, $rows);
$output .= drupal_render($form);
return $output;
}
function domain_prefix_form($domain_id, $arguments = array()) {
$default = domain_default();
domain_goto($default);
$domain = domain_lookup($domain_id);
drupal_set_title(t('Table prefixing for @domain', array(
'@domain' => $domain['sitename'],
)));
$disallow = domain_prefix_disallow();
$default = domain_prefix_get_tables();
$info = unserialize(variable_get('domain_prefix', NULL));
$settings = $info['settings'];
$source_defaults = $info['sources'];
$result = db_query("SELECT tablename, source FROM {domain_prefix} WHERE domain_id = %d", $domain['domain_id']);
while ($sourcedata = db_fetch_array($result)) {
$source_defaults['_source_' . $sourcedata['tablename']] = $sourcedata['source'];
}
$root = domain_default();
if (empty($settings) && !$_POST) {
drupal_set_message(t('There are no default settings configured.'));
}
$tables = domain_prefix_lookup($domain_id);
$submit = t('Update domain tables');
if (empty($tables)) {
if (!$_POST && !$form_values['execute'] && !$arguments['user_submitted']) {
drupal_set_message(t('The table creation sequence has not run for this domain.'));
}
$submit = t('Generate domain tables');
$table_options = $default;
}
else {
$table_options = array();
$settings = array();
foreach ($tables as $name => $table) {
if (array_key_exists($name, $default)) {
$table_options[$table['tablename']] = $table;
$settings[$table['tablename']] = $table['status'];
}
}
}
uasort($table_options, '_domain_prefix_sort');
$prefix = domain_prefix_string($domain_id);
$form = array();
if (!empty($arguments)) {
$form['domain_arguments'] = array(
'#type' => 'value',
'#value' => $arguments,
);
}
$delete_flag = 0;
$last = '';
foreach ($table_options as $table => $info) {
if (!in_array($table, $disallow)) {
if (empty($settings[$table])) {
$settings[$table] = DOMAIN_PREFIX_IGNORE;
}
$options = array();
$options[DOMAIN_PREFIX_IGNORE] = t('ignore');
$options[DOMAIN_PREFIX_CREATE] = t('create');
$options[DOMAIN_PREFIX_COPY] = t('copy');
if ($settings[$table] > 0) {
$exists = domain_prefix_table_exists($prefix, $table);
if ($exists > 0) {
$options[DOMAIN_PREFIX_UPDATE] = t('update');
$options[DOMAIN_PREFIX_DROP] = t('drop');
$delete_flag++;
}
}
$module = $info['module'];
if ($last != $module) {
$last = $module;
}
else {
$module = '';
}
$form['domain_prefix'][$table] = array(
'#type' => 'radios',
'#title' => $table,
'#options' => $options,
'#default_value' => $settings[$table],
'#description' => $module,
);
$sources = array();
$sources[0] = $root['sitename'];
$result = db_query("SELECT dp.domain_id, d.sitename FROM {domain_prefix} dp INNER JOIN {domain} d ON dp.domain_id = d.domain_id WHERE dp.tablename = '%s' AND dp.status > 1", $table);
while ($data = db_fetch_array($result)) {
if ($data['domain_id'] != $domain['domain_id']) {
$sources[$data['domain_id']] = $data['sitename'];
}
}
$form['domain_source']['_source_' . $table] = array(
'#type' => 'select',
'#title' => '',
'#options' => $sources,
'#default_value' => $source_defaults['_source_' . $table],
);
}
}
$form['#theme'] = 'domain_prefix_configure_form';
$form['prefix_theme'] = array(
'#type' => 'value',
'#value' => $delete_flag,
);
$form['domain_id'] = array(
'#type' => 'value',
'#value' => $domain_id,
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => $submit,
);
return $form;
}
function domain_prefix_table_exists($prefix, $table) {
global $db_type;
$string = db_escape_table($prefix . $table);
switch ($db_type) {
case 'pgsql':
$query = "SELECT table_name FROM information_schema.tables WHERE table_schema = 'public' AND table_name = '{%s}'";
break;
default:
$query = "SHOW TABLES LIKE '{%s}'";
break;
}
return db_num_rows(db_query($query, $string));
}
function domain_prefix_form_submit($form_id, $form_values) {
$msg = TRUE;
$create = TRUE;
if ($form_values['domain_arguments']['user_submitted']) {
$msg = FALSE;
$create = variable_get('domain_user_prefixing', 0);
}
if ($create) {
$prefix = domain_prefix_string($form_values['domain_id']);
$unset = array(
'prefix_theme',
'domain_id',
'op',
'submit',
'restore',
'form_token',
'form_id',
'execute',
);
$data = $form_values;
foreach ($unset as $key) {
unset($data[$key]);
}
$current = domain_prefix_lookup($form_values['domain_id']);
db_query("DELETE FROM {domain_prefix} WHERE domain_id = %d", $form_values['domain_id']);
$db_type = $GLOBALS['db_type'];
foreach ($data as $key => $value) {
if (substr($key, 0, 8) != '_source_') {
$source = $data['_source_' . $key];
if ($source > 0) {
$source_prefix = domain_prefix_string($source);
}
else {
$source_prefix = '';
}
$update = FALSE;
if (empty($value)) {
$value = DOMAIN_PREFIX_IGNORE;
$update = TRUE;
}
$newtable = db_escape_table($prefix . $key);
$module = domain_prefix_module_lookup($key);
$exists = domain_prefix_table_exists($prefix, $key);
$oldtable = db_escape_table($key);
$sourcetable = db_escape_table($source_prefix . $key);
if ($value == DOMAIN_PREFIX_CREATE) {
if (!$exists) {
if ($db_type == 'pgsql') {
db_query("CREATE TABLE {%s} AS SELECT * FROM {%s}", $newtable, $sourcetable);
db_query("TRUNCATE TABLE {%s}", $newtable);
}
else {
db_query("CREATE TABLE {%s} LIKE {%s}", $newtable, $sourcetable);
}
if ($msg) {
drupal_set_message(t('!string table created.', array(
'!string' => $newtable,
)));
}
$update = TRUE;
}
else {
if ($current[$oldtable]['status'] == DOMAIN_PREFIX_COPY) {
drupal_set_message(t('!string table cannot be created, since it already exists.', array(
'!string' => $newtable,
)));
}
}
}
else {
if ($value == DOMAIN_PREFIX_COPY) {
if (!$exists) {
if ($db_type == 'pgsql') {
db_query("CREATE TABLE {%s} AS SELECT * FROM {%s}", $newtable, $sourcetable);
}
else {
db_query("CREATE TABLE {%s} LIKE {%s}", $newtable, $sourcetable);
db_query("INSERT INTO {%s} SELECT * FROM {%s}", $newtable, $sourcetable);
}
domain_prefix_update_sequences('update', $newtable, $sourcetable);
if ($msg) {
drupal_set_message(t('!string table copied.', array(
'!string' => $newtable,
)));
}
$update = TRUE;
}
else {
if ($current[$oldtable]['status'] == DOMAIN_PREFIX_CREATE) {
drupal_set_message(t('!string table cannot be copied, since it already exists.', array(
'!string' => $newtable,
)));
}
}
}
else {
if ($value == DOMAIN_PREFIX_UPDATE) {
if ($exists > 0) {
db_query("TRUNCATE TABLE {%s}", $newtable);
db_query("INSERT INTO {%s} SELECT * FROM {%s}", $newtable, $sourcetable);
domain_prefix_update_sequences('update', $newtable, $sourcetable);
if ($msg) {
drupal_set_message(t('!string table updated from source.', array(
'!string' => $newtable,
)));
}
$update = TRUE;
$value = DOMAIN_PREFIX_COPY;
}
}
else {
if ($value == DOMAIN_PREFIX_DROP) {
if ($exists > 0) {
db_query("DROP TABLE {%s}", $newtable);
$value = DOMAIN_PREFIX_IGNORE;
domain_prefix_update_sequences('drop', $newtable, $sourcetable);
if ($msg) {
drupal_set_message(t('!string table dropped.', array(
'!string' => $newtable,
)));
}
$update = TRUE;
}
else {
drupal_set_message(t('!string table does not exist.', array(
'!string' => $newtable,
)));
}
}
}
}
}
if (!$update && $value != 1) {
$value = $current[$oldtable]['status'];
}
db_query("INSERT INTO {domain_prefix} (domain_id, status, tablename, module, source) VALUES (%d, %d, '%s', '%s', %d)", $form_values['domain_id'], $value, $key, $module, $form_values['_source_' . $key]);
}
}
}
cache_clear_all();
}
function domain_prefix_update_sequences($op, $newtable, $sourcetable) {
$result = db_query("SELECT name, id FROM {sequences} WHERE name LIKE '{%s%}'", $sourcetable);
$dbprefix = domain_prefix_get_prefix();
$source = explode('_', $dbprefix . $sourcetable);
while ($variable = db_fetch_array($result)) {
$var = explode('_', $variable['name']);
array_pop($var);
$diff = array_diff($var, $source);
if (empty($diff)) {
$newvariable = $newtable . substr($variable['name'], strlen($dbprefix . $sourcetable));
$target = db_result(db_query("SELECT id FROM {sequences} WHERE name = '{%s}'", $newvariable));
if (!$target) {
if ($op == 'update') {
db_query("INSERT INTO {sequences} (name, id) VALUES ('{%s}', %d)", $newvariable, $variable['id']);
}
}
else {
if ($op == 'update') {
db_query("UPDATE {sequences} SET id = %d WHERE name = '{%s}'", $variable['id'], $newvariable);
}
else {
db_query("DELETE FROM {sequences} WHERE name = '{%s}'", $newvariable);
}
}
}
}
}
function domain_prefix_module_lookup($table) {
$match = explode('_', $table);
$module = $match[0];
switch ($table) {
default:
break;
case 'boxes':
$module = 'blocks';
break;
case 'file_revisions':
$module = 'files';
break;
case 'cache_menu':
$module = 'menu';
break;
case 'filter_formats':
$module = 'filters';
break;
case 'access':
case 'permission':
case 'role':
case 'users':
case 'users_roles':
$module = 'users';
break;
case 'url_alias':
$module = 'path';
break;
case 'variable':
$module = 'cache';
break;
case 'client':
case 'client_system':
$module = 'drupal';
break;
case 'accesslog':
$module = 'statistics';
break;
case 'term_data':
case 'term_hierarchy':
case 'term_node':
case 'term_relation':
case 'term_synonym':
$module = 'taxonomy';
break;
}
return $module;
}
function domain_prefix_lookup($domain_id, $clear = FALSE) {
static $domain_prefix;
if ($clear || !isset($domain_prefix[$domain_id])) {
$domain_prefix[$domain_id] = array();
$result = db_query("SELECT domain_id, status, tablename, module, source FROM {domain_prefix} WHERE domain_id = %d", $domain_id);
while ($data = db_fetch_array($result)) {
$domain_prefix[$domain_id][$data['tablename']] = $data;
}
}
return $domain_prefix[$domain_id];
}
function domain_prefix_disallow() {
return array(
'domain',
'domain_conf',
'domain_prefix',
'domain_theme',
'domain_user',
);
}
function domain_prefix_domainupdate($op, $domain = array(), $edit = array()) {
switch ($op) {
case 'create':
$rule = variable_get('domain_prefix_options', 1);
if ($rule) {
$settings = unserialize(variable_get('domain_prefix', NULL));
if (!empty($settings)) {
$settings['domain_id'] = $domain['domain_id'];
drupal_execute('domain_prefix_form', $settings, $domain['domain_id'], $edit['domain_arguments']);
}
}
break;
case 'delete':
domain_prefix_drop_records($domain['domain_id']);
break;
}
}
function domain_prefix_drop_records($domain_id) {
$result = db_query("SELECT tablename FROM {domain_prefix} WHERE domain_id = %d AND status > 1", $domain_id);
$prefix = domain_prefix_string($domain_id);
while ($tables = db_fetch_array($result)) {
$table = db_escape_table($prefix . $tables['tablename']);
$exists = domain_prefix_table_exists($prefix, $tables['tablename']);
if ($exists > 0) {
db_query("DROP TABLE {%s}", $table);
drupal_set_message(t('!string table dropped.', array(
'!string' => $table,
)));
}
}
db_query("DELETE FROM {domain_prefix} WHERE domain_id = %d", $domain_id);
}
function domain_prefix_string($domain_id) {
return 'domain_' . $domain_id . '_';
}
function domain_prefix_domaininstall() {
if (module_exists('domain_prefix') && !function_exists('_domain_prefix_load')) {
drupal_set_message(t('The Domain Prefix module is not installed correctly. Please edit your settings.php file as described in <a href="!url">INSTALL.txt</a>', array(
'!url' => base_path() . drupal_get_path('module', 'domain_prefix') . '/INSTALL.txt',
)));
}
}