array('info' => t('Crossref: Create referrer')), 'xref' => array('info' => t('Crossref: Referrers')), ); case 'view': switch ($delta) { case 'create': $node = menu_get_object(); if ($node && !empty($node->nid)) { $xref_links = xref_links($node->type, $node->nid); if (!empty($xref_links)) { return array('subject' => t('Reference this'), 'content' => theme('links', $xref_links)); } } break; case 'xref': $node = menu_get_object(); if ($node) { $xref_view = xref_view($node->type, $node->nid); if (!empty($xref_view)) { return array('content' => $xref_view); } } break; } break; } } /** * Implemenation of hook_nodeapi(). */ function xref_nodeapi(&$node, $op, $teaser = NULL, $page = NULL) { switch ($op) { case 'view': // Node page if ($page && !$teaser) { // Xref links if (variable_get('xref_links_'. $node->type, 'template') == 'node') { $xref_links = xref_links($node->type, $node->nid); if (!empty($xref_links)) { $links = theme('links', $xref_links); $node->content['xref_links'] = array( '#weight' => -10, '#value' => theme('xref_links', $links, t('Reference this via')), ); } } // Xref view if (variable_get('xref_view_'. $node->type, true)) { $xref_view = xref_view($node->type, $node->nid); if (!empty($xref_view)) { $node->content['xref_view'] = array('#weight' => 100, '#value' => $xref_view); } } } break; } } /** * Implementation of hook_form_alter. * * Adds xref setting to nodetype editing pages. */ function xref_form_alter(&$form, $form_state, $form_id) { if ($form_id == 'node_type_form' && isset($form['identity']['type'])) { $fields = xref_fields($form['#node_type']->type); if (!empty($fields)) { $types = array(); foreach ($fields as $k => $v) { $types[$v['type_name']] = $v['type_name']; } $form['xref'] = array( '#type' => 'fieldset', '#title' => t('Cross reference settings'), '#description' => t('This type of content can be referenced by: %type', array('%type' => implode(', ', $types))), '#collapsible' => TRUE, '#collapsed' => TRUE, ); $form['xref']['xref_links'] = array( '#type' => 'select', '#title' => t('Display "Reference this via" links'), '#options' => array( FALSE => '-- '. t('Don\'t display') .' --', 'template' => t('Provide $xref_links variable in node.tpl.php'), 'node' => t('Display in node content'), ), '#default_value' => variable_get('xref_links_'. $form['#node_type']->type, 'template'), ); $form['xref']['xref_view'] = array( '#type' => 'checkbox', '#title' => t('Display summary of referencing content'), '#default_value' => variable_get('xref_view_'. $form['#node_type']->type, true), ); } } } /** * Implementation of hook_theme(). */ function xref_theme() { return array('xref_links' => array()); } /** * Theme xref links. */ function theme_xref_links($links, $label) { return "
$label
$links
"; } /** * Preprocessor for theme_node(). */ function xref_preprocess_node(&$vars) { $node = $vars['node']; if (variable_get('xref_links_'. $node->type, 'template') == 'template') { $links = xref_links($node->type, $node->nid); if (!empty($links)) { $links = theme('links', $links); $vars['xref_links'] = theme('xref_links', $links, t('Reference this')); } } } /** * API function. */ function xref_fields($nodetype, $reset = FALSE) { static $fields; if (!isset($fields) || $reset) { $fields = array(); } if (!isset($fields[$nodetype])) { $fields[$nodetype] = array(); // Get nodereference fields that may reference this node foreach (content_fields() as $field) { if ($field['type'] == 'nodereference' && is_array($field['referenceable_types'])) { foreach ($field['referenceable_types'] as $type) { if ($type === $nodetype) { $fields[$nodetype][$field['field_name']] = $field; } } } } } return $fields[$nodetype]; } /** * Provides links to create any nodes that could potentially reference this node. */ function xref_links($nodetype, $nid) { $fields = array_keys(xref_fields($nodetype)); if ($fields) { // Wrap each field in quotes in prep for SQL IN() foreach ($fields as $k => $v) { $fields[$k] = "'$v'"; } // Build link of nodetypes with instances of all valid referencing fields $links = array(); $node_types = node_get_types(); $fields = implode(',', $fields); $result = db_query("SELECT field_name, type_name FROM {content_node_field_instance} WHERE widget_active = 1 AND field_name IN ($fields)"); while ($row = db_fetch_object($result)) { if (node_access('create', $row->type_name)) { $node = node_load($nid); $type = $row->type_name; $item = menu_get_item('node/add/'. str_replace('_', '-', $type)); if ($item['access']) { $links[$type] = array( 'title' => t('via @nodetype', array('@nodetype' => $item['title'])), 'href' => $item['href'], 'query' => check_plain("edit[{$row->field_name}][0][nid][nid]= ". urlencode($node->title) ." [nid: {$nid}]"), ); } } } return $links; } return ''; } /** * Provides a view of any nodes that reference the given node. * * @param $nodetype * the node type of the content to detect references to. * * @param $nid * the nid of the content to detect references to. * * @param $fieldname * Optional. The id of the particular field to be used to build the view. If * omitted the first field returned by xref_fields() will be used. * * @param $viewname * Optional. */ function xref_view($nodetype, $nid, $fieldname = null, $viewname = null) { $output = ''; $fields = xref_fields($nodetype); if (empty($fields)) { return ''; } if (!empty($fieldname)) { $field = $fields[$fieldname]; } else { $field = array_shift($fields); } if (empty($viewname)) { $viewname = 'xref'; } // Xref nodes if ($view = views_get_view($viewname)) { $field_info = content_database_info($field); module_load_include('inc', 'content', 'includes/views/content.views'); $view->set_display(); $handler = $view->display['default']->handler; $handler->override_option('arguments', array( $field['field_name'] => array( 'default_action' => 'not found', 'style_plugin' => 'default_summary', 'style_options' => array(), 'wildcard' => 'all', 'wildcard_substitution' => 'All', 'title' => '', 'default_argument_type' => 'php', 'default_argument' => '', 'validate_type' => 'none', 'validate_fail' => 'not found', 'break_phrase' => 0, 'not' => 0, 'id' => $field['field_name'] .'_nid', 'table' => content_views_tablename($field), 'field' => $field['field_name'] .'_nid', 'relationship' => 'none', 'default_options_div_prefix' => '', 'default_argument_user' => 0, 'default_argument_fixed' => '', 'default_argument_php' => '', 'validate_argument_node_type' => array(), 'validate_argument_node_access' => 0, 'validate_argument_nid_type' => 'nid', 'validate_argument_vocabulary' => array(), 'validate_argument_type' => 'tid', 'validate_argument_is_member' => 0, 'validate_argument_php' => '', ), )); $view->pre_execute(array($nid)); $view->execute(); if (count($view->result)) { $output = $view->render(); } } return $output; } /** * Implementation of hook_views_api(). */ function xref_views_api() { return array('api' => 2); }