social_geolocation-8.x-1.2/modules/social_geolocation_maps/social_geolocation_maps.module
modules/social_geolocation_maps/social_geolocation_maps.module
<?php
/**
* @file
* Contains hook implementations for the Social Geolocation module.
*/
use Drupal\block\Entity\Block;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Url;
use Drupal\group\Entity\GroupInterface;
use Drupal\node\NodeInterface;
use Drupal\views\Plugin\views\cache\CachePluginBase;
use Drupal\views\Plugin\views\query\QueryPluginBase;
use Drupal\views\ViewExecutable;
/**
* Implements hook_help().
*/
function social_geolocation_maps_help($route_name, RouteMatchInterface $route_match): ?string {
switch ($route_name) {
case 'help.page.social_geolocation_maps':
return 'This module provides a Map on the events page. Enable the module and create an event with an address so it shows up on the map.';
}
return NULL;
}
/**
* Implements hook_field_widget_form_alter().
*/
function social_geolocation_maps_field_widget_form_alter(&$element, FormStateInterface $form_state, $context): void {
// Change title in form for adding Event Maps block on Landing pages.
if ($context['items']->getName() === 'field_block_reference' ||
$context['items']->getName() === 'field_block_reference_secondary') {
$name = $element['plugin_id']['#options']['Basic']['views_block:social_geolocation_leaflet_commonmap_with_marker_icons-block_upcomming_events_map'];
if ($name !== NULL) {
$element['plugin_id']['#options']['Basic']['views_block:social_geolocation_leaflet_commonmap_with_marker_icons-block_upcomming_events_map'] = t('Upcoming Events shown on a map');
}
}
}
/**
* Implements hook_views_query_alter().
*/
function social_geolocation_maps_views_query_alter(ViewExecutable $view, QueryPluginBase $query): void {
if ($view->id() === 'social_geolocation_members' &&
$view->getDisplay()->display['id'] === 'members_map_block') {
// Do not show users on the map who hide their location.
$users_data = \Drupal::service('user.data');
$users_data = $users_data->get('social_profile_privacy', NULL, 'private_info');
if (!empty($users_data)) {
$profile_ids = [];
$storage = \Drupal::entityTypeManager()->getStorage('profile');
foreach ($users_data as $uid => $user_data) {
if (empty($user_data['group_profile_contact_info'])) {
/** @var \Drupal\profile\Entity\ProfileInterface|null $profile */
$profile = current($storage->loadByProperties([
'uid' => $uid,
]));
if ($profile) {
$profile_ids[] = $profile->id();
}
}
}
if ($profile_ids) {
$query->addWhere(NULL, 'profile.profile_id', $profile_ids, 'NOT IN');
}
}
}
// Check if filtering with multiple terms use AND condition in the query.
if ($view->id() === 'social_geolocation_groups' && $view->getDisplay()->getBaseId() === 'block') {
// Check if tagging service is available.
if (!\Drupal::hasService('social_tagging.tag_service')) {
return;
}
/** @var \Drupal\social_tagging\SocialTaggingService $tag_service */
$tag_service = \Drupal::service('social_tagging.tag_service');
if (!($tag_service->active() && $tag_service->hasContent()) || $tag_service->queryCondition() === 'OR') {
return;
}
/** @var \Drupal\views\Plugin\views\query\Sql $query */
$org_query = $query->where['2'];
$conditions = $org_query['conditions'] ?? [];
$count_conditions = count($conditions);
// This only make sense if there are multiple terms.
if ($count_conditions <= 1) {
return;
}
// Extract the term ids.
$values = [];
foreach ($conditions as $condition) {
$values[] = $condition['value'];
}
// Update the condition and use IN instead of =.
$new_condition = end($conditions);
$new_condition['value'] = $values;
$new_condition['operator'] = 'IN';
$field = $new_condition['field'];
// Make sure we only get results that has all the required terms.
$query->addHavingExpression(
0,
"COUNT(DISTINCT($field)) = $count_conditions",
[],
);
}
}
/**
* Implements hook_page_attachments_alter().
*/
function social_geolocation_maps_page_attachments_alter(array &$attachments): void {
$route_name = \Drupal::routeMatch()->getRouteName();
// If bigpipe is enabled, the attachments don't get loaded for LU.
// So this is necessary to fix https://www.drupal.org/node/3018719.
if ($route_name === 'view.upcoming_events.page_community_events'
&& \Drupal::moduleHandler()->moduleExists('social_geolocation')
&& \Drupal::moduleHandler()->moduleExists('big_pipe')
&& !\Drupal::currentUser()->isAnonymous()) {
$attachments['#attached']['library'][] = 'geolocation_leaflet/widget.leaflet';
$attachments['#attached']['library'][] = 'geolocation_leaflet/geolocation.leaflet';
$attachments['#attached']['library'][] = 'geolocation_leaflet/leaflet.markerclusterer';
}
}
/**
* Implements hook_form_FORM_ID_alter().
*/
function social_geolocation_maps_form_social_geolocation_settings_form_alter(&$form, FormStateInterface $form_state, $form_id): void {
$config = \Drupal::config('social_geolocation_maps.settings');
foreach (['members', 'groups'] as $page) {
$page_map = $page . '_map';
$form[$page_map] = [
'#type' => 'checkbox',
'#title' => t('Enable @page map', ['@page' => $page]),
'#description' => t('Display map with geolocation of members on the members page'),
'#default_value' => $config->get($page_map),
];
}
$form['#submit'][] = 'social_geolocation_maps_form_social_geolocation_settings_form_submit';
}
/**
* Form submission handler for social_geolocation_settings().
*/
function social_geolocation_maps_form_social_geolocation_settings_form_submit(array $form, FormStateInterface $form_state): void {
$config = \Drupal::configFactory()->getEditable('social_geolocation_maps.settings');
$config->set('members_map', $form_state->getValue('members_map'));
$config->set('groups_map', $form_state->getValue('groups_map'));
$config->save();
}
/**
* Implements hook_form_FORM_ID_alter().
*/
function social_geolocation_maps_form_user_form_alter(&$form, FormStateInterface $form_state, $form_id): void {
$form['actions']['submit']['#submit'][] = 'social_geolocation_maps_account_settings_form_submit';
}
/**
* Form submission handler for account_settings().
*/
function social_geolocation_maps_account_settings_form_submit(array $form, FormStateInterface $form_state): void {
// If the Social Profile Privacy module is not installed we have nothing to
// do.
if (!\Drupal::moduleHandler()->moduleExists('social_profile_privacy')) {
return;
}
$account = $form_state->getFormObject()->getEntity();
$account_data = \Drupal::service('user.data')
->get('social_profile_privacy', $account->id(), 'private_info');
$profile_privacy = $form_state->getValue('profile_privacy');
if (
!empty($account_data['group_profile_contact_info']) &&
!empty($profile_privacy['group_profile_contact_info_visible']) &&
$account_data['group_profile_contact_info'] !== $profile_privacy['group_profile_contact_info_visible']
) {
\Drupal::service('cache_tags.invalidator')->invalidateTags(['social_geolocation_members_map']);
}
}
/**
* Implements hook_form_FORM_ID_alter().
*/
function social_geolocation_maps_form_social_tagging_settings_alter(&$form, FormStateInterface $form_state, $form_id): void {
$form['#submit'][] = 'social_geolocation_maps_social_tagging_settings_form_submit';
}
/**
* Form submission handler for social_tagging_settings form.
*/
function social_geolocation_maps_social_tagging_settings_form_submit(array $form, FormStateInterface $form_state): void {
\Drupal::service('cache_tags.invalidator')->invalidateTags([
'social_geolocation_members_map',
'social_geolocation_groups_map'
]);
}
/**
* Implements hook_block_access().
*/
function social_geolocation_maps_block_access(Block $block, $operation, AccountInterface $account): AccessResult {
if ($operation === 'view') {
$block_ids = [
'views_block:social_geolocation_members-members_map_block' => 'members_map',
'views_block:social_geolocation_groups-groups_map_block' => 'groups_map',
];
foreach ($block_ids as $block_id => $enabled) {
if($block->getPluginId() === $block_id){
$config = \Drupal::config('social_geolocation_maps.settings');
// Check if enabled map block and if it doesn't just hide it.
if (empty($config->get($enabled))) {
return AccessResult::forbidden();
}
}
}
}
return AccessResult::neutral();
}
/**
* Implements hook_preprocess_HOOK().
*/
function social_geolocation_maps_preprocess_profile(&$variables): void {
/** @var \Drupal\profile\Entity\ProfileInterface $profile */
$profile = $variables['profile'];
if ($profile->bundle() === 'profile') {
// Add lazy loading to profile pages.
$variables['content']['#attached']['library'][] = 'social_geolocation_maps/maps.members';
$variables['profile_stream_url'] = Url::fromRoute('social_user.stream', ['user' => $profile->getOwnerId()]);
}
}
/**
* Implements hook_preprocess_HOOK().
*/
function social_geolocation_maps_preprocess_geolocation_map_wrapper(&$variables): void {
$variables['#attached']['library'][] = 'social_geolocation_maps/social.geolocation.map';
}
/**
* Implements hook_preprocess_field().
*/
function social_geolocation_maps_preprocess_field(&$variables): void {
if ($variables['element']['#formatter'] === 'geolocation_address') {
$entity = $variables['element']['#object'];
if ($entity && $entity instanceof NodeInterface && $entity->getType() === 'event') {
$social_event_settings = \Drupal::config('social_event.settings');
$address_visibility_settings = $social_event_settings->get('address_visibility_settings');
if (isset($address_visibility_settings['street_code_private']) && !empty($address_visibility_settings['street_code_private'])) {
if (!_social_event_get_enrollment_status($entity) && isset($variables['items'][0]['content'][0]['#coordinates'])) {
$lat = $variables['items'][0]['content'][0]['#coordinates']['lat'];
$lng = $variables['items'][0]['content'][0]['#coordinates']['lng'];
$variables['items'][0]['content'][0]['#coordinates']['lat'] = (string) ($lat + ((rand(0, 1) ? rand(-9, -1) : rand(1, 9)) / 100));
$variables['items'][0]['content'][0]['#coordinates']['lng'] = (string) ($lng + ((rand(0, 1) ? rand(-9, -1) : rand(1, 9)) / 100));
}
}
}
}
}
/**
* Implements hook_views_post_render().
*/
function social_geolocation_maps_views_post_render(ViewExecutable $view, &$output, CachePluginBase $cache): void {
if (in_array($view->current_display, ['block_upcomming_events_map', 'block_community_events_map']) && $view->id() === 'social_geolocation_leaflet_commonmap_with_marker_icons' && isset($output['#rows'])) {
$social_event_settings = \Drupal::config('social_event.settings');
$address_visibility_settings = $social_event_settings->get('address_visibility_settings');
if (!isset($address_visibility_settings['street_code_private']) || empty($address_visibility_settings['street_code_private'])) {
return;
}
if (empty($output['#rows']['locations'])) {
return;
}
foreach ($output['#rows']['locations'] as &$location) {
$entity = $location['content']['#node'];
if ($entity && $entity instanceof NodeInterface && $entity->getType() === 'event') {
if (!_social_event_get_enrollment_status($entity) && isset($location['#position'])) {
$lat = $location['#position']['lat'];
$lng = $location['#position']['lng'];
$location['#position']['lat'] = (string) ($lat + (rand(-9, 9) / 100));
$location['#position']['lng'] = (string) ($lng + (rand(-9, 9) / 100));
}
}
}
}
}
/**
* Implements hook_preprocess_HOOK() for "group--small-teaser.html.twig".
*/
function social_geolocation_maps_preprocess_group__small_teaser(array &$variables): void {
// Location (City/Country) field should be displayed in the group popup and
// only on the "/all-groups" page.
if (\Drupal::routeMatch()->getRouteName() !== 'view.newest_groups.page_all_groups') {
return;
}
/** @var \Drupal\group\Entity\GroupInterface $group */
$group = $variables['group'];
if ($group instanceof GroupInterface && !$group->hasField('field_group_address')) {
return;
}
// Display City/Country field.
if (!$group->get('field_group_address')->isEmpty() && $group->get('field_group_address')->first()) {
$address = $group->get('field_group_address')->first()->getValue();
if (is_array($address)) {
$variables['location'] = _social_geolocation_maps_get_address($address);
}
}
}
/**
* Converts an address field value to a formatted string.
*
* @param array $address
* The address field value array.
*
* @return string
* The "City/Country" that can be displayed in the popup of group map.
*/
function _social_geolocation_maps_get_address(array $address): string {
$countries = \Drupal::service('address.country_repository')->getList();
$country = $address['country_code'];
if (isset($countries[$country])) {
$country = $countries[$country];
}
$formatted_address = [
$address['locality'],
$country,
];
return implode(', ', array_filter($formatted_address));
}
/**
* Implements hook_theme().
*/
function social_geolocation_maps_theme(): array {
$blocks = [
'block__social_geolocation_map',
'block__social_geolocation_groups_groups_map_block',
'block__social_geolocation_members_members_map_block',
'block_community_events_map',
];
$templates = [];
foreach ($blocks as $block) {
$templates['big_pipe_interface_preview__block__views_' . $block] = [
'variables' => [
'callback' => NULL,
'arguments' => NULL,
]
];
}
return $templates;
}
