I am in the concept phase of a project and the Group module seems to provide some functionality needed. I only used the Group module in a Drupal 7 site before.

In the new project, I want to realise an assessment system, where each idea (= content type) is a group. In each group there will be more than 10 other nodes (each has its own content type) but it would be required that there is only one node for each content type per group.

In other words, the author of the idea shall have the permission to create any of the other content types and add it to the group, but only do that once for each content type.

Is there a way to do that? I haven't found such an option, yet, but I guess it is maybe not in the scope of the Group module neither. If I would code such a restriction myself, does anyone have a starting point how that would be done? I am not yet bound to use Drupal 8, so if it might be easier in D7, I can go for that, too.

Comments

Paul Broon created an issue. See original summary.

waspper’s picture

Maybe writing a custom form validation (form_alter) to the node form. There, making a validation according to the selected group and desired content type. For this, you have to query for at least one node of type that user is trying to add, to the selected group.

broon’s picture

I am currently going for a slightly different solution. First, I am using Drupal 8, but the same process is probably nearly identical in D7.

Since the group content is a highly customized node type anyway, I am providing the user with a form which in turn creates a node upon submit and adds that node to the group. When the user tries to add a new content of same type, the form is loaded with the previously created node values and upon submitting the form again, the first node is just updated.

Right now, I am trying to wrap that up by automatically creating the node upon group creation, thus the user never actually creates the node himself but only does updates.

michaelvanh’s picture

Hey Paul,
I am working on a similar project where the group needs to be limited to only a few nodes. Any chance you could share your solution for automated creation of the nodes?

broon’s picture

Status: Active » Closed (won't fix)

Sure, but this is a rather specialised solution. As said before, my use case was an assessment system, thus the user needed to enter a lot of data and answer quite a few questions. So obviously, I created a custom module featuring several Form controllers, one for each of the twelve assessment exercises. These Form controllers had custom validation and submit handlers. The submit function for each exercise gathers the submitted data and converts it into "Drupal", e.g. nodes, paragraphs, file entities and so on. The function will also check, if the current group already contains the target node (by checking Group Membership Relation) and if so updates the existing node. Otherwise, a node of the target type is created and added to the group. When showing the respective form to the user, the Form controller also checks for the existence of a node of target type and includes both group id and node id in the form (hidden fields). These values are used in the submit form.

Here is an excerpt of a submitForm() function:

    $group = \Drupal\group\Entity\Group::load($form_state->getValue('groupid'));
    $node_title = "EXERCISE 1";
    if ($group) {
      $node_title .= ': ' . $group->get('label')->value . ' (' . $group->get('id')->value . ')';
    }

    $nid = $form_state->getValue('nodeid');
    $node = NULL;
    if ($nid > 0) {
      $node = \Drupal\node\Entity\Node::load($nid);
    }

    if (is_null($node)) {
      $node_entity_type = \Drupal::entityTypeManager()->getDefinition('node');
      // Create node object with attached file.
      $values = [
        $node_entity_type->getKey('bundle') => 'exercise_01',
        $node_entity_type->getKey('label') => $node_title,
        'field_abc' => $form_state->getValue('abc'),
        'field_xyz' => $form_state->getValue('xyz'),
        'uid' => \Drupal::currentUser()->id(),
      ];
      $entity = \Drupal::entityTypeManager()
        ->getStorage('node')
        ->create($values);
      $entity->save();

      if (isset($group)) {
        $group->addContent($entity, 'group_node:exercise_01');
      }
      drupal_set_message($this->t('Exercise 1 saved and added to group.'));
    }
    else {
      $node->set('field_abc', $form_state->getValue('abc'));
      $node->set('field_xyz', $form_state->getValue('xyz'));
      $node->setTitle($node_title);
      $node->save();
      drupal_set_message($this->t('Changes to Exercise 1 saved.'));
    }

In the buildForm() function, this is how I get the group ID from the URL and check for an existing node:

    $route_match = \Drupal::service('current_route_match');
    $group = $route_match->getParameter('group');

    if (is_numeric($group)) {
      $groupid = $group;
      $group = \Drupal\group\Entity\Group::load($groupid);
    }
    else {
      /** @var Group $group */
      $groupid = $group->id();
    }

    $contents = $group->getContent('group_node:exercise_01');
    $node = NULL;
    if (count($contents)) {
      $content = reset($contents);
      $node = $content->getEntity();
    }

In addition to that, I am setting the issue to "won't fix" as I think, this is out of scope for the core Group module. If you still have question, you can also send me a mail or find me on DrupalChat.me.