Skip to content

Commit c135bff

Browse files
committedSep 26, 2023
Adding code for baseball_migration module.
1 parent a7a021d commit c135bff

File tree

6 files changed

+417
-0
lines changed

6 files changed

+417
-0
lines changed
 
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
name: Baseball Migration
2+
type: module
3+
description: Example custom migration imports from MySQL database of baseball stats.
4+
core_version_requirement: ^9.5 || ^10
5+
package: Custom
6+
dependencies:
7+
- migrate
8+
- migrate_plus
9+
- migrate_tools
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
# The machine name for a migration. Also used by various CLI tools when
2+
# referencing the migration as an argument for a command.
3+
id: baseball_player
4+
5+
# A human-friendly description of the migration. This is used by varous UI and
6+
# CLI tools when showing a list of available migrations.
7+
label: Migrate list of players
8+
9+
# Optional group for the migration. This is a feature provided by the
10+
# migrate_plus module and allows for running an entire group of migrations
11+
# together.
12+
migration_group: baseball
13+
14+
# Every migration must have a source plugin. Set this to the ID of the plugin to
15+
# use.
16+
#
17+
# For our custom migration this should be the source plugin we wrote.
18+
# \Drupal\baseball_migration\Plugin\migrate\source\BaseballPlayer The value here is
19+
# the ID value from the source plugin's annotation.
20+
source:
21+
plugin: baseball_player
22+
23+
# Every migration must also have a destination plugin, which handles writing
24+
# the migrated data in the appropriate form for that particular kind of data.
25+
# This value should be the ID of the destination plugin to use.
26+
destination:
27+
plugin: entity:node
28+
29+
# Here's the meat of the migration - the processing pipeline. This describes how
30+
# each destination field is to be populated based on the source data. For each
31+
# destination field, one or more process plugins may be invoked.
32+
process:
33+
# Hardcode the destination node type (bundle) as 'player' using the
34+
# 'default_value' process plugin.
35+
type:
36+
plugin: default_value
37+
default_value: player
38+
39+
# Simple field mappings that require no extra processing can use the default
40+
# 'get' process plugin. This just copies the value from the source to the
41+
# destination. 'get' is the default when no plugin is defined, so you can just
42+
# do destination_field: source_field.
43+
#
44+
# Our player content type in Drupal has a field named, 'field_player_weight'
45+
# and our Source plugin defines a 'weight' field in it's ::getFields() method.
46+
# The destination field (or property) name goes on the left and the source
47+
# field goes on the right.
48+
field_player_weight: weight
49+
field_player_height: height
50+
field_player_bats: bats
51+
field_player_throws: throws
52+
field_player_given_name: nameGiven
53+
54+
# We generate the node.title (which we treat as the name) by concatnating
55+
# two soure fields together and putting a space between them using the
56+
# 'concat' process plugin.
57+
title:
58+
plugin: concat
59+
source:
60+
- nameFirst
61+
- nameLast
62+
delimiter: " "
63+
64+
# Same thing with the birthday, concat these fields together using the
65+
# 'concat' process plugin.
66+
field_player_birth:
67+
plugin: concat
68+
source:
69+
- birthMonth
70+
- birthDay
71+
- birthYear
72+
delimiter: /
73+
74+
# For death day we need to provide a default value in the case where the
75+
# player hasn't died yet. Also provides an example of using multiple process
76+
# plugins together. In this case we first use the 'concat' plugin to combine
77+
# three fields from the source data, and then use the 'default_value' plugin
78+
# to provide a default value for the field in the case that the previous step
79+
# resulted in an empty value.
80+
field_player_death:
81+
-
82+
plugin: concat
83+
source:
84+
- deathMonth
85+
- deathDay
86+
- deathYear
87+
delimiter: /
88+
-
89+
plugin: default_value
90+
default_value: ""
91+
92+
# Declare optional dependencies for a migration. This one has none.
93+
migration_dependencies: {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
id: baseball_team
2+
label: Migrate list of teams
3+
migration_group: baseball
4+
5+
# For our custom migration this should be the source plugin we wrote.
6+
# \Drupal\baseball_migration\Plugin\migrate\source\BaseballTeam The value here is
7+
# the ID value from the source plugin's annotation.
8+
source:
9+
plugin: baseball_player
10+
11+
# Every migration must also have a destination plugin, which handles writing
12+
# the migrated data in the appropriate form for that particular kind of data.
13+
# This value should be the ID of the destination plugin to use.
14+
destination:
15+
plugin: entity:node
16+
17+
# Here's the meat of the migration - the processing pipeline. This describes how
18+
# each destination field is to be populated based on the source data. For each
19+
# destination field, one or more process plugins may be invoked.
20+
process:
21+
# Hardcode the destination node type (bundle) as 'player' using the
22+
# 'default_value' process plugin.
23+
type:
24+
plugin: default_value
25+
default_value: player
26+
27+
# Simple field mappings that require no extra processing can use the default
28+
# 'get' process plugin. This just copies the value from the source to the
29+
# destination. 'get' is the default when no plugin is defined, so you can just
30+
# do destination_field: source_field.
31+
#
32+
# Our player content type in Drupal has a field named, 'field_player_weight'
33+
# and our Source plugin defines a 'weight' field in it's ::getFields() method.
34+
# The destination field (or property) name goes on the left and the source
35+
# field goes on the right.
36+
field_player_weight: weight
37+
field_player_height: height
38+
field_player_bats: bats
39+
field_player_throws: throws
40+
field_player_given_name: nameGiven
41+
42+
# We generate the node.title (which we treat as the name) by concatnating
43+
# two soure fields together and putting a space between them using the
44+
# 'concat' process plugin.
45+
title:
46+
plugin: concat
47+
source:
48+
- nameFirst
49+
- nameLast
50+
delimiter: " "
51+
52+
# Same thing with the birthday, concat these fields together using the
53+
# 'concat' process plugin.
54+
field_player_birth:
55+
plugin: concat
56+
source:
57+
- birthMonth
58+
- birthDay
59+
- birthYear
60+
delimiter: /
61+
62+
# For death day we need to provide a default value in the case where the
63+
# player hasn't died yet. Also provides an example of using multiple process
64+
# plugins together. In this case we first use the 'concat' plugin to combine
65+
# three fields from the source data, and then use the 'default_value' plugin
66+
# to provide a default value for the field in the case that the previous step
67+
# resulted in an empty value.
68+
field_player_death:
69+
-
70+
plugin: concat
71+
source:
72+
- deathMonth
73+
- deathDay
74+
- deathYear
75+
delimiter: /
76+
-
77+
plugin: default_value
78+
default_value: ""
79+
80+
# Declare optional dependencies for a migration. This one has none.
81+
migration_dependencies: {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
/**
3+
* @file
4+
* Example of how to write a Migrate API process plugin.
5+
*/
6+
7+
// Process plugins live in the Drupal\{MODULE}\Plugin\migrate\process
8+
// namespace.
9+
namespace Drupal\baseball_migration\Plugin\migrate\process;
10+
11+
use Drupal\migrate\ProcessPluginBase;
12+
use Drupal\migrate\MigrateException;
13+
use Drupal\migrate\MigrateExecutableInterface;
14+
use Drupal\migrate\Row;
15+
16+
/**
17+
* This plugin converts a string to uppercase.
18+
*
19+
* @MigrateProcessPlugin(
20+
* id = "strtoupper"
21+
* )
22+
*/
23+
class StrToUpper extends ProcessPluginBase {
24+
25+
/**
26+
* {@inheritdoc}
27+
*/
28+
public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
29+
// In the transform() method we perform whatever operations our process
30+
// plugin is going to do in order to transform the $value provided into its
31+
// desired form, and then return that value.
32+
if (is_string($value)) {
33+
// Check the plugin configuration to see if we should be using the ucfirst
34+
// or strtoupper function to perform our transformation. Configuration is
35+
// read from the migration YAML file where we've specified that we want
36+
// this process plugin to be used for a specific field.
37+
if (isset($this->configuration['ucfirst']) && $this->configuration['ucfirst'] == TRUE) {
38+
return ucfirst($value);
39+
}
40+
else {
41+
return strtoupper($value);
42+
}
43+
}
44+
else {
45+
// Throw an exception indicating our process plugin failed to transform
46+
// this value.
47+
throw new MigrateException(sprintf('%s is not a string', var_export($value, TRUE)));
48+
}
49+
}
50+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
<?php
2+
3+
namespace Drupal\baseball_migration\Plugin\migrate\source;
4+
5+
use Drupal\migrate\Plugin\migrate\source\SqlBase;
6+
use Drupal\migrate\Row;
7+
8+
/**
9+
* Source plugin for baseball players.
10+
*
11+
* @MigrateSource(
12+
* id = "baseball_player"
13+
* )
14+
*/
15+
class BaseballPlayer extends SqlBase {
16+
17+
/**
18+
* {@inheritdoc}
19+
*/
20+
public function query() {
21+
// Write a query that will be run against the {source} database to retrieve
22+
// information about players. Each row returned from the query should
23+
// represent one item that we would like to import. So, basically, one row
24+
// per player.
25+
//
26+
// In this case, we can just select all rows from the people table in the
27+
// {source} database, and limit to just the fields we plan to migrate.
28+
$query = $this->select('people', 'm')
29+
->fields('m', array(
30+
'playerID',
31+
'birthYear',
32+
'birthMonth',
33+
'birthDay',
34+
'deathYear',
35+
'deathMonth',
36+
'deathDay',
37+
'nameFirst',
38+
'nameLast',
39+
'nameGiven',
40+
'weight',
41+
'height',
42+
'bats',
43+
'throws',
44+
));
45+
return $query;
46+
}
47+
48+
/**
49+
* {@inheritdoc}
50+
*/
51+
public function fields() {
52+
// Provide documentation about source fields that are available for
53+
// mapping as key/value pairs. The key is the name of the field from the
54+
// database, and the value is the human readable description of the field.
55+
$fields = array(
56+
'playerID' => $this->t('Player ID'),
57+
'birthYear' => $this->t('Birth year'),
58+
'birthMonth' => $this->t('Birth month'),
59+
'birthDay' => $this->t('Birth day'),
60+
'deathYear' => $this->t('Death year'),
61+
'deathMonth' => $this->t('Death month'),
62+
'deathDay' => $this->t('Death day'),
63+
'nameFirst' => $this->t('First name'),
64+
'nameLast' => $this->t('Last name'),
65+
'nameGiven' => $this->t('Given name'),
66+
'weight' => $this->t('Weight'),
67+
'height' => $this->t('Height'),
68+
'bats' => $this->t('Bats'),
69+
'throws' => $this->t('Throws'),
70+
);
71+
72+
// If using prepareRow() to create computed fields you can describe them
73+
// here as well.
74+
75+
return $fields;
76+
}
77+
78+
/**
79+
* {@inheritdoc}
80+
*/
81+
public function getIds() {
82+
// Use a Schema Definition array to describe the field from the source row
83+
// that will be used as the unique ID for each row.
84+
//
85+
// @link https://www.drupal.org/node/146939 - Schema array docs.
86+
//
87+
// @see \Drupal\migrate\Plugin\migrate\source\SqlBase::initializeIterator
88+
// for more about the 'alias' key.
89+
return [
90+
// Key is the name of the field from the fields() method above that we
91+
// want to use as the unique ID for each row.
92+
'playerID' => [
93+
// Type is from the schema array definition.
94+
'type' => 'text',
95+
// This is an optional key currently only used by SqlBase.
96+
'alias' => 'm',
97+
],
98+
];
99+
}
100+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
<?php
2+
3+
namespace Drupal\baseball_migration\Plugin\migrate\source;
4+
5+
use Drupal\migrate\Plugin\migrate\source\SqlBase;
6+
use Drupal\migrate\Row;
7+
8+
/**
9+
* Source plugin for baseball teams.
10+
*
11+
* @MigrateSource(
12+
* id = "baseball_team"
13+
* )
14+
*/
15+
class BaseballTeam extends SqlBase {
16+
17+
/**
18+
* {@inheritdoc}
19+
*/
20+
public function query() {
21+
// Write a query that will be run against the {source} database to retrieve
22+
// information about teams. Each row returned from the query should
23+
// represent one item that we would like to import.
24+
$query = $this->select('teams', 't')
25+
->fields('m', array(
26+
'ID',
27+
'teamID'
28+
));
29+
return $query;
30+
}
31+
32+
/**
33+
* {@inheritdoc}
34+
*/
35+
public function fields() {
36+
// Provide documentation about source fields that are available for
37+
// mapping as key/value pairs. The key is the name of the field from the
38+
// database, and the value is the human readable description of the field.
39+
$fields = array(
40+
'playerID' => $this->t('Player ID'),
41+
'birthYear' => $this->t('Birth year'),
42+
'birthMonth' => $this->t('Birth month'),
43+
'birthDay' => $this->t('Birth day'),
44+
'deathYear' => $this->t('Death year'),
45+
'deathMonth' => $this->t('Death month'),
46+
'deathDay' => $this->t('Death day'),
47+
'nameFirst' => $this->t('First name'),
48+
'nameLast' => $this->t('Last name'),
49+
'nameGiven' => $this->t('Given name'),
50+
'weight' => $this->t('Weight'),
51+
'height' => $this->t('Height'),
52+
'bats' => $this->t('Bats'),
53+
'throws' => $this->t('Throws'),
54+
);
55+
56+
// If using prepareRow() to create computed fields you can describe them
57+
// here as well.
58+
59+
return $fields;
60+
}
61+
62+
/**
63+
* {@inheritdoc}
64+
*/
65+
public function getIds() {
66+
// Use a Schema Definition array to describe the field from the source row
67+
// that will be used as the unique ID for each row.
68+
//
69+
// @link https://www.drupal.org/node/146939 - Schema array docs.
70+
//
71+
// @see \Drupal\migrate\Plugin\migrate\source\SqlBase::initializeIterator
72+
// for more about the 'alias' key.
73+
return [
74+
// Key is the name of the field from the fields() method above that we
75+
// want to use as the unique ID for each row.
76+
'playerID' => [
77+
// Type is from the schema array definition.
78+
'type' => 'text',
79+
// This is an optional key currently only used by SqlBase.
80+
'alias' => 'm',
81+
],
82+
];
83+
}
84+
}

0 commit comments

Comments
 (0)
Please sign in to comment.