There are currently few node access options, but i would like to have option to limit CREATION of node only if user has option to edit referenced node. So it would be some sort of crationg/edit node access option, is it possible to somehow set it up or does module need upgrade for this?

Comments

Marko B’s picture

Just realized this are options of this module http://drupal.org/project/nodeaccess_nodereference and doesnt have to do with this module. sorry

quicksketch’s picture

Status: Active » Fixed

Thanks for the update. This question has been asked before and it is out of scope for this module. This module is a convenience, it doesn't provide any sort of access control. That said it does check existing node access control before showing the link to create new content, so if you have a node access system in place that enforces this sort of behavior, Node Reference URL Widget will obey it.

Marko B’s picture

Yes but it will only enforce access to node type that you create, it wont check is the creator also owner of node which is referenced. And i would like option that if you are logged as one user you can make new nodes referenced to only the nodes or node that you are owner and currently i can make to any node of type. This cannot be done, right?

yellek’s picture

It would be possible to do something like this if there was some sort of hook built in to the permission check that the module does before putting the link up. My current thought for a solution is to use module weights and create a module that runs after node reference URL, looks for the links and removes them. Very clunky.

Is there a possibility of calling a rule or some other way of doing this?

quicksketch’s picture

hook built in to the permission check that the module does before putting the link up.

This module already calls a hook through the node_access system (hook_node_access()). If you'd like to hide the link, you should implement a real access control system so that users can't just type in the URL directly.

quicksketch’s picture

If necessary we could add a property to the node (like $node->node_reference_candidate) to indicate what NID was about to be referenced and then hook_node_access() would provide enough information to deny the creation of a new node.

yellek’s picture

I've been having a think about this and it would certainly be possible to put together a little module that does this using hook_link_alter(). I need to do it for a site that I'm doing at the moment however I don't have the cycles to spare to do the legwork of formally supporting it here. If there was someone who would be willing to take on the maintenance of such a module I would be happy to contribute.

yellek’s picture

Just a quick update to say that I have a module working that does this. I have appended the code below in case anyone needs it:

<?php
// $Id$
/**
 * Display help and module information
 * @param path which path of the site we're displaying help
 * @param arg array that holds the current path as would be returned from arg() function
 * @return help text for the path
 */
function nodereference_create_access_help($path, $arg) {
  $output = '';  
  switch ($path) {
    case "admin/help#nodereference_create_access":
      $output = '<p>'.  t("Prevents the creation of nodes if the user does not have edit access to the nodes they link to via nodereference URL controls") .'</p>';
      break;
  }
  return $output;
} // function nodereference_create_access_help

/**
 * Implementation of hook_field_settings_alter().
 */
function nodereference_create_access_field_settings_alter(&$form, $op, $field) {

  if ($field['type'] == 'nodereference') {
    switch ($op){
      case 'form':
        $form['nodereference_restrict_create'] = array(
          '#type' => 'checkbox',
          '#title' => t('Only allow references to nodes with edit access'),
          '#default_value' => isset($field['nodereference_restrict_create']) ? (bool) $field['nodereference_restrict_create'] : FALSE,
          '#description' => t('Restricts access depending upon the edit permissions of the node being linked to.'),
        );
        break;
      case 'save':
        // Add our new options to the list of settings to be saved.
        $form = array_merge($form, array('nodereference_restrict_create'));
        break;
    }
  }
}

/**
 * Implementation of hook_link_alter()
 */
function nodereference_create_access_link_alter(&$links, $node, $comment = NULL) {
  //dvm($links);
  //determine which links, if any, were built by nodereference_url
  foreach($links as $link_name => $this_link) {
    if (preg_match('%node/add/([^/]*)/[^/]*%',$this_link['href'], $matches)) {
      dvm($link_name);
      $node_type = $matches[1];
      $field_name = preg_replace('/^'.$node_type.'_/i', '', $link_name, 1);
      dpm("Field name: " . $field_name);
      $field_info = content_fields($field_name);
      if ($field_info["nodereference_restrict_create"]) {
        if (!node_access("update", $node)) {
          unset($links[$link_name]);
        }
      }
    }
  }
  dvm($links);
}

/**
 * Implementation of hook_nodeapi()
 */
function nodereference_create_access_nodeapi($node, $op) {
  switch ($op) {
    case 'validate':
      // grab some info about this content type from cck
      $content_type = content_types($node->type);
      // pull out the fields settings
      $fields = &$content_type['fields'];
      foreach ($fields as $field) {
        // Check if it is a nodereference
        if ($field['type'] == 'nodereference') {
          $field_name = $field['field_name'];
          dpm($field_name, NULL);
          if ($field["nodereference_restrict_create"]) { 
            $referenced_nid = $node->{$field_name}[0]['nid'];
            dpm('referenced NID' . $referenced_nid, NULL);
            $referenced_node = node_load($referenced_nid);
            if ($referenced_node) {
              if (!node_access("update", $referenced_node)) {
                form_set_error($field_name, 'Update access to node ' . $referenced_node->title . ' is required before linking to it. Please select another node to link to.');
              }
            }
          }
        }
      }
      break;
  }
}
?>
johnpitcairn’s picture

Subscribing for future reference, thanks.

babycourageous’s picture

subscribing

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

Marko B’s picture

@Yellek

how is this working? should i just add this code to this module and install http://drupal.org/project/nodeaccess_nodereference ?