Programmatically change primary links menu for a domain?

svdoord - February 2, 2009 - 13:51
Project:Domain Access
Version:6.x-2.0-rc6
Component:Code
Category:feature request
Priority:normal
Assigned:Unassigned
Status:patch (to be ported)
Description

I'm currently building a site using domain access. So far I like it a lot, I'm really glad this module exists, job well done! :-)

In this particular case my users will create new 'subsites' themselves. I already succeeded in making a very simple form with only two fields that they can fill out. This form creates a new domain record (using drupal_execute on the correct form id) and creates a new menu, because I want each site to have it's own primary links menu. The challenge I'm facing now, is to programmatically assign this new primary links menu to the domain that was just created. I could do this of course by querying the domain_conf table, unserializing the data, modify it, serialize it again, and update the table. I consider that hacking though, as I'm sure this is not guaranteed to work in future versions.

I tried to come up with a way of doing this through the functions defined in domain_conf, but I guess the problem is that domain_conf relies on the current domain being the one you're editing. I would like all this to be done invisible to the end-user.

So my question is: is there a better, more "official" way to do this? Any hints? Your help is greatly appreciated!

#1

agentrickard - February 2, 2009 - 14:51
Category:support request» feature request
Status:active» needs work

There really is no better method than what you describe.

However, I would be willing to commit a patch for a new function, domain_conf_set_variable(), which would have the following structure:

<?php
/**
* Change the variable setting for a domain.
* This function is called by external modules that wish
* to alter Domain Conf settings.
*
* See <a href="http://drupal.org/node/367963
" title="http://drupal.org/node/367963
" rel="nofollow">http://drupal.org/node/367963
</a> *
* @param $domain_id
* The unique domain ID that is being edited.
* @param $variable
* The name of the variable you wish to set.
* @param $value
* The value of the variable to set. You may leave this
* value blank in order to unset the custom variable.
*/
function domain_conf_variable_set($domain_id, $variable, $value = NULL) {
 
// code to come.
}
?>

Then we can put your code into the main module so we don't have to worry about deprecation, since this becomes an API function.

#2

svdoord - February 2, 2009 - 15:16

It seems to me like a good idea to add a facility for this to the API. I don't have any code yet for the suggested method I described above, so I'm afraid you cannot put my code there :-)

Meanwhile, I have been able to solve my issue in a better way than the one I suggested first. I use the following code now, which is called from hook_domainupdate() in my custom module (when $op == 'create').

<?php
function _configure_domain_primary_menu($domain) {
 
module_load_include('inc', 'system', 'system.admin');
 
module_load_include('inc', 'domain', 'domain.admin');
 
module_load_include('module', 'domain_conf');
 
module_load_include('inc', 'domain_conf', 'domain_conf.admin');
 
 
$subdomain = $domain['subdomain'];
 
$subdomain = explode('.', $subdomain);
 
$subdomain = array_shift($subdomain);
 
 
// This is a helper function that creates the menu:
 
_create_menu(
   
'primary-links-' . $subdomain,
   
$domain['sitename'],
   
t('Main menu for event ') . $domain['sitename']
  );
 
 
$form_state = array('values' => array(
   
'domain_id' => $domain['domain_id'],
   
'menu_primary_links_source' => 'menu-primary-links-' . $subdomain
 
));
 
 
$storedQuery = $_GET['q'];
 
$domain_conf = domain_conf_domainlinks($domain);
 
$_GET['q'] = $domain_conf[0]['path'];
 
drupal_execute('system_site_information_settings', $form_state);
 
$_GET['q'] = $storedQuery;
}
?>

So the trick is basically to use a normal drupal_execute, but because I manually change $_GET['q'], I trick domain_conf into using the correct settings entry. To me this solution is acceptable, because I don't need to access the database and rely on the internals stored in the domain_conf table.

Again, an API function like the one you suggest would be a very nice addition. I would then not even have to rely on the fact that domain_conf_system() uses arg(4) to determine the current domain. By the way, I'm not entirely sure if I should use domain_conf_domainlinks(), but I also don't want to put the literal URL in my module (because it's an internal of the domain access module).

#3

agentrickard - February 21, 2009 - 16:12
Version:6.x-2.0-rc5» 6.x-2.0-rc6
Status:needs work» patch (to be ported)

I have committed this function to HEAD. Here is the API documentation.

<?php
/**
* Demonstrates domain_conf_variable_set().
*
* Allows module to reset domain-specific variables.
* This function is not a hook, it is a helper function
* that is implemented by the Domain Configuration module.
*
* Use this function if you need to reset a domain-specific variable
* from your own code. It is especially useful in conjunction with
* hook_domainupdate().
*
* @param $domain_id
* The unique domain ID that is being edited.
* @param $variable
* The name of the variable you wish to set.
* @param $value
* The value of the variable to set. You may leave this
* value blank in order to unset the custom variable.
*/
function mymodule_form_submit($form_state) {
 
// When we save these changes, replicate them across all domains.
 
if (!module_exists('domain_conf')) {
    return;
  }
 
$domains = domain_domains();
  foreach (
$domains as $domain) {
   
$value = $form_state['values']['my_variable'];
   
domain_conf_variable_set($domain['domain_id'], 'my_variable', $value);
  }
}
?>

#4

orangecoat-ciallella - March 4, 2009 - 04:34

@agentrickard - any interest in adding the sort of feature svdoord described if some like me is willing/able to develop it? I could use this functionality as well for a client project and wouldn't mind building it into Domains.

I think some of the code above could be used as a start. I'd likely try to create each primary links menu using drupal_execute() to simulate how a users create new menus in Drupal. Also adding at least one checkbox to the general Domains settings to control whether to auto-generate primary links. Or else, adding an option on the Domain creation form.

Menu Names in Drupal core are limited to 27 characters and technically the menu_name value shouldn't change once set, so this would require a bit of thinking to build something that works well with Drupal Core, the Domains modules, and is still obvious to end users. Perhaps using domain-{domain_id}-primary , or some such.

Anyway, I figured I'd gauge interest.

#5

agentrickard - March 4, 2009 - 19:01

@orangecoat-ciallella -

Please open a new issue that describes what you are trying to do.

#6

gunzip - April 24, 2009 - 15:06

you can prefix the menu tables (so each domain has its own one) then

you can execute any functions in the scope of any domain with a code like that one posted here:

http://drupal.org/node/343281#comment-1195947

 
 

Drupal is a registered trademark of Dries Buytaert.