<?php

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

use Drupal\Core\Extension\Extension;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\field\Entity\FieldConfig;
use Drupal\field\Entity\FieldStorageConfig;
use Drupal\field\FieldConfigInterface;
use Drupal\user\RoleInterface;

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

/**
 * Enable the Social Featured Items module.
 */
function social_landing_page_update_8801() {
  $module = 'social_featured_items';
  // We don't actually install the module because this would cause issues with
  // configuration already existing. The configuration has been moved from this
  // module to the separate sub module so we simply mark the module as enabled.
  $extension_config = \Drupal::configFactory()->getEditable('core.extension');
  // Only enable the module if it's not installed already.
  if ($extension_config->get("module.$module") !== NULL) {
    // Nothing to do.
    return;
  }

  // Mark the module as enabled. From ModuleInstaller::install().
  $extension_config
    ->set("module.$module", 0)
    ->set('module', module_config_sort($extension_config->get('module')))
    ->save(TRUE);

  // Prepare the new module list, sorted by weight, including filenames.
  // This list is used for both the ModuleHandler and DrupalKernel. It
  // needs to be kept in sync between both. A DrupalKernel reboot or
  // rebuild will automatically re-instantiate a new ModuleHandler that
  // uses the new module list of the kernel. However, DrupalKernel does
  // not cause any modules to be loaded.
  // Furthermore, the currently active (fixed) module list can be
  // different from the configured list of enabled modules. For all active
  // modules not contained in the configured enabled modules, we assume a
  // weight of 0.
  $current_module_filenames = \Drupal::moduleHandler()->getModuleList();
  $current_modules = array_fill_keys(array_keys($current_module_filenames), 0);
  $current_modules = module_config_sort(array_merge($current_modules, $extension_config->get('module')));
  $module_filenames = [];
  foreach ($current_modules as $name => $weight) {
    if (isset($current_module_filenames[$name])) {
      $module_filenames[$name] = $current_module_filenames[$name];
    }
    else {
      $module_path = \Drupal::service('extension.list.module')->getPath($name);
      $pathname = "$module_path/$name.info.yml";
      $filename = file_exists($module_path . "/$name.module") ? "$name.module" : NULL;
      $module_filenames[$name] = new Extension(\Drupal::root(), 'module', $pathname, $filename);
    }
  }

  // Update the module handler in order to load the module's code.
  // This allows the module to participate in hooks and its existence to
  // be discovered by other modules.
  // The current ModuleHandler instance is obsolete with the kernel
  // rebuild below.
  \Drupal::moduleHandler()->setModuleList($module_filenames);
  \Drupal::moduleHandler()->load($module);
  // No need to module_load_install($module); since there is no such file.
  //
  // Clear the static cache of the "extension.list.module" service to pick
  // up the new module, since it merges the installation status of modules
  // into its statically cached list.
  \Drupal::service('extension.list.module')->reset();

  // Given that we know that the module only contains existing configuration at
  // this point we don't need to go through the rest of the install process.
}

/**
 * Import new block type for featured items.
 */
function social_landing_page_update_8802() {
  // This creates some new configuration that can be used by the dashboard
  // module. This is done in this module because we also enable the
  // social_featured_items module. If that module is enabled through another
  // module then that will take care of the module installation.
  $configs = _social_landing_page_featured_items_config();

  foreach ($configs as $name => $config) {
    \Drupal::configFactory()
      ->getEditable($name)
      ->setData($config)
      ->save(TRUE);
  }
}

/**
 * Returns the featured item block config details.
 *
 * @return array
 *   Contains the config details.
 */
function _social_landing_page_featured_items_config() {
  return [
    'block_content.type.featured_items' => [
      'langcode' => 'en',
      'status' => TRUE,
      'dependencies' => [],
      'id' => 'featured_items',
      'label' => t('Featured Items'),
      'revision' => 0,
      'description' => 'A list of featured items that can have a title, link, image/icon, and description.',
    ],
    'field.storage.block_content.field_featured_items' => [
      'langcode' => 'en',
      'status' => TRUE,
      'dependencies' => [
        'module' => [
          'block_content',
          'entity_reference_revisions',
          'paragraphs',
        ],
      ],
      'id' => 'block_content.field_featured_items',
      'field_name' => 'field_featured_items',
      'entity_type' => 'block_content',
      'type' => 'entity_reference_revisions',
      'settings' => [
        'target_type' => 'paragraph',
      ],
      'module' => 'entity_reference_revisions',
      'locked' => FALSE,
      'cardinality' => -1,
      'translatable' => TRUE,
      'indexes' => [],
      'persist_with_no_fields' => FALSE,
      'custom_storage' => FALSE,
    ],
    'field.field.block_content.featured_items.field_featured_items' => [
      'langcode' => 'en',
      'status' => TRUE,
      'dependencies' => [
        'config' => [
          'block_content.type.featured_items',
          'field.storage.block_content.field_featured_items',
          'paragraphs.paragraphs_type.featured_item',
        ],
        'module' => [
          'entity_reference_revisions',
        ],
      ],
      'id' => 'block_content.featured_items.field_featured_items',
      'field_name' => 'field_featured_items',
      'entity_type' => 'block_content',
      'bundle' => 'featured_items',
      'label' => t('Featured Items'),
      'description' => '',
      'required' => TRUE,
      'translatable' => TRUE,
      'default_value' => [],
      'default_value_callback' => '',
      'settings' => [
        'handler' => 'default:paragraph',
        'handler_settings' => [
          'negate' => 0,
          'target_bundles' => [
            'featured_item' => 'featured_item',
          ],
          'target_bundles_drag_drop' => [
            'featured_item' => [
              'enabled' => TRUE,
              'weight' => 3,
            ],
            'featured_items' => [
              'weight' => 4,
              'enabled' => FALSE,
            ],
          ],
        ],
      ],
      'field_type' => 'entity_reference_revisions',
    ],
    'core.entity_form_display.block_content.featured_items.default' => [
      'langcode' => 'en',
      'status' => TRUE,
      'dependencies' => [
        'config' => [
          'block_content.type.featured_items',
          'field.field.block_content.featured_items.field_featured_items',
        ],
        'module' => [
          'paragraphs',
        ],
      ],
      'id' => 'block_content.featured_items.default',
      'targetEntityType' => 'block_content',
      'bundle' => 'featured_items',
      'mode' => 'default',
      'content' => [
        'field_featured_items' => [
          'type' => 'entity_reference_paragraphs',
          'weight' => 27,
          'settings' => [
            'title' => t('Paragraph'),
            'title_plural' => t('Paragraphs'),
            'edit_mode' => 'open',
            'add_mode' => 'dropdown',
            'form_display_mode' => 'default',
            'default_paragraph_type' => '',
          ],
          'third_party_settings' => [],
          'region' => 'content',
        ],
        'info' => [
          'type' => 'string_textfield',
          'weight' => -5,
          'region' => 'content',
          'settings' => [
            'size' => 60,
            'placeholder' => '',
          ],
          'third_party_settings' => [],
        ],
      ],
      'hidden' => [],
    ],
    'core.entity_view_display.block_content.featured_items.default' => [
      'langcode' => 'en',
      'status' => TRUE,
      'dependencies' => [
        'config' => [
          'block_content.type.featured_items',
          'field.field.block_content.featured_items.field_featured_items',
        ],
        'module' => [
          'entity_reference_revisions',
        ],
      ],
      'id' => 'block_content.featured_items.default',
      'targetEntityType' => 'block_content',
      'bundle' => 'featured_items',
      'mode' => 'default',
      'content' => [
        'field_featured_items' => [
          'type' => 'entity_reference_revisions_entity_view',
          'weight' => 1,
          'label' => 'hidden',
          'settings' => [
            'view_mode' => 'default',
            'link' => '',
          ],
          'third_party_settings' => [],
          'region' => 'content',
        ],
      ],
    ],
  ];
}

/**
 * Update fields for featured items.
 */
function social_landing_page_update_8803() {
  // Delete our last attempt in reverse order.
  $configs = array_reverse(_social_landing_page_featured_items_config());

  foreach ($configs as $name => $config) {
    \Drupal::configFactory()->getEditable($name)->delete();
  }

  // Re-create it now with better usage of config.
  // In the last we used the ConfigInterface
  // for Fields and FieldStorage we need to do better.
  $new_config = _social_landing_page_featured_items_config();
  foreach ($new_config as $name => $data) {
    $parts = explode('.', $name);
    switch ($parts[0] . '.' . $parts[1]) {
      case 'field.storage':
        FieldStorageConfig::create($data)->save();
        break;

      case 'field.field':
        $field_config = FieldConfig::loadByName($parts[2], $parts[3], $parts[4]);

        if (!$field_config instanceof FieldConfigInterface) {
          $field_config = FieldConfig::create($data);
        }

        $field_config->save();
        break;

      default:
        // Fallback similar to before.
        \Drupal::configFactory()
          ->getEditable($name)
          ->setData($data)
          ->save(TRUE);
    }
  }
}

/**
 * Add organization and function fields to profile featured teasers.
 */
function social_landing_page_update_8804() {
  /** @var \Drupal\update_helper\Updater $updateHelper */
  $updateHelper = \Drupal::service('update_helper.updater');

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

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

/**
 * Enable the Social Featured Content module.
 */
function social_landing_page_update_8805() {
  $module = 'social_featured_content';
  // We don't actually install the module because this would cause issues with
  // configuration already existing. The configuration has been moved from this
  // module to the separate sub module so we simply mark the module as enabled.
  $extension_config = \Drupal::configFactory()->getEditable('core.extension');
  // Only enable the module if it's not installed already.
  if ($extension_config->get("module.$module") !== NULL) {
    // Nothing to do.
    return;
  }

  // Mark the module as enabled. From ModuleInstaller::install().
  $extension_config
    ->set("module.$module", 0)
    ->set('module', module_config_sort($extension_config->get('module')))
    ->save(TRUE);

  // Prepare the new module list, sorted by weight, including filenames.
  // This list is used for both the ModuleHandler and DrupalKernel. It
  // needs to be kept in sync between both. A DrupalKernel reboot or
  // rebuild will automatically re-instantiate a new ModuleHandler that
  // uses the new module list of the kernel. However, DrupalKernel does
  // not cause any modules to be loaded.
  // Furthermore, the currently active (fixed) module list can be
  // different from the configured list of enabled modules. For all active
  // modules not contained in the configured enabled modules, we assume a
  // weight of 0.
  $current_module_filenames = \Drupal::moduleHandler()->getModuleList();
  $current_modules = array_fill_keys(array_keys($current_module_filenames), 0);
  $current_modules = module_config_sort(array_merge($current_modules, $extension_config->get('module')));
  $module_filenames = [];
  foreach ($current_modules as $name => $weight) {
    if (isset($current_module_filenames[$name])) {
      $module_filenames[$name] = $current_module_filenames[$name];
    }
    else {
      $module_path = \Drupal::service('extension.list.module')->getPath($name);
      $pathname = "$module_path/$name.info.yml";
      $filename = file_exists($module_path . "/$name.module") ? "$name.module" : NULL;
      $module_filenames[$name] = new Extension(\Drupal::root(), 'module', $pathname, $filename);
    }
  }

  // Update the module handler in order to load the module's code.
  // This allows the module to participate in hooks and its existence to
  // be discovered by other modules.
  // The current ModuleHandler instance is obsolete with the kernel
  // rebuild below.
  \Drupal::moduleHandler()->setModuleList($module_filenames);
  \Drupal::moduleHandler()->load($module);
  // No need to module_load_install($module); since there is no such file.
  //
  // Clear the static cache of the "extension.list.module" service to pick
  // up the new module, since it merges the installation status of modules
  // into its statically cached list.
  \Drupal::service('extension.list.module')->reset();

  // Given that we know that the module only contains existing configuration at
  // this point we don't need to go through the rest of the install process.
}

/**
 * Import new block type for featured content.
 */
function social_landing_page_update_8806() {
  // This creates some new configuration that can be used by the dashboard
  // module. This is done in this module because we also enable the
  // social_follow_content module. If that module is enabled through another
  // module then that will take care of the module installation.
  $configs = [
    'block_content.type.featured' => [
      'langcode' => 'en',
      'status' => TRUE,
      'dependencies' => [],
      'id' => 'featured',
      'label' => t('Featured Content'),
      'revision' => 0,
      'description' => 'A list of featured content that can have a title, link, group/node/profile, and description.',
    ],
    'field.storage' => [
      'langcode' => 'en',
      'status' => TRUE,
      'dependencies' => [
        'module' => [
          'block_content',
          'entity_reference_revisions',
          'paragraphs',
        ],
      ],
      'id' => 'block_content.field_featured',
      'field_name' => 'field_featured',
      'entity_type' => 'block_content',
      'type' => 'entity_reference_revisions',
      'settings' => [
        'target_type' => 'paragraph',
      ],
      'module' => 'entity_reference_revisions',
      'locked' => FALSE,
      'cardinality' => 1,
      'translatable' => TRUE,
      'indexes' => [],
      'persist_with_no_fields' => FALSE,
      'custom_storage' => FALSE,
    ],
    'field.field' => [
      'langcode' => 'en',
      'status' => TRUE,
      'dependencies' => [
        'config' => [
          'block_content.type.featured',
          'field.storage.block_content.field_featured',
          'paragraphs.paragraphs_type.featured',
        ],
        'module' => [
          'entity_reference_revisions',
        ],
      ],
      'id' => 'block_content.featured.field_featured',
      'field_name' => 'field_featured',
      'entity_type' => 'block_content',
      'bundle' => 'featured',
      'label' => t('Featured Content'),
      'description' => '',
      'required' => TRUE,
      'translatable' => FALSE,
      'default_value' => [],
      'default_value_callback' => '',
      'settings' => [
        'handler' => 'default:paragraph',
        'handler_settings' => [
          'negate' => 0,
          'target_bundles' => [
            'featured' => 'featured',
          ],
          'target_bundles_drag_drop' => [
            'featured' => [
              'enabled' => TRUE,
              'weight' => 0,
            ],
          ],
        ],
      ],
      'field_type' => 'entity_reference_revisions',
    ],
    'core.entity_form_display.block_content.featured.default' => [
      'langcode' => 'en',
      'status' => TRUE,
      'dependencies' => [
        'config' => [
          'block_content.type.featured',
          'field.field.block_content.featured.field_featured',
        ],
        'module' => [
          'paragraphs',
        ],
      ],
      'id' => 'block_content.featured.default',
      'targetEntityType' => 'block_content',
      'bundle' => 'featured',
      'mode' => 'default',
      'content' => [
        'field_featured' => [
          'type' => 'entity_reference_paragraphs',
          'weight' => 1,
          'settings' => [
            'title' => t('Paragraph'),
            'title_plural' => t('Paragraphs'),
            'edit_mode' => 'open',
            'add_mode' => 'dropdown',
            'form_display_mode' => 'default',
            'default_paragraph_type' => '',
          ],
          'third_party_settings' => [],
          'region' => 'content',
        ],
        'info' => [
          'type' => 'string_textfield',
          'weight' => 0,
          'region' => 'content',
          'settings' => [
            'size' => 60,
            'placeholder' => '',
          ],
          'third_party_settings' => [],
        ],
      ],
      'hidden' => [],
    ],
    'core.entity_view_display.block_content.featured.default' => [
      'langcode' => 'en',
      'status' => TRUE,
      'dependencies' => [
        'config' => [
          'block_content.type.featured',
          'field.field.block_content.featured.field_featured',
        ],
        'module' => [
          'entity_reference_revisions',
        ],
      ],
      'id' => 'block_content.featured.default',
      'targetEntityType' => 'block_content',
      'bundle' => 'featured',
      'mode' => 'default',
      'content' => [
        'field_featured' => [
          'type' => 'entity_reference_revisions_entity_view',
          'weight' => 0,
          'label' => 'hidden',
          'settings' => [
            'view_mode' => 'default',
            'link' => '',
          ],
          'third_party_settings' => [],
          'region' => 'content',
        ],
      ],
      'hidden' => [],
    ],
  ];

  $entity_type_ids = [
    'field.storage' => 'field_storage_config',
    'field.field' => 'field_config',
  ];

  foreach ($configs as $name => $data) {
    if (isset($entity_type_ids[$name])) {
      \Drupal::entityTypeManager()->getStorage($entity_type_ids[$name])
        ->create($data)
        ->save();
    }
    else {
      \Drupal::service('config.storage')->write($name, $data);
    }
  }
}

/**
 * Makes the items field multiple.
 */
function social_landing_page_update_8807() {
  $manager = \Drupal::entityDefinitionUpdateManager();
  $storage_definition = $manager->getFieldStorageDefinition('field_featured_items', 'paragraph');
  assert($storage_definition instanceof FieldStorageDefinitionInterface);
  $storage_definition->setCardinality(FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED);
  $manager->updateFieldStorageDefinition($storage_definition);

  $update_helper = \Drupal::service('update_helper.updater');
  $update_helper->executeUpdate('social_landing_page', 'social_landing_page_update_8807');
  return $update_helper->logger()->output();
}

/**
 * Enable helper modules if flexible group and / or social_book are enabled.
 */
function social_landing_page_update_8808() {
  // If we have flexible groups enabled, we want to enable the helper module
  // social_flexible_group_featured which provides a featured view mode to be
  // used on landing pages.
  if (\Drupal::moduleHandler()->moduleExists('social_group_flexible_group')) {
    \Drupal::service('module_installer')->install(['social_flexible_group_featured']);
  }

  // If social_book is enabled, we enable the helper module social_book_featured
  // which provides a featured view mode to be used on landing pages.
  if (\Drupal::moduleHandler()->moduleExists('social_book')) {
    \Drupal::service('module_installer')->install(['social_book_featured']);
  }
}

/**
 * Allow using any URLs in link fields by CM+.
 */
function social_landing_page_update_8809() {
  foreach (['contentmanager', 'sitemanager'] as $role) {
    user_role_grant_permissions($role, ['link to any page']);
  }
}

/**
 * Enable helper modules if secret group is enabled.
 */
function social_landing_page_update_8810() {
  // If we have secret groups enabled, we want to enable the helper module
  // social_secret_group_featured which provides a featured view mode to be
  // used on landing pages.
  if (\Drupal::moduleHandler()->moduleExists('social_group_secret')) {
    \Drupal::service('module_installer')->install(['social_secret_group_featured']);
  }
}

/**
 * Added a new fieldset 'group_settings' to landing page & move fields to it.
 */
function social_landing_page_update_8811() {
  /** @var \Drupal\update_helper\Updater $updateHelper */
  $updateHelper = \Drupal::service('update_helper.updater');

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

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

/**
 * Update landing page form labels.
 */
function social_landing_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_landing_page', 'social_landing_page_update_10201');

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

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

/**
 * Make "Landing Page" translatable.
 */
function social_landing_page_update_10302() {
  /** @var \Drupal\update_helper\Updater $updateHelper */
  $updateHelper = \Drupal::service('update_helper.updater');

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

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

/**
 * Moved to OS 11.0.0.
 */
function social_landing_page_update_10303() {
  // Removed in OS 10.3.1 and moved to OS 11.0.0.
  // @see https://www.drupal.org/project/social/issues/3243511
}

/**
 * Revoke permission.
 */
function social_landing_page_update_10304() {
  foreach (['contentmanager', 'sitemanager'] as $role) {
    user_role_revoke_permissions($role, ['link to any page']);
  }
}

/**
 * Update configuration for the types of the block_field field.
 */
function social_landing_page_update_11001(): string {
  /** @var \Drupal\update_helper\Updater $updateHelper */
  $updateHelper = \Drupal::service('update_helper.updater');

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

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

/**
 * Update exposed filter button name.
 */
function social_landing_page_update_11401(): string {
  /** @var \Drupal\update_helper\Updater $updateHelper */
  $updateHelper = \Drupal::service('update_helper.updater');

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

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

/**
 * Remove deprecated permissions.
 *
 * Deprecated permissions:
 * - "override landing_page revision log entry",
 * - "override landing_page promote to front landing_page option".
 */
function social_landing_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 landing_page revision log entry',
    // Permission below does not exist because it has a typo. It should be
    // 'override landing_page promote to front page option'. The permission
    // with typo is not replaced with correct one, because we want to remove
    // the permission anyway.
    'override landing_page promote to front landing_page option',
  ];

  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 landing_page node".
 */
function social_landing_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 landing_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();
        }
      }
    }
  }
}
