<?php /** * @file * Install, update and uninstall for Configuration of all common WCMS. */ use Drupal\Core\Config\FileStorage; use Drupal\field\Entity\FieldConfig; use Drupal\node\Entity\Node; use Drupal\taxonomy\Entity\Term; use Drupal\user\Entity\Role; use Drupal\uw_cfg_common\UwPermissions\UwPermissions; use Drupal\uw_cfg_common\UwRoles\UwRoles; use Drupal\webform\WebformInterface; use Symfony\Component\Yaml\Yaml; /** * Implements hook_install(). */ function uw_cfg_common_install() { // ISTWCMS-5865: this the attempt to fix features for our build. // Moving the actual installing of workflows to here, so that // we can include workflows as a dependency in our modules and // that it will allow new site installs. $name = 'workflows.workflow.uw_workflow'; $path = \Drupal::service('extension.list.module')->getPath('uw_cfg_common') . '/config/custom/'; $source = new FileStorage($path); $active_storage = \Drupal::service('config.storage'); $active_storage->write($name, $source->read($name)); // Get the role ids for UW roles. $uw_rids = UwRoles::getUwRoleIds(); // Step through each of the rids and create // role and set permissions. foreach ($uw_rids as $uw_rid) { // Create the role. $role = Role::create( [ 'id' => $uw_rid, 'label' => UwRoles::getUwRoleLabel($uw_rid), ] ); $role->save(); // Get the info about the role. $uw_role = UwRoles::getUwRole($uw_rid); // Set the permissions for the role. UwRoles::setUwPermissions($uw_role); } // Get the role ids for Drupal roles. $drupal_rids = UwRoles::getDrupalRoleIds(); // Step through each of the Drupal roles and // set the permissions. foreach ($drupal_rids as $drupal_rid) { // Get the info about the role. $uw_role = UwRoles::getUwRole($drupal_rid); // Set the permissions for the role. UwRoles::setUwPermissions($uw_role); } // Build the access permissions array. $module_handler = \Drupal::service('module_handler'); $module_path = $module_handler->getModule('uw_cfg_common')->getPath(); $permissions_to_process = Yaml::parseFile($module_path . '/src/UwRoles/access_content_permissions.yml'); UwPermissions::grantRevoke($permissions_to_process, 'grant'); // Add terms to the vocabulary 'uw_vocab_audience'. $terms = [ 'Current students' => [ 'Current undergraduate students', 'Current graduate students', ], 'Future students' => [ 'Future undergraduate students', 'Future graduate students', ], 'Faculty' => 'Faculty', 'Staff' => 'Staff', 'Alumni' => 'Alumni', 'Parents' => 'Parents', 'Donors | Friends | Supporters' => 'Donors | Friends | Supporters', 'Employers' => 'Employers', 'International' => 'International', 'Media' => 'Media', ]; $weight = 0; foreach ($terms as $key => $term) { if (is_array($term)) { $parent = _uw_cfg_common_create_term($key, 'uw_vocab_audience', $weight, []); $childweight = 0; foreach ($term as $child) { _uw_cfg_common_create_term($child, 'uw_vocab_audience', $childweight, [$parent]); $childweight++; } } else { _uw_cfg_common_create_term($term, 'uw_vocab_audience', $weight, []); } $weight++; } } /** * @file * Contains various helper functions. */ /** * Helper function to create a taxonomy term programmatically. * * @code * // Create top level term * $term_id = _nodemaker_term_create('My Term', 'my_vocab', 0, []); * * // Create term with parent term with an id of 999 * $term_id = _nodemaker_term_create('My Term', 'my_vocab', 0, [999]); * @endcode * * @param string $taxonomy_name * - Term Name. * @param string $vocab_machine_name * - System id of the vocabulary term will be added to. * @param string|int $weight * - Taxonomy term weight. * @param array $parent_tid * - Array of term ids to be assigned as parent. * * @return int|null * - Returns the term id of the created term on success, null on failure. * * @throws \Drupal\Core\Entity\EntityStorageException */ function _uw_cfg_common_create_term($taxonomy_name, $vocab_machine_name, $weight, array $parent_tid = []) { // Create the taxonomy term. $new_term = Term::create([ 'name' => $taxonomy_name, 'vid' => $vocab_machine_name, 'parent' => $parent_tid, 'weight' => $weight, ]); // Save the taxonomy term. $new_term->save(); // Return the taxonomy term id. return $new_term->id(); } /** * Implements hook_update_dependencies(). */ function uw_cfg_common_update_dependencies() { $dependencies['uw_cfg_common'][8103] = [ 'uw_sites_all' => 8105, ]; return $dependencies; } /** * Implements hook_update_N(). */ /** * Update listing blocks items per page when needed. * * For listing blocks items per page, when default settings were used, * change to the original default number of items. */ function uw_cfg_common_update_8101() { // Block ids that need to be changed, and what the original default was. // For some reason, we didn't originally use the same number for everything. $block_ids = [ 'views_block:uw_view_blogs-blogs_listing_block' => 5, 'views_block:uw_view_events-events_listing_block' => 10, 'views_block:uw_view_news_items-news_items_listing_block' => 10, ]; // Load all the nodes. $nodes = Node::loadMultiple(); // Step through each node and set any that were using the default setting // to the number that was the default before this change. foreach ($nodes as $node) { // Flag to save the node, have this to save processing // time if we don't need to save the node after the checks. $save_node_flag = FALSE; // Load the layout and sections. $layout = $node->get('layout_builder__layout'); $sections = $layout->getSections(); // Step through each of the sections. foreach ($sections as $section) { // Load the components for the section. $components = $section->getComponents(); // Step through each of the components. foreach ($components as $component) { // If this component is one that needs to be changed, // then check for setting and change if required. if (in_array($component->getPluginId(), array_keys($block_ids))) { // Load the config for the block. $configurations = $component->get('configuration'); // If the config is set to "none", it needs to be changed to // be set to the number that was the old default value. if ($configurations['items_per_page'] == 'none') { // Change the config and save the component. $configurations['items_per_page'] = $block_ids[$component->getPluginId()]; $component->setConfiguration($configurations); // Set the save node flag so that we know to // save this node as the last step in the loop. $save_node_flag = TRUE; } } } // If we need to save the node, then save it. if ($save_node_flag) { $node->save(); } } // Load all the revisions for the node. $vids = \Drupal::service('entity_type.manager')->getStorage('node')->revisionIds($node); // Step through each revision, and check if we have to // change the settings for the listing blocks. foreach ($vids as $vid) { // Flag to see if we have to save the revision. $save_revision_flag = FALSE; // Load the revision node. $revision_node = \Drupal::service('entity_type.manager')->getStorage('node')->loadRevision($vid); // Comments from here down are the same as above. $layout = $revision_node->get('layout_builder__layout'); $sections = $layout->getSections(); foreach ($sections as $section) { $components = $section->getComponents(); foreach ($components as $component) { if (in_array($component->getPluginId(), $block_ids)) { $configurations = $component->get('configuration'); if ( $configurations['items_per_page'] == 'none' || $configurations['items_per_page'] == '5' ) { $configurations['items_per_page'] = '3'; $component->setConfiguration($configurations); $save_revision_flag = TRUE; } } } } if ($save_revision_flag) { $revision_node->save(); } } } } /** * Set draggable views permissions, since cd-update doesn't do it reliably. */ function uw_cfg_common_update_8102() { $roles = [ 'uw_role_content_author', 'uw_role_content_editor', 'uw_role_form_editor', 'uw_role_form_results_access', 'uw_role_site_manager', 'uw_role_site_owner', ]; foreach ($roles as $role_name) { $role_object = Role::load($role_name); $role_object->grantPermission('access draggableviews'); $role_object->save(); } } /** * Load config and assigns permissions to roles. * * Load quick_node_clone config. */ function uw_cfg_common_update_8103() { // Load config that is not being set properly by config distro update. $config_path = drupal_get_path('module', 'uw_cfg_common') . '/config/install'; $source = new FileStorage($config_path); $config_storage = \Drupal::service('config.storage'); $config_storage->write('quick_node_clone.settings', $source->read('quick_node_clone.settings')); // List of permissions needed to be applied to roles. $permissions = [ 'clone uw_ct_blog content', 'clone uw_ct_catalog_item content', 'clone uw_ct_contact content', 'clone uw_ct_event content', 'clone uw_ct_news_item content', 'clone uw_ct_profile content', 'clone uw_ct_sidebar content', 'clone uw_ct_web_page content', ]; // Roles that require updated permissions. $role_ids = [ 'uw_role_site_manager', 'uw_role_content_editor', 'uw_role_content_author', ]; $roles = Role::loadMultiple($role_ids); // Grant all all roles. foreach ($permissions as $permission) { $roles['uw_role_site_manager']->grantPermission($permission); $roles['uw_role_content_editor']->grantPermission($permission); $roles['uw_role_content_author']->grantPermission($permission); } // Save role with new permissions. $roles['uw_role_site_manager']->save(); $roles['uw_role_content_editor']->save(); $roles['uw_role_content_author']->save(); } /** * Give default access to Webforms that have no access to create submissions. */ function uw_cfg_common_update_8104() { $counter = 0; $webforms = \Drupal::entityTypeManager()->getStorage('webform')->loadMultiple(); foreach ($webforms as $webform) { $access = $webform->getAccessRules(); if (empty($access['create']['roles'])) { $access['create']['roles'] = [ 'anonymous', 'authenticated', ]; $webform->setAccessRules($access); $webform->save(); $counter++; } } return t('Set default access for @counter Webforms.', ['@counter' => $counter]); } /** * Update the fields required for new media section. */ function uw_cfg_common_update_9101() { // The content types to get updated. $node_types = [ 'uw_ct_blog', 'uw_ct_event', 'uw_ct_news_item', ]; // We need to a feature revert first, so tha the fields for // type of media are created. // Reverting uw_cfg_common first so that the fields get created. \Drupal::service('uw_cfg_common.features')->import(['uw_cfg_common']); // Revert the rest of the content types. \Drupal::service('uw_cfg_common.features')->import($node_types); // Step through each of the content types and update the field. foreach ($node_types as $node_type) { // Get all the nids of the content type. $nids = \Drupal::service('entity_type.manager')->getStorage('node')->getQuery()->condition('type', $node_type)->execute(); // Step through each of the nids, get the node and check // if we have to update the field. foreach ($nids as $nid) { // Load the node. $node = \Drupal::service('entity_type.manager')->getStorage('node')->load($nid); // If there is a hero image, update the type of media field, // then save the node. if ($node->field_uw_hero_image->entity) { $node->set("field_uw_type_of_media", 'image'); $node->save(); } } } } /** * Set all Webforms to use the access denied page. */ function uw_cfg_common_update_9102() { $webforms = \Drupal::entityTypeManager()->getStorage('webform')->loadMultiple(); foreach ($webforms as $webform) { // This is set as the default in uw_cfg_common_webform_create(). $webform->setSetting('form_access_denied', WebformInterface::ACCESS_DENIED_PAGE); $webform->save(); } } /** * Add Private content viewer role for the existing site. */ function uw_cfg_common_update_9103() { Role::create([ 'id' => 'uw_role_private_content_viewer', 'label' => 'Private content viewer', ])->save(); } /** * Removes missing blocks from temp storage and saved nodes (revisions too). */ function uw_cfg_common_update_9104(&$sandbox) { $service = \Drupal::service('uw_cfg_common.missing_blocks'); $service->removeMissingBlocksFromUnsaved(); $service->removeMissingBlocksFromSaved(); } /** * Feature revert for workflows. */ function uw_cfg_common_update_9105(&$sandbox) { $name = 'workflows.workflow.uw_workflow'; $path = \Drupal::service('extension.list.module')->getPath('uw_cfg_common') . '/config/custom/'; $source = new FileStorage($path); $active_storage = \Drupal::service('config.storage'); $active_storage->write($name, $source->read($name)); } /** * Add new fields for banners above. */ function uw_cfg_common_update_9106(&$sandbox) { // The content types that are not getting any changes. $cts_not_to_install = [ 'uw_ct_sidebar', 'uw_ct_site_footer', 'uw_ct_expand_collapse_group', ]; // The content types with media already in it (hero image). $cts_with_media = [ 'uw_ct_blog', 'uw_ct_event', 'uw_ct_news_item', ]; // Get all the node types. $node_types = \Drupal::entityTypeManager()->getStorage('node_type')->loadMultiple(); // Step through each node type and get the path to // the module and the machine name. foreach ($node_types as $node_type) { // Get the id from the node type. $id = $node_type->id(); // Ensure we are only getting the node type // that need updating. if (!in_array($id, $cts_not_to_install)) { // Catalogs and opportunities have different paths // and ids, so setup the content types array with // the correct info. if ($id == 'uw_ct_catalog_item') { $content_types['uw_ct_catalog'] = $id; } elseif ($id == 'uw_ct_opportunity') { $content_types['uw_ct_opportunities'] = $id; } else { $content_types[$id] = $id; } } } // Get the type of media field that we need to udpate. $type_of_media = current(\Drupal::entityTypeManager()->getStorage('field_storage_config')->loadByProperties(['id' => 'node.field_uw_type_of_media'])); // Get the type of media settings. $settings = $type_of_media->getSettings(); // Update the settings to remove the allowed values and // add the allowed values function. $settings['allowed_values'] = []; $settings['allowed_values_function'] = '_uw_cfg_common_allowed_media_types'; // Set the update settings. $type_of_media->setSettings($settings); // Save the field. $type_of_media->save(); // The names of the fields we need to install. $names = [ 'field.storage.node.field_uw_banner', 'field.storage.node.field_uw_media_width', 'field.storage.node.field_uw_slide_speed', 'field.storage.node.field_uw_transition_speed', 'field.storage.node.field_uw_text_overlay_style', ]; // Get the path to cfg common config install directory. $path = \Drupal::service('extension.list.module')->getPath('uw_cfg_common') . '/config/install/'; $config_dir = new FileStorage($path); // Step through each of the field names and install them. foreach ($names as $name) { // Get the config from the yml file into an array. $config_record = $config_dir->read($name); // Get the entity type. $entity_type = \Drupal::service('config.manager')->getEntityTypeIdByName($name); // Get the storage. $storage = \Drupal::entityTypeManager()->getStorage($entity_type); // Create the new field from the converted yml. $field = $storage->createFromStorageRecord($config_record); // Save the new field. $field->save(); } // Step through each of the content types and install the fields, // and also setup default values for the fields. foreach ($content_types as $path => $id) { // Get the path to the content type. $path = \Drupal::service('extension.list.module')->getPath($path) . '/config/install/'; $config_dir = new FileStorage($path); // The names of the fields to install. $names = [ 'field.field.node.' . $id . '.field_uw_banner', 'field.field.node.' . $id . '.field_uw_type_of_media', 'field.field.node.' . $id . '.field_uw_media_width', 'field.field.node.' . $id . '.field_uw_text_overlay_style', 'field.field.node.' . $id . '.field_uw_transition_speed', ]; // Step through each of the fields and install them. foreach ($names as $name) { // Get the config from the yml into an array. $config_record = $config_dir->read($name); // If the field config is not install, install it. if (!FieldConfig::loadByName( $config_record['entity_type'], $config_record['bundle'], $config_record['field_name']) ) { FieldConfig::create($config_record)->save(); } } // If there is no media yet on the content type, // then install the type of hero image field. if (!in_array($id, $cts_with_media)) { // Name of the hero image field. $name = 'field.field.node.' . $id . '.field_uw_hero_image'; // Get the config from the yml into an array. $config_record = $config_dir->read($name); // If the field config is not install, install it. if (!FieldConfig::loadByName($config_record['entity_type'], $config_record['bundle'], $config_record['field_name'])) { FieldConfig::create($config_record)->save(); } } // Get all the nodes of the content type. $nodes = \Drupal::entityTypeManager()->getStorage('node')->loadByProperties(['type' => $id]); // Step through each of the nodes and set the default // values of the fields. foreach ($nodes as $node) { // Set default values for banners. $node->field_uw_banner = NULL; $node->field_uw_media_width = 'uw_lbs_full_width'; $node->field_uw_slide_speed = 7000; $node->field_uw_transition_speed = 400; $node->field_uw_text_overlay_style = 'full-width'; // If the content type does not have media yet, // set the default value for type of media. if (!in_array($id, $cts_with_media)) { $node->field_uw_type_of_media = NULL; } // Save the node. $node->save(); } } }