The following instructions apply to setting up the Domain Access Module to work with Organic Groups in Drupal 5.
The requirement was to have a main site where admin controls the content and a subsite where registered users are able to create groups and post content. Admin then has the power to publish any chosen content from the subsite to the main site. It is conceivable that this set up would work with multiple subsites and not just one.
The subsite(s) is/are a subdomain of the main site.
Firstly, setup Drupal and install Domain Module and Organic Groups as per instructions that accompany them.
settings.php
$cookie_domain = 'mysite.com';
Mysite.com should be the domain name with no prefix (eg 'www.' or 'subsite.'). This ensures that cookies are uniform throughout all subdomains and when logged into one subdomain users will also be logged into all others and the main site.
require_once 'sites/all/modules/domain/settings_custom_url.inc';
require_once 'sites/all/modules/domain/domain_conf/settings_domain_conf.inc';
These should go at the end of the settings.php file and are optional. The first helps with url rewrites and the second with the domain configuration module.
node.module
Apply the multiple_node_access_cvs.patch (see instructions here: http://drupal.org/node/234087#comment-865035, and get the upgraded patch from here: http://drupal.org/node/243731#comment-810681, which solves problems with private groups). Download OG User Roles and configure according to instructions provided in the first thread. You only need to configure OG and DA. No need to configure TAC or even install it.
At admin/build/domain=>domain module behaviors:
Select Only show on selected sites. This ensures that content is only posted on selected site.
Select Take user to their assigned domain. This links the selected site above with the site to which the author belongs.
At admin/build/domain=>advanced settings:
Select Use access control for editors. This enables control over who edits what
Select Drupal default access
(Select Check Domain Access in addition to other modules if using restricted access - more complex - requires mulitnode access)
At admin/build/domain/advanced:
Select the node types that are to be published on all sites, making sure that you don't select content types that you want users to have restricted publishing rights with.
At admin/user/access:
Domain Module Permissions:
If you select edit domain nodes then users in this role will be able to edit any node in the realm in which they have permissions, so leave this unchecked.
Select view domain publishing. This limits the previous permission to just those domains governed by the selection for the current user, which in our case is Take user to their assigned domain.
Node Permissions:
Do not select administer nodes for roles which you require to have limited publishing rights.
That takes care of the module setup. Now for some customizations to fine tune behavior and overcome some limitations.
User Login
In order for editor publishing to be restricted to the subsite, they have to register through the subsite and not the main site. It is during this action that Domain Access supplies a user with the domain they belong to. There are a number of ways of doing this but I used hook_init. If you haven't created a module for your site, do so and use something like the following:
function mysite_init() {
if($_GET['q']=="user/register" && $_SERVER['SERVER_NAME']=='www.mysite.com') {
$destination = drupal_get_destination();
header('Location: http://subsite.mysite.com/user/register?'.$destination);
}
}
This will direct all registrations to the subsite.
Editor View Rights
Most content types come with a hard coded script that gives an editor viewing rights for any nodes they have created themselves. In the required site configuration it was considered confusing for users to be able to see the content that they wrote that is supposed to only be viewable on the subsite, on the main site as well, so I came up with the following solution:
1. For node listings use the module viewsphpfilter (http://drupal.org/project/viewsphpfilter) which supplies you with a filter option, NODE: ID and a textarea in which to enter some php code. Make sure you read the instructions accompanying this module. The code I used for all the views that I wanted to control is as follows:
if(module_exists('mysite')) return mysite_views_author_filter(10);
which in turn calls a function in my custom site module:
/**
* Return an array of nodes to exclude from listings, used in Views. This avoids users seeing nodes they authored on the main site when they are not published there
*/
function mysite_views_author_filter($num) {
global $user, $_domain, $conf;
if($user->uid>0) {
if(!user_access('administer nodes')) {
static $exceptions;
if(!$exceptions) {
$result = db_query("SELECT * FROM {node} WHERE uid=%d AND status=1 ORDER BY created DESC LIMIT %d", $user->uid, $num);
while($row = db_fetch_object($result)) {
$node = node_load($row->nid);
//$exceptions[] = $row->nid;
foreach($node->subdomains as $subdomain) {
if($subdomain!="All affiliates") {
foreach($user->domain_user as $domain) {
if($domain!=$_domain['domain_id'] ) {
if($subdomain=="Subdomain Name" && $domain==1 && $_domain['domain_id']==1) continue;
elseif($subdomain=="Main Site Name" && $domain==0 && $_domain['domain_id']==0) continue;
else $exceptions[] = $row->nid;
//else if( return FALSE;
}
}
}
}
}
}
return $exceptions;
}
return array();
}
return array();
}
Note that the sql is restricted to $num number of records. The allocation of that number depends on the number of records required for the view and the likelihood of any single user having a large consequetive number of posts that they are the editor of. For overhead reasons we do not want to select every node the user has authored, so with each view there will be an optimum. This is rather crude but it works.
Another thing I found is that if a node is ticked 'promote to front page' then it will over-ride the Domain Access settings and appear in views regardless.
2. For single node views I added another patch to the node.module(optional -see below)
if (user_access('administer nodes')) {
return TRUE;
}
if (!user_access('access content')) {
return FALSE;
}
+ New code
+ if($user->uid == $node->uid && $user->uid != 0 && module_exists('getting_outside')) {
+ if(mysite_check_node_author($node)) return FALSE;
+ }
// Can't use node_invoke(), because the access hook takes the $op parameter
// before the $node parameter.
$module = node_get_types('module', $node);
if ($module == 'node') {
$module = 'node_content'; // Avoid function name collisions.
}
which in turn calls:
/**
* This is called from the node.module to restrict access to nodes authored by the user to the correct place
* It only works on single node views and not listings.
*/
function mysite_check_node_author($node) {
global $user, $_domain, $conf;
foreach($node->subdomains as $subdomain) {
if($subdomain=="All affiliates") return FALSE;
foreach($user->domain_user as $domain) {
if($domain==$_domain['domain_id'] ) {
if($subdomain=="Subsite Name" && $domain==1) return FALSE;
if($subdomain=="Main Site Name" && $domain==0) return FALSE;
}
}
}
return TRUE;
}
While it is not good to hack a core module Domain Access already comes with a patch for the node_access. If you don't fancy doing this there is probably no need to if your users are mainly only going to see listings on the main site. This patch/hack will only come into play if a user somehow manages to find the url to view the node without using a listing.
There is no special configuration requirement here.