/[drupal]/contributions/modules/domain/domain.admin.inc
ViewVC logotype

Contents of /contributions/modules/domain/domain.admin.inc

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.41 - (show annotations) (download) (as text)
Sun Nov 1 18:20:19 2009 UTC (3 weeks, 6 days ago) by agentken
Branch: MAIN
CVS Tags: DRUPAL-6--2-0, HEAD
Branch point for: DRUPAL-6--2
Changes since 1.40: +30 -1 lines
File MIME type: text/x-php
-- #372887 patch by nonsie and blackdog. Super-awesome set values for all domains in domain batch.
-- Creates the 6.x.2.0 stable release.
1 <?php
2 // $Id: domain.admin.inc,v 1.40 2009/10/31 18:28:32 agentken Exp $
3
4 /**
5 * @file
6 * Administration functions for the domain module.
7 *
8 * These functions only need to be accessed from admin/build/domain, so we put them in a separate include file.
9 * @ingroup domain
10 */
11
12 /**
13 * The main administration page, a list of active domains.
14 *
15 * @return
16 * A sortable table of active domain records, or an error message.
17 */
18 function domain_view() {
19 global $_domain;
20 $output = t('<p>The following domains have been created for your site. The currently active domain <b>is shown in boldface</b>. You
21 may click on a domain to change the currently active domain. Your default domain has an ID of zero (0).</p>');
22 $header = array(
23 array('data' => t('Id'), 'field' => 'd.domain_id'),
24 array('data' => t('Domain'), 'field' => 'd.subdomain'),
25 array('data' => t('Site name'), 'field' => 'd.sitename'),
26 array('data' => t('Status'), 'field' => 'd.valid'),
27 array('data' => t('Scheme'), 'field' => 'd.scheme'),
28 );
29 // Get header elements from other modules
30 $extra = module_invoke_all('domainview', 'header');
31 $header = array_merge($header, $extra);
32 $header[] = array('data' => t('Actions'), 'colspan' => 6);
33
34 // Cannot use domain_domains() here because we need to sort the output.
35 $domains = array();
36 $actions = array();
37 // Get any select sql from other modules.
38 $select = module_invoke_all('domainview', 'select');
39 $select_sql = '';
40 if (!empty($select)) {
41 $select_sql = ', '. implode(', ', $select);
42 $select_sql = rtrim($select_sql, ',');
43 }
44
45 // Get any tablesort sql from other modules.
46 $join = module_invoke_all('domainview', 'join');
47 $join_sql = '';
48 if (!empty($join)) {
49 $join_sql = ' '. implode(' ', $join);
50 }
51
52 $sql = 'SELECT d.*'. $select_sql .' FROM {domain} d'. $join_sql . tablesort_sql($header);
53 $result = pager_query($sql, variable_get('domain_list_size', DOMAIN_LIST_SIZE));
54 while ($data = db_fetch_array($result)) {
55 $domains[] = $data;
56 }
57 foreach ($domains as $domain) {
58 // Let submodules overwrite the defaults, if they wish.
59 $domain = domain_api($domain);
60 $link = l($domain['subdomain'], domain_get_uri($domain), array('absolute' => TRUE));
61 if ($domain['domain_id'] == 0) {
62 // Grab any extra elements defined by other modules. If so, allow configuration.
63 $extra = array();
64 if (module_exists('domain_conf')) {
65 $extra = domain_conf_api();
66 }
67 if (!empty($extra)) {
68 $actions[] = l(t('settings'), 'admin/build/domain/conf/0');
69 }
70 else {
71 $actions[] = array('data' => t('primary'), 'colspan' => 2);
72 }
73 }
74 else {
75 $actions = array();
76 $actions[] = l(t('edit'), 'admin/build/domain/edit/'. $domain['domain_id']);
77 $actions[] = l(t('delete'), 'admin/build/domain/delete/'. $domain['domain_id']);
78 }
79 // Add advanced settings from other modules.
80 $items = array();
81 $items = module_invoke_all('domainlinks', $domain);
82 if (!empty($items)) {
83 foreach ($items as $item) {
84 if (!empty($item)) {
85 $actions[] = l($item['title'], $item['path']);
86 }
87 else {
88 $actions[] = '<br />';
89 }
90 }
91 }
92 // Set the valid flag.
93 ($domain['valid'] == 1) ? $valid = t('Active') : $valid = t('Inactive');
94 $row = array($domain['domain_id'], ($domain['domain_id'] == $_domain['domain_id']) ? '<b>'. $link .'</b>' : $link, filter_xss_admin($domain['sitename']), $valid, $domain['scheme']);
95 // Let other modules add data.
96 foreach (module_implements('domainview') as $module) {
97 $row[] = module_invoke($module, 'domainview', 'data', $domain);
98 }
99 // Add the actions.
100 $rows[] = array_merge($row, $actions);
101 }
102 if (!empty($rows)) {
103 $output .= theme_table($header, $rows);
104 $output .= theme('pager', NULL, variable_get('domain_list_size', DOMAIN_LIST_SIZE), 0);
105 return $output;
106 }
107 else {
108 return t('No domains have been configured.');
109 }
110 }
111
112 /**
113 * Module settings and behaviors.
114 */
115 function domain_configure() {
116 if (empty($_POST)) {
117 // Is the module installed correctly?
118 module_invoke_all('domaininstall');
119 }
120 // Return the configuration form.
121 return drupal_get_form('domain_configure_form');
122 }
123
124 /**
125 * FormsAPI for configuring the domain module.
126 */
127 function domain_configure_form($form_state, $user_submitted = FALSE) {
128 $root = variable_get('domain_root', '');
129 if (empty($root)) {
130 domain_set_primary_domain();
131 }
132 $form = array();
133 $form['domain'] = array(
134 '#type' => 'fieldset',
135 '#title' => t('Default domain settings'),
136 '#collapsible' => TRUE
137 );
138 $sitename = variable_get('site_name', 'Drupal');
139 $form['domain']['domain_root'] = array(
140 '#type' => 'textfield',
141 '#title' => t('Primary domain name'),
142 '#size' => 40,
143 '#maxlength' => 80,
144 '#required' => TRUE,
145 '#default_value' => variable_get('domain_root', ''),
146 '#description' => t('The primary domain for your site. Typically <em>example.com</em> or <em>www.example.com</em>. Do not use http or slashes.
147 <br />This domain will be used as the default URL for your site.
148 <br />If an invalid domain is requested, users will be sent next available domain or to the primary domain.')
149 );
150 $form['domain']['domain_sitename'] = array(
151 '#type' => 'textfield',
152 '#title' => t('Site name'),
153 '#size' => 40,
154 '#maxlength' => 80,
155 '#required' => TRUE,
156 '#default_value' => variable_get('domain_sitename', $sitename),
157 '#description' => t('The site name to display for this domain.')
158 );
159 $form['domain']['domain_scheme'] = array(
160 '#type' => 'radios',
161 '#title' => t('Domain URL scheme'),
162 '#required' => TRUE,
163 '#options' => array('http' => 'http://', 'https' => 'https://'),
164 '#default_value' => variable_get('domain_scheme', 'http'),
165 '#description' => t('The URL scheme for accessing the primary domain.')
166 );
167 $form['domain_behavior'] = array(
168 '#type' => 'fieldset',
169 '#title' => t('Domain module behaviors'),
170 '#collapsible' => TRUE,
171 '#collapsed' => TRUE
172 );
173
174 $form['domain_behavior']['domain_behavior'] = array(
175 '#type' => 'radios',
176 '#title' => t('New content settings'),
177 '#required' => TRUE,
178 '#default_value' => variable_get('domain_behavior', DOMAIN_INSTALL_RULE),
179 '#options' => array(1 => t('Show on all affiliate sites'), 2 => t('Only show on selected sites')),
180 '#description' => t('If set to <em>Show on all affiliate sites</em>, this value will automatically assign new content to all affiliates.<br />If set to <em>Only show on selected sites</em>, you must configure the <a href="!url">Node-type specific settings</a>.', array('!url' => url('admin/build/domain/advanced')))
181 );
182
183 $form['domain_behavior']['domain_debug'] = array(
184 '#type' => 'radios',
185 '#title' => t('Debugging status'),
186 '#required' => TRUE,
187 '#default_value' => variable_get('domain_debug', 0),
188 '#options' => array(0 => t('Do not show debugging output'), 1 => t('Show debugging output on node view')),
189 '#description' => t('If set, users with the <em>set domain access</em> permission will be able to view the node access rules for each node. See the README for more details.')
190 );
191
192 $form['domain_behavior']['domain_force_admin'] = array(
193 '#type' => 'radios',
194 '#title' => t('Enforce rules on administrators'),
195 '#required' => TRUE,
196 '#default_value' => variable_get('domain_force_admin', 0),
197 '#options' => array(0 => t('Do not enforce'), 1 => t('Restrict node views for administrators')),
198 '#description' => t('If set, users with the <em>administer nodes</em> permission and user 1 <em>will view the site with Domain Access restrictions enforced</em>. See the README for more details.')
199 );
200
201 $options = array(
202 'id' => t('Creation order, oldest > newest'),
203 'rid' => t('Creation order, newest > oldest'),
204 'name' => t('Sitename, A > Z'),
205 'rname' => t('Sitename, Z > A'),
206 'url' => t('URL, A > Z'),
207 'rurl' => t('URL, Z > A')
208 );
209 $form['domain_behavior']['domain_sort'] = array(
210 '#type' => 'radios',
211 '#title' => t('Sort domain lists'),
212 '#required' => TRUE,
213 '#default_value' => variable_get('domain_sort', 'id'),
214 '#options' => $options,
215 '#description' => t('Controls the display of domain lists to end users.')
216 );
217 $form['domain_behavior']['domain_list_size'] = array(
218 '#type' => 'select',
219 '#title' => t('Domain list size'),
220 '#required' => TRUE,
221 '#default_value' => variable_get('domain_list_size', DOMAIN_LIST_SIZE),
222 '#options' => drupal_map_assoc(array(5, 10, 20, 25, 30, 40, 50, 75, 100, 150, 200, 250, 500, 750, 1000)),
223 '#description' => t('Sets a break point for the size of domain lists shown to users. After this point, user interfaces will use tables, pagination, and select lists to prevent too many domains from appearing in a list. <em>Note: setting this value higher than 200 may cause memory and display issues for your site.</em>')
224 );
225 $form['domain_behavior']['domain_select_format'] = array(
226 '#type' => 'select',
227 '#title' => t('Domain selection format'),
228 '#required' => TRUE,
229 '#default_value' => domain_select_format(),
230 '#options' => array(t('Checkboxes'), t('Select list')),
231 '#description' => t('Determines the display format of form elements that display domain lists.')
232 );
233
234 $form['domain_advanced'] = array(
235 '#type' => 'fieldset',
236 '#title' => t('Advanced settings'),
237 '#collapsible' => TRUE,
238 '#collapsed' => TRUE
239 );
240
241 $form['domain_advanced']['domain_www'] = array(
242 '#type' => 'radios',
243 '#title' => t('WWW prefix handling'),
244 '#default_value' => variable_get('domain_www', 0),
245 '#options' => array(0 => t('Process all host requests normally'), 1 => t('Treat www.*.example.com as an alias of *.example.com')),
246 '#description' => t('If set, calls to www.* will be treated as if the www. did not exist.
247 <em>Users will be taken from www.example.com to example.com, so your domains must be registered without the www. prefix.</em>')
248 );
249
250 // Check to see if the node_access patch is enabled. If it is, then
251 // we need to know if more than one node_access module is running.
252 $modules = count(module_implements('node_grants'));
253
254 if (!function_exists('node_access_grants_sql') || $modules < 2) {
255 $disabled = TRUE;
256 variable_set('domain_access_rules', 0);
257 }
258 // Do not show this form element unless it is necessary
259 if ($modules > 1) {
260 $form['domain_advanced']['domain_access_rules'] = array(
261 '#type' => 'radios',
262 '#title' => t('Node access settings'),
263 '#disabled' => $disabled,
264 '#default_value' => variable_get('domain_access_rules', 0),
265 '#options' => array(0 => t('Use the default Drupal behavior (OR)'), 1 => t('Check Domain Access in addition to other modules (AND)')),
266 '#description' => t('Controls how Domain Access interacts with access control modules such as Organic Groups. Requires the multiple_node_access patch.')
267 );
268 }
269 $form['domain_advanced']['domain_search'] = array(
270 '#type' => 'radios',
271 '#title' => t('Search settings'),
272 '#default_value' => variable_get('domain_search', 0),
273 '#options' => array(0 => t('Search content for the current domain only'), 1 => t('Search all domains from any URL')),
274 '#description' => t('Options for content searching.')
275 );
276
277 $form['domain_advanced']['domain_seo'] = array(
278 '#type' => 'radios',
279 '#title' => t('Search engine optimization'),
280 '#default_value' => variable_get('domain_seo', 0),
281 '#options' => array(0 => t('Do not rewrite URLs'), 1 => t('Rewrite all URLs to point to a single source')),
282 '#description' => t('If rewrite is turned on, all node links will point to a single instance of the node. This
283 option reduces the chance that search engines will recognize duplicate content.')
284 );
285
286 $options = array('-1' => t('Do not change domain'));
287 foreach (domain_domains() as $data) {
288 // The domain must be valid.
289 if ($data['valid']) {
290 $options[$data['domain_id']] = $data['sitename'];
291 }
292 }
293
294 $form['domain_advanced']['domain_default_source'] = array(
295 '#type' => 'select',
296 '#title' => t('Default source domain'),
297 '#options' => $options,
298 '#default_value' => variable_get('domain_default_source', 0),
299 '#description' => t('When rewriting urls, nodes assigned to all affiliates will be sent to this domain. <em>NOTE: This option only fires if you enable SEO rewrites or use the Domain Source module.</em>'),
300 );
301
302 $form['domain_all'] = array(
303 '#type' => 'fieldset',
304 '#title' => t('Special page requests'),
305 '#collapsible' => TRUE,
306 '#collapsed' => TRUE
307 );
308
309 $form['domain_all']['domain_grant_all'] = array(
310 '#type' => 'textarea',
311 '#rows' => 5,
312 '#cols' => 40,
313 '#default_value' => variable_get('domain_grant_all', "user/*/track"),
314 '#description' => t('Content on these pages should be viewable on any domain. Enter one path per line.
315 You may use the * as a wildcard. Use this for aggregate pages like those provided by <a href="!url">MySite</a> or if you
316 intend to show all user posts on a specific page. See the README for more details.', array('!url' => 'http://drupal.org/project/mysite'))
317 );
318
319 $form['domain_all']['domain_cron_rule'] = array(
320 '#type' => 'checkbox',
321 '#default_value' => variable_get('domain_cron_rule', 1),
322 '#title' => t('Treat cron.php as a special page request.'),
323 '#description' => t('Normally, you should leave this setting active. See the README for more information.')
324 );
325
326 $form['domain_paths'] = array(
327 '#type' => 'fieldset',
328 '#title' => t('Node link patterns'),
329 '#collapsible' => TRUE,
330 '#collapsed' => TRUE
331 );
332 $form['domain_paths']['domain_paths'] = array(
333 '#type' => 'textarea',
334 '#rows' => 5,
335 '#cols' => 40,
336 '#default_value' => variable_get('domain_paths', "node/%n\r\nnode/%n/edit\r\ncomment/reply/%n\r\nnode/add/book/parent/%n\r\nbook/export/html/%n\r\nnode/%n/outline"),
337 '#description' => t('When using SEO or other path rewrites, the following link paths should be turned into absolute URLs. Enter
338 the Drupal path of the link, using the <em>%n</em> placeholder to represent the node id.
339 Enter one path per line. See the README for more details.')
340 );
341
342 // Allow submodules to add elements to the form.
343 $modules = module_implements('domainform');
344 if (!empty($modules)) {
345 foreach ($modules as $module) {
346 $func = $module .'_domainform';
347 $func($form);
348 }
349 }
350 // Add our additional submit handlers.
351 $form['#submit'] = array('domain_configure_form_submit');
352 return system_settings_form($form);
353 }
354
355 /**
356 * Validate the primary domain string.
357 */
358 function domain_configure_form_validate($form, &$form_state) {
359 if ($form_state['values']['op'] == $form_state['values']['reset']) {
360 $subdomain = strtolower(rtrim($_SERVER['SERVER_NAME']));
361 }
362 else {
363 $subdomain = $form_state['values']['domain_root'];
364 }
365 $domain_changed = (bool) strcmp($form_state['values']['domain_root'], $form['domain']['domain_root']['#default_value']);
366 if ($domain_changed) {
367 $error_list = domain_validate($subdomain);
368 foreach ($error_list as $error) {
369 form_set_error('domain_root', $error);
370 }
371 }
372 }
373
374 /**
375 * Save any changes to the primary domain record.
376 */
377 function domain_configure_form_submit($form, &$form_state) {
378 if ($form_state['values']['op'] == $form_state['values']['reset']) {
379 domain_set_primary_domain();
380 return;
381 }
382 $subdomain = $form_state['values']['domain_root'];
383 db_query("UPDATE {domain} SET subdomain = '%s', sitename = '%s', scheme = '%s', valid = 1 WHERE domain_id = 0", $form_state['values']['domain_root'], $form_state['values']['domain_sitename'], $form_state['values']['domain_scheme']);
384 if (!db_affected_rows()) {
385 db_query("INSERT INTO {domain} (subdomain, sitename, scheme, valid) VALUES ('%s', '%s', '%s', %d)", $form_state['values']['domain_root'], $form_state['values']['domain_sitename'], $form_state['values']['domain_scheme'], 1);
386 // MySQL won't let us insert row 0 into an autoincrement table.
387 db_query("UPDATE {domain} SET domain_id = 0 WHERE subdomain = '%s'", $form_state['values']['domain_root']);
388 }
389 // Allow other modules to respond to changes.
390 module_invoke_all('domainupdate', 'update', domain_default(TRUE));
391 }
392
393 /**
394 * Return an array of values suitable for both create and update sql statements
395 *
396 * The last element on this array is ignored by the create sql because it has
397 * one fewer placeholder argument as it doesnt require a WHERE clause.
398 *
399 * @param $form_state
400 * From state from the submit_hook
401 * @return array
402 * Array of domain values for insert and update sql operations
403 */
404 function domain_values_from_form_state($form_state) {
405 return array(
406 'subdomain' => $form_state['values']['subdomain'],
407 'sitename' => $form_state['values']['sitename'],
408 'scheme' => $form_state['values']['scheme'],
409 'valid' => $form_state['values']['valid'],
410 'domain_id' => $form_state['values']['domain_id'],
411 );
412 }
413
414 /**
415 * FormsAPI for editing a domain record
416 *
417 * @param $form_state
418 * The current form state, passed by FormsAPI.
419 * @param $domain
420 * An array containing the record from the {domain} table.
421 * @param $arguments
422 * An array of additional hidden key/value pairs to pass to the form.
423 * Used by child modules to control behaviors.
424 * Currently supported arguments are:
425 * 'user_submitted' => TRUE
426 * Indicates that a form should not process administrative messages and paths
427 * upon form submit. Used by the Domain User module.
428 */
429 function domain_form($form_state, $domain = array(), $arguments = array()) {
430 // This action should be performed from the primary domain unless overridden.
431 if (!isset($arguments['ignore_domain_status_check'])) {
432 domain_check_primary();
433 if (empty($_POST) && !empty($domain)) {
434 domain_check_response($domain);
435 }
436 }
437 $form = array();
438 // The $arguments arrray allows other modules to pass values to change the bahavior
439 // of submit and validate functions.
440 if (!empty($arguments)) {
441 $form['domain_arguments'] = array('#type' => 'value', '#value' => $arguments);
442 }
443 $form['domain'] = array(
444 '#type' => 'fieldset',
445 '#title' => t('Domain record'),
446 '#collapsible' => TRUE
447 );
448 $form['domain_id'] = array('#type' => 'value', '#value' => $domain['domain_id']);
449 $form['domain']['subdomain'] = array(
450 '#type' => 'textfield',
451 '#title' => t('Domain'),
452 '#size' => 40,
453 '#maxlength' => 80,
454 '#required' => TRUE,
455 '#default_value' => $domain['subdomain'],
456 '#description' => t('The allowed domain, using the full <em>path.example.com</em> format. Can only contain lower-case alphanumeric characters, dashes and a colon (if using alternative ports). Leave off the http:// and the trailing slash and do not include any paths.')
457 );
458 $form['domain']['sitename'] = array(
459 '#type' => 'textfield',
460 '#title' => t('Site name'),
461 '#size' => 40,
462 '#maxlength' => 80,
463 '#required' => TRUE,
464 '#default_value' => $domain['sitename'],
465 '#description' => t('The human-readable name of this domain.')
466 );
467 $form['domain']['scheme'] = array(
468 '#type' => 'radios',
469 '#title' => t('Domain URL scheme'),
470 '#required' => TRUE,
471 '#options' => array('http' => 'http://', 'https' => 'https://'),
472 '#default_value' => !empty($domain['scheme']) ? $domain['scheme'] : 'http',
473 '#description' => t('The URL scheme for accessing this domain.')
474 );
475 $form['domain']['valid'] = array(
476 '#type' => 'radios',
477 '#title' => t('Domain status'),
478 '#required' => TRUE,
479 '#options' => array(1 => t('Active'), 0 => t('Inactive')),
480 '#default_value' => isset($domain['valid']) ? $domain['valid'] : 1,
481 '#description' => t('Must be set to "Active" for users to navigate to this domain.')
482 );
483 $form['submit'] = array('#type' => 'submit', '#value' => t('Save domain record'));
484 $form['#validate'][] = 'domain_form_validate';
485 $form['#redirect'] = array('admin/build/domain/view');
486 return $form;
487 }
488
489 /**
490 * Implement domain_form validate hook.
491 */
492 function domain_form_validate($form, &$form_state) {
493 $subdomain = $form_state['values']['subdomain'];
494 $domain_changed = (bool) strcmp($form_state['values']['subdomain'], $form['domain']['subdomain']['#default_value']);
495 if ($domain_changed) {
496 $error_list = domain_validate($subdomain);
497 foreach ($error_list as $error) {
498 form_set_error('subdomain', $error);
499 }
500 }
501 }
502
503 /**
504 * Implement domain_form submit hook.
505 */
506 function domain_form_submit($form, &$form_state) {
507 // Populate sql values used in both queries.
508 $values = domain_values_from_form_state($form_state);
509
510 // Update or create a new domain depending on presence of domain_id.
511 if ($values['domain_id']) {
512 $sql = "UPDATE {domain} SET subdomain = '%s', sitename = '%s', scheme = '%s', valid = %d WHERE domain_id = %d";
513 $action = 'update';
514 $message = t('Domain record updated.');
515 }
516 else {
517 $sql = "INSERT INTO {domain} (subdomain, sitename, scheme, valid) VALUES ('%s', '%s', '%s', %d)";
518 $action = 'create';
519 $message = t('Domain record created.');
520 }
521
522 // Update the record.
523 db_query($sql, $values);
524
525 // Let other modules act.
526 $domain = domain_lookup(NULL, $values['subdomain']);
527 module_invoke_all('domainupdate', $action, $domain, $form_state);
528
529 // Hide the message for the Domain User module.
530 if (empty($form_state['values']['domain_arguments']['user_submitted'])) {
531 drupal_set_message($message);
532 }
533
534 return $domain;
535 }
536
537 /**
538 * Implement domain_delete_form.
539 *
540 * @param $form_state
541 * The current form state, passed by FormsAPI.
542 * @param $domain
543 * An array containing the record from the {domain} table.
544 * @param $arguments
545 * An array of additional hidden key/value pairs to pass to the form.
546 * Used by child modules to control behaviors.
547 * Currently supported arguments are:
548 * 'user_submitted' => TRUE
549 * Indicates that a form should not process administrative messages and paths
550 * upon form submit. Used by the Domain User module.
551 */
552 function domain_delete_form($form_state, $domain, $arguments = array()) {
553 // This action should be performed from the primary domain.
554 domain_check_primary();
555
556 $form = array();
557 // The $arguments arrray allows other modules to pass values to change the bahavior
558 // of submit and validate functions.
559 if (!empty($arguments)) {
560 $form['domain_arguments'] = array('#type' => 'value', '#value' => $arguments);
561 }
562 $form['domain_id'] = array('#type' => 'value', '#value' => $domain['domain_id']);
563
564 return confirm_form(
565 $form,
566 t('Are you sure you wish to delete the domain record for <strong>%domain</strong>?', array('%domain' => $domain['subdomain'])),
567 'admin/build/domain/view',
568 NULL,
569 t('Delete domain record'),
570 t('Cancel')
571 );
572 }
573
574 /**
575 * Implement domain_delete_form submit hook.
576 */
577 function domain_delete_form_submit($form, &$form_state) {
578 // Run the lookup before we delete the row!
579 $domain = domain_lookup($form_state['values']['domain_id']);
580 db_query("DELETE FROM {domain} WHERE domain_id = %d", $form_state['values']['domain_id']);
581
582 // Let other modules act.
583 module_invoke_all('domainupdate', 'delete', $domain, $form_state);
584
585 // Hide the message from the Domain User module.
586 if (empty($form_state['values']['domain_arguments']['user_submitted'])) {
587 drupal_set_message(t('Domain record deleted.'));
588 $form_state['redirect'] = 'admin/build/domain/view';
589 }
590
591 // Notify that node access needs to be rebuilt.
592 node_access_needs_rebuild(TRUE);
593 }
594
595 /**
596 * Implement domain_advanced_form.
597 *
598 * @param $form_state
599 * The current form state, passed by FormsAPI.
600 */
601 function domain_advanced_form($form_state) {
602 $form = array();
603 $node_types = node_get_types('names');
604 $default = variable_get('domain_behavior', DOMAIN_INSTALL_RULE);
605 $form['domain_node'] = array(
606 '#type' => 'fieldset',
607 '#title' => t('Domain node types'),
608 '#collapsible' => TRUE
609 );
610 $form['domain_node']['intro'] = array('#value' => t('<p>Check the content types that should be published to all affiliates when new content is created.</p>'));
611 foreach ($node_types as $key => $value) {
612 $form['domain_node']['domain_node_'. $key] = array(
613 '#type' => 'checkbox',
614 '#title' => check_plain($value),
615 '#default_value' => variable_get('domain_node_'. $key, $default),
616 );
617 }
618 // Some editors will not have full node editing permissions. This allows us
619 // to give selected permissions for nodes within the editor's domain.
620 $form['domain_form'] = array(
621 '#type' => 'fieldset',
622 '#title' => t('Domain node editing'),
623 '#collapsible' => TRUE
624 );
625 $form['domain_form']['intro'] = array('#value' => t('<p>When editors view domain-access restricted nodes, which form elements should be exposed?</p>'));
626 $options = array(
627 'log' => t('Log messages'),
628 'options' => t('Publishing options'),
629 'comment_settings' => t('Comment settings'),
630 'path' => t('Path aliasing'),
631 'attachments' => t('File attachments')
632 );
633 ksort($options);
634 $form['domain_form']['domain_form_elements'] = array(
635 '#type' => 'checkboxes',
636 '#default_value' => variable_get('domain_form_elements', array('options', 'delete', 'comment_settings', 'path')),
637 '#options' => $options,
638 '#description' => t('Some elements may not be editable for all users due to permission restrictions.'),
639 );
640 return system_settings_form($form);
641 }
642
643 /**
644 * Checks to see if the webserver returns a valid response
645 * for a request to a domain.
646 *
647 * @param $domain
648 * An array containing the record from the {domain} table
649 */
650 function domain_check_response($domain) {
651 $url = domain_get_path($domain) . drupal_get_path('module', 'domain') .'/tests/200.png';
652 $response = drupal_http_request($url);
653 if ($response->code != 200) {
654 drupal_set_message(t('%server is not responding and may not be configured correctly at the server level.
655 Server code !code was returned.',
656 array('%server' => $url, '!code' => $response->code)), 'warning');
657 }
658 }
659
660 /**
661 * Allows for the batch update of certain elements.
662 *
663 * @param $action
664 * The name of the action to perform; corresponds to the keys of the $batch array
665 * returned by hook_domainbatch().
666 * @return
667 * The appropriate form, or a list of actions, or an error.
668 */
669 function domain_batch($action = NULL) {
670 // We must have the module configured correctly.
671 $domains = domain_domains();
672 if (empty($domains)) {
673 return t('There are no domains configured for this site.');
674 }
675
676 $batch = module_invoke_all('domainbatch');
677 // We must have some actions, otherwise, no point.
678 if (empty($batch)) {
679 return t('There are no batch actions configured.');
680 }
681
682 // If we are on the main page, just list the actions.
683 if (empty($action)) {
684 return domain_batch_list($batch);
685 }
686
687 // If #variable is not set, eliminate the root domain.
688 if (empty($batch[$action]['#variable'])) {
689 unset($domains[0]);
690 }
691 // If we are doing a delete action, only valid domains can be acted upon.
692 $allowed = array();
693 if (!empty($batch[$action]['#table'])) {
694 $data = db_query("SELECT domain_id FROM {%s}", $batch[$action]['#table']);
695 while ($test = db_result($data)) {
696 $allowed[] = $domains[$test];
697 }
698 if (empty($allowed)) {
699 return t('There are no valid domains on which to perform this action. The likely reason is that no records exist in the specified table.');
700 }
701 }
702 else {
703 $allowed = $domains;
704 }
705 // If we passed all the checks, generate the form.
706 return drupal_get_form('domain_batch_form', $action, $batch[$action], $allowed);
707 }
708
709 /**
710 * Lists available batch updates for the domain module.
711 *
712 * @param $batch
713 * An array of batch actions, as defined by hook_domainbatch().
714 * @return
715 * A themed table of links and descriptions for batch actions.
716 */
717 function domain_batch_list($batch) {
718 $header = array(t('Action'), t('Description'));
719 $rows = array();
720 foreach ($batch as $key => $value) {
721 if (!isset($value['#module'])) {
722 $value['#module'] = t('Other');
723 }
724 }
725 uasort($batch, 'domain_batch_sort');
726 $group = '';
727 foreach ($batch as $key => $value) {
728 if ($group != $value['#module']) {
729 $rows[] = array(array('data' => '<strong>'. t('%module options', array('%module' => $value['#module'])) .'</strong>', 'colspan' => 2));
730 $group = $value['#module'];
731 }
732 $rows[] = array(l($value['#form']['#title'], 'admin/build/domain/batch/'. $key), $value['#meta_description']);
733 }
734 $output = '<p>'. t('Batch updates allow you to edit values for multiple domains at one time. These functions are helpful when moving your sites from staging to production, or any time you need to make mass changes quickly. The following batch update actions may be performed.') .'</p>';
735 $output .= '<p><em>'. t('Note that you will only be shown domains on which each action may be performed. If the module is not yet configured, some actions may be empty.') .'</em></p>';
736 return $output . theme('table', $header, $rows);
737 }
738
739 /**
740 * Sorting function for domain batch options.
741 */
742 function domain_batch_sort($a, $b) {
743 if ($a['#module'] != $b['#module']) {
744 return strcmp($a['#module'], $b['#module']);
745 }
746 if ($a['#weight'] == $b['#weight']) {
747 return strcmp($a['#form']['#title'], $b['#form']['#title']);
748 }
749 else {
750 return ($a['#weight'] < $b['#weight']) ? -1 : 1;
751 }
752 }
753
754 /**
755 * Generate the form data for a batch update.
756 *
757 * @param $form_state
758 * The current form state, passed by FormsAPI.
759 * @param $action
760 * The name of the action to perform; corresponds to the keys of the $batch array
761 * returned by hook_domainbatch().
762 * @param $batch
763 * The batch data for this $action, as defined by hook_domainbatch().
764 * @param $domains
765 * The current settings for each domain.
766 * @return
767 * A themed table of links and descriptions for batch actions.
768 */
769 function domain_batch_form($form_state, $action, $batch, $domains) {
770 $default = array();
771 drupal_set_title($batch['#form']['#title']);
772
773 $form = array();
774 $form['message'] = array(
775 '#type' => 'markup',
776 '#value' => theme('domain_batch_title', $batch)
777 );
778
779 // For some values, allow every record to be updated.
780 if (!empty($batch['#update_all'])) {
781 $form['domain_batch_all'] = array(
782 '#type' => 'fieldset',
783 '#title' => t('Update value for all domains'),
784 '#weight' => -10,
785 '#collapsible' => TRUE,
786 '#collapsed' => TRUE,
787 '#description' => t('By entering a value below and checking the <strong>Apply to all domains</strong> option, you can set the desired value for all domains.'),
788 );
789 $form['domain_batch_all']['batch_all_setting'] = $batch['#form'];
790 $form['domain_batch_all']['batch_all_setting']['#default_value'] = $batch['#system_default'];
791 $form['domain_batch_all']['batch_override'] = array(
792 '#type' => 'checkbox',
793 '#title' => t('Apply to all domains'),
794 );
795 $form['domain_batch_all']['submit'] = array('#type' => 'submit', '#value' => t('Update all domain settings'));
796 }
797 $form['domain_batch'] = array(
798 '#tree' => TRUE,
799 '#title' => $batch['#form']['#title'],
800 '#description' => $batch['#meta_description']
801 );
802
803 foreach ($domains as $domain) {
804 // Set the current value according to the stored values.
805 if (isset($domain[$action])) {
806 $default[$domain['domain_id']] = $domain[$action];
807 }
808 if ($batch['#domain_action'] == 'domain_conf') {
809 // Set the default value to the main settings.
810 // In rare cases, variable_get() returns unusable data, so we override it.
811 if (empty($batch['#override_default'])) {
812 $default[$domain['domain_id']] = variable_get($action, $batch['#system_default']);
813 }
814 else {
815 $default[$domain['domain_id']] = $batch['#system_default'];
816 }
817 // Check for domain-specific settings.
818 $result = db_result(db_query("SELECT settings FROM {domain_conf} WHERE domain_id = %d", $domain['domain_id']));
819 $settings = unserialize($result);
820 if (isset($settings[$action])) {
821 $default[$domain['domain_id']] = $settings[$action];
822 }
823 }
824 else if ($batch['#domain_action'] == 'custom' && isset($batch['#lookup'])) {
825 $default[$domain['domain_id']] = $batch['#system_default'];
826 $func = $batch['#lookup'];
827 $setting = $func($domain);
828 if ($setting != -1) {
829 $default[$domain['domain_id']] = $setting;
830 }
831 }
832 // Take the settings from the $batch array.
833 $form['domain_batch'][$domain['domain_id']] = $batch['#form'];
834 // Add the domain-specific elements.
835 $form['domain_batch'][$domain['domain_id']]['#sitename'] = $domain['sitename'];
836 if (isset($default[$domain['domain_id']])) {
837 $form['domain_batch'][$domain['domain_id']]['#default_value'] = $default[$domain['domain_id']];
838 }
839 }
840 $api_keys = array('variable', 'table', 'data_type');
841 // These are optional elements, only passed if present.
842 foreach ($api_keys as $key) {
843 if (isset($batch['#'. $key])) {
844 $form[$key] = array('#type' => 'value', '#value' => $batch['#'. $key]);
845 }
846 }
847 // Custom submit and validate handlers.
848 foreach (array('submit', 'validate') as $key) {
849 if (isset($batch['#'. $key])) {
850 $form[$key .'_handler'] = array('#type' => 'value', '#value' => $batch['#'. $key]);
851 }
852 }
853 $form['handler'] = array('#type' => 'value', '#value' => $batch['#domain_action']);
854 $form['batch_item'] = array('#type' => 'value', '#value' => $action);
855 $form['submit'] = array('#type' => 'submit', '#value' => t('Update domain settings'));
856
857 return $form;
858 }
859
860 /**
861 * FormsAPI
862 */
863 function theme_domain_admin_users_form($form) {
864 // Overview table:
865 $header = array(
866 theme('table_select_header_cell'),
867 array('data' => t('Username'), 'field' => 'u.name'),
868 array('data' => t('Status'), 'field' => 'u.status'),
869 t('Roles'),
870 t('Domains'),
871 array('data' => t('Member for'), 'field' => 'u.created', 'sort' => 'desc'),
872 array('data' => t('Last access'), 'field' => 'u.access'),
873 t('Operations')
874 );
875
876 $output = drupal_render($form['options']);
877 $output .= drupal_render($form['domain']);
878 if (isset($form['name']) && is_array($form['name'])) {
879 foreach (element_children($form['name']) as $key) {
880 $rows[] = array(
881 drupal_render($form['accounts'][$key]),
882 drupal_render($form['name'][$key]),
883 drupal_render($form['status'][$key]),
884 drupal_render($form['roles'][$key]),
885 drupal_render($form['user_domains'][$key]),
886 drupal_render($form['member_for'][$key]),
887 drupal_render($form['last_access'][$key]),
888 drupal_render($form['operations'][$key]),
889 );
890 }
891 }
892 else {
893 $rows[] = array(array('data' => t('No users available.'), 'colspan' => '7'));
894 }
895
896 $output .= theme('table', $header, $rows);
897 if ($form['pager']['#value']) {
898 $output .= drupal_render($form['pager']);
899 }
900
901 $output .= drupal_render($form);
902
903 return $output;}
904 /**
905 * FormsAPI
906 */
907 function theme_domain_batch_form($form) {
908 $output = '';
909 $output = drupal_render($form['message']);
910 if (isset($form['domain_batch_all'])) {
911 $output .= drupal_render($form['domain_batch_all']);
912 }
913 $header = array(t('Id'), t('Domain'), t('Setting'));
914 $rows = array();
915 foreach (element_children($form['domain_batch']) as $key) {
916 $temp = $form['domain_batch'][$key]['#title'];
917 unset($form['domain_batch'][$key]['#title']);
918 $row = array($key, $form['domain_batch'][$key]['#sitename'], drupal_render($form['domain_batch'][$key]));
919 $rows[] = $row;
920 $form['domain_batch'][$key]['#title'] = $temp;
921 }
922 $output .= drupal_render($form['domain_batch']);
923 $output .= theme('table', $header, $rows);
924 $output .= drupal_render($form);
925 return $output;
926 }
927
928 /**
929 * Theme function for displaying batch editing.
930 *
931 * @param $batch
932 * the batch function to be performed.
933 */
934 function theme_domain_batch_title($batch) {
935 $output = '';
936 $output = '<p>'. $batch['#meta_description'] .'</p>';
937 if (!empty($batch['#required'])) {
938 $output .= '<p><em>'. t('All values are required.') .'</em></p>';
939 }
940 return $output;
941 }
942
943 /**
944 * FormsAPI for validating batch form actions.
945 */
946 function domain_batch_form_validate($form, &$form_state) {
947 // Define the validation function and call it.
948 if (isset($form_state['values']['validate_handler']) && function_exists($form_state['values']['validate_handler'])) {
949 $form_state['values']['validate_handler']($form_state['values']);
950 }
951 }
952
953 /**
954 * FormsAPI for saving batch form actions.
955 */
956 function domain_batch_form_submit($form, &$form_state) {
957 if (!empty($form_state['values']['batch_override'])) {
958 foreach ($form_state['values']['domain_batch'] AS $domain_id => $value) {
959 $options_all[$domain_id] = $form_state['values']['batch_all_setting'];
960 }
961 $form_state['values']['domain_batch'] = $options_all;
962 }
963
964 $item = $form_state['values']['batch_item'];
965 switch ($form_state['values']['handler']) {
966 case 'domain':
967 foreach ($form_state['values']['domain_batch'] as $key => $value) {
968 // Note that $type in the query below is a sanitzed value passed from domain_batch_data_type().
969 db_query("UPDATE {domain} SET %s = ". domain_batch_data_type($form_state['values']['data_type']) ." WHERE domain_id = %d", $item, $value, $key);
970 // Update the variable for the root domain
971 if (!empty($form_state['values']['variable']) && $key == 0) {
972 variable_set($form_state['values']['variable'], $value);
973 }
974 }
975 break;
976 case 'domain_conf':
977 foreach ($form_state['values']['domain_batch'] as $key => $value) {
978 $settings = array();
979 if ($key > 0 || empty($form_state['values']['variable'])) {
980 $data = db_fetch_array(db_query("SELECT settings FROM {domain_conf} WHERE domain_id = %d", $key));
981 if (isset($data['settings'])) {
982 $settings = unserialize($data['settings']);
983 $settings[$item] = $value;
984 db_query("UPDATE {domain_conf} SET settings = %b WHERE domain_id = %d", serialize($settings), $key);
985 }
986 else {
987 $settings[$item] = $value;
988 db_query("INSERT INTO {domain_conf} (domain_id, settings) VALUES (%d, %b)", $key, serialize($settings));
989 }
990 }
991 else if (!empty($form_state['values']['variable'])) {
992 variable_set($form_state['values']['variable'], $value);
993 }
994 }
995 break;
996 case 'domain_delete':
997 $table = $form_state['values']['table'];
998 foreach ($form_state['values']['domain_batch'] as $key => $value) {
999 if ($value == 1) {
1000 if (is_array($table)) {
1001 foreach ($table as $current) {
1002 db_query("DELETE FROM {%s} WHERE domain_id = %d", $current, $key);
1003 }
1004 }
1005 else {
1006 db_query("DELETE FROM {%s} WHERE domain_id = %d", $table, $key);
1007 }
1008 }
1009 }
1010 break;
1011 case 'custom':
1012 if (isset($form_state['values']['submit_handler']) && function_exists($form_state['values']['submit_handler'])) {
1013 $func = $form_state['values']['submit_handler'];
1014 $func($form_state['values']);
1015 }
1016 break;
1017 }
1018 drupal_set_message(t('Settings have been updated successfully.'));
1019 }
1020
1021 /**
1022 * Converts a data type indicator into a sql-safe string.
1023 *
1024 * @param $type
1025 * The data type defined in hook_domainbatch().
1026 * @return
1027 * A sql-safe string ('%s', %d, %f, %b) for use with db_query().
1028 */
1029 function domain_batch_data_type($type) {
1030 $return = "'%s'";
1031 switch ($type) {
1032 case 'string':
1033 break;
1034 case 'integer':
1035 $return = "%d";
1036 break;
1037 case 'float':
1038 $return = "%f";
1039 break;
1040 case 'binary':
1041 $return = "%b";
1042 break;
1043 }
1044 return $return;
1045 }
1046
1047 /**
1048 * FormsAPI to set default domain membership for each role.
1049 *
1050 * These settigns are added to the $user object.
1051 *
1052 * @see domain_get_user_domains()
1053 */
1054 function domain_roles_form($form_state) {
1055 $form = array();
1056 $form['domain_add_roles'] = array(
1057 '#type' => 'radios',
1058 '#options' => array(
1059 0 => t('Add default roles dynamically'),
1060 1 => t('Add default roles to the user account'),
1061 ),
1062 '#title' => t('Role settings behavior'),
1063 '#description' => t('Adding role settings to the user account will permanently save them for each user on account updates. Otherwise, role-based settings can be added or removed at will.'),
1064 '#default_value' => variable_get('domain_add_roles', 0),
1065 );
1066
1067 $roles = user_roles();
1068 $defaults = variable_get('domain_roles', array());
1069 $roles[0] = t('new user');
1070 ksort($roles);