diff --git a/.gitignore b/.gitignore index 2adf16bf34..245d03fbd6 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,5 @@ /.gitattributes .env **/.DS_Store + +*.sql diff --git a/docker/php/Dockerfile b/docker/php/Dockerfile index 03e734047d..7c1efad187 100644 --- a/docker/php/Dockerfile +++ b/docker/php/Dockerfile @@ -32,9 +32,9 @@ RUN docker-php-ext-configure gd --with-freetype --with-jpeg \ RUN apt-get update -y; \ apt-get install mariadb-client -y; \ - pecl install apcu; \ + pecl install xdebug-3.1.5 apcu; \ docker-php-ext-install pdo_mysql; \ - docker-php-ext-enable apcu; \ + docker-php-ext-enable xdebug apcu; \ pecl clear-cache; # Change the fpm user diff --git a/lib/modules/eic_groups/eic_groups.module b/lib/modules/eic_groups/eic_groups.module index e39f92aca3..29ee6acbeb 100644 --- a/lib/modules/eic_groups/eic_groups.module +++ b/lib/modules/eic_groups/eic_groups.module @@ -102,7 +102,10 @@ function eic_groups_theme($existing, $type, $theme, $path) { /** * Implements hook_eic_groups_group_feature_public_alter(). */ -function eic_groups_eic_groups_group_feature_public_alter(bool &$is_publicly_available, array $context) { +function eic_groups_eic_groups_group_feature_public_alter( + bool &$is_publicly_available, + array $context +) { /** @var \Drupal\group\Entity\GroupInterface $group */ $group = $context['group']; @@ -118,7 +121,10 @@ function eic_groups_eic_groups_group_feature_public_alter(bool &$is_publicly_ava /** * Implements hook_oec_group_flex_plugin_permission_alter(). */ -function eic_groups_oec_group_flex_plugin_permission_alter(bool &$is_allowed, array $context) { +function eic_groups_oec_group_flex_plugin_permission_alter( + bool &$is_allowed, + array $context +) { /** @var \Drupal\group\Entity\GroupInterface $group */ $group = $context['group']; /** @var \Drupal\group\Entity\GroupRoleInterface $role */ @@ -153,14 +159,18 @@ function eic_groups_views_data() { ]; $data['groups_field_data']['group_visibility_custom_restricted_organisations'] = [ 'title' => t('Visibility Custom: Restricted organisations'), - 'help' => t('The chosen organisations for group Custom - Restricted email organisations.'), + 'help' => t( + 'The chosen organisations for group Custom - Restricted email organisations.' + ), 'field' => [ 'id' => 'group_visibility_custom_restricted_organisations', ], ]; $data['groups_field_data']['group_visibility_custom_restricted_organisation_types'] = [ 'title' => t('Visibility Custom: Restricted organisations types'), - 'help' => t('The chosen organisation types for group Custom - Restricted email organisations types.'), + 'help' => t( + 'The chosen organisation types for group Custom - Restricted email organisations types.' + ), 'field' => [ 'id' => 'group_visibility_custom_restricted_organisation_types', ], @@ -192,7 +202,8 @@ function eic_groups_preprocess_views_view_field(&$vars) { $group = $group_content->getGroup(); // Get the group visibility. - $group_visibility = \Drupal::service('eic_groups.helper')->getGroupVisibilityLabel($group); + $group_visibility = \Drupal::service('eic_groups.helper') + ->getGroupVisibilityLabel($group); // Check if user has access to the group. if ($group->access('view')) { @@ -230,17 +241,24 @@ function eic_groups_group_content_insert(EntityInterface $entity) { // Re-creates URL alias of the group content related entity if pathauto // settings "update_action" setting is set to 0 (UPDATE_ACTION_NO_NEW). if ( - $pathauto_config->get('update_action') === PathautoGeneratorInterface::UPDATE_ACTION_NO_NEW && + $pathauto_config->get( + 'update_action' + ) === PathautoGeneratorInterface::UPDATE_ACTION_NO_NEW && $related_entity->hasLinkTemplate('canonical') && $related_entity instanceof ContentEntityInterface && $related_entity->hasField('path') && $related_entity->getFieldDefinition('path')->getType() == 'path' ) { // Deletes old alias. - \Drupal::service('pathauto.alias_storage_helper')->deleteEntityPathAll($related_entity); + \Drupal::service('pathauto.alias_storage_helper')->deleteEntityPathAll( + $related_entity + ); $related_entity->get('path')->first()->get('pathauto')->purge(); // Re-create entity alias. - \Drupal::service('pathauto.generator')->createEntityAlias($related_entity, 'insert_group_content_node'); + \Drupal::service('pathauto.generator')->createEntityAlias( + $related_entity, + 'insert_group_content_node' + ); } $bundle_resync_group = [ @@ -279,7 +297,8 @@ function eic_groups_group_content_insert(EntityInterface $entity) { */ function eic_groups_node_update(EntityInterface $entity) { /** @var \Drupal\group\Entity\GroupContentInterface[] $group_contents */ - $group_contents = \Drupal::service('eic_content.helper')->getGroupContentByEntity($entity, [], ["group_node:{$entity->bundle()}"]); + $group_contents = \Drupal::service('eic_content.helper') + ->getGroupContentByEntity($entity, [], ["group_node:{$entity->bundle()}"]); if (empty($group_contents)) { return; @@ -314,7 +333,12 @@ function eic_groups_group_view( /** * Implements hook_ENTITY_TYPE_view(). */ -function eic_groups_node_view(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display, $view_mode) { +function eic_groups_node_view( + array &$build, + EntityInterface $entity, + EntityViewDisplayInterface $display, + $view_mode +) { \Drupal::classResolver(EntityOperations::class) ->nodeView($build, $entity, $display, $view_mode); } @@ -322,7 +346,11 @@ function eic_groups_node_view(array &$build, EntityInterface $entity, EntityView /** * Implements hook_form_BASE_FORM_ID_alter(). */ -function eic_groups_form_group_form_alter(&$form, FormStateInterface $form_state, $form_id) { +function eic_groups_form_group_form_alter( + &$form, + FormStateInterface $form_state, + $form_id +) { // Act on group add forms. if ($form_state->getFormObject()->getOperation() == 'add') { \Drupal::classResolver(FormOperations::class) @@ -361,7 +389,10 @@ function eic_groups_form_group_form_alter(&$form, FormStateInterface $form_state // If the group is not yet blocked, we remove the possibility to block it // from the group edit form. if ($moderation_state !== GroupsModerationHelper::GROUP_BLOCKED_STATE) { - if (\Drupal::service('eic_flags.block_request_handler')->canRequest($current_user->getAccount(), $entity)) { + if (\Drupal::service('eic_flags.block_request_handler')->canRequest( + $current_user->getAccount(), + $entity + )) { if (isset($form['moderation_state']['widget'][0]['state']['#options'][GroupsModerationHelper::GROUP_BLOCKED_STATE])) { unset($form['moderation_state']['widget'][0]['state']['#options'][GroupsModerationHelper::GROUP_BLOCKED_STATE]); } @@ -373,7 +404,10 @@ function eic_groups_form_group_form_alter(&$form, FormStateInterface $form_state /** * Custom submit handler for form_group forms. */ -function eic_groups_group_form_submit(array $form, FormStateInterface $form_state) { +function eic_groups_group_form_submit( + array $form, + FormStateInterface $form_state +) { \Drupal::classResolver(FormOperations::class) ->formGroupSubmit($form, $form_state); } @@ -399,11 +433,16 @@ function eic_groups_module_implements_alter(&$implementations, $hook) { /** * Implements hook_form_alter(). */ -function eic_groups_form_alter(&$form, FormStateInterface $form_state, $form_id) { +function eic_groups_form_alter( + &$form, + FormStateInterface $form_state, + $form_id +) { // Get group types. $group_types = []; /** @var \Drupal\group\Entity\GroupTypeInterface $group_type */ - foreach (\Drupal::service('eic_groups.helper')->getGroupTypes() as $group_type) { + foreach (\Drupal::service('eic_groups.helper')->getGroupTypes( + ) as $group_type) { $group_types[] = $group_type->id(); } @@ -460,7 +499,13 @@ function eic_groups_token_info() { /** * Implements hook_tokens(). */ -function eic_groups_tokens($type, $tokens, array $data, array $options, BubbleableMetadata $bubbleable_metadata) { +function eic_groups_tokens( + $type, + $tokens, + array $data, + array $options, + BubbleableMetadata $bubbleable_metadata +) { /** @var \Drupal\eic_groups\Hooks\GroupTokens $class */ $class = \Drupal::classResolver(GroupTokens::class); return $class->tokens($type, $tokens, $data, $options, $bubbleable_metadata); @@ -507,7 +552,11 @@ function eic_groups_entity_field_access( /** * Implements hook_ENTITY_TYPE_access(). */ -function eic_groups_group_access(EntityInterface $entity, $operation, AccountInterface $account) { +function eic_groups_group_access( + EntityInterface $entity, + $operation, + AccountInterface $account +) { $access = GroupAccessResult::neutral(); $moderation_state = $entity->get('moderation_state')->value; @@ -530,7 +579,11 @@ function eic_groups_group_access(EntityInterface $entity, $operation, AccountInt } // User is a group admin, therefore we should allow access. - if ($membership && EICGroupsHelper::userIsGroupAdmin($entity, $account, $membership)) { + if ($membership && EICGroupsHelper::userIsGroupAdmin( + $entity, + $account, + $membership + )) { $is_group_admin = TRUE; } @@ -557,7 +610,11 @@ function eic_groups_group_access(EntityInterface $entity, $operation, AccountInt $is_group_admin = FALSE; // User is a group admin, therefore we should allow access. - if ($membership && EICGroupsHelper::userIsGroupAdmin($entity, $account, $membership)) { + if ($membership && EICGroupsHelper::userIsGroupAdmin( + $entity, + $account, + $membership + )) { $is_group_admin = TRUE; } @@ -585,7 +642,10 @@ function eic_groups_group_access(EntityInterface $entity, $operation, AccountInt case 'delete': // Deny access to delete group if the group is NOT in pending state and // the user is NOT a poweruser. - if ($moderation_state !== GroupsModerationHelper::GROUP_PENDING_STATE) { + if ( + $moderation_state !== GroupsModerationHelper::GROUP_PENDING_STATE && + !UserHelper::isPowerUser($account) + ) { $access = GroupAccessResult::forbidden() ->addCacheableDependency($account) ->addCacheableDependency($entity); @@ -623,7 +683,11 @@ function eic_groups_group_content_info_alter(array &$definitions) { /** * Implements hook_ENTITY_TYPE_access(). */ -function eic_groups_flagging_access(EntityInterface $entity, $operation, AccountInterface $account) { +function eic_groups_flagging_access( + EntityInterface $entity, + $operation, + AccountInterface $account +) { $access = AccessResult::neutral(); $flagged_entity = $entity->get('flagged_entity')->entity; @@ -680,13 +744,19 @@ function eic_groups_flagging_access(EntityInterface $entity, $operation, Account /** * Implements hook_entity_operation_alter(). */ -function eic_groups_entity_operation_alter(array &$operations, EntityInterface $entity) { +function eic_groups_entity_operation_alter( + array &$operations, + EntityInterface $entity +) { if ($entity->getEntityTypeId() !== 'group') { return; } // Add publish group operation. - $publish_url = Url::fromRoute('eic_groups.group.publish.confirm_form', ['group' => $entity->id()]); + $publish_url = Url::fromRoute( + 'eic_groups.group.publish.confirm_form', + ['group' => $entity->id()] + ); if ($publish_url->access()) { $operations['publish'] = [ 'title' => t('Publish'), @@ -701,7 +771,10 @@ function eic_groups_entity_operation_alter(array &$operations, EntityInterface $ */ function eic_groups_preprocess_block__group_content_menu(&$variables) { $block_manager = \Drupal::service('plugin.manager.block'); - $plugin_block = $block_manager->createInstance('eic_groups_search_menu_group', []); + $plugin_block = $block_manager->createInstance( + 'eic_groups_search_menu_group', + [] + ); $variables['search_block'] = $plugin_block->build(); } @@ -742,12 +815,18 @@ function eic_groups_entity_base_field_info(EntityTypeInterface $entity_type) { $fields = []; if ($entity_type->id() === 'node') { - $fields[NodeProperty::MEMBER_CONTENT_EDIT_ACCESS] = BaseFieldDefinition::create('boolean') + $fields[NodeProperty::MEMBER_CONTENT_EDIT_ACCESS] = BaseFieldDefinition::create( + 'boolean' + ) ->setLabel(t('Editable by members')) ->setName(NodeProperty::MEMBER_CONTENT_EDIT_ACCESS) ->setRevisionable(TRUE) ->setDefaultValue(FALSE) - ->setDescription(t('When checked, group members are able to edit the content of this page.')) + ->setDescription( + t( + 'When checked, group members are able to edit the content of this page.' + ) + ) ->setDisplayOptions('view', ['weight' => 1]) ->setDisplayOptions('form', ['weight' => 1]) ->setDisplayConfigurable('form', TRUE) @@ -770,7 +849,9 @@ function eic_groups_entity_predelete(EntityInterface $entity) { // from the group permission entity. At that point the group has already been // deleted which means it cannot retrieve the canonical url of the group // permissions since it requires the group ID as route parameter. - if ($group_permissions = \Drupal::service('group_permission.group_permissions_manager')->loadByGroup($entity)) { + if ($group_permissions = \Drupal::service( + 'group_permission.group_permissions_manager' + )->loadByGroup($entity)) { $group_permissions->delete(); } } @@ -936,7 +1017,11 @@ function eic_groups_flag_action_access( /** * Implements hook_overview_page_access(). */ -function eic_groups_overview_page_access(EntityInterface $entity, $operation, AccountInterface $account) { +function eic_groups_overview_page_access( + EntityInterface $entity, + $operation, + AccountInterface $account +) { $overview_type_id = $entity->get('field_overview_id')->value; $overview_type_forbidden_anonymous = [ GlobalOverviewPages::ORGANISATIONS, @@ -964,11 +1049,17 @@ function eic_groups_entity_operation(EntityInterface $entity) { } $current_user = \Drupal::currentUser(); - if ($entity->hasPermission('view group_membership content', $current_user->getAccount())) { + if ($entity->hasPermission( + 'view group_membership content', + $current_user->getAccount() + )) { return [ 'edit-members' => [ 'title' => t('Edit members'), - 'url' => Url::fromRoute('view.eic_group_members.page_group_members', ['group' => $entity->id()]), + 'url' => Url::fromRoute( + 'view.eic_group_members.page_group_members', + ['group' => $entity->id()] + ), ], ]; } @@ -1003,7 +1094,9 @@ function eic_groups_views_pre_render(ViewExecutable $view) { function eic_groups_metatags_alter(array &$metatags, array &$context) { // Includes group title in the node metatags. if (\Drupal::routeMatch()->getRouteName() === 'entity.node.canonical') { - if($group = \Drupal::service('eic_groups.helper')->getOwnerGroupByEntity($context['entity'])) { + if ($group = \Drupal::service('eic_groups.helper')->getOwnerGroupByEntity( + $context['entity'] + )) { $metatags['title'] = $metatags['og_title'] = "[current-page:title] | {$group->label()} | [site:name]"; } } @@ -1015,18 +1108,18 @@ function eic_groups_metatags_alter(array &$metatags, array &$context) { * @param \Drupal\Core\Entity\EntityInterface $entity * * @return void - * @throws \Drupal\Core\Entity\EntityStorageException */ function eic_groups_entity_delete(\Drupal\Core\Entity\EntityInterface $entity) { // We delete only nodes. - if (!$entity instanceof \Drupal\group\Entity\GroupContentInterface || !$entity->getEntity() instanceof \Drupal\node\NodeInterface) { + if (!$entity instanceof \Drupal\group\Entity\GroupContentInterface || !$entity->getEntity( + ) instanceof \Drupal\node\NodeInterface) { return; } $node = $entity->getEntity(); - $title = $entity->label(); - $node->delete(); - - \Drupal::messenger()->addMessage('The content: ' . $title . ' has been deleted.'); + $queue = \Drupal::service('queue')->get( + CronOperations::REMOVE_CONTENT_API_QUEUE + ); + $queue->createItem($node->id()); } diff --git a/lib/modules/eic_groups/src/Hooks/CronOperations.php b/lib/modules/eic_groups/src/Hooks/CronOperations.php index 1016a6809e..951139c14e 100644 --- a/lib/modules/eic_groups/src/Hooks/CronOperations.php +++ b/lib/modules/eic_groups/src/Hooks/CronOperations.php @@ -55,6 +55,11 @@ class CronOperations implements ContainerInjectionInterface { */ const REINDEX_CONTENT_SEARCH_API_QUEUE = 'eic_groups_reindex_content'; + /** + * Reindex content search api queue name. + */ + const REMOVE_CONTENT_API_QUEUE = 'eic_group_remove_content'; + /** * Reindex content search api queue name. */ @@ -192,6 +197,7 @@ public function cron() { $this->processGroupWaitingApprovalReminder(); $this->processGroupInvitationsReminder(); $this->processContentSolrReindex(); + $this->processGroupContentRemove(); } /** @@ -458,4 +464,24 @@ private function processContentSolrReindex() { } } + /** + * Trigger queue each minutes to remove content in the background. + * + * @throws \Drupal\Component\Plugin\Exception\PluginException + */ + private function processGroupContentRemove() { + $queue = $this->queueFactory->get(self::REMOVE_CONTENT_API_QUEUE); + $queue_worker = $this->queueManager->createInstance(self::REMOVE_CONTENT_API_QUEUE); + + while ($item = $queue->claimItem()) { + try { + $queue_worker->processItem($item->data); + $queue->deleteItem($item); + } catch (SuspendQueueException $e) { + $queue->releaseItem($item); + break; + } + } + } + } diff --git a/lib/modules/eic_groups/src/Plugin/QueueWorker/RemoveGroupContentApi.php b/lib/modules/eic_groups/src/Plugin/QueueWorker/RemoveGroupContentApi.php new file mode 100644 index 0000000000..cf8120ad01 --- /dev/null +++ b/lib/modules/eic_groups/src/Plugin/QueueWorker/RemoveGroupContentApi.php @@ -0,0 +1,53 @@ +bundle() === 'document') { + $media = $node->get('field_document_media')->entity; + + if ($media instanceof MediaInterface) { + // Loads up the entity usage for the media. + $media_usage = \Drupal::service('entity_usage.usage')->listSources($media); + + $count = 0; + + foreach ($media_usage as $usage) { + $count += count($usage); + } + + if ($count <= 1) { + $media->delete(); + } + } + } + + $node->delete(); + } + +}