contacts_events-8.x-1.x-dev/modules/villages/contacts_events_villages.module
modules/villages/contacts_events_villages.module
<?php
/**
* @file
* Contains contacts_events_villages.module.
*/
use Drupal\commerce_order\Entity\OrderInterface;
use Drupal\contacts_events\Entity\Event;
use Drupal\contacts_events_villages\Controller\AllocatedVillageController;
use Drupal\contacts_events_villages\Controller\VillageHostInfoController;
use Drupal\contacts_events_villages\Entity\Village;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\entity\BundleFieldDefinition;
use Drupal\user\UserInterface;
/**
* Implements hook_theme().
*/
function contacts_events_villages_theme(array $existing, $type, $theme, $path) {
return [
'contacts_events_villages_host_info' => [
'render element' => 'content',
],
'views_view__contacts_events_village_hosts_report' => [
'base hook' => 'views_view',
'template' => 'views-view--contacts-events-village-hosts-report',
],
];
}
/**
* Implements hook_entity_field_storage_info().
*/
function contacts_events_villages_entity_field_storage_info(EntityTypeInterface $entity_type) {
if ($entity_type->id() === 'commerce_order') {
$fields['village_group'] = BundleFieldDefinition::create('entity_reference')
->setName('village_group')
->setTargetEntityTypeId('commerce_order')
->setTargetBundle('contacts_booking')
->setLabel(new TranslatableMarkup('Camping Location'))
->setRequired(TRUE);
return $fields;
}
}
/**
* Implements hook_entity_bundle_field_info().
*/
function contacts_events_villages_entity_bundle_field_info(EntityTypeInterface $entity_type, $bundle, array $base_field_definitions) {
if ($entity_type->id() === 'commerce_order' && $bundle == 'contacts_booking') {
$fields['village_group'] = BundleFieldDefinition::create('entity_reference')
->setName('village_group')
->setTargetEntityTypeId('commerce_order')
->setTargetBundle('contacts_booking')
->setLabel(new TranslatableMarkup('Camping Location'))
->setDescription(new TranslatableMarkup('Please select who you would like to be placed near.'))
->setSetting('target_type', 'c_events_village_group')
->setDisplayOptions('form', ['region' => 'hidden'])
->setDisplayConfigurable('form', TRUE)
->setDisplayConfigurable('view', FALSE)
->setRequired(TRUE);
return $fields;
}
}
/**
* Implements hook_entity_base_field_info().
*/
function contacts_events_villages_entity_base_field_info(EntityTypeInterface $entity_type) {
$fields = [];
if ($entity_type->id() == 'contacts_event') {
$fields['village_group_types'] = BaseFieldDefinition::create('list_string')
->setName('village_group_types')
->setLabel(new TranslatableMarkup('Village Group types'))
->setDescription(new TranslatableMarkup('Select which village group types are available for this event. If none are selected, camping villages will be disabled.'))
->setDisplayConfigurable('form', TRUE)
->setDisplayOptions('form', [
'type' => 'options_buttons',
'label' => 'above',
'weight' => 9,
])
// phpcs:ignore Drupal.Arrays.Array.LongLineDeclaration
->setSetting('allowed_values_function', ['\Drupal\contacts_events_villages\Entity\VillageGroup', 'getVillageTypes'])
->setCardinality(FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED);
}
return $fields;
}
/**
* Implements hook_ENTITY_TYPE_update() for user.
*
* Rename village groups when organisation name changes.
*/
function contacts_events_villages_user_update(UserInterface $account) {
// Only check organisations.
if (!in_array('crm_org', $account->getRoles())) {
return;
}
// Because label callback is user_format_name we can't check if label changed
// before loading entities so search for different names.
$village_storage = \Drupal::entityTypeManager()->getStorage('c_events_village_group');
$query = $village_storage->getQuery()
->condition('name', $account->label(), '!=')
->condition('type', 'organisation')
->condition('organisation', $account->id());
$query->accessCheck(TRUE);
foreach ($village_storage->loadMultiple($query->execute()) as $group) {
/** @var \Drupal\contacts_events_villages\Entity\VillageGroupInterface $group */
$group->setName($account->label());
$group->save();
}
}
/**
* Implements hook_ENTITY_TYPE_presave() for commerce_order.
*/
function contacts_events_villages_commerce_order_presave(OrderInterface $entity) {
// We're only interested in updates of bookings.
if (!$entity->isNew() || $entity->bundle() != 'contacts_booking') {
return;
}
// Make sure our required fields are present.
$required_fields = [
'accommodation_requirements',
'village_requirements',
'village_requirements_processed',
];
foreach ($required_fields as $field) {
if (!$entity->hasField($field)) {
return;
}
}
if (isset($entity->original)) {
/** @var \Drupal\commerce_order\Entity\OrderInterface $original */
$original = $entity->original;
// Check if the accommodation requirements has changed.
if ($entity->get('accommodation_requirements')->value != $original->get('accommodation_requirements')->value) {
// Reset the processed indicator.
$entity->set('village_requirements_processed', FALSE);
}
}
}
/**
* Implements hook_views_data_alter().
*/
function contacts_events_villages_views_data_alter(array &$data) {
$data['commerce_order']['village_requirements_checkboxes'] = [
'title' => new TranslatableMarkup('Village Requirements (as checkboxes)'),
'field' => ['id' => 'contacts_events_village_requirements'],
];
$data['commerce_order']['village_requirements_processed_checkbox'] = [
'title' => new TranslatableMarkup('Village Requirements Processed (as checkbox)'),
'field' => ['id' => 'contacts_events_village_requirements_processed'],
];
$data['commerce_order__village_requirements_processed']['village_requirements_processed_value']['filter']['accept null'] = TRUE;
// Use custom bundle handlers which know how to handle non-config bundles.
// Workaround for core issue #3056998.
$data['c_events_village_group']['type']['field']['id'] = 'commerce_entity_bundle';
$data['c_events_village_group']['type']['filter']['id'] = 'village_group_bundle';
}
/**
* Preprocess for the host report view.
*/
function contacts_events_villages_preprocess_views_view(array &$variables) {
/** @var \Drupal\views\ViewExecutable $view */
$view = $variables['view'];
if ($view->id() != 'contacts_events_village_hosts_report') {
return;
}
/** @var \Drupal\contacts_events\Entity\EventInterface $event */
$event = Event::load($view->args[0]);
$variables['event'] = [
'display' => TRUE,
'name' => $event->label(),
'date' => $event->get('date')->view(['label' => 'hidden']),
];
/** @var \Drupal\contacts_events_villages\Entity\Village $village */
$village = Village::load($view->args[1]);
$variables['village'] = [
'name' => $village->label(),
'colour' => $village->get('colour')->value,
];
}
/**
* Implements hook_menu_local_actions_alter().
*/
function contacts_events_villages_menu_local_actions_alter(&$local_actions) {
// If the Village Groups View exists, ensure all actions that appear on the
// collection also appear on it.
if (Drupal::service('router')->getRouteCollection()->get('view.contacts_events_village_groups.page_1') !== NULL) {
foreach ($local_actions as &$local_action) {
if (isset($local_action['appears_on']) && in_array('entity.c_events_village_group.collection', $local_action['appears_on'])) {
$local_action['appears_on'][] = 'view.contacts_events_village_groups.page_1';
}
}
}
}
/**
* Implements hook_local_tasks_alter().
*/
function contacts_events_villages_local_tasks_alter(&$local_tasks) {
// If the Village Groups View exists, update the collection route to use it.
if (Drupal::service('router')->getRouteCollection()->get('view.contacts_events_village_groups.page_1') !== NULL) {
if (isset($local_tasks['entity.c_events_village_group.collection'])) {
$local_tasks['entity.c_events_village_group.collection']['route_name'] = 'view.contacts_events_village_groups.page_1';
}
}
}
/**
* Implements hook_contacts_user_dashboard_user_summary_blocks_alter().
*/
function contacts_events_villages_contacts_user_dashboard_user_summary_blocks_alter(&$content, UserInterface $user) {
$controller = AllocatedVillageController::create(\Drupal::getContainer());
$output = $controller->myAllocatedVillages($user);
if (!empty($output)) {
$content['my_villages'] = [
'#type' => 'user_dashboard_summary',
'#buttons' => [],
'#title' => t('Camping villages'),
'#content' => $output,
];
}
}
/**
* Implements hook_ENTITY_TYPE_access() for contacts_event.
*
* Allow village hosts to access village host files stored on the event.
*/
function contacts_events_villages_contacts_event_access(EntityInterface $entity, $operation, AccountInterface $account) {
if ($operation != 'view') {
return AccessResult::neutral();
}
/** @var \Drupal\contacts_events\Entity\EventInterface $entity */
/** @var \Drupal\Core\DependencyInjection\ClassResolver $resolver */
$resolver = \Drupal::service('class_resolver');
/** @var \Drupal\contacts_events_villages\Controller\VillageHostInfoController $controller */
$controller = $resolver->getInstanceFromDefinition(VillageHostInfoController::class);
$access = $controller->access($entity);
if ($access->isAllowed()) {
return $access;
}
return AccessResult::neutral();
}
