diff --git a/composer.json b/composer.json index a0c62e2..0b6fce5 100644 --- a/composer.json +++ b/composer.json @@ -19,7 +19,8 @@ "drupal/migrate_tools": "^4.0", "drupal/migrate_plus": "^4.0", "drupal/webform": "^5.0@RC", - "drupal/wysiwyg_linebreaks": "^1.9" + "drupal/wysiwyg_linebreaks": "^1.9", + "drupal/redirect": "^1.2" }, "repositories": { "drupal": { diff --git a/config/sync/core.extension.yml b/config/sync/core.extension.yml index 0f6fd51..7fe722c 100644 --- a/config/sync/core.extension.yml +++ b/config/sync/core.extension.yml @@ -84,6 +84,7 @@ module: path: 0 quickedit: 0 rdf: 0 + redirect: 0 responsive_image: 0 search_api: 0 search_api_db: 0 diff --git a/config/sync/pathauto.pattern.user.yml b/config/sync/pathauto.pattern.user.yml new file mode 100644 index 0000000..bf3036c --- /dev/null +++ b/config/sync/pathauto.pattern.user.yml @@ -0,0 +1,14 @@ +uuid: 9e4d7ba6-e074-48d4-a979-367f85d51409 +langcode: en +status: true +dependencies: + module: + - user +id: user +label: User +type: 'canonical_entities:user' +pattern: 'people/[user:name]' +selection_criteria: { } +selection_logic: and +weight: 0 +relationships: { } diff --git a/config/sync/redirect.settings.yml b/config/sync/redirect.settings.yml new file mode 100644 index 0000000..79c09c8 --- /dev/null +++ b/config/sync/redirect.settings.yml @@ -0,0 +1,9 @@ +auto_redirect: true +default_status_code: 301 +passthrough_querystring: true +warning: false +ignore_admin_path: false +access_check: false +route_normalizer_enabled: true +_core: + default_config_hash: FEwQLW1wXW7fiJdG1B2bxW1c_-k6w-r-3V3bSsW6PqM diff --git a/config/sync/views.view.redirect.yml b/config/sync/views.view.redirect.yml new file mode 100644 index 0000000..80dffdb --- /dev/null +++ b/config/sync/views.view.redirect.yml @@ -0,0 +1,600 @@ +uuid: b03f0b78-a311-427e-9377-59633aee7985 +langcode: en +status: true +dependencies: + module: + - link + - redirect + - user +_core: + default_config_hash: nyKyD0xiKPzp-sRYnfEnHSMz29rdivJvMv2Qjnm5jvk +id: redirect +label: Redirect +module: views +description: 'List of redirects' +tag: '' +base_table: redirect +base_field: rid +core: 8.x +display: + default: + display_plugin: default + id: default + display_title: Master + position: 0 + display_options: + access: + type: perm + options: + perm: 'administer redirects' + cache: + type: tag + options: { } + query: + type: views_query + options: + disable_sql_rewrite: false + distinct: false + replica: false + query_comment: '' + query_tags: { } + exposed_form: + type: basic + options: + submit_button: Apply + reset_button: false + reset_button_label: Reset + exposed_sorts_label: 'Sort by' + expose_sort_order: true + sort_asc_label: Asc + sort_desc_label: Desc + pager: + type: full + options: + items_per_page: 50 + offset: 0 + id: 0 + total_pages: null + tags: + previous: '‹ previous' + next: 'next ›' + first: '« first' + last: 'last »' + expose: + items_per_page: false + items_per_page_label: 'Items per page' + items_per_page_options: '5, 10, 25, 50' + items_per_page_options_all: false + items_per_page_options_all_label: '- All -' + offset: false + offset_label: Offset + quantity: 9 + style: + type: table + options: + grouping: { } + row_class: '' + default_row_class: true + override: true + sticky: false + caption: '' + summary: '' + description: '' + columns: + redirect_source__path: redirect_source__path + redirect_redirect__uri: redirect_redirect__uri + status_code: status_code + language: language + created: created + operations: operations + info: + redirect_source__path: + sortable: true + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + redirect_redirect__uri: + sortable: true + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + status_code: + sortable: true + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + language: + sortable: true + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + created: + sortable: true + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + operations: + sortable: false + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + default: created + empty_table: false + row: + type: fields + fields: + redirect_bulk_form: + id: redirect_bulk_form + table: redirect + field: redirect_bulk_form + relationship: none + group_type: group + admin_label: '' + label: '' + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: false + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + action_title: 'With selection' + include_exclude: exclude + selected_actions: { } + entity_type: redirect + plugin_id: redirect_bulk_form + redirect_source__path: + id: redirect_source__path + table: redirect + field: redirect_source__path + relationship: none + group_type: group + admin_label: '' + label: From + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + click_sort_column: path + type: redirect_source + settings: { } + group_column: '' + group_columns: { } + group_rows: true + delta_limit: 0 + delta_offset: 0 + delta_reversed: false + delta_first_last: false + multi_type: separator + separator: ', ' + field_api_classes: false + entity_type: redirect + entity_field: redirect_source + plugin_id: field + redirect_redirect__uri: + id: redirect_redirect__uri + table: redirect + field: redirect_redirect__uri + entity_type: redirect + entity_field: redirect_redirect + plugin_id: field + status_code: + id: status_code + table: redirect + field: status_code + entity_type: redirect + entity_field: status_code + plugin_id: field + language: + id: language + table: redirect + field: language + entity_type: redirect + entity_field: language + plugin_id: field + created: + id: created + table: redirect + field: created + relationship: none + group_type: group + admin_label: '' + label: Created + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + date_format: fallback + custom_date_format: '' + timezone: '' + entity_type: redirect + entity_field: created + plugin_id: date + operations: + id: operations + table: redirect + field: operations + entity_type: redirect + plugin_id: entity_operations + filters: + redirect_source__path: + id: redirect_source__path + table: redirect + field: redirect_source__path + relationship: none + group_type: group + admin_label: '' + operator: contains + value: '' + group: 1 + exposed: true + expose: + operator_id: redirect_source__path_op + label: From + description: '' + use_operator: false + operator: redirect_source__path_op + identifier: redirect_source__path + required: false + remember: false + multiple: false + remember_roles: + authenticated: authenticated + anonymous: '0' + administrator: '0' + is_grouped: false + group_info: + label: '' + description: '' + identifier: '' + optional: true + widget: select + multiple: false + remember: false + default_group: All + default_group_multiple: { } + group_items: { } + entity_type: redirect + entity_field: redirect_source + plugin_id: string + redirect_redirect__uri: + id: redirect_redirect__uri + table: redirect + field: redirect_redirect__uri + relationship: none + group_type: group + admin_label: '' + operator: contains + value: '' + group: 1 + exposed: true + expose: + operator_id: redirect_redirect__uri_op + label: To + description: '' + use_operator: false + operator: redirect_redirect__uri_op + identifier: redirect_redirect__uri + required: false + remember: false + multiple: false + remember_roles: + authenticated: authenticated + anonymous: '0' + administrator: '0' + is_grouped: false + group_info: + label: '' + description: '' + identifier: '' + optional: true + widget: select + multiple: false + remember: false + default_group: All + default_group_multiple: { } + group_items: { } + entity_type: redirect + entity_field: redirect_redirect + plugin_id: string + status_code: + id: status_code + table: redirect + field: status_code + relationship: none + group_type: group + admin_label: '' + operator: '=' + value: + min: '' + max: '' + value: '' + group: 1 + exposed: true + expose: + operator_id: status_code_op + label: 'Status code' + description: '' + use_operator: false + operator: status_code_op + identifier: status_code + required: false + remember: false + multiple: false + remember_roles: + authenticated: authenticated + anonymous: '0' + administrator: '0' + is_grouped: true + group_info: + label: 'Status code' + description: '' + identifier: status_code + optional: true + widget: select + multiple: false + remember: false + default_group: All + default_group_multiple: { } + group_items: + 1: + title: '300 Multiple Choices' + operator: '=' + value: + value: '300' + min: '' + max: '' + 2: + title: '301 Moved Permanently' + operator: '=' + value: + value: '301' + min: '' + max: '' + 3: + title: '302 Found' + operator: '=' + value: + value: '302' + min: '' + max: '' + 4: + title: '303 See Other' + operator: '=' + value: + value: '303' + min: '' + max: '' + 5: + title: '304 Not Modified' + operator: '=' + value: + value: '304' + min: '' + max: '' + 6: + title: '305 Use Proxy' + operator: '=' + value: + value: '305' + min: '' + max: '' + 7: + title: '307 Temporary Redirect' + operator: '=' + value: + value: '307' + min: '' + max: '' + entity_type: redirect + entity_field: status_code + plugin_id: numeric + language: + id: language + table: redirect + field: language + relationship: none + group_type: group + admin_label: '' + operator: in + value: { } + group: 1 + exposed: true + expose: + operator_id: language_op + label: 'Original language' + description: '' + use_operator: false + operator: language_op + identifier: language + required: false + remember: false + multiple: false + remember_roles: + authenticated: authenticated + anonymous: '0' + administrator: '0' + reduce: false + is_grouped: false + group_info: + label: '' + description: '' + identifier: '' + optional: true + widget: select + multiple: false + remember: false + default_group: All + default_group_multiple: { } + group_items: { } + entity_type: redirect + entity_field: language + plugin_id: language + sorts: { } + title: Redirect + header: { } + footer: { } + empty: + area_text_custom: + id: area_text_custom + table: views + field: area_text_custom + relationship: none + group_type: group + admin_label: '' + empty: true + tokenize: false + content: 'There is no redirect yet.' + plugin_id: text_custom + relationships: { } + arguments: { } + display_extenders: { } + filter_groups: + operator: AND + groups: + 1: AND + cache_metadata: + contexts: + - 'languages:language_content' + - 'languages:language_interface' + - url + - url.query_args + - user.permissions + cacheable: false + max-age: 0 + tags: { } + page_1: + display_plugin: page + id: page_1 + display_title: Page + position: 1 + display_options: + display_extenders: { } + path: admin/config/search/redirect + cache_metadata: + contexts: + - 'languages:language_content' + - 'languages:language_interface' + - url + - url.query_args + - user.permissions + cacheable: false + max-age: 0 + tags: { } diff --git a/web/modules/custom/agaric_migration/migrations/redirect.yml b/web/modules/custom/agaric_migration/migrations/redirect.yml new file mode 100644 index 0000000..e31a881 --- /dev/null +++ b/web/modules/custom/agaric_migration/migrations/redirect.yml @@ -0,0 +1,41 @@ +id: agaric_redirect +migration_group: agaric +label: Agaric Path Redirect +source: + plugin: d7_path_redirect + scheme: public +process: + rid: rid + uid: + - plugin: migration_lookup + migration: agaric_user + source: uid + no_stub: true + - # If the user id does not exists then migrate it as anonymous. + plugin: default_value + default_value: 0 + redirect_source/path: source + redirect_source/query: + plugin: d7_redirect_source_query + source: source_options + redirect_redirect/uri: + - + plugin: migration_lookup_uri + source: + - redirect + - redirect_options + - + plugin: d7_path_redirect + language: + plugin: default_value + source: language + default_value: und + status_code: + - + plugin: static_map + source: status_code + map: + 0: 301 + bypass: TRUE +destination: + plugin: entity:redirect diff --git a/web/modules/custom/agaric_migration/src/Plugin/migrate/process/MigrationLookupUri.php b/web/modules/custom/agaric_migration/src/Plugin/migrate/process/MigrationLookupUri.php new file mode 100644 index 0000000..3c0bccf --- /dev/null +++ b/web/modules/custom/agaric_migration/src/Plugin/migrate/process/MigrationLookupUri.php @@ -0,0 +1,102 @@ +connection = $database; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { + return new static( + $configuration, + $plugin_id, + $plugin_definition, + $container->get('database') + ); + } + + /** + * {@inheritdoc} + */ + public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) { + $redirect = $value[0]; + $new_value = []; + // We just pass along the $redirect_options. + $new_value[1] = $value[1]; + + // The entities used in the old agaric sites are: user and node. + if (preg_match('/^(user|node)\/([0-9]+)$/', $redirect, $matches)) { + $entity_type = $matches[1]; + $id = $matches[2]; + + if ($entity_type == 'node') { + $node_migrations = [ + 'migrate_map_agaric_blog', + 'migrate_map_agaric_page', + ]; + foreach ($node_migrations as $node_migration) { + $result = $this->connection->select($node_migration, 'm') + ->fields('m') + ->condition('sourceid1', $id) + ->execute(); + $row = $result->fetchAssoc(); + if (!empty($row)) { + $new_value[0] = 'node/' . $row['destid1']; + break; + } + $new_value[0] = 'node/' . $row['destid1']; + } + } + elseif ($entity_type == 'user') { + $result = $this->connection->select('migrate_map_agaric_user', 'm') + ->fields('m') + ->condition('sourceid1', $id) + ->execute(); + $row = $result->fetchAssoc(); + $id = (!empty($row)) ? $row['destid1'] : $id; + $new_value[0] = 'user/' . $id; + } + } + else { + // Anything different that a redirect to user or node will be ignored. + $new_value[0] = $value[0]; + } + + return $new_value; + } + +}