<?php

/**
 * @file
 * Install, update and uninstall functions for the social_page module.
 */

use Drupal\Core\Config\FileStorage;
use Drupal\user\RoleInterface;
use Symfony\Component\Yaml\Yaml;

/**
 * Implements hook_install().
 *
 * Perform actions related to the installation of social_page.
 */
function social_page_install() {
  // Grant the default permissions for this feature.
  user_role_grant_permissions(
    RoleInterface::ANONYMOUS_ID,
    [
      'view node.page.field_content_visibility:public content',
    ]
  );
  user_role_grant_permissions(
    RoleInterface::AUTHENTICATED_ID,
    [
      'view node.page.field_content_visibility:public content',
    ]
  );
  user_role_grant_permissions(
    'verified',
    [
      'view node.page.field_content_visibility:community content',
    ]
  );
  user_role_grant_permissions(
    'contentmanager',
    [
      'view node.page.field_content_visibility:community content',
      'create page content',
      'delete any page content',
      'delete own page content',
      'edit any page content',
      'edit own page content',
      'view page revisions',
      'delete page revisions',
      'revert page revisions',
      'override page authored by option',
      'override page published option',
      'override page authored on option',
      'override page promote to front page option',
      'override page revision option',
      'override page sticky option',
    ]
  );
  user_role_grant_permissions(
    'sitemanager',
    [
      'view node.page.field_content_visibility:community content',
      'create page content',
      'delete any page content',
      'delete own page content',
      'edit any page content',
      'edit own page content',
      'view page revisions',
      'delete page revisions',
      'revert page revisions',
      'override page authored by option',
      'override page published option',
      'override page authored on option',
      'override page promote to front page option',
      'override page revision option',
      'override page sticky option',
      'administer visibility settings',
    ]
  );
}

/**
 * Implements hook_update_dependencies().
 */
function social_page_update_dependencies() {
  // New config changes should run after the update helper module is enabled.
  $dependencies['social_page'][8801] = [
    'social_core' => 8805,
  ];

  // New image style change should run after the new image style is imported.
  $dependencies['social_page'][8907] = [
    'social_core' => 8908,
  ];

  return $dependencies;
}

/**
 * Ensure the hero image field label is not visible.
 */
function social_page_update_8001() {
  /** @var \Drupal\update_helper\Updater $updateHelper */
  $updateHelper = \Drupal::service('update_helper.updater');

  // Execute configuration update definitions with logging of success.
  $updateHelper->executeUpdate('social_page', 'social_page_update_8001');

  // Output logged messages to related channel of update execution.
  return $updateHelper->logger()->output();
}

/**
 * Hide image label in teasers.
 */
function social_page_update_8002() {
  /** @var \Drupal\update_helper\Updater $updateHelper */
  $updateHelper = \Drupal::service('update_helper.updater');

  // Execute configuration update definitions with logging of success.
  $updateHelper->executeUpdate('social_page', 'social_page_update_8002');

  // Output logged messages to related channel of update execution.
  return $updateHelper->logger()->output();
}

/**
 * Empty, moved to social_page_update_8907().
 */
function social_page_update_8903() {
  // Code has been moved to social_page_update_8907().
}

/**
 * Add image file extensions to be added as attachments.
 */
function social_page_update_8904() {
  $config_file = \Drupal::service('extension.list.module')->getPath('social_page') . '/config/static/field.field.node.page.field_files_8904.yml';

  if (is_file($config_file)) {
    $settings = Yaml::parse(file_get_contents($config_file));
    if (is_array($settings)) {
      $config = \Drupal::configFactory()
        ->getEditable('field.field.node.page.field_files');

      $config->setData($settings)->save(TRUE);
    }
  }
}

/**
 * Updated fieldsets and field arrangement in entity form view of basic page.
 */
function social_page_update_8905() {
  /** @var \Drupal\update_helper\Updater $updateHelper */
  $updateHelper = \Drupal::service('update_helper.updater');

  // Execute configuration update definitions with logging of success.
  $updateHelper->executeUpdate('social_page', 'social_page_update_8905');

  // Output logged messages to related channel of update execution.
  return $updateHelper->logger()->output();
}

/**
 * Remove group_topic_description fieldgroup from topic content type.
 */
function social_page_update_8906() {
  // There can be possibility that someone might have added fields in
  // fieldgroup we are removing. So, we want to skip removal if there are any
  // children present in fieldgroup.
  $group = field_group_load_field_group('group_page_description', 'node', 'page', 'form', 'default');
  if ($group && empty($group->children)) {
    field_group_delete_field_group($group);
  }
}

/**
 * Show thumbnail on File fields when attachment is an image.
 */
function social_page_update_8907() {
  $config_file = \Drupal::service('extension.list.module')->getPath('social_page') . '/config/static/core.entity_view_display.node.page.default_8907.yml';

  if (is_file($config_file)) {
    $settings = Yaml::parse(file_get_contents($config_file));
    if (is_array($settings)) {
      $config = \Drupal::configFactory()
        ->getEditable('core.entity_view_display.node.page.default');

      $config->setData($settings)->save(TRUE);
    }
  }
}

/**
 * Add small_teaser view mode for page.
 */
function social_page_update_8908() {
  $config_path = \Drupal::service('extension.list.module')->getPath('social_page') . '/config/static';
  $source = new FileStorage($config_path);
  /** @var \Drupal\Core\Config\StorageInterface $config_storage */
  $config_storage = \Drupal::service('config.storage');
  $config_storage->write(
    'core.entity_view_display.node.page.small_teaser',
    $source->read('social_page_static_update_8908')
  );
}

/**
 * Updated basic page form labels.
 */
function social_page_update_10201() {
  /** @var \Drupal\update_helper\Updater $updateHelper */
  $updateHelper = \Drupal::service('update_helper.updater');

  // Execute configuration update definitions with logging of success.
  $updateHelper->executeUpdate('social_page', 'social_page_update_10201');

  // Output logged messages to related channel of update execution.
  return $updateHelper->logger()->output();
}

/**
 * Allow CM+ translate "Basic Page" node type.
 */
function social_page_update_10301() {
  foreach (['sitemanager', 'contentmanager'] as $role_id) {
    user_role_grant_permissions($role_id, ['translate page node']);
  }
}

/**
 * Remove layout_builder settings from small_teaser view mode for page.
 */
function social_page_update_10302() {
  $config = \Drupal::configFactory()->getEditable('core.entity_view_display.node.page.small_teaser');
  $config->set('third_party_settings', [])->save();
}

/**
 * Remove deprecated permission "override page revision log entry".
 */
function social_page_update_111101(): void {
  $entity_type_manager = \Drupal::entityTypeManager();
  /** @var \Drupal\user\RoleInterface[] $roles */
  $roles = $entity_type_manager->getStorage('user_role')->loadMultiple();

  $deprecated_permissions = [
    'override page revision log entry',
  ];

  foreach ($deprecated_permissions as $deprecated_permission) {
    foreach ($roles as $role) {
      if ($role->hasPermission($deprecated_permission)) {
        $role->revokePermission($deprecated_permission);
        $role->save();
      }
    }
  }
}

/**
 * Search for invalid permission(s) and remove them from existing roles.
 *
 * Permissions to check:
 * - "translate page node".
 */
function social_page_update_111102(): void {
  $entity_type_manager = \Drupal::entityTypeManager();
  $all_permissions = array_keys(\Drupal::service('user.permissions')->getPermissions());
  /** @var \Drupal\user\RoleInterface[] $roles */
  $roles = $entity_type_manager->getStorage('user_role')->loadMultiple();

  $permissions_to_check = [
    'translate page node',
  ];

  // If permission is not valid (is not on the list of all permissions),
  // we need to revoke it from all existing roles.
  foreach ($permissions_to_check as $permission_to_check) {
    if (!in_array($permission_to_check, $all_permissions)) {
      foreach ($roles as $role) {
        if ($role->hasPermission($permission_to_check)) {
          $role->revokePermission($permission_to_check);
          $role->save();
        }
      }
    }
  }
}
