started custom migration module migrate_leshed

This commit is contained in:
2026-07-11 15:20:42 +02:00
parent a1201aff21
commit ec5b13be3c
16 changed files with 3287 additions and 244 deletions

25
.vscode/launch.json vendored Normal file
View File

@@ -0,0 +1,25 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Listen for Xdebug",
"type": "php",
"request": "launch",
"port": 9001,
"pathMappings": {
"/var/www/leshed": "${workspaceFolder}"
},
},
{
"name": "Launch currently open script",
"type": "php",
"request": "launch",
"program": "${file}",
"cwd": "${fileDirname}",
"port": 9001
}
]
}

View File

@@ -20,6 +20,8 @@
"drupal/core-composer-scaffold": "^10.6", "drupal/core-composer-scaffold": "^10.6",
"drupal/core-project-message": "^10.6", "drupal/core-project-message": "^10.6",
"drupal/core-recommended": "^10.6", "drupal/core-recommended": "^10.6",
"drupal/migrate_google_sheets": "^2.3",
"drupal/migrate_tools": "^6.1",
"wikimedia/composer-merge-plugin": "^2.1" "wikimedia/composer-merge-plugin": "^2.1"
}, },
"conflict": { "conflict": {

662
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -63,6 +63,11 @@ module:
menu_block: 0 menu_block: 0
menu_link_content: 0 menu_link_content: 0
menu_ui: 0 menu_ui: 0
migrate: 0
migrate_google_sheets: 0
migrate_leshed: 0
migrate_plus: 0
migrate_tools: 0
mysql: 0 mysql: 0
node: 0 node: 0
options: 0 options: 0
@@ -73,6 +78,7 @@ module:
path_alias_xt: 0 path_alias_xt: 0
pathologic: 0 pathologic: 0
persistent_login: 0 persistent_login: 0
redirect: 0
redis: 0 redis: 0
responsive_image: 0 responsive_image: 0
search_api: 0 search_api: 0

View File

@@ -0,0 +1,13 @@
uuid: bc346faf-2574-409d-bbe1-325f4498ade5
langcode: en
status: true
dependencies:
module:
- redirect
_core:
default_config_hash: y734AXEpjry1Ppff_hQQBFQGJvYjF0fk1JoWtp5q2JY
id: redirect.redirect
target_entity_type_id: redirect
target_bundle: redirect
default_langcode: und
language_alterable: true

View File

@@ -0,0 +1 @@
api_key: AIzaSyBOzRmGI0voXH7Ly8eva3PmphdzGuaNKsc

View File

@@ -0,0 +1,61 @@
uuid: a3812d6e-7a67-4110-bb47-d1062709f806
langcode: fr
status: true
dependencies:
- migrate_google_sheets
- migrate_plus
id: projet_node
class: null
field_plugin_method: null
cck_plugin_method: null
migration_tags: null
migration_group: le_shed
label: 'Import des projets depuis Google Sheets'
source:
plugin: projet_node
data_fetcher_plugin: http
data_parser_plugin: google_sheets
urls: 'https://sheets.googleapis.com/v4/spreadsheets/1561Gv1C-IlCTmg64Z8HnznvOeLbvwhA_k1l6aq95zFA/values/Projets?key=AIzaSyBOzRmGI0voXH7Ly8eva3PmphdzGuaNKsc'
fields:
-
name: id
label: 'Unique identifier'
selector: UID
-
name: title
label: Title
selector: 'Nom du projet'
-
name: date_start
label: 'Date start'
selector: 'Date de début de projet'
-
name: date_end
label: 'Date end'
selector: 'Date de fin de projet'
ids:
id:
type: integer
process:
type:
plugin: default_value
default_value: projet
title: title
field_dates/value:
plugin: format_date
source: date_start
from_format: d/m/Y
to_format: Y-m-d
field_dates/end_value:
plugin: format_date
source: date_end
from_format: d/m/Y
to_format: Y-m-d
uid:
plugin: default_value
default_value: 3
destination:
plugin: 'entity:node'
idMap: { }
migration_dependencies: { }
include: null

View File

@@ -0,0 +1,10 @@
uuid: 98ad5e45-0e03-4a77-97e3-93fe57fee1ed
langcode: en
status: true
dependencies: { }
id: le_shed
label: 'Le shed'
description: ''
source_type: 'google doc sheets'
module: null
shared_configuration: null

View File

@@ -0,0 +1,13 @@
uuid: 526a6b2c-b190-400b-871c-f05493f0d560
langcode: fr
status: true
dependencies:
module:
- redirect
_core:
default_config_hash: 2T-yEyZvw_9I2XVc5fquqcWBvzm6y2o3be2YbQwKe8E
id: redirect_delete_action
label: 'Supprimer une redirection'
type: redirect
plugin: redirect_delete_action
configuration: { }

View File

@@ -0,0 +1,675 @@
uuid: 9a4699d7-3273-4b1b-86d8-4162478dcbe8
langcode: fr
status: true
dependencies:
module:
- link
- redirect
- user
_core:
default_config_hash: DexqLBdD7TB7piALIPEvcHI9NvY1BNibYaTSF-aJWUw
id: redirect
label: Rediriger
module: views
description: 'List of redirects'
tag: ''
base_table: redirect
base_field: rid
display:
default:
id: default
display_title: Principal
display_plugin: default
position: 0
display_options:
title: Rediriger
fields:
redirect_bulk_form:
id: redirect_bulk_form
table: redirect
field: redirect_bulk_form
relationship: none
group_type: group
admin_label: ''
entity_type: redirect
plugin_id: redirect_bulk_form
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: { }
redirect_source__path:
id: redirect_source__path
table: redirect
field: redirect_source__path
relationship: none
group_type: group
admin_label: ''
entity_type: redirect
entity_field: redirect_source
plugin_id: field
label: 'A partir de'
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
redirect_redirect__uri:
id: redirect_redirect__uri
table: redirect
field: redirect_redirect__uri
entity_type: redirect
entity_field: redirect_redirect
plugin_id: field
enabled:
id: enabled
table: redirect
field: enabled
relationship: none
group_type: group
admin_label: ''
entity_type: redirect
entity_field: enabled
plugin_id: field
label: Activé
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: value
type: boolean
settings:
format: enabled-disabled
format_custom_false: ''
format_custom_true: ''
group_column: value
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
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: ''
entity_type: redirect
entity_field: created
plugin_id: date
label: Créé
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: ''
operations:
id: operations
table: redirect
field: operations
entity_type: redirect
plugin_id: entity_operations
pager:
type: full
options:
offset: 0
pagination_heading_level: h4
items_per_page: 50
total_pages: null
id: 0
tags:
next: 'next '
previous: ' previous'
first: '« first'
last: 'last »'
expose:
items_per_page: false
items_per_page_label: 'Éléments par page'
items_per_page_options: '5, 10, 25, 50'
items_per_page_options_all: false
items_per_page_options_all_label: '- Tout -'
offset: false
offset_label: Décalage
quantity: 9
exposed_form:
type: basic
options:
submit_button: Filtrer
reset_button: true
reset_button_label: Réinitialiser
exposed_sorts_label: 'Trier par'
expose_sort_order: true
sort_asc_label: Asc
sort_desc_label: Desc
access:
type: perm
options:
perm: 'administer redirects'
cache:
type: tag
options: { }
empty:
area_text_custom:
id: area_text_custom
table: views
field: area_text_custom
relationship: none
group_type: group
admin_label: ''
plugin_id: text_custom
empty: true
content: 'There is no redirect yet.'
tokenize: false
sorts: { }
arguments: { }
filters:
redirect_source__path:
id: redirect_source__path
table: redirect
field: redirect_source__path
relationship: none
group_type: group
admin_label: ''
entity_type: redirect
entity_field: redirect_source
plugin_id: string
operator: contains
value: ''
group: 1
exposed: true
expose:
operator_id: redirect_source__path_op
label: 'A partir de'
description: ''
use_operator: false
operator: redirect_source__path_op
operator_limit_selection: false
operator_list: { }
identifier: redirect_source__path
required: false
remember: false
multiple: false
remember_roles:
authenticated: authenticated
is_grouped: false
group_info:
label: ''
description: ''
identifier: ''
optional: true
widget: select
multiple: false
remember: false
default_group: All
default_group_multiple: { }
group_items: { }
redirect_redirect__uri:
id: redirect_redirect__uri
table: redirect
field: redirect_redirect__uri
relationship: none
group_type: group
admin_label: ''
entity_type: redirect
entity_field: redirect_redirect
plugin_id: string
operator: contains
value: ''
group: 1
exposed: true
expose:
operator_id: redirect_redirect__uri_op
label: À
description: ''
use_operator: false
operator: redirect_redirect__uri_op
operator_limit_selection: false
operator_list: { }
identifier: redirect_redirect__uri
required: false
remember: false
multiple: false
remember_roles:
authenticated: authenticated
is_grouped: false
group_info:
label: ''
description: ''
identifier: ''
optional: true
widget: select
multiple: false
remember: false
default_group: All
default_group_multiple: { }
group_items: { }
status_code:
id: status_code
table: redirect
field: status_code
relationship: none
group_type: group
admin_label: ''
entity_type: redirect
entity_field: status_code
plugin_id: numeric
operator: '='
value:
min: ''
max: ''
value: ''
group: 1
exposed: true
expose:
operator_id: status_code_op
label: 'Code du statut'
description: ''
use_operator: false
operator: status_code_op
operator_limit_selection: false
operator_list: { }
identifier: status_code
required: false
remember: false
multiple: false
remember_roles:
authenticated: authenticated
is_grouped: true
group_info:
label: 'Code du statut'
description: ''
identifier: status_code
optional: true
widget: select
multiple: false
remember: false
default_group: All
default_group_multiple: { }
group_items:
1:
title: '300 Choix Multiples'
operator: '='
value:
min: ''
max: ''
value: '300'
2:
title: '301 Redirection Permanente'
operator: '='
value:
min: ''
max: ''
value: '301'
3:
title: '302 Trouvé'
operator: '='
value:
min: ''
max: ''
value: '302'
4:
title: '303 Voir Ailleurs'
operator: '='
value:
min: ''
max: ''
value: '303'
5:
title: '304 Non Modifié'
operator: '='
value:
min: ''
max: ''
value: '304'
6:
title: '305 Utilise un Proxy'
operator: '='
value:
min: ''
max: ''
value: '305'
7:
title: '307 Redirection Temporaire'
operator: '='
value:
min: ''
max: ''
value: '307'
language:
id: language
table: redirect
field: language
relationship: none
group_type: group
admin_label: ''
entity_type: redirect
entity_field: language
plugin_id: language
operator: in
value: { }
group: 1
exposed: true
expose:
operator_id: language_op
label: 'Langue initiale'
description: ''
use_operator: false
operator: language_op
operator_limit_selection: false
operator_list: { }
identifier: language
required: false
remember: false
multiple: false
remember_roles:
authenticated: authenticated
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: { }
filter_groups:
operator: AND
groups:
1: AND
style:
type: table
options:
grouping: { }
row_class: ''
default_row_class: true
columns:
redirect_source__path: redirect_source__path
redirect_redirect__uri: redirect_redirect__uri
enabled: enabled
status_code: status_code
language: language
created: created
operations: operations
default: created
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: ''
enabled:
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: ''
override: true
sticky: false
summary: ''
empty_table: false
caption: ''
description: ''
row:
type: fields
query:
type: views_query
options:
query_comment: ''
disable_sql_rewrite: false
distinct: false
replica: false
query_tags: { }
relationships: { }
header: { }
footer: { }
display_extenders: { }
cache_metadata:
max-age: 0
contexts:
- 'languages:language_content'
- 'languages:language_interface'
- url
- url.query_args
- user.permissions
tags: { }
cacheable: false
page_1:
id: page_1
display_title: Page
display_plugin: page
position: 1
display_options:
display_extenders: { }
path: admin/config/search/redirect
cache_metadata:
max-age: 0
contexts:
- 'languages:language_content'
- 'languages:language_interface'
- url
- url.query_args
- user.permissions
tags: { }
cacheable: false

1901
googlesheet/Projets.json Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,75 @@
langcode: fr
status: true
dependencies:
- migrate_google_sheets
- migrate_plus
id: projet_node
label: 'Import des projets depuis Google Sheets'
migration_group: le_shed
source:
plugin: projet_node
data_fetcher_plugin: http
data_parser_plugin: google_sheets
# The feed file for the spreadsheet. The Google Spreadsheet should be either “Public” or set to “Anyone with link can
# view” in order for the feed to work.
# Template: 'https://sheets.googleapis.com/v4/spreadsheets/<SHEET>/values/<TAB>?key=<KEY>'
urls: 'https://sheets.googleapis.com/v4/spreadsheets/1561Gv1C-IlCTmg64Z8HnznvOeLbvwhA_k1l6aq95zFA/values/Projets?key=AIzaSyBOzRmGI0voXH7Ly8eva3PmphdzGuaNKsc'
# Under 'fields', we list the data items to be imported. The first level keys
# are the source field names we want to populate (the names to be used as
# sources in the process configuration below). For each field we're importing,
# we provide a label (optional - this is for display in migration tools) and
# an selector (xpath) for retrieving that value. It's important to note that this xpath
# is relative to the elements retrieved by item_selector.
# For Google Spreadsheet XML feeds the actual columns are named with gsx: followed by the cleaned column name (lower,
# limited punctuation, etc).destination:
fields:
-
name: id
label: 'Unique identifier'
selector: 'UID'
-
name: title
label: 'Title'
selector: 'Nom du projet'
-
name: date_start
label: 'Date start'
selector: 'Date de début de projet'
-
name: date_end
label: 'Date end'
selector: 'Date de fin de projet'
-
name: projet_type
label: 'Type de projet'
selector: 'Type de projet'
# Under 'ids', we identify source fields populated above which will uniquely
# identify each imported item. The 'type' makes sure the migration map table
# uses the proper schema type for stored the IDs.
ids:
id:
type: integer
process:
type:
plugin: default_value
default_value: projet
title: title
field_dates/value:
plugin: format_date
source: date_start
from_format: 'd/m/Y'
to_format: 'Y-m-d'
field_dates/end_value:
plugin: format_date
source: date_end
from_format: 'd/m/Y'
to_format: 'Y-m-d'
field_type_de_projet:
uid:
plugin: default_value
default_value: 3
migration_dependencies: { }
destination:
plugin: entity:node

View File

@@ -0,0 +1,8 @@
status: true
dependencies: { }
id: le_shed
label: 'Le shed'
description: ''
source_type: 'google doc sheets'
module: null
shared_configuration: null

View File

@@ -0,0 +1,21 @@
type: module
name: Migrate Le Shed
description: 'Importing contents from google sheet.'
package: Migration
core_version_requirement: '^10.5 || ^11'
hidden: false
dependencies:
- migrate_plus:migrate_plus
- migrate_tools:migrate_tools
- migrate_google_sheets:migrate_google_sheets
- drupal:image
- drupal:text
- drupal:options
- drupal:taxonomy
# Information added by Drupal.org packaging script on 2026-01-23
version: '0.0.1'
project: 'leshed'
# https://sheets.googleapis.com/v4/spreadsheets/1561Gv1C-IlCTmg64Z8HnznvOeLbvwhA_k1l6aq95zFA/values/Projets/?key=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

View File

@@ -0,0 +1,58 @@
<?php
declare(strict_types=1);
namespace Drupal\migrate_leshed\Plugin\migrate\source;
use Drupal\migrate\Attribute\MigrateSource;
use Drupal\migrate_plus\Plugin\migrate\source\Url;
use Drupal\migrate\Row;
/**
* @MigrateSource(
* id = "projet_node"
* )
*/
#[MigrateSource(id: 'projet_node')]
final class ProjetNode extends Url {
/**
* {@inheritdoc}
*/
public function fields(): array {
// theese are source fields
return [
'id' => $this->t('Project ID'),
'title' => $this->t('Project Title'),
'date_start' => $this->t('Project date start'),
'date_end' => $this->t('Project date end')
];
}
/**
* {@inheritdoc}
*/
public function getIds(): array {
return [
'id' => [
'type' => 'string',
],
];
}
/**
* {@inheritdoc}
*/
public function prepareRow(Row $row) {
// $nid = $row->getSourceProperty('entity_id');
// $vid = $row->getSourceProperty('revision_id');
// $type = $row->getSourceProperty('type');
// $language = $row->getSourceProperty('language');
// $title = $row->getSourceProperty('title');
// // drush_print('-- '.$nid."\t".$title."\t".$language);
return parent::prepareRow($row);
}
}