You are here

social_core.install in Open Social 10.3.x

Install, update and uninstall functions for the social_core module.

File

modules/social_features/social_core/social_core.install
View source
<?php

/**
 * @file
 * Install, update and uninstall functions for the social_core module.
 */
use Drupal\Core\File\FileSystemInterface;
use Drupal\block\Entity\Block;
use Drupal\block_content\Entity\BlockContent;
use Drupal\crop\Entity\Crop;
use Drupal\Core\Database\Database;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Field\FieldItemList;
use Drupal\Core\StreamWrapper\PrivateStream;
use Drupal\file\Entity\File;
use Drupal\menu_link_content\Entity\MenuLinkContent;
use Drupal\crop\Entity\CropType;
use Drupal\node\Entity\Node;
use Drupal\profile\Entity\Profile;
use Drupal\group\Entity\Group;
use Symfony\Component\Yaml\Yaml;
use Drupal\field\Entity\FieldConfig;
use Drupal\field\Entity\FieldStorageConfig;
use Drupal\field\FieldConfigInterface;

/**
 * Implements hook_requirements().
 */
function social_core_requirements($phase) {
  $requirements = [];
  switch ($phase) {
    case 'runtime':
      if (!\Drupal::service('module_handler')
        ->moduleExists('social_file_private')) {
        $requirements['social_file_private_module_check'] = [
          'title' => 'Social Private Files',
          'value' => t('All your uploaded files on the Open Social entities are potentially reachable by unauthorized users'),
          'severity' => REQUIREMENT_WARNING,
          'description' => t('It is strongly recommended to enable social_file_private module to make sure your file and image uploads on Open Social entities can not be accessed by unauthorized users. More info: https://www.drupal.org/docs/8/distributions/open-social/private-files'),
        ];
      }
      break;
    case 'update':

      // From 9.0 on-wards a site must update to 8.1 first to ensure that the
      // features removal update hooks have run that are no longer present in
      // Open Social 9.0.
      if (drupal_get_installed_schema_version('social_core') <= 8805) {
        $requirements['social_core_update_version'] = [
          'title' => t('Open Social Update Version'),
          'description' => t('You must update Open Social to the latest version of 8.x before upgrading to 9.0 or later.'),
          'severity' => REQUIREMENT_ERROR,
        ];
      }
      break;
  }
  return $requirements;
}

/**
 * Implements hook_install().
 *
 * Perform actions related to the installation of social_core.
 */
function social_core_install() {

  // Set some default permissions.
  _social_core_set_permissions();

  // Create AN Homepage block.
  _social_core_create_an_homepage_block();

  // Add menu items.
  _social_core_create_menu_links();

  // Set image quality defaults.
  $config = \Drupal::service('config.factory')
    ->getEditable('system.image.gd');
  $config
    ->set('jpeg_quality', 90)
    ->save();

  // If social blue is enabled, and default image is still Open Social.
  // Lets add the default e-mail logo for open social as well.
  _social_core_set_default_email_logo_for_socialblue();

  // Add favicon to GIN.
  _social_core_set_favicon();
}

/**
 * Implements hook_update_dependencies().
 */
function social_core_update_dependencies() {

  // Update field schema only after Profile module bug fixed.
  $dependencies['social_core'][8020] = [
    'profile' => 8001,
  ];
  return $dependencies;
}

/**
 * Re-set permissions.
 */
function social_core_update_8001() {

  // Set some default permissions.
  _social_core_set_permissions();
}

/**
 * Function to set permissions.
 */
function _social_core_set_permissions() {
  $roles = \Drupal::entityQuery('user_role')
    ->condition('id', 'administrator', '<>')
    ->execute();
  foreach ($roles as $role) {
    $permissions = _social_core_get_permissions($role);
    user_role_grant_permissions($role, $permissions);
  }
}

/**
 * Build the permissions.
 *
 * @param string $role
 *   The role.
 *
 * @return array
 *   Returns an array containing the permissions.
 */
function _social_core_get_permissions($role) {

  // Anonymous.
  $permissions['anonymous'] = [
    'access content',
  ];

  // Authenticated.
  $permissions['authenticated'] = array_merge($permissions['anonymous'], [
    'view own unpublished content',
    'use text format basic_html',
    'use text format simple_text',
    'view the administration theme',
  ]);

  // Content manager.
  $permissions['contentmanager'] = array_merge($permissions['authenticated'], [
    'access content overview',
    'access toolbar',
    'administer nodes',
    'administer menu',
    'access site reports',
    'access administration pages',
    'view all revisions',
    'revert all revisions',
    'delete all revisions',
    'create url aliases',
    'use text format full_html',
  ]);

  // Site manager.
  $permissions['sitemanager'] = array_merge($permissions['contentmanager'], [
    'administer taxonomy',
    'delete terms in expertise',
    'edit terms in expertise',
    'delete terms in interests',
    'edit terms in interests',
    'delete terms in topic_types',
    'edit terms in topic_types',
    'administer site configuration',
    'administer users',
    'administer account settings',
    'administer themes',
    'administer blocks',
    'access contextual links',
  ]);
  return $permissions[$role] ?? [];
}

/**
 * Custom function to create the homepage block for AN users.
 */
function _social_core_create_an_homepage_block() {

  // @todo use a better image from the theme.
  // Block image.
  $path = drupal_get_path('module', 'social_core');
  $image_path = $path . DIRECTORY_SEPARATOR . 'images' . DIRECTORY_SEPARATOR . 'homepage-block.jpg';
  $uri = \Drupal::service('file_system')
    ->copy($image_path, 'public://homepage-block.jpg', FileSystemInterface::EXISTS_REPLACE);
  $media = File::create([
    'langcode' => 'en',
    'uid' => 1,
    'status' => 1,
    'uri' => $uri,
  ]);
  $media
    ->save();
  $fid = $media
    ->id();

  // Apply image cropping.
  $data = [
    'x' => 0,
    'y' => 0,
    'width' => 1200,
    'height' => 490,
  ];
  $crop_type = \Drupal::entityTypeManager()
    ->getStorage('crop_type')
    ->load('hero_an');
  if (!empty($crop_type) && $crop_type instanceof CropType) {
    $image_widget_crop_manager = \Drupal::service('image_widget_crop.manager');
    $image_widget_crop_manager
      ->applyCrop($data, [
      'file-uri' => $uri,
      'file-id' => $fid,
    ], $crop_type);
  }

  // Create a block with a specific uuid so we can use it in the config
  // to load it into the theme see block.block.anhomepageheroblock.yml.
  $block = \Drupal::entityTypeManager()
    ->getStorage('block_content')
    ->create([
    'type' => 'hero_call_to_action_block',
    'info' => 'AN homepage hero block',
    'uuid' => '8bb9d4bb-f182-4afc-b138-8a4b802824e4',
  ]);
  $block->field_text_block = [
    'value' => '<h3>Become a member or log in to your community</h3><p>This community is powered by Open Social, the plug-and-play community solution for NGOs and semi-governmental organizations.</p>',
    'format' => 'full_html',
  ];
  $block_image = [
    'target_id' => $fid,
    'alt' => "Anonymous front page image homepage'",
  ];
  $block->field_hero_image = $block_image;

  // Set the links.
  $action_links = [
    [
      'uri' => 'internal:/user/register',
      'title' => t('Sign up'),
    ],
    [
      'uri' => 'internal:/user/login',
      'title' => t('Login'),
    ],
  ];
  $itemList = new FieldItemList($block->field_call_to_action_link
    ->getFieldDefinition());
  $itemList
    ->setValue($action_links);
  $block->field_call_to_action_link = $itemList;
  $block
    ->save();
}

/**
 * Function to create some menu items.
 */
function _social_core_create_menu_links() {

  // Home.
  MenuLinkContent::create([
    'title' => t('Home'),
    'link' => [
      'uri' => 'internal:/',
    ],
    'menu_name' => 'main',
    'expanded' => FALSE,
    'weight' => 10,
  ])
    ->save();

  // Explore.
  MenuLinkContent::create([
    'title' => t('Explore'),
    // This way we get an empty link.
    'link' => [
      'uri' => 'internal:',
    ],
    'menu_name' => 'main',
    'expanded' => TRUE,
    'weight' => 20,
  ])
    ->save();
}

/**
 * Enable full_html format for contentmanager and sitemanager roles.
 */
function social_core_update_8002() {
  $roles = \Drupal::entityQuery('user_role')
    ->condition('id', [
    'contentmanager',
    'sitemanager',
  ], 'IN')
    ->execute();
  $permissions = [
    'use text format full_html',
  ];
  foreach ($roles as $role) {
    user_role_grant_permissions($role, $permissions);
  }
}

/**
 * Install image_widget_crop module.
 */
function social_core_update_8003() {
  $modules = [
    'image_widget_crop',
  ];
  \Drupal::service('module_installer')
    ->install($modules);
}

/**
 * Add permission to view admin theme for contentmanager and sitemanager roles.
 */
function social_core_update_8004() {
  $roles = \Drupal::entityQuery('user_role')
    ->condition('id', [
    'contentmanager',
    'sitemanager',
  ], 'IN')
    ->execute();
  $permissions = [
    'view the administration theme',
  ];
  foreach ($roles as $role) {
    user_role_grant_permissions($role, $permissions);
  }
}

/**
 * Crop images for groups, profiles and nodes.
 */
function social_core_update_8005(&$sandbox) {
  if (!isset($sandbox['progress'])) {
    $sandbox['progress'] = 0;
    $sandbox['items'] = [];
    $sandbox['max'] = 0;

    // First retrieve all the nodes, groups and profiles.
    $query = \Drupal::entityQuery('node', 'OR')
      ->condition('type', 'event')
      ->condition('type', 'topic')
      ->condition('type', 'page')
      ->condition('type', 'book');
    $sandbox['items']['node_ids'] = $query
      ->execute();
    $sandbox['max'] = count($sandbox['items']['node_ids']);
    $query = \Drupal::entityQuery('group');
    $sandbox['items']['group_ids'] = $query
      ->execute();
    $sandbox['max'] += count($sandbox['items']['group_ids']);
    $query = \Drupal::entityQuery('profile');
    $sandbox['items']['profile_ids'] = $query
      ->execute();
    $sandbox['max'] += count($sandbox['items']['profile_ids']);
  }
  $value = NULL;

  // Check if this is a node, group or profile and continue by retrieving the:
  // - Image uri value.
  // - Crop style names we need to crop for.
  if ($sandbox['items']['node_ids']) {
    $nid = array_shift($sandbox['items']['node_ids']);
    $node = Node::load($nid);
    switch ($node
      ->getType()) {
      case 'topic':
        $value = $node->field_topic_image
          ->first() ? $node->field_topic_image
          ->first()
          ->getValue() : NULL;
        break;
      case 'event':
        $value = $node->field_event_image
          ->first() ? $node->field_event_image
          ->first()
          ->getValue() : NULL;
        break;
      case 'page':
        $value = $node->field_page_image
          ->first() ? $node->field_page_image
          ->first()
          ->getValue() : NULL;
        break;
      case 'book':
        $value = $node->field_book_image
          ->first() ? $node->field_book_image
          ->first()
          ->getValue() : NULL;
        break;
    }
    $crop_type_names = [
      'hero',
      'teaser',
    ];
  }
  elseif ($sandbox['items']['group_ids']) {
    $gid = array_shift($sandbox['items']['group_ids']);
    $group = Group::load($gid);
    $value = $group->field_group_image
      ->first() ? $group->field_group_image
      ->first()
      ->getValue() : NULL;
    $crop_type_names = [
      'hero',
      'teaser',
    ];
  }
  elseif ($sandbox['items']['profile_ids']) {
    $pid = array_shift($sandbox['items']['profile_ids']);
    $profile = Profile::load($pid);
    $value = $profile->field_profile_image
      ->first() ? $profile->field_profile_image
      ->first()
      ->getValue() : NULL;
    $crop_type_names = [
      'teaser',
      'profile_medium',
      'profile_small',
    ];
  }
  if ($value && isset($crop_type_names)) {
    $image_widget_crop_manager = \Drupal::service('image_widget_crop.manager');
    foreach ($crop_type_names as $crop_type_name) {
      $crop_type = \Drupal::entityTypeManager()
        ->getStorage('crop_type')
        ->load($crop_type_name);
      if (!empty($crop_type) && $crop_type instanceof CropType) {
        $file = File::load($value['target_id']);
        $crop_element = [
          'file-uri' => $file
            ->getFileUri(),
          'file-id' => $file
            ->id(),
        ];
        $image_styles = $image_widget_crop_manager
          ->getImageStylesByCrop($crop_type_name);
        $crops = $image_widget_crop_manager
          ->loadImageStyleByCrop($image_styles, $crop_type, $crop_element['file-uri']);

        // Only crop if this uri is not yet cropped for this crop style already.
        if (!$crops) {
          list($ratio_width, $ratio_height) = explode(':', $crop_type->aspect_ratio);
          $ratio = $ratio_width / $ratio_height;
          if ($ratio > 1) {
            $width = $value['width'];
            $height = $value['height'] * ($value['width'] / $value['height'] / $ratio);
          }
          elseif ($ratio === 1) {
            $width = $height = min([
              $value['width'],
              $value['height'],
            ]);
          }
          else {
            $width = $value['width'] * ($value['width'] / $value['height'] / $ratio);
            $height = $value['height'];
          }
          $center_x = round($value['width'] / 2);
          $center_y = round($value['height'] / 2);
          $crop_width_half = round($width / 2);
          $crop_height_half = round($height / 2);
          $x = max(0, $center_x - $crop_width_half);
          $y = max(0, $center_y - $crop_height_half);
          $properties = [
            'x' => $x,
            'y' => $y,
            'width' => $width,
            'height' => $height,
          ];
          $field_value = [
            'file-uri' => $crop_element['file-uri'],
            'file-id' => $value['target_id'],
          ];
          $image_widget_crop_manager
            ->applyCrop($properties, $field_value, $crop_type);
          image_path_flush($file
            ->getFileUri());
        }
      }
    }
  }
  $sandbox['progress']++;
  $sandbox['#finished'] = empty($sandbox['max']) ? 1 : $sandbox['progress'] / $sandbox['max'];
}

/**
 * Install social_follow_content module.
 */
function social_core_update_8006(&$sandbox) {
  $modules = [
    'social_follow_content',
  ];
  \Drupal::service('module_installer')
    ->install($modules);
}

/**
 * Set higher jpeg quality instead of default 75%.
 */
function social_core_update_8007() {
  $config = \Drupal::service('config.factory')
    ->getEditable('system.image.gd');
  $config
    ->set('jpeg_quality', 90)
    ->save();
}

/**
 * Install social_mentions module.
 */
function social_core_update_8008() {
  $modules = [
    'social_mentions',
  ];
  \Drupal::service('module_installer')
    ->install($modules);
}

/**
 * Enable socialblue theme and make default if socialbase is current default.
 */
function social_core_update_8009() {
  $system_theme_settings = \Drupal::configFactory()
    ->get('system.theme')
    ->get('default');
  if ($system_theme_settings === 'socialbase') {
    $themes = [
      'socialblue',
    ];
    \Drupal::service('theme_handler')
      ->install($themes);
    \Drupal::configFactory()
      ->getEditable('system.theme')
      ->set('default', 'socialblue')
      ->save();

    // Ensure that the install profile's theme is used.
    // @see _drupal_maintenance_theme()
    \Drupal::service('theme.manager')
      ->resetActiveTheme();
    \Drupal::messenger()
      ->addStatus(t('Installed socialblue theme and made this the default. Please check release notes.'));
  }
  else {
    \Drupal::messenger()
      ->addStatus(t('Skipped installing socialblue theme. Please check release notes.'));
  }
}

/**
 * Install social_font module.
 */
function social_core_update_8010() {
  $modules = [
    'social_font',
  ];
  \Drupal::service('module_installer')
    ->install($modules);
}

/**
 * Install color & improved theme settings module.
 */
function social_core_update_8011() {
  $modules = [
    'color',
    'improved_theme_settings',
  ];
  \Drupal::service('module_installer')
    ->install($modules);
}

/**
 * Install social_like module.
 */
function social_core_update_8012() {
  $modules = [
    'social_like',
  ];
  \Drupal::service('module_installer')
    ->install($modules);
}

/**
 * Change socialbase and socialblue theme settings config.
 */
function social_core_update_8013() {
  $config_factory = \Drupal::service('config.factory');
  $config = $config_factory
    ->getEditable('socialbase.settings');
  $config
    ->set('button_colorize', 0);
  $config
    ->set('button_iconize', 0);
  $config
    ->save();
  $config = $config_factory
    ->getEditable('socialblue.settings');
  $config
    ->set('button_colorize', 0);
  $config
    ->set('button_iconize', 0);
  $config
    ->save();
}

/**
 * Update topics path.
 */
function social_core_update_8014(&$sandbox) {
  $links = \Drupal::entityTypeManager()
    ->getStorage('menu_link_content')
    ->loadByProperties([
    'link__uri' => 'internal:/newest-topics',
  ]);
  if ($link = reset($links)) {
    $link
      ->set('link', [
      'uri' => 'internal:/all-topics',
    ]);
    $link
      ->save();
  }
}

/**
 * Update members path.
 */
function social_core_update_8015(&$sandbox) {
  $links = \Drupal::entityTypeManager()
    ->getStorage('menu_link_content')
    ->loadByProperties([
    'link__uri' => 'internal:/newest-members',
  ]);
  if ($link = reset($links)) {
    $link
      ->set('link', [
      'uri' => 'internal:/all-members',
    ]);
    $link
      ->save();
  }
}

/**
 * Install social_tour module.
 */
function social_core_update_8018(&$sandbox) {
  $modules = [
    'social_tour',
  ];
  \Drupal::service('module_installer')
    ->install($modules);
}

/**
 * Install the social_file_private module.
 */
function social_core_update_8019() {
  $file_private_path_base_path = PrivateStream::basePath();
  if ($file_private_path_base_path !== NULL) {
    $modules = [
      'social_file_private',
    ];
    \Drupal::service('module_installer')
      ->install($modules);
    \Drupal::messenger()
      ->addStatus(t('Installed the social_file_private module. Make sure to read: https://www.drupal.org/docs/8/distributions/open-social/private-files'));
  }
  else {
    \Drupal::messenger()
      ->addWarning(t('Skipped installing the social_file_private module because your Private file system is not set. This could have some security implications. More info: https://www.drupal.org/docs/8/distributions/open-social/private-files'));
  }
}

/**
 * Fix an schema issue caused by Flag module.
 */
function social_core_update_8020() {
  $bundle_schema = [
    'description' => 'The Flag ID.',
    'type' => 'varchar_ascii',
    'length' => EntityTypeInterface::BUNDLE_MAX_LENGTH,
    'not null' => TRUE,
  ];

  /** @var \Drupal\Core\Database\Schema $schema */
  $schema = \Drupal::database()
    ->schema();
  $schema
    ->changeField('flagging', 'flag_id', 'flag_id', $bundle_schema);
  $schema
    ->dropIndex('flagging', 'flag_id');
  $schema
    ->dropIndex('flagging', 'flagging_field__flag_id__target_id');
  $schema
    ->addIndex('flagging', 'flagging_field__flag_id__target_id', [
    'flag_id',
  ], [
    'fields' => [
      'flag_id' => $bundle_schema,
    ],
  ]);

  // Update the field storage repository.

  /** @var \Drupal\Core\Entity\EntityFieldManagerInterface $efm */
  $efm = \Drupal::service('entity_field.manager');

  /** @var \Drupal\Core\KeyValueStore\KeyValueStoreInterface $kv */
  $kv = \Drupal::service('keyvalue');

  /** @var \Drupal\Core\Entity\EntityLastInstalledSchemaRepositoryInterface $repo */
  $repo = \Drupal::service('entity.last_installed_schema.repository');
  $efm
    ->clearCachedFieldDefinitions();
  $storage_definition = $efm
    ->getFieldStorageDefinitions('flagging')['flag_id'];
  $repo
    ->setLastInstalledFieldStorageDefinition($storage_definition);

  // Update the stored field schema.
  // @todo There has to be a better way to do this.
  $kv_collection = 'entity.storage_schema.sql';
  $kv_name = 'flagging.field_schema_data.flag_id';
  $field_schema = $kv
    ->get($kv_collection)
    ->get($kv_name);
  $field_schema['flagging']['fields']['flag_id'] = $bundle_schema;
  $field_schema['flagging']['indexes']['flagging_field__flag_id__target_id'] = [
    'flag_id',
  ];
  $kv
    ->get($kv_collection)
    ->set($kv_name, $field_schema);
}

/**
 * Update social_post existing content.
 */
function social_core_update_8021(&$sandbox) {
  $database = \Drupal::database();
  $table_post = 'post';
  $table_data = 'post_field_data';

  // Get the old data.
  $existing_data_post = $database
    ->select($table_post)
    ->fields($table_post)
    ->execute()
    ->fetchAll(PDO::FETCH_ASSOC);

  // Wipe it.
  $database
    ->truncate($table_post)
    ->execute();
  $existing_data_data = $database
    ->select($table_data)
    ->fields($table_data)
    ->execute()
    ->fetchAll(PDO::FETCH_ASSOC);

  // Wipe it.
  $database
    ->truncate($table_data)
    ->execute();

  // Add new field to tables.
  $spec = [
    'type' => 'varchar',
    'length' => 32,
    'not null' => TRUE,
    'default' => 'post',
    'description' => 'The ID of the target entity.',
  ];
  $schema = Database::getConnection()
    ->schema();
  if ($schema
    ->fieldExists($table_post, 'type')) {
    $schema
      ->changeField($table_post, 'type', 'type', $spec);
  }
  else {
    $schema
      ->addField($table_post, 'type', $spec);
  }
  if ($schema
    ->fieldExists($table_data, 'type')) {
    $schema
      ->changeField($table_data, 'type', 'type', $spec);
  }
  else {
    $schema
      ->addField($table_data, 'type', $spec);
  }

  // Update definitions and schema.
  $list = \Drupal::entityDefinitionUpdateManager()
    ->getChangeList();
  if (!empty($list['post'])) {
    foreach ($list['post'] as $post) {
      \Drupal::entityDefinitionUpdateManager()
        ->updateEntityType($post);
    }
  }

  // Update config post_type.
  $path = drupal_get_path('module', 'social_post') . '/config/install';
  $config_factory = \Drupal::configFactory();
  $config_name = "social_post.post_type.post";
  $filepath = "{$path}/{$config_name}.yml";
  $data = Yaml::parse($filepath);
  if (is_array($data)) {
    $config_factory
      ->getEditable($config_name)
      ->setData($data)
      ->save();
  }
  if (!empty($existing_data_post)) {

    // Set the old data.
    $insert_query_post = $database
      ->insert($table_post)
      ->fields(array_keys(end($existing_data_post)));
    foreach ($existing_data_post as $row) {
      $insert_query_post
        ->values(array_values($row));
    }
    $insert_query_post
      ->execute();
  }
  if (!empty($existing_data_data)) {
    $insert_query_data = $database
      ->insert($table_data)
      ->fields(array_keys(end($existing_data_data)));
    foreach ($existing_data_data as $row) {
      $insert_query_data
        ->values(array_values($row));
    }
    $insert_query_data
      ->execute();
  }

  // Unset default value for post entity.
  $schema
    ->changeField($table_data, 'type', 'type', $spec);
}

/**
 * Install social_post_photo module.
 */
function social_core_update_8022() {
  $modules = [
    'social_post_photo',
  ];
  \Drupal::service('module_installer')
    ->install($modules);
}

/**
 * Update the context_mapping for account_header_block blocks.
 */
function social_core_update_8023() {
  $blocks = Block::loadMultiple();

  /** @var \Drupal\block\Entity\Block $block */
  foreach ($blocks as $block) {
    if ($block
      ->getPluginId() === 'account_header_block') {
      $block_settings = $block
        ->get('settings');
      if (!isset($block_settings['context_mapping']['user'])) {
        $block_settings['context_mapping']['user'] = '@user.current_user_context:current_user';
        $block
          ->set('settings', $block_settings);
        $block
          ->save();
      }
    }
  }
}

/**
 * Install image_effects module.
 */
function social_core_update_8024() {
  $modules = [
    'image_effects',
  ];
  \Drupal::service('module_installer')
    ->install($modules);
}

/**
 * Install social_swiftmail module.
 */
function social_core_update_8025() {
  $modules = [
    'social_swiftmail',
  ];
  \Drupal::service('module_installer')
    ->install($modules);
}

/**
 * Automatically try to set a new crop for the anonymous hero image.
 */
function social_core_update_8026() {

  // Load the anonymous hero block.
  $block_storage = \Drupal::entityTypeManager()
    ->getStorage('block_content');
  $block = $block_storage
    ->loadByProperties([
    'uuid' => '8bb9d4bb-f182-4afc-b138-8a4b802824e4',
  ]);
  $block = current($block);
  if ($block instanceof BlockContent) {

    // Get the hero image file ID.
    $hero_image = $block
      ->get('field_hero_image')
      ->getValue();

    // Check if we already have a crop for the new hero_an style.
    $query = \Drupal::entityQuery('crop')
      ->condition('entity_type', 'file')
      ->condition('entity_id', $hero_image[0]['target_id'])
      ->condition('type', 'hero_an');
    $hero_an_crop = $query
      ->execute();

    // No crop style found yet. Let's try to set one automatically.
    if (!$hero_an_crop) {

      // Find and load the current hero crop to get the dimensions.
      $query = \Drupal::entityQuery('crop')
        ->condition('entity_type', 'file')
        ->condition('entity_id', $hero_image[0]['target_id'])
        ->condition('type', 'hero')
        ->sort('cid')
        ->range(0, 1);
      $crop = $query
        ->execute();

      /** @var \Drupal\crop\Entity\Crop $crop */
      $crop = Crop::load(current($crop));

      // Crop object found, set the crop type to hero_an.
      if ($crop instanceof Crop) {
        $size = $crop
          ->size();

        // We need to adjust the width, as this is the safest way to set the new
        // crop automatically.
        // Aspect ratio was 2.836879433 (width 1200, height 423). It became
        // 2.448979592 (width 1200, height 490).
        $crop
          ->set('width', $size['width'] / 2.836879433 * 2.448979592);
        $crop
          ->set('type', 'hero_an');
        $crop
          ->save();
      }
    }
  }
}

/**
 * Re-save settings for r4032login to enable redirect to destination.
 */
function social_core_update_8027() {
  if (\Drupal::moduleHandler()
    ->moduleExists('r4032login')) {
    $config = \Drupal::configFactory()
      ->getEditable('r4032login.settings');
    if (!$config
      ->get('redirect_to_destination')) {
      $config
        ->set('redirect_to_destination', TRUE);
    }
    if (!$config
      ->get('destination_parameter_override')) {
      $config
        ->set('destination_parameter_override', '');
    }
    $config
      ->save();
  }
}

/**
 * Turn off comment user verification setting.
 */
function social_core_update_8028() {

  // Change setting for socialbase.
  $socialbase_settings = \Drupal::configFactory()
    ->getEditable('socialbase.settings');
  $socialbase_settings
    ->set('features.comment_user_verification', FALSE)
    ->save();

  // Change setting for socialblue.
  $socialblue_settings = \Drupal::configFactory()
    ->getEditable('socialblue.settings');
  $socialblue_settings
    ->set('features.comment_user_verification', FALSE)
    ->save();
}

/**
 * Install exif_orientation module.
 */
function social_core_update_8301() {
  $modules = [
    'exif_orientation',
  ];
  \Drupal::service('module_installer')
    ->install($modules);
}

/**
 * Install social_lets_connect_usage module.
 */
function social_core_update_8501() {

  // Let's enable the sharing usage data module.
  $modules = [
    'social_lets_connect_usage',
  ];
  \Drupal::service('module_installer')
    ->install($modules);

  // Let's disable sharing data by default for existing sites because this
  // changes behaviour. For new installs this will be enabled through settings.
  $config = \Drupal::configFactory()
    ->getEditable('social_lets_connect_usage.settings');
  $config
    ->set('usage_data_enabled', 0);
  $config
    ->save();
}

/**
 * Enable social_node module.
 */
function social_core_update_8801() {
  \Drupal::service('module_installer')
    ->install([
    'social_node',
  ]);
}

/**
 * Perform features revert for the last time.
 */
function social_core_update_8802() {

  // This update has been removed in 9.0.
}

/**
 * Set the view mode for nodes to use when shown in activities.
 */
function social_core_update_8803() {
  activity_creator_set_entity_view_mode('node', 'activity');
}

/**
 * Allow site managers to use contextual links.
 */
function social_core_update_8804() {
  user_role_grant_permissions('sitemanager', [
    'access contextual links',
  ]);
}

/**
 * Install update helper for config update usage.
 */
function social_core_update_8805() {
  \Drupal::service('module_installer')
    ->install([
    'update_helper',
  ]);
}

/**
 * Add new basic block config items.
 */
function social_core_update_8806(&$sandbox) {
  if (!isset($sandbox['total'])) {

    // Declare all the config render arrays,
    // keyed by the config name.
    $sandbox['configs'] = [
      'field.storage.block_content.field_basic_link' => [
        'id' => 'block_content.field_basic_link',
        'field_name' => 'field_basic_link',
        'entity_type' => 'block_content',
        'type' => 'link',
        'settings' => [],
        'module' => 'link',
        'locked' => FALSE,
        'cardinality' => 1,
        'translatable' => TRUE,
      ],
      'field.field.block_content.basic.field_basic_link' => [
        'id' => 'block_content.basic.field_basic_link',
        'field_name' => 'field_basic_link',
        'entity_type' => 'block_content',
        'bundle' => 'basic',
        'label' => 'Read more link',
        'description' => '',
        'required' => FALSE,
        'translatable' => TRUE,
        'default_value' => [],
        'default_value_callback' => '',
        'settings' => [
          'link_type' => 17,
          'title' => 1,
        ],
        'field_type' => 'link',
      ],
      'field.field.block_content.basic.field_text_block' => [
        'id' => 'block_content.basic.field_text_block',
        'field_name' => 'field_text_block',
        'entity_type' => 'block_content',
        'bundle' => 'basic',
        'label' => 'Text block',
        'description' => '',
        'required' => FALSE,
        'translatable' => TRUE,
        'default_value' => [],
        'default_value_callback' => '',
        'settings' => [],
        'field_type' => 'text_long',
      ],
      'core.entity_form_display.block_content.basic.default' => [
        'langcode' => 'en',
        'status' => TRUE,
        'dependencies' => [
          'config' => [
            'block_content.type.basic',
            'field.field.block_content.basic.field_basic_link',
            'field.field.block_content.basic.field_text_block',
          ],
          'module' => [
            'text',
            'link',
          ],
        ],
        'id' => 'block_content.basic.default',
        'targetEntityType' => 'block_content',
        'bundle' => 'basic',
        'mode' => 'default',
        'content' => [
          'info' => [
            'region' => 'content',
            'settings' => [
              'placeholder' => '',
              'size' => 60,
            ],
            'third_party_settings' => [],
            'type' => 'string_textfield',
            'weight' => -5,
          ],
        ],
        'hidden' => [
          'field_text_block' => TRUE,
          'field_basic_link' => TRUE,
        ],
      ],
      'core.entity_view_display.block_content.basic.default' => [
        'langcode' => 'en',
        'status' => TRUE,
        'dependencies' => [
          'config' => [
            'block_content.type.basic',
            'field.field.block_content.basic.field_basic_link',
            'field.field.block_content.basic.field_text_block',
          ],
          'module' => [
            'text',
            'link',
          ],
        ],
        'id' => 'block_content.basic.default',
        'targetEntityType' => 'block_content',
        'bundle' => 'basic',
        'mode' => 'default',
        'content' => [],
        'hidden' => [
          'field_basic_link' => TRUE,
          'field_text_block' => TRUE,
        ],
      ],
    ];

    // Count the amount we need to add to cover batching..
    $sandbox['total'] = count($sandbox['configs']);
    $sandbox['current'] = 0;
  }
  $names = array_keys($sandbox['configs']);
  $name = $names[$sandbox['current']++];
  $data = $sandbox['configs'][$name];
  $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
          ->setDescription($data);
      }
      else {
        $field_config = FieldConfig::create($data);
      }
      $field_config
        ->save();
      break;
    default:

      // Insert newly created config in the storage.
      \Drupal::service('config.storage')
        ->write($name, $data);
  }
  $sandbox['#finished'] = $sandbox['current'] / $sandbox['total'];
}

/**
 * Basic block config changes.
 */
function social_core_update_8807() {

  /** @var \Drupal\update_helper\Updater $updateHelper */
  $updateHelper = \Drupal::service('update_helper.updater');

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

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

/**
 * Hide tabs from /user/x/profile page.
 */
function social_core_update_8808() {

  /** @var \Drupal\update_helper\Updater $updateHelper */
  $updateHelper = \Drupal::service('update_helper.updater');

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

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

/**
 * Hide primary admin actions from /user/x/edit and some other pages.
 */
function social_core_update_8809() {

  /** @var \Drupal\update_helper\Updater $updateHelper */
  $updateHelper = \Drupal::service('update_helper.updater');

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

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

/**
 * Install the role delegation module.
 */
function social_core_update_8810() {
  \Drupal::service('module_installer')
    ->install([
    'role_delegation',
  ]);
}

/**
 * Block changes for the social_event request enrollment feature.
 */
function social_core_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_core', 'social_core_update_8811');

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

/**
 * Install the Gin theme(as admin) and Install Gin Toolbar.
 */
function social_core_update_8812(&$sandbox) {

  // Install Gin Admin Theme.
  \Drupal::service('theme_installer')
    ->install([
    'gin',
  ]);

  // Set Gin Admin Theme as admin theme.
  \Drupal::configFactory()
    ->getEditable('system.theme')
    ->set('admin', 'gin')
    ->save();

  // Install Gin Toolbar module.
  \Drupal::service('module_installer')
    ->install([
    'gin_toolbar',
  ]);
}

/**
 * Block changes for the social_group_request feature.
 */
function social_core_update_8813() {

  /** @var \Drupal\update_helper\Updater $updateHelper */
  $updateHelper = \Drupal::service('update_helper.updater');

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

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

/**
 * Add the administration theme to authenticated users for batch operations.
 */
function social_core_update_8901() {
  $roles = \Drupal::entityQuery('user_role')
    ->condition('id', [
    'authenticated',
  ], 'IN')
    ->execute();
  $permissions = [
    'view the administration theme',
  ];
  foreach ($roles as $role) {
    user_role_grant_permissions($role, $permissions);
  }
}

/**
 * Update GIN theme settings based on SocialBlue primary secondary.
 */
function social_core_update_8902() {

  // Only when GIN is the admin theme and SocialBlue is the active theme.
  if (\Drupal::configFactory()
    ->get('system.theme')
    ->get('admin') === 'gin' && \Drupal::theme()
    ->getActiveTheme()
    ->getName() === 'socialblue') {

    // Grab the default socialblue colors, these are set if the color settings
    // aren't overridden yet.
    $default_colors = \Drupal::configFactory()
      ->getEditable('socialblue.settings')
      ->getRawData();

    // Unfortunately the color module doesnt add the color details to the
    // $form_state. So we need to grab it from the config once overridden.
    // luckily color does set their submit function as first, so we can
    // safely assume the config uses the updated colors.
    $socialblue_colors = \Drupal::configFactory()
      ->getEditable('color.theme.socialblue')
      ->getRawData();

    // The brand colors are first of all coming from the overridden color
    // settings. But if that is not set, we will grab them from the
    // default Social Blue settings.
    $brand_primary = !empty($socialblue_colors) ? $socialblue_colors['palette']['brand-primary'] : $default_colors['color_primary'];
    $brand_secondary = !empty($socialblue_colors) ? $socialblue_colors['palette']['brand-secondary'] : $default_colors['color_secondary'];

    // See if we can update GIN settings with our brand colors.
    if (isset($brand_primary, $brand_secondary)) {
      $config = \Drupal::configFactory()
        ->getEditable('gin.settings');
      if (!empty($config
        ->getRawData())) {
        $gin_config = $config
          ->getRawData();

        // Override preset colors as custom so we can fill in the hex colors.
        $gin_config['preset_accent_color'] = 'custom';
        $gin_config['preset_focus_color'] = 'custom';

        // Update the accent and focus with our branded colors.
        $gin_config['accent_color'] = $brand_primary;
        $gin_config['focus_color'] = $brand_secondary;
        $config
          ->setData($gin_config);
        $config
          ->save();
      }
    }
  }
}

/**
 * Install the redirect module to prevent index.php from being accessed.
 */
function social_core_update_8903() {
  \Drupal::service('module_installer')
    ->install([
    'redirect',
  ]);
}

/**
 * Update Social Blue theme with new accent text color.
 */
function social_core_update_8904() {
  $config = \Drupal::configFactory()
    ->getEditable('color.theme.socialblue');
  if (!empty($config
    ->getRawData())) {
    $socialblue_colors = $config
      ->getRawData();
    $socialblue_colors['palette']['brand-accent-text'] = '#4d4d4d';
    $config
      ->setData($socialblue_colors);
    $config
      ->save();
  }
}

/**
 * Sets the Content Entity Forms to Open Social style.
 */
function social_core_update_8905() {

  // Only when socialblue is default we set this.
  if (\Drupal::service('theme.manager')
    ->getActiveTheme()
    ->getName() === 'socialblue') {
    try {

      // Sets it to Open Social.
      $config = \Drupal::configFactory()
        ->getEditable('socialblue.settings');
      $config
        ->set('content_entity_form_style', 'open_social')
        ->save();
    } catch (Exception $e) {
      \Drupal::logger('social_core')
        ->error('Could not install Content Entity forms as Open Social please do so manually in the Socialblue settings.');
    }
  }
}

/**
 * Sets the Default E-mail logo to the rebranded version, if possible.
 */
function social_core_update_8906() {
  _social_core_set_default_email_logo_for_socialblue();
}

/**
 * Adds social_post_album.
 */
function social_core_update_8907() {
  $modules = [
    'social_post_album',
  ];
  \Drupal::service('module_installer')
    ->install($modules);
}

/**
 * Add a new image thumbnail 'social_file_thumbnail' files field.
 */
function social_core_update_8908() {
  $config_file = drupal_get_path('module', 'social_core') . '/config/static/image.style.social_file_thumbnails_8908.yml';
  if (is_file($config_file)) {
    $settings = Yaml::parse(file_get_contents($config_file));
    if (is_array($settings)) {
      $config = \Drupal::configFactory()
        ->getEditable('image.style.social_file_thumbnails');
      $config
        ->setData($settings)
        ->save(TRUE);
    }
  }
}

/**
 * Install ultimate cron module.
 */
function social_core_update_10101() {
  $modules = [
    'ultimate_cron',
    'social_advanced_queue',
  ];
  \Drupal::service('module_installer')
    ->install($modules);
}

/**
 * Empty update hook.
 */
function social_core_update_10102() {

  // Removed as it was an incorrect update hook use 10103 instead.
}

/**
 * Add a OS favicon on the admin pages.
 */
function social_core_update_10103() {
  $config = \Drupal::configFactory()
    ->getEditable('gin.settings');
  if (!empty($config
    ->getRawData())) {
    $gin_config = $config
      ->getRawData();

    // Update the favicon in GIN.
    $gin_config['favicon']['use_default'] = FALSE;
    $gin_config['favicon']['path'] = 'themes/contrib/socialblue/favicon.ico';
    $gin_config['favicon']['mimetype'] = 'image/vnd.microsoft.icon';
    $config
      ->setData($gin_config);
    $config
      ->save();
  }
}

/**
 * Set default settings to use entity access API as FALSE.
 */
function social_core_update_10104() {
  $config = \Drupal::configFactory()
    ->getEditable('social_core.settings');
  $config
    ->set('use_entity_access_api', 0)
    ->save();
}

/**
 * Add default classic_toolbar of the Gin theme.
 */
function social_core_update_10105() {
  $config = \Drupal::configFactory()
    ->getEditable('gin.settings');
  if (!empty($config
    ->getRawData())) {
    $gin_config = $config
      ->getRawData();
    $gin_config['classic_toolbar'] = 'vertical';
    $config
      ->setData($gin_config);
    $config
      ->save();
  }
}

/**
 * Add translation support for custom blocks fields.
 */
function social_core_update_10300() {

  /** @var \Drupal\update_helper\Updater $updateHelper */
  $updateHelper = \Drupal::service('update_helper.updater');

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

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

Functions

Namesort descending Description
social_core_install Implements hook_install().
social_core_requirements Implements hook_requirements().
social_core_update_10101 Install ultimate cron module.
social_core_update_10102 Empty update hook.
social_core_update_10103 Add a OS favicon on the admin pages.
social_core_update_10104 Set default settings to use entity access API as FALSE.
social_core_update_10105 Add default classic_toolbar of the Gin theme.
social_core_update_10300 Add translation support for custom blocks fields.
social_core_update_8001 Re-set permissions.
social_core_update_8002 Enable full_html format for contentmanager and sitemanager roles.
social_core_update_8003 Install image_widget_crop module.
social_core_update_8004 Add permission to view admin theme for contentmanager and sitemanager roles.
social_core_update_8005 Crop images for groups, profiles and nodes.
social_core_update_8006 Install social_follow_content module.
social_core_update_8007 Set higher jpeg quality instead of default 75%.
social_core_update_8008 Install social_mentions module.
social_core_update_8009 Enable socialblue theme and make default if socialbase is current default.
social_core_update_8010 Install social_font module.
social_core_update_8011 Install color & improved theme settings module.
social_core_update_8012 Install social_like module.
social_core_update_8013 Change socialbase and socialblue theme settings config.
social_core_update_8014 Update topics path.
social_core_update_8015 Update members path.
social_core_update_8018 Install social_tour module.
social_core_update_8019 Install the social_file_private module.
social_core_update_8020 Fix an schema issue caused by Flag module.
social_core_update_8021 Update social_post existing content.
social_core_update_8022 Install social_post_photo module.
social_core_update_8023 Update the context_mapping for account_header_block blocks.
social_core_update_8024 Install image_effects module.
social_core_update_8025 Install social_swiftmail module.
social_core_update_8026 Automatically try to set a new crop for the anonymous hero image.
social_core_update_8027 Re-save settings for r4032login to enable redirect to destination.
social_core_update_8028 Turn off comment user verification setting.
social_core_update_8301 Install exif_orientation module.
social_core_update_8501 Install social_lets_connect_usage module.
social_core_update_8801 Enable social_node module.
social_core_update_8802 Perform features revert for the last time.
social_core_update_8803 Set the view mode for nodes to use when shown in activities.
social_core_update_8804 Allow site managers to use contextual links.
social_core_update_8805 Install update helper for config update usage.
social_core_update_8806 Add new basic block config items.
social_core_update_8807 Basic block config changes.
social_core_update_8808 Hide tabs from /user/x/profile page.
social_core_update_8809 Hide primary admin actions from /user/x/edit and some other pages.
social_core_update_8810 Install the role delegation module.
social_core_update_8811 Block changes for the social_event request enrollment feature.
social_core_update_8812 Install the Gin theme(as admin) and Install Gin Toolbar.
social_core_update_8813 Block changes for the social_group_request feature.
social_core_update_8901 Add the administration theme to authenticated users for batch operations.
social_core_update_8902 Update GIN theme settings based on SocialBlue primary secondary.
social_core_update_8903 Install the redirect module to prevent index.php from being accessed.
social_core_update_8904 Update Social Blue theme with new accent text color.
social_core_update_8905 Sets the Content Entity Forms to Open Social style.
social_core_update_8906 Sets the Default E-mail logo to the rebranded version, if possible.
social_core_update_8907 Adds social_post_album.
social_core_update_8908 Add a new image thumbnail 'social_file_thumbnail' files field.
social_core_update_dependencies Implements hook_update_dependencies().
_social_core_create_an_homepage_block Custom function to create the homepage block for AN users.
_social_core_create_menu_links Function to create some menu items.
_social_core_get_permissions Build the permissions.
_social_core_set_permissions Function to set permissions.