contacts-8.x-1.x-dev/modules/group/contacts_group.module

modules/group/contacts_group.module
<?php

/**
 * @file
 * General hook implementations for Contacts Group.
 */

use Drupal\Core\Access\AccessResult;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\Core\Url;
use Drupal\contacts_group\Form\ContactOrgRelationshipForm;
use Drupal\contacts_group\Plugin\Field\ContactsOrgGroupItemList;
use Drupal\contacts_group\Plugin\Validation\Constraint\GroupRelationshipCardinality;
use Drupal\entity\BundleFieldDefinition;
use Drupal\group\Entity\GroupMembershipInterface;

/**
 * Implements hook_entity_type_build().
 */
function contacts_group_entity_type_build(array &$entity_types) {
  /** @var \Drupal\Core\Entity\EntityTypeInterface[] $entity_types */
  if (isset($entity_types['group_relationship'])) {
    // Group 3.x.
    $entity_types['group_relationship']->setFormClass('contacts-org', ContactOrgRelationshipForm::class);
  }
  elseif (isset($entity_types['group_content'])) {
    // Group 2.x.
    $entity_types['group_content']->setFormClass('contacts-org', ContactOrgRelationshipForm::class);
  }
}

/**
 * Implements hook_entity_base_field_info().
 */
function contacts_group_entity_base_field_info(EntityTypeInterface $entity_type) {
  $fields = [];

  if ($entity_type->id() == 'user') {
    $fields['group'] = BaseFieldDefinition::create('entity_reference')
      ->setName('group')
      ->setLabel('Organisation group')
      ->setComputed(TRUE)
      ->setSetting('target_type', 'group')
      ->setClass(ContactsOrgGroupItemList::class);

    $fields['organisations'] = BaseFieldDefinition::create('group_membership')
      ->setName('group_memberships')
      ->setLabel('Group memberships')
      ->setComputed(TRUE)
      ->setCardinality(-1)
      ->setSetting('target_type', _contacts_group_get_group_relationship_entity_type_id())
      ->setSetting('group_type', 'contacts_org');
  }

  return $fields;
}

/**
 * Implements hook_entity_field_storage_info().
 */
function contacts_group_entity_field_storage_info(EntityTypeInterface $entity_type) {
  $fields = [];

  if ($entity_type->id() == 'group') {
    $fields['contacts_org'] = BundleFieldDefinition::create('entity_reference')
      ->setTargetEntityTypeId('group')
      ->setName('contacts_org')
      ->setLabel(new TranslatableMarkup('Organisation'))
      ->setDescription(new TranslatableMarkup('The organisation this group is for.'))
      ->setSetting('target_type', 'user');
  }

  return $fields;
}

/**
 * Implements hook_entity_bundle_field_info().
 */
function contacts_group_entity_bundle_field_info(EntityTypeInterface $entity_type, $bundle, array $base_field_definitions) {
  $fields = [];

  if ($entity_type->id() == 'group' && $bundle == 'contacts_org') {
    $fields['contacts_org'] = BundleFieldDefinition::create('entity_reference')
      ->setTargetEntityTypeId('group')
      ->setTargetBundle('contacts_org')
      ->setName('contacts_org')
      ->setRequired(TRUE)
      ->setReadOnly(TRUE)
      ->setLabel(new TranslatableMarkup('Organisation'))
      ->setDescription(new TranslatableMarkup('The organisation this group is for.'))
      ->setSetting('target_type', 'user')
      ->setSetting('handler', 'default:user')
      ->setSetting('handler_settings', [
        'include_anonymous' => FALSE,
        'filter' => [
          'type' => 'role',
          'role' => ['crm_org'],
        ],
        'auto_create' => FALSE,
      ])
      ->addConstraint('ContactsUniqueReference', [
        'bundle' => TRUE,
      ])
      ->setDisplayOptions('form', [
        'type' => 'entity_reference_autocomplete',
        'weight' => -1,
      ])
      ->setDisplayConfigurable('form', FALSE)
      ->setDisplayConfigurable('view', TRUE);
  }

  return $fields;
}

/**
 * Implements hook_entity_bundle_field_info_alter().
 */
function contacts_group_entity_bundle_field_info_alter(&$fields, EntityTypeInterface $entity_type, $bundle) {
  // Support both group 3.x (group_relationship)
  // and group 2.x (group_content).
  if (($entity_type->id() == 'group_content' || $entity_type->id() == 'group_relationship') && $bundle == 'contacts_org-group_membership') {
    // Default user selection applies an additional check on the user's status
    // when validating the entity reference, to ensure that users are always
    // active. For contacts, we don't want this as we want to be able to add
    // inactive users to groups. Do this by overriding the entity reference
    // selection handler to use our search_api_user_multiline handler instead.
    $fields['entity_id']
      ->setSetting('handler', 'search_api_user_multiline')
      ->setSetting('handler_settings', [
        'index' => 'contacts_index',
      ]);
  }
}

/**
 * Implements hook_form_BASE_FORM_ID_alter() for group_form.
 */
function contacts_group_form_group_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  /** @var \Drupal\group\Entity\GroupInterface $group */
  $group = $form_state->getFormObject()->getEntity();
  if ($group->bundle() == 'contacts_org') {
    $form['label']['#access'] = FALSE;
    if (!$group->isNew()) {
      $form['contacts_org']['widget'][0]['target_id']['#disabled'] = TRUE;
    }
    $form['#entity_builders'][] = 'contacts_group_form_group_form_contacts_org_entity_builder';
  }
}

/**
 * Entity builder callback for the group form.
 */
function contacts_group_form_group_form_contacts_org_entity_builder($entity_type_id, EntityInterface $entity, array $form, FormStateInterface $form_state) {
  /** @var \Drupal\user\UserInterface|null $organisation */
  if ($organisation = $entity->contacts_org->entity) {
    $entity->set('label', $organisation->label());
  }
}

/**
 * Implements hook_entity_field_access().
 */
function contacts_group_entity_field_access($operation, FieldDefinitionInterface $field_definition, AccountInterface $account, ?FieldItemListInterface $items = NULL) {
  // Field access for organisation memberships.
  // Support both group 2.x (group_content)
  // and group 3.x (group_relationship).
  if (($field_definition->getTargetEntityTypeId() == 'group_content' || $field_definition->getTargetEntityTypeId() == 'group_relationship') && $field_definition->getTargetBundle() == 'contacts_org-group_membership') {
    // Deny access for all operations for roles and job title unless we know
    // we're dealing with an individual member. Organisation members don't have
    // roles or titles.
    $field_names = ['indiv_role', 'group_roles', 'job_title'];
    if (in_array($field_definition->getName(), $field_names)) {
      if ($items) {
        /** @var \Drupal\user\UserInterface $member */
        $member = $items->getEntity()->getEntity();
        return AccessResult::forbiddenIf(!$member || !$member->hasRole('crm_indiv'));
      }
    }
  }
  return AccessResult::neutral();
}

/**
 * Implements hook_validation_constraint_alter().
 */
function contacts_group_validation_constraint_alter(array &$definitions) {
  $definitions['GroupRelationshipCardinality']['class'] = GroupRelationshipCardinality::class;
}

/**
 * Implements hook_preprocess_HOOK() for block.
 */
function contacts_group_preprocess_block(&$variables) {
  // The title still shows for the relationship view, even if argument
  // validation should hide the view.
  if ($variables['base_plugin_id'] == 'views_block' && substr($variables['derivative_plugin_id'], 0, 13) == 'contacts_orgs') {
    if (!isset($variables['content']['#view'])) {
      unset($variables['label']);
    }
  }
}

/**
 * Implements hook_block_alter().
 *
 * Declare the membership enabler relationship block under the old machine name.
 */
function contacts_group_block_alter(&$definitions) {
  if (isset($definitions['contacts_org_relationship_form:group_membership'])) {
    $definitions['contacts_org_relationship_form'] = $definitions['contacts_org_relationship_form:group_membership'];
  }
}

/**
 * Implements hook_form_BASE_ID_alter() for group_relationship_confirm_form.
 *
 * This is the Group 3.x version of the hook.
 */
function contacts_group_form_group_relationship_confirm_form_alter(array &$form, FormStateInterface $form_state, string $form_id) {
  // Just delegate to the group 2.x version of the hook.
  contacts_group_form_group_content_confirm_form_alter($form, $form_state, $form_id);
}

/**
 * Implements hook_form_BASE_ID_alter().
 *
 * This is the Group 2.x version of the hook.
 */
function contacts_group_form_group_content_confirm_form_alter(array &$form, FormStateInterface $form_state, string $form_id) {
  // If this member is a group admin, prevent removal unless there is at least
  // one more.
  $form_ids = [
    'group_content_contacts_org-group_membership_delete_form',
    'group_relationship_contacts_org-group_membership_delete_form',
  ];

  if (!in_array($form_id, $form_ids)) {
    return;
  }

  /** @var \Drupal\group\Entity\GroupRelationshipInterface $relationship */
  $relationship = $form_state->getFormObject()->getEntity();
  $group = $relationship->getGroup();

  if (!($relationship instanceof GroupMembershipInterface)) {
    return;
  }

  $form['#title'] = new TranslatableMarkup(
    'Are you sure you want to remove %indiv from %org?',
    [
      '%indiv' => $relationship->label(),
      '%org' => $group->label(),
    ]
  );
  $form['actions']['submit']['#value'] = new TranslatableMarkup('Remove');
  if (!in_array('contacts_org-admin', array_keys($relationship->getRoles()))) {
    return;
  }

  $admin_members = $group->getMembers(['admin']);
  if (count($admin_members) > 1) {
    return;
  }

  $form['description']['#markup'] = new TranslatableMarkup(
    'You cannot remove the only administrator of %org. Please add a new administrator first.',
    ['%org' => $group->label()]
  );
  $form['actions']['submit']['#access'] = FALSE;
}

/**
 * Implements hook_link_alter().
 */
function contacts_group_link_alter(&$variables) {
  if (($variables['options']['attributes']['target'] ?? NULL) == '_contacts_modal') {
    unset($variables['options']['attributes']['target']);
    $variables['options']['attributes'] += [
      'data-dialog-type' => 'modal',
    ];
    $variables['options']['attributes']['class'][] = 'use-ajax';

    // Set a redirect URL if there isn't one.
    if (empty($variables['options']['query']['destination'])) {
      $variables['options']['query']['destination'] = Url::fromRoute('<current>')->toString();
    }
  }
}

/**
 * Implements hook_ENTITY_TYPE_update() for profile.
 */
function contacts_group_profile_update(EntityInterface $entity) {
  // When an organisation is renamed, ensure that the group is renamed too.
  if ($entity->bundle() === 'crm_org' && $entity->hasField('crm_org_name')) {
    /** @var \Drupal\user\UserInterface $user */
    $user = $entity->getOwner();
    if ($user->hasField('group')) {
      /** @var \Drupal\group\Entity\Group $group */
      $group = $user->group->entity;
      if ($group && $group->bundle() === 'contacts_org') {
        if ($group->label() !== $entity->get('crm_org_name')->value) {
          $group->set('label', $entity->get('crm_org_name')->value);
          $group->save();
        }
      }
    }
  }
}

/**
 * Gets the entity type ID of the group_relationship entity type.
 *
 * This is different depending on whether we're running on group 2.x
 * (group_content) or group 3.x (group_relationship).
 *
 * @return string|null
 *   Entity type id, or null if group isn't installed.
 */
function _contacts_group_get_group_relationship_entity_type_id(): ?string {
  /** @var \Drupal\Core\Extension\ModuleExtensionList $module_extension_list */
  $module_extension_list = \Drupal::service('extension.list.module');
  $group_version = $module_extension_list->getExtensionInfo('group')['version'] ?? '0';

  if (version_compare($group_version, '2.0.0', '>=') && version_compare($group_version, '3.0.0', '<')) {
    return 'group_content';
  }

  if (version_compare($group_version, '3.0.0', '>=')) {
    return 'group_relationship';
  }

  return NULL;
}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc