You are here

domain_content.module in Domain Access 6.2

Editorial overview module.

Provides batch node editing for users with 'edit domain nodes' permission but without the 'administer nodes' permission.

File

domain_content/domain_content.module
View source
<?php

/**
 * @defgroup domain_content Domain Content : administer nodes for affiliate sites
 *
 * Allows for the batch editing of select node settings.  Refactors the default content
 * editng screen to show content only from selected domains.
 */

/**
 * @file
 * Editorial overview module.
 *
 * Provides batch node editing for users with 'edit domain nodes' permission
 * but without the 'administer nodes' permission.
 *
 * @ingroup domain_content
 */

/**
 * Implement hook_menu()
 */
function domain_content_menu() {
  $items = array();
  $items['admin/domain/content'] = array(
    'title' => 'Affiliated content',
    'page callback' => 'domain_content_list',
    'access callback' => 'domain_content_menu_check',
    'file' => 'domain_content.admin.inc',
  );
  $items['admin/domain/content/all'] = array(
    'title' => 'Content assigned to all affiliates',
    'page callback' => 'domain_content_view',
    'page arguments' => array(
      NULL,
      TRUE,
    ),
    'access callback' => 'domain_content_menu_check',
    'file' => 'domain_content.admin.inc',
    'description' => 'View content assigned to all affiliate sites.',
    'weight' => -10,
  );

  // Generate the list of active domains as menu items
  $domains = domain_domains();
  if (count($domains) <= variable_get('domain_list_size', DOMAIN_LIST_SIZE)) {
    foreach ($domains as $domain) {
      $items['admin/domain/content/' . $domain['domain_id']] = array(
        'title' => filter_xss_admin($domain['sitename']) . ' content',
        'page callback' => 'domain_content_view',
        'page arguments' => array(
          $domain['domain_id'],
          FALSE,
        ),
        'access callback' => 'domain_content_check',
        'access arguments' => array(
          $domain['domain_id'],
        ),
        'file' => 'domain_content.admin.inc',
        'description' => 'View content assigned to ' . filter_xss_admin($domain['subdomain']),
        'weight' => $domain['domain_id'],
      );
    }
  }
  else {
    $items['admin/domain/content/list'] = array(
      'title' => 'Affiliate site list',
      'page callback' => 'domain_content_list',
      'access callback' => 'domain_content_menu_check',
      'file' => 'domain_content.admin.inc',
      'description' => 'View your list of affiliates',
      'weight' => -10,
    );
    $items['admin/domain/content/%'] = array(
      'title' => 'Affiliate site list',
      'page callback' => 'domain_content_view',
      'page arguments' => array(
        3,
        TRUE,
      ),
      'access callback' => 'domain_content_check',
      'access arguments' => array(
        3,
      ),
      'file' => 'domain_content.admin.inc',
      'description' => 'Content list for a domain',
      'weight' => -10,
    );
  }
  return $items;
}

/**
 * Implement hook_perm().
 */
function domain_content_perm() {
  return array(
    'review content for all domains',
  );
}

/**
 * Implement hook_theme().
 */
function domain_content_theme() {
  $themes = array(
    'domain_content_admin_nodes' => array(
      'arguments' => array(
        'form' => array(),
      ),
      'file' => 'domain_content.admin.inc',
    ),
  );
  return $themes;
}

/**
 * Access control for menu items.  There may be another way to do this in Drupal 6.
 *
 * @param $check
 *  The access check value passed from hook_menu().
 */
function domain_content_menu_check() {
  if (user_access('administer nodes')) {
    return TRUE;
  }
  if (user_access('edit domain nodes') || user_access('review content for all domains')) {
    return TRUE;
  }
  return FALSE;
}

/**
 * Access checking routine for menu and node editing checks.
 *
 * @param $domain_id
 *   An id representing the currently active domain record.
 *
 * @return
 *  Boolean true or false.
 */
function domain_content_check($domain_id) {
  global $user;

  // If the user can administer nodes, just return TRUE.
  if (user_access('administer nodes') || user_access('review content for all domains')) {
    return TRUE;
  }

  // Otherwise, the user must be able to edit domain nodes.
  $rule = user_access('edit domain nodes');
  if (!$rule) {
    return FALSE;
  }
  $domains = domain_get_user_domains($user);
  $key = $domain_id == 0 ? -1 : $domain_id;

  // Can this user see the requested site?
  if (!empty($domains[$key])) {
    return TRUE;
  }
  return FALSE;
}

/**
 * Implement hook_domainlinks()
 */
function domain_content_domainlinks($domain) {
  $links[] = array(
    'title' => t('content'),
    'path' => 'admin/domain/content/' . $domain['domain_id'],
  );
  return $links;
}

/**
 * Implement hook_node_operations()
 */
function domain_content_node_operations() {

  // Only privileged users can perform this operation.
  // Do not show this on the default node editing form.
  if (user_access('set domain access')) {
    $operations = array(
      'domain' => array(
        'label' => t('Change affiliate publishing options'),
        'callback' => 'domain_content_node_operations_process',
        'configurable' => TRUE,
      ),
    );
    return $operations;
  }
}

/**
 * Callback for domain_content_node_operations().
 *
 * This callback is required, but we actually do our action inside
 * of domain_content_process_nodes().
 */
function domain_content_node_operations_process($nodes) {
}

/**
 * The multiple delete form issues a redirect in its submit function.
 * So we must supply the proper path as a form element.
 *
 * @link http://drupal.org/node/336218
 */
function domain_content_form_node_multiple_delete_confirm_alter(&$form, &$form_state) {
  $form['#redirect'] = $_GET['q'];
}

/**
 * Allow domain assignment to be made from the default content form.
 */
function domain_content_form_node_admin_content_alter(&$form, &$form_state) {

  // Privileged users can make global changes to Domain Access permissions.
  if (!user_access('set domain access')) {
    return;
  }

  // Do nothing on the delete screen.
  if (isset($form['operation']['#value']) && $form['operation']['#value'] == 'delete') {
    return;
  }

  // Add our form elements.
  domain_content_add_form_widget($form);
  $form['domain']['#weight'] = -1;
  $form['admin']['options']['submit']['#submit'][] = 'domain_content_process_nodes';
}

/**
 * Abstraction function for selecting domains for batch operations.
 */
function domain_content_add_form_widget(&$form) {
  global $_domain;

  // We have different settings for the two form contexts.
  // A blank form comes from core.
  $prefix = '<div class="description">' . t('If you select <em>Change affiliate publishing options</em>, you should confirm the <em>Affiliate publishing options</em> settings below.') . '</div>';
  $collapsed = TRUE;
  if (empty($form)) {
    $prefix = '';
    $collapsed = FALSE;
  }
  $options = array();
  $format = domain_select_format();
  foreach (domain_domains() as $data) {

    // Cannot pass zero in checkboxes.
    $key = $data['domain_id'] == 0 ? -1 : $data['domain_id'];

    // The domain must be valid.
    if ($data['valid'] || user_access('access inactive domains')) {

      // Filter checkboxes but not select lists.
      $options[$key] = empty($format) ? check_plain($data['sitename']) : $data['sitename'];
    }
  }
  $form['domain'] = array(
    '#type' => 'fieldset',
    '#title' => t('Affiliate publishing options'),
    '#collapsible' => TRUE,
    '#collapsed' => $collapsed,
    '#prefix' => $prefix,
  );
  $form['domain']['behavior'] = array(
    '#type' => 'radios',
    '#title' => t('Update behavior'),
    '#options' => array(
      0 => t('Replace old values with new settings'),
      1 => t('Add new settings to existing values'),
      2 => t('Remove selected domains from existing values'),
    ),
    '#description' => t('Defines how new grants will be applied to the updated nodes.'),
    '#default_value' => 0,
  );
  $form['domain']['domain_site'] = array(
    '#type' => 'checkbox',
    '#prefix' => t('<p><b>Publishing options:</b>'),
    '#suffix' => '</p>',
    '#title' => t('Send to all affiliates'),
    '#required' => FALSE,
    '#description' => t('Select if this content can be shown to all affiliates.  This setting will override the options below.'),
    '#default_value' => variable_get('domain_behavior', DOMAIN_INSTALL_RULE),
  );
  $form['domain']['domains'] = array(
    '#type' => empty($format) ? 'checkboxes' : 'select',
    '#title' => t('Publish to'),
    '#options' => $options,
    '#required' => FALSE,
    '#description' => t('Select which affiliates can access this content.'),
    '#default_value' => array(
      $_domain['domain_id'] == 0 ? -1 : $_domain['domain_id'],
    ),
  );
  if ($format) {
    $form['domain']['domains']['#multiple'] = TRUE;
    $form['domain']['domains']['#size'] = count($options) > 10 ? 10 : count($options);
  }
}

/**
 * Process the form submission.
 *
 * This callback works for the normal operations callback.
 */
function domain_content_process_nodes($form, &$form_state) {
  if ($form_state['values']['operation'] != 'domain') {
    return;
  }
  $options = array();
  $options['domain_site'] = FALSE;
  if ($form_state['values']['domain_site']) {
    $options['domain_site'] = TRUE;
  }
  $options['domain_id'] = array_filter($form_state['values']['domains']);
  $nids = array_filter($form_state['values']['nodes']);
  $options['behavior'] = $form_state['values']['behavior'];
  domain_content_update_nodes($nids, $options);
}

/**
 * Abstraction function that lets us update access rules.
 */
function domain_content_update_nodes($nids, $options) {
  static $load_nodes;

  // Do other modules have a stake in the node grants set by Domain Access?
  if (!isset($load_nodes)) {
    $load_nodes = (bool) count(module_implements('domainrecords'));
  }

  // If our operation is run, then we have to manually change the
  // {node_access} table.  The rest of the process will clear the cache,
  // so this should be a safe operation.
  $domain_site = $options['domain_site'];
  $domains = $options['domain_id'];
  $behavior = $options['behavior'];
  foreach ($nids as $nid) {

    // If other modules need to respond, we have to load the full node.
    if ($load_nodes) {
      $node = node_load($nid);
    }
    else {
      $node = new stdClass();
      $node->nid = $nid;
    }

    // Make sure the node is valid.
    if ($node->nid > 0) {

      // If modifying values, do so here.
      if (!empty($behavior)) {
        $current = domain_get_node_domains($node->nid);

        // Add values to the current set.
        if ($behavior == 1) {
          if (!empty($current['domain_site'])) {
            $domain_site = TRUE;
          }
          $domains += $current['domain_id'];
        }
        else {
          foreach ($domains as $domain_id) {
            if (isset($current['domain_id'][$domain_id])) {
              unset($current['domain_id'][$domain_id]);
            }
          }
          $domains = $current['domain_id'];

          // If all affiliates is selected, remove it.
          if ($domain_site) {
            $domain_site = FALSE;
          }
        }
      }

      // Use our new options, as set above.
      $node->domain_site = $domain_site;
      $node->domains = $domains;

      // Run our storage hook. This handles {domain_access} and returns
      // the records we need for {node_access}.
      $grants = domain_node_access_records($node);

      // Get all the grants returned.
      $realms = array(
        'domain_site',
        'domain_id',
      );
      foreach ($grants as $grant) {
        if (!in_array($grant['realm'], $realms)) {
          $realms[] = $grant['realm'];
        }
      }

      // Delete our grants and rebuild.
      foreach ($realms as $realm) {
        node_access_write_grants($node, $grants, $realm);
      }
    }
  }

  // Clear the cache.
  cache_clear_all();
}

Related topics

Functions

Namesort descending Description
domain_content_add_form_widget Abstraction function for selecting domains for batch operations.
domain_content_check Access checking routine for menu and node editing checks.
domain_content_domainlinks Implement hook_domainlinks()
domain_content_form_node_admin_content_alter Allow domain assignment to be made from the default content form.
domain_content_form_node_multiple_delete_confirm_alter The multiple delete form issues a redirect in its submit function. So we must supply the proper path as a form element.
domain_content_menu Implement hook_menu()
domain_content_menu_check Access control for menu items. There may be another way to do this in Drupal 6.
domain_content_node_operations Implement hook_node_operations()
domain_content_node_operations_process Callback for domain_content_node_operations().
domain_content_perm Implement hook_perm().
domain_content_process_nodes Process the form submission.
domain_content_theme Implement hook_theme().
domain_content_update_nodes Abstraction function that lets us update access rules.