nid)) { $default_source = db_query("SELECT domain_id FROM {domain_source} WHERE nid = :nid", array(':nid' => $form['#node']->nid))->fetchField(); } if (!isset($default_source)) { $default_source = $_domain['domain_id']; } // Prevent invalid domains from being used. $lookup = domain_lookup($default_source); if ($default_source != DOMAIN_SOURCE_USE_ACTIVE && empty($lookup['valid'])) { $default_source = NULL; } $account = $user; domain_get_user_domains($account); // Only uses with 'set domain access' can assign content to all affilaites, so they get a new option. // This option allows domain source to be ignored on a per-node basis. $options = array(); $domains = domain_domains(); $show = FALSE; if (user_access('set domain access')) { $show = TRUE; $options[DOMAIN_SOURCE_USE_ACTIVE] = t('Use active domain'); foreach ($domains as $domain) { if ($domain['valid'] || user_access('access inactive domains')) { $options[$domain['domain_id']] = $domain['sitename']; } } } // In the case of users with limited permissions, option 3 is the "show options" value. elseif (user_access('publish to any assigned domain') && !empty($account->domain_user)) { $show = FALSE; $options[DOMAIN_SOURCE_USE_ACTIVE] = t('Use active domain'); // Get the user's allowed domains. foreach ($domains as $domain) { $key = $domain['domain_id']; if ($domain['domain_id'] == 0) { $key = -1; } if (!empty($user->domain_user[$key]) && ($domain['valid'] || user_access('access inactive domains'))) { $options[$key] = $domain['sitename']; } } // Is this node assigned to a source that the user can control? if (isset($form['#node']->domain_source)) { // Transform the 0 to -1 for lookups. $source = ($form['#node']->domain_source == 0) ? -1 : $form['#node']->domain_source; } else { $source = NULL; $show = TRUE; } if (!is_null($source) && isset($account->domain_user[$source])) { if ($account->domain_user[$source] == $source) { $show = TRUE; } else { $name = ($source != -5) ? $domains[$source]['sitename'] : t('the active domain'); $form['domain']['domain_source_notes'] = array( '#type' => 'item', '#title' => t('Source domain'), '#markup' => t('This content is assigned to %domain and cannot be reassigned.', array('%domain' => $name)), ); } } } // Determine how to show the form element. if ($show) { $form['domain']['domain_source'] = array( '#type' => 'select', '#title' => t('Source domain'), '#options' => $options, '#default_value' => $default_source, '#description' => t('This affiliate will be used to write links to this content from other affiliates, as needed.') ); } // Non-privileged users just have the current domain assigned. else { $form['domain']['domain_source'] = array( '#type' => 'value', '#value' => $default_source, ); } } /** * Integrate with Domain Content. */ function domain_source_form_domain_content_admin_alter(&$form, &$form_state) { $_domain = domain_get_domain(); if (!user_access('set domain access')) { return; } $options = array(); $domains = domain_domains(); // Options. $options[DOMAIN_SOURCE_IGNORE] = t('Do not change'); $options[DOMAIN_SOURCE_USE_ACTIVE] = t('Use active domain'); foreach ($domains as $domain) { $options[$domain['domain_id']] = $domain['sitename']; } $form['domain']['domain_source'] = array( '#type' => 'select', '#title' => t('Source domain'), '#options' => $options, '#default_value' => $_domain['domain_id'], '#description' => t('The canonical domain for the selected content. This element replaces existing settings for all selections.') ); $form['admin']['options']['submit']['#validate'][] = 'domain_source_validate'; $form['admin']['options']['submit']['#submit'][] = 'domain_source_update_nodes'; } /** * Form integration with Administer nodes. */ function domain_source_form_node_admin_content_alter(&$form, &$form_state) { // Do nothing on the delete screen. if (isset($form['operation']['#value']) && $form['operation']['#value'] == 'delete') { return; } domain_source_form_domain_content_admin_alter($form, $form_state); } /** * Implements hook_node_validate(). */ function domain_source_node_validate($node, $form) { // If not set, we ignore. if (!isset($node->domain_source)) { return; } // Cast the key from zero to -1 to match the data coming from the input. ($node->domain_source == 0) ? $key = -1 : $key = $node->domain_source; // Check the domain and domains_raw variables to set up the allowed source list. $allowed = array(); if (!empty($node->domains)) { $allowed = $node->domains; } if (!empty($node->domains_raw)) { $allowed = array_merge($allowed, $node->domains_raw); } if ($node->domain_site && $key == -1) { // This case is acceptable, so we let it pass. // I find this code easier to read than a compound IF statement. } // Here we account for both the 'domains_raw' and 'domains' options. elseif ($node->domain_source != DOMAIN_SOURCE_USE_ACTIVE && !in_array($key, $allowed)) { form_set_error('domain_source', t('The source affiliate must be selected as a publishing option.')); } } /** * Implements hook_node_load(). */ function domain_source_node_load($nodes, $types) { $source = domain_source_lookup($nodes); foreach ($nodes as $node) { // Cannot load if the node has not been created yet. if (!isset($node->nid)) { continue; } $nodes[$node->nid]->domain_source = $source[$node->nid]['domain_id']; } } /** * Implements hook_node_insert() */ function domain_source_node_insert($node) { // If not set, we ignore. if (!isset($node->domain_source) || is_null($node->domain_source)) { return; } domain_source_node_delete($node); db_insert('domain_source') ->fields(array( 'nid' => $node->nid, 'domain_id' => $node->domain_source, )) ->execute(); // Clear the cache. domain_source_lookup($node->nid, array(), NULL, TRUE); } /** * Implements hook_node_update() */ function domain_source_node_update($node) { domain_source_node_insert($node); } /** * Implements hook_node_delete() */ function domain_source_node_delete($node) { db_delete('domain_source') ->condition('nid', $node->nid) ->execute(); } /** * Implements hook_node_view() * * Display debugging information for a node. */ function domain_source_node_view($node, $view_mode) { if (empty($node->nid) || !in_array($view_mode, array('full', 'teaser'))) { return; } if (variable_get('domain_debug', 0) && user_access('set domain access') && isset($node->domain_source)) { $source = domain_get_node_match($node->nid); $extra = ' '; $use_active = db_query("SELECT domain_id FROM {domain_source} WHERE nid = :nid", array(':nid' => $node->nid))->fetchField(); if ($use_active === FALSE) { $extra .= t('(determined automatically)'); } elseif ($use_active == DOMAIN_SOURCE_USE_ACTIVE) { $extra .= t('(using active domain)'); } if (!isset($node->content['domain']['#markup'])) { $node->content['domain']['#markup'] = ''; } $node->content['domain']['#markup'] .= '
' . t('Source domain: %source', array('%source' => $source['sitename'])) . $extra . '
'; } } /** * Get the source domains for multiple matches, mimicking node_load(). * * @param $nodes * An array of nodes, keyed by node id, or a single node id. * @param $domains * An optional array of domain ids; can only be used for a single node. * @param $domain_site * Optional flag indicating that the node is assigned to all domains. * @param $reset * Force a reset of the static data lookup. * @return * An associative array of data, keyed by node id, or a single array. * The data array is the active source domain to use, as returned by domain_lookup(). */ function domain_source_lookup($nodes, $domains = array(), $domain_site = FALSE, $reset = FALSE) { global $_domain; static $lookups; // Reset? if ($reset) { $lookups = array(); } // Ensure we format the lookup correctly. if (!is_array($nodes)) { $nid = $nodes; $node_ids = array($nid); $array = FALSE; } else { $node_ids = array_keys($nodes); $array = TRUE; } // Static cache. if (!$reset && isset($nid) && isset($lookups[$nid])) { return $lookups[$nid]; } $result = db_query("SELECT nid, domain_id FROM {domain_source} WHERE nid IN (:nid)", array(':nid' => $node_ids))->fetchAll(); foreach ($result as $data) { $source = $data->domain_id; // DOMAIN_SOURCE_USE_ACTIVE is the status for 'Use active domain.' if ($source == DOMAIN_SOURCE_USE_ACTIVE) { $source = $_domain['domain_id']; } // When called from url_rewrite_outbound(), we have no data. if (empty($domains)) { $lookup = domain_get_node_domains($data->nid); $domain_site = $lookup['domain_site']; $domains = $lookup['domain_id']; } // domain_get_node_domains() returns the default (0) domain as -1, so we // must transform it here before running a check. $source = ($source == 0) ? -1 : $source; // If no valid source is found, take the first match from the $domains array. if (empty($domain_site) && !empty($domains) && !in_array($source, $domains)) { $source = current($domains); } // Convert the source id from -1 to 0 and run the lookup. $domain_id = ($source == -1) ? 0 : $source; // Lookup the source domain. $lookups[$data->nid] = domain_lookup($domain_id); } // Make sure we found something for every requested node. $no_records = $node_ids; if (!empty($lookups)) { $no_records = array_diff($node_ids, array_keys($lookups)); } foreach ($no_records as $nid) { $default_source = variable_get('domain_default_source', 0); // Global setting for 'do not change domain.' if ($default_source == -1) { $lookups[$nid] = $_domain; } else { $lookups[$nid] = domain_lookup($default_source); } } if ($array) { return $lookups; } return $lookups[$nid]; } /** * Implements hook_domain_source_alter(). * * @param &$source * The domain array from domain_get_node_match(), passed by reference. * @param $nid * The node id. * @return * No return value; modify $source by reference. */ function domain_source_domain_source_alter(&$source, $nid) { $source = domain_source_lookup($nid); } /** * FormAPI function that lets us update access rules. */ function domain_source_update_nodes($form, &$form_state) { // If our operation is flagged, 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. if ($form_state['values']['operation'] == 'domain') { $source = $form_state['values']['domain_source']; foreach ($form_state['values']['nodes'] as $key => $value) { if ($key == $value) { db_delete('domain_source') ->condition('nid', $key) ->execute(); db_insert('domain_source') ->fields(array( 'nid' => $key, 'domain_id' => $source, )) ->execute(); } } } } /** * Form validation step */ function domain_source_validate($form, &$form_state) { if ($form_state['values']['operation'] == 'domain') { ($form_state['values']['domain_source'] == 0) ? $key = -1 : $key = $form_state['values']['domain_source']; if ($form_state['values']['domain_site'] && $key == -1 || $key == DOMAIN_SOURCE_USE_ACTIVE) { // These cases are acceptable, so we let them pass. // I find this code easier to read than a compound negative IF statement. } elseif ($key == DOMAIN_SOURCE_IGNORE) { // In this case, we need to check all the selected nodes, which is resource intensive. $nodes = array_filter($form_state['values']['nodes']); foreach ($nodes as $nid) { $source = domain_source_lookup($nid, array(), $form_state['values']['domain_site'], TRUE); $key = ($source['domain_id'] == 0) ? -1 : $source['domain_id']; // Test for the first two behaviors, which add domains to the node. $behavior = $form_state['values']['behavior']; if ($behavior < 2) { if (empty($form_state['values']['domains'][$key])) { $node = node_load($nid); form_set_error('domain_source', t('The source affiliate must be selected as a publishing option. %title is assigned to %domain.', array('%title' => $node->title, '%domain' => $source['sitename']))); } } // Do not allow removal of the source domain when removing domains from the node. elseif (!empty($form_state['values']['domains'][$key])) { $node = node_load($nid); form_set_error('domain_source', t('The source affiliate must be selected as a publishing option. %title is assigned to %domain.', array('%title' => $node->title, '%domain' => $source['sitename']))); } } } // The source domain must have been selected. elseif (empty($form_state['values']['domains'][$key])) { form_set_error('domain_source', t('The source affiliate must be selected as a publishing option.')); } } } /** * Implements hook_domainupdate() * * When deleting domain records, we remove all traces from the {domain_source} table. */ function domain_source_domainupdate($op, $domain, $form_state = array()) { if ($op == 'delete' && $domain['domain_id'] > 0) { db_delete('domain_source') ->condition('domain_id', $domain['domain_id']) ->execute(); } } /** * Implements hook_views_api(). */ function domain_source_views_api() { if (module_exists('domain_views')) { return array('api' => 2.0); } }