added migration modules
This commit is contained in:
@@ -0,0 +1,339 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
||||
@@ -0,0 +1,77 @@
|
||||
The migrate_plus module extends the core migration system with API enhancements
|
||||
and additional functionality, as well as providing practical examples.
|
||||
|
||||
Extensions to base API
|
||||
======================
|
||||
* A Migration configuration entity is provided, enabling persistance of dynamic
|
||||
migration configuration.
|
||||
* A MigrationGroup configuration entity is provided, which enables migrations to
|
||||
be organized in groups, and to maintain shared configuration in one place.
|
||||
* A MigrateEvents::PREPARE_ROW event is provided to dispatch hook_prepare_row()
|
||||
invocations as events.
|
||||
* A SourcePluginExtension class is provided, enabling one to define fields and
|
||||
IDs for a source plugin via configuration rather than requiring PHP code.
|
||||
|
||||
Plugin types
|
||||
============
|
||||
migrate_plus provides the following plugin types, for use with the url source
|
||||
plugin.
|
||||
|
||||
* A data_parser type, for parsing different formats on behalf of the url source
|
||||
plugin.
|
||||
* A data_fetcher type, for fetching data to feed into a data_parser plugin.
|
||||
* An authentication type, for adding authentication headers with the http
|
||||
data_fetcher plugin.
|
||||
|
||||
Plugins
|
||||
=======
|
||||
|
||||
Process
|
||||
-------
|
||||
* The entity_lookup process plugin allows you to populate references to entities
|
||||
which already exist in Drupal, whether they were migrated or not.
|
||||
* The entity_generate process plugin extends entity_lookup to also create the
|
||||
desired entity when it doesn't already exist.
|
||||
* The file_blob process plugin supports creating file entities from blob data.
|
||||
* The merge process plugin allows the merging of multiple arrays into a single
|
||||
field.
|
||||
* The skip_on_value process plugin allows you to skip a row, or a given field,
|
||||
for specific source values.
|
||||
|
||||
Source
|
||||
------
|
||||
* A url source plugin is provided, implementing a common structure for
|
||||
file-based data providers.
|
||||
|
||||
Data parsers
|
||||
------------
|
||||
* The xml parser plugin uses PHP's XMLReader interface to incrementally parse
|
||||
XML files. This should be used for XML sources which are potentially very
|
||||
large.
|
||||
* The simple_xml parser plugin uses PHP's SimpleXML interface to fully parse
|
||||
XML files. This should be used for XML sources where you need to be able to
|
||||
use complex xpaths for your item selectors, or have to access elements outside
|
||||
of the current item element via xpaths.
|
||||
* The json parser plugin supports JSON sources.
|
||||
* The soap parser plugin supports SOAP sources.
|
||||
|
||||
Data fetchers
|
||||
-------------
|
||||
* The file fetcher plugin works for most URLs regardless of protocol, as well as
|
||||
local filesystems.
|
||||
* The http fetcher plugin provides the ability to add headers to an HTTP
|
||||
request (particularly through authentication plugins).
|
||||
|
||||
Authentication
|
||||
--------------
|
||||
* The basic authentication plugin provides HTTP Basic authentication.
|
||||
* The digest authentication plugin provides HTTP Digest authentication.
|
||||
* The oauth2 authentication plugin provides OAuth2 authentication over HTTP.
|
||||
|
||||
Examples
|
||||
========
|
||||
* The migrate_example submodule provides a fully functional and runnable
|
||||
example migration scenario demonstrating the basic concepts and most common
|
||||
techniques for SQL-based migrations.
|
||||
* The migrate_example_advanced submodule provides examples of migration from
|
||||
different kinds of sources, as well as less common techniques.
|
||||
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"name": "drupal/migrate_plus",
|
||||
"description": "Enhancements to core migration support.",
|
||||
"type": "drupal-module",
|
||||
"license": "GPL-2.0+",
|
||||
"homepage": "https://www.drupal.org/project/migrate_plus",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Mike Ryan",
|
||||
"homepage":"https://www.drupal.org/u/mikeryan",
|
||||
"role": "Maintainer"
|
||||
}
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://www.drupal.org/project/issues/migrate_plus",
|
||||
"irc": "irc://irc.freenode.org/drupal-migrate",
|
||||
"source": "https://cgit.drupalcode.org/migrate_plus"
|
||||
},
|
||||
"minimum-stability": "dev",
|
||||
"require": {},
|
||||
"suggest": {
|
||||
"sainsburys/guzzle-oauth2-plugin": "3.0 required for the OAuth2 authentication plugin"
|
||||
}
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
# Basic data types for Migrate.
|
||||
|
||||
migrate_plugin:
|
||||
type: mapping
|
||||
mapping:
|
||||
plugin:
|
||||
type: string
|
||||
label: 'Plugin'
|
||||
|
||||
migrate_destination:
|
||||
type: migrate_plugin
|
||||
label: 'Destination'
|
||||
mapping:
|
||||
overwrite_properties:
|
||||
type: sequence
|
||||
label: 'Properties to overwrite'
|
||||
sequence:
|
||||
type: string
|
||||
label: 'Property'
|
||||
|
||||
migrate_source:
|
||||
type: migrate_plugin
|
||||
label: 'Source'
|
||||
mapping:
|
||||
constants:
|
||||
type: ignore
|
||||
label: 'Constants'
|
||||
|
||||
migrate_process:
|
||||
type: migrate_plugin
|
||||
label: 'Process'
|
||||
|
||||
# Base schema for migrate source plugins that extend
|
||||
# \Drupal\migrate\Plugin\migrate\source\SqlBase.
|
||||
migrate_source_sql:
|
||||
type: migrate_source
|
||||
mapping:
|
||||
target:
|
||||
type: string
|
||||
label: 'The migration database target'
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
# Schema for the migrate destination plugins.
|
||||
|
||||
migrate_plus.destination.*:
|
||||
type: migrate_destination
|
||||
label: 'Default destination'
|
||||
mapping:
|
||||
no_stub:
|
||||
type: boolean
|
||||
label: 'Whether stubbing is allowed.'
|
||||
default: false
|
||||
|
||||
migrate_plus.destination.config:
|
||||
type: migrate_destination
|
||||
label: 'Config'
|
||||
mapping:
|
||||
config_name:
|
||||
type: string
|
||||
label: 'Configuration name'
|
||||
+145
@@ -0,0 +1,145 @@
|
||||
# Schema for the migrate process plugins.
|
||||
|
||||
migrate_plus.process.*:
|
||||
type: migrate_process
|
||||
label: 'Default process'
|
||||
|
||||
migrate_plus.process.callback:
|
||||
type: migrate_process
|
||||
label: 'Callback process'
|
||||
mapping:
|
||||
callback:
|
||||
type: string
|
||||
label: 'Callback'
|
||||
|
||||
migrate_plus.process.concat:
|
||||
type: migrate_process
|
||||
label: 'Concat process'
|
||||
mapping:
|
||||
delimiter:
|
||||
type: string
|
||||
label: 'Delimiter'
|
||||
|
||||
migrate_plus.process.dedupe_entity:
|
||||
type: migrate_process
|
||||
label: 'Dedupe Entity process'
|
||||
mapping:
|
||||
entity_type:
|
||||
type: string
|
||||
label: 'Entity type'
|
||||
field:
|
||||
type: string
|
||||
label: 'Field name'
|
||||
postfix:
|
||||
type: string
|
||||
label: 'Postfix'
|
||||
start:
|
||||
type: integer
|
||||
label: 'Start'
|
||||
length:
|
||||
type: integer
|
||||
label: 'Length'
|
||||
|
||||
migrate_plus.process.explode:
|
||||
type: migrate_process
|
||||
label: 'Explode process'
|
||||
mapping:
|
||||
delimiter:
|
||||
type: string
|
||||
label: 'Delimiter'
|
||||
limit:
|
||||
type: integer
|
||||
label: 'Limit'
|
||||
|
||||
migrate_plus.process.extract:
|
||||
type: migrate_process
|
||||
label: 'Extract process'
|
||||
mapping:
|
||||
default:
|
||||
type: string
|
||||
label: 'Default value'
|
||||
|
||||
migrate_plus.process.flatten:
|
||||
type: migrate_process
|
||||
label: 'Flatten process'
|
||||
|
||||
migrate_plus.process.get:
|
||||
type: migrate_process
|
||||
label: 'Get process'
|
||||
mapping:
|
||||
source:
|
||||
type: string
|
||||
label: 'Source key'
|
||||
|
||||
migrate_plus.process.iterator:
|
||||
type: migrate_process
|
||||
label: 'Iterator process'
|
||||
mapping:
|
||||
process:
|
||||
type: ignore
|
||||
label: 'Process'
|
||||
key:
|
||||
type: string
|
||||
label: 'Key'
|
||||
|
||||
migrate_plus.process.machine_name:
|
||||
type: migrate_process
|
||||
label: 'Machine name process'
|
||||
|
||||
migrate_plus.process.migration:
|
||||
type: migrate_process
|
||||
label: 'Migration process'
|
||||
mapping:
|
||||
migration:
|
||||
type: sequence
|
||||
label: 'Migration'
|
||||
source:
|
||||
type: sequence
|
||||
label: 'Source keys'
|
||||
source_ids:
|
||||
type: string
|
||||
label: 'Source IDs'
|
||||
stub_id:
|
||||
type: string
|
||||
label: 'Stub ID'
|
||||
|
||||
migrate_plus.process.route:
|
||||
type: migrate_process
|
||||
label: 'Route process'
|
||||
|
||||
migrate_plus.process.skip_on_empty:
|
||||
type: migrate_process
|
||||
label: 'Skip on Empty'
|
||||
|
||||
migrate_plus.process.skip_row_if_not_set:
|
||||
type: migrate_process
|
||||
label: 'Skip Row process if not set'
|
||||
mapping:
|
||||
index:
|
||||
type: integer
|
||||
label: 'Index'
|
||||
|
||||
migrate_plus.process.static_map:
|
||||
type: migrate_process
|
||||
label: 'Static Map'
|
||||
mapping:
|
||||
map:
|
||||
type: sequence
|
||||
label: 'Map'
|
||||
default_value:
|
||||
type: string
|
||||
label: 'Default value'
|
||||
bypass:
|
||||
type: boolean
|
||||
label: 'Bypass lookup'
|
||||
|
||||
migrate_plus.process.default_value:
|
||||
type: migrate_process
|
||||
label: 'Default value'
|
||||
mapping:
|
||||
strict:
|
||||
type: boolean
|
||||
label: 'Strict type check'
|
||||
default_value:
|
||||
type: string
|
||||
label: 'Default value'
|
||||
@@ -0,0 +1,78 @@
|
||||
# Schema for the configuration files of the Migrate Plus module.
|
||||
|
||||
migrate_plus.migration.*:
|
||||
type: config_entity
|
||||
label: 'Migration'
|
||||
mapping:
|
||||
id:
|
||||
type: string
|
||||
label: 'ID'
|
||||
class:
|
||||
type: string
|
||||
label: 'Class'
|
||||
field_plugin_method:
|
||||
type: string
|
||||
label: 'Field Plugin Method'
|
||||
cck_plugin_method:
|
||||
type: string
|
||||
label: 'BC layer for Field Plugin Method'
|
||||
migration_tags:
|
||||
type: sequence
|
||||
label: 'Migration Tags'
|
||||
sequence:
|
||||
type: string
|
||||
label: 'Tag'
|
||||
migration_group:
|
||||
type: string
|
||||
label: 'Group'
|
||||
label:
|
||||
type: label
|
||||
label: 'Label'
|
||||
source:
|
||||
type: migrate_plus.source.[plugin]
|
||||
label: 'Source'
|
||||
process:
|
||||
type: ignore
|
||||
label: 'Process'
|
||||
destination:
|
||||
type: migrate_plus.destination.[plugin]
|
||||
label: 'Destination'
|
||||
migration_dependencies:
|
||||
type: mapping
|
||||
label: 'Dependencies'
|
||||
mapping:
|
||||
required:
|
||||
type: sequence
|
||||
label: 'Required dependencies'
|
||||
sequence:
|
||||
type: string
|
||||
label: 'Dependency'
|
||||
optional:
|
||||
type: sequence
|
||||
label: 'Optional dependencies'
|
||||
sequence:
|
||||
type: string
|
||||
label: 'Dependency'
|
||||
|
||||
migrate_plus.migration_group.*:
|
||||
type: config_entity
|
||||
label: 'Migration Group'
|
||||
mapping:
|
||||
id:
|
||||
type: string
|
||||
label: 'ID'
|
||||
label:
|
||||
type: label
|
||||
label: 'Label'
|
||||
description:
|
||||
type: string
|
||||
label: 'Description'
|
||||
source_type:
|
||||
type: string
|
||||
label: 'Source type'
|
||||
module:
|
||||
type: string
|
||||
label: 'Dependent module'
|
||||
shared_configuration:
|
||||
type: ignore
|
||||
label: 'Shared migration configuration'
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
# Schema for the migrate source plugins.
|
||||
|
||||
migrate_plus.source.*:
|
||||
type: migrate_source
|
||||
label: 'Default source'
|
||||
|
||||
migrate_plus.source.empty:
|
||||
type: migrate_source_sql
|
||||
label: 'Empty source'
|
||||
mapping:
|
||||
provider:
|
||||
type: string
|
||||
label: 'Provider'
|
||||
|
||||
migrate_plus.source.embedded_data:
|
||||
type: migrate_source
|
||||
label: 'Embedded data source'
|
||||
mapping:
|
||||
data_rows:
|
||||
type: sequence
|
||||
label: 'Data rows'
|
||||
sequence:
|
||||
type: ignore
|
||||
label: 'Data row'
|
||||
ids:
|
||||
type: sequence
|
||||
label: 'Unique key'
|
||||
sequence:
|
||||
type: mapping
|
||||
label: 'Key column'
|
||||
mapping:
|
||||
type:
|
||||
type: string
|
||||
label: 'Column type'
|
||||
@@ -0,0 +1,111 @@
|
||||
INTRODUCTION
|
||||
------------
|
||||
The migrate_example module demonstrates how to implement custom migrations
|
||||
for Drupal 8. It includes a group of "beer" migrations demonstrating a complete
|
||||
simple migration scenario.
|
||||
|
||||
THE BEER SITE
|
||||
-------------
|
||||
In this scenario, we have a beer aficionado site which stores its data in MySQL
|
||||
tables - there are content items for each beer on the site, user accounts with
|
||||
profile data, categories to classify the beers, and user-generated comments on
|
||||
the beers. We want to convert this site to Drupal with just a few modifications
|
||||
to the basic structure.
|
||||
|
||||
To make the example as simple as to run as possible, the source data is placed
|
||||
in tables directly in your Drupal database - in most real-world scenarios, your
|
||||
source data will be in an external database. The migrate_example_setup submodule
|
||||
creates and populates these tables, as well as configuring your Drupal 8 site
|
||||
(creating a node type, vocabulary, fields, etc.) to receive the data.
|
||||
|
||||
STRUCTURE
|
||||
---------
|
||||
There are two primary components to this example:
|
||||
|
||||
1. Migration configuration, in the migrations and config/install directories.
|
||||
These YAML files describe the migration process and provide the mappings from
|
||||
the source data to Drupal's destination entities. The difference between the
|
||||
two possible directories:
|
||||
|
||||
a. Files in the migrations directory provide configuration directly for the
|
||||
migration plugins. The filenames are of the form <migration ID>.yml. This
|
||||
approach is recommended when your migration configuration is fully hardcoded
|
||||
and does not need to be overridden (e.g., you don't need to change the URL to
|
||||
a source web service through an admin UI). While developing migrations,
|
||||
changes to these files require at most a 'drush cr' to load your changes.
|
||||
|
||||
b. Files in the config/install directory provide migration configuration as
|
||||
configuration entities, and have names of the form
|
||||
migrate_plus.migration.<migration ID>.yml ("migration" because they define
|
||||
entities of the "migration" type, and "migrate_plus" because that is the
|
||||
module which implements the "migration" type). Migrations defined in this way
|
||||
may have their configuration modified (in particular, through a web UI) by
|
||||
loading the configuration entity, modifying its configuration, and saving the
|
||||
entity. When developing, to get edits to the .yml files in config/install to
|
||||
take effect in active configuration, use the config_devel module.
|
||||
|
||||
Configuration in either type of file is identical - the only differences are
|
||||
the directories and filenames.
|
||||
|
||||
2. Source plugins, in src/Plugin/migrate/source. These are referenced from the
|
||||
configuration files, and provide the source data to the migration processing
|
||||
pipeline, as well as manipulating that data where necessary to put it into
|
||||
a canonical form for migrations.
|
||||
|
||||
UNDERSTANDING THE MIGRATIONS
|
||||
----------------------------
|
||||
The YAML and PHP files are copiously documented in-line. To best understand
|
||||
the concepts described in a more-or-less narrative form, it is recommended you
|
||||
read the files in the following order:
|
||||
|
||||
1. migrate_plus.migration_group.beer.yml
|
||||
2. migrate_plus.migration.beer_term.yml
|
||||
3. BeerTerm.php
|
||||
4. migrate_plus.migration.beer_user.yml
|
||||
5. BeerUser.php
|
||||
6. migrate_plus.migration.beer_node.yml
|
||||
7. BeerNode.php
|
||||
8. migrate_plus.migration.beer_comment.yml
|
||||
9. BeerComment.php
|
||||
|
||||
RUNNING THE MIGRATIONS
|
||||
----------------------
|
||||
The migrate_tools module (https://www.drupal.org/project/migrate_tools) provides
|
||||
the tools you need to perform migration processes. At this time, the web UI only
|
||||
provides status information - to perform migration operations, you need to use
|
||||
the drush commands.
|
||||
|
||||
# Enable the tools and the example module if you haven't already.
|
||||
drush en -y migrate_tools,migrate_example
|
||||
|
||||
# Look at the migrations. Just look at them. Notice that they are displayed in
|
||||
# the order they will be run, which reflects their dependencies. For example,
|
||||
# because the node migration references the imported terms and users, it must
|
||||
# run after those migrations have been run.
|
||||
drush ms # Abbreviation for migrate-status
|
||||
|
||||
# Run the import operation for all the beer migrations.
|
||||
drush mi --group=beer # Abbreviation for migrate-import
|
||||
|
||||
# Look at what you've done! Also, visit the site and see the imported content,
|
||||
# user accounts, etc.
|
||||
drush ms
|
||||
|
||||
# Look at the duplicate username message.
|
||||
drush mmsg beer_user # Abbreviation for migrate-messages
|
||||
|
||||
# Run the rollback operation for all the migrations (removing all the imported
|
||||
# content, user accounts, etc.). Note that it will rollback the migrations in
|
||||
# the opposite order as they were imported.
|
||||
drush mr --group=beer # Abbreviation for migrate-rollback
|
||||
|
||||
# You can import specific migrations.
|
||||
drush mi beer_term,beer_user
|
||||
# At this point, go look at your content listing - you'll see beer nodes named
|
||||
# "Stub", generated from the user's favbeers references.
|
||||
|
||||
drush mi beer_node,beer_comment
|
||||
# Refresh your content listing - the stub nodes have been filled with real beer!
|
||||
|
||||
# You can rollback specific migrations.
|
||||
drush mr beer_comment,beer_node
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
# Migration configuration for beer content.
|
||||
id: beer_node
|
||||
label: Beers of the world
|
||||
migration_group: beer
|
||||
source:
|
||||
plugin: beer_node
|
||||
destination:
|
||||
plugin: entity:node
|
||||
process:
|
||||
# Hardcode the destination node type (bundle) as 'migrate_example_beer'.
|
||||
type:
|
||||
plugin: default_value
|
||||
default_value: migrate_example_beer
|
||||
title: name
|
||||
nid: bid
|
||||
uid:
|
||||
plugin: migration
|
||||
migration: beer_user
|
||||
source: aid
|
||||
sticky:
|
||||
plugin: default_value
|
||||
default_value: 0
|
||||
field_migrate_example_country: countries
|
||||
field_migrate_example_beer_style:
|
||||
plugin: migration
|
||||
migration: beer_term
|
||||
source: terms
|
||||
# Some Drupal fields may have multiple components we may want to set
|
||||
# separately. For example, text fields may have summaries (teasers) in
|
||||
# addition to the full text value. We use / to separate the field name from
|
||||
# the internal field value being set, and put it in quotes because / is a
|
||||
# YAML special character.
|
||||
'body/value': body
|
||||
'body/summary': excerpt
|
||||
# Our beer nodes have references to terms and users, so we want those to be
|
||||
# imported first. We make that dependency explicit here - by putting those
|
||||
# migrations under the 'required' key, we ensure that the tools will prevent
|
||||
# us from running the beer_node migration unless the beer_term and beer_user
|
||||
# migrations are complete (although we can override the dependency check by
|
||||
# passing --force to the drush migrate-import command). We can also add
|
||||
# 'optional' dependencies - these affect the order in which migrations are
|
||||
# displayed, and run by default, but does not force you run them in that
|
||||
# order.
|
||||
# The general rule of thumb is that any migrations referenced by migration
|
||||
# process plugins should be required here.
|
||||
migration_dependencies:
|
||||
required:
|
||||
- beer_term
|
||||
- beer_user
|
||||
dependencies:
|
||||
enforced:
|
||||
module:
|
||||
- migrate_example
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
# A "migration" is, in technical terms, a plugin whose configuration describes
|
||||
# how to read source data, process it (generally by mapping source fields to
|
||||
# destination fields), and write it to Drupal.
|
||||
|
||||
# The machine name for a migration, used to uniquely identify it.
|
||||
id: beer_term
|
||||
|
||||
# A human-friendly description of the migration.
|
||||
label: Migrate style categories from the source database to taxonomy terms
|
||||
|
||||
# The machine name of the group containing this migration (which contains shared
|
||||
# configuration to be merged with our own configuration here).
|
||||
migration_group: beer
|
||||
|
||||
# Every migration must have a source plugin, which controls the delivery of our
|
||||
# source data. In this case, our source plugin has the name "beer_term", which
|
||||
# Drupal resolves to the PHP class defined in
|
||||
# src/Plugin/migrate/source/BeerTerm.php.
|
||||
source:
|
||||
plugin: beer_term
|
||||
|
||||
# Every migration must also have a destination plugin, which handles writing
|
||||
# the migrated data in the appropriate form for that particular kind of data.
|
||||
# Most Drupal content is an "entity" of one type or another, and we need to
|
||||
# specify what entity type we are populating (in this case, taxonomy terms).
|
||||
# Unlike the source plugin (which is specific to our particular scenario), this
|
||||
# destination plugin is implemented in Drupal itself.
|
||||
destination:
|
||||
plugin: entity:taxonomy_term
|
||||
|
||||
# Here's the meat of the migration - the processing pipeline. This describes how
|
||||
# each destination field is to be populated based on the source data. For each
|
||||
# destination field, one or more process plugins may be invoked.
|
||||
process:
|
||||
# The simplest process plugin is named 'get' - it is the default plugin, so
|
||||
# does not need to be explicitly named. It simply copies the source value
|
||||
# (the 'style' field from the source database in this case) to the destination
|
||||
# field (the taxonomy term 'name' field). You can see we simply copy the
|
||||
# source 'details' field to destination 'description' field in the same way.
|
||||
name: style
|
||||
description: details
|
||||
|
||||
# Here is a new plugin - default_value. In its simplest usage here, it is used
|
||||
# to hard-code a destination value, the vid (vocabulary ID) our taxonomy terms
|
||||
# should be assigned to. It's important to note that while above the right
|
||||
# side of the mappings was a source field name, here the right side of the
|
||||
# 'default_value:' line is an actual value.
|
||||
vid:
|
||||
plugin: default_value
|
||||
default_value: migrate_example_beer_styles
|
||||
|
||||
# Here's another new plugin - migration. When importing data from another
|
||||
# system, typically the unique identifiers for items on the destination side
|
||||
# are not the same as the identifiers were on the source side. For example, in
|
||||
# our style data the term names are the unique identifiers for each term,
|
||||
# while in Drupal each term is assigned a unique integer term ID (tid). When
|
||||
# any such items are referenced in Drupal, the reference needs to be
|
||||
# translated from the old ID ('ale') to the new ID (1). The migration
|
||||
# framework keeps track of the relationships between source and destination
|
||||
# IDs in map tables, and the migration plugin is the means of performing a
|
||||
# lookup in those map tables during processing.
|
||||
parent:
|
||||
plugin: migration
|
||||
# Here we reference the migration whose map table we're performing a lookup
|
||||
# against. You'll note that in this case we're actually referencing this
|
||||
# migration itself, since category parents are imported by the same
|
||||
# migration. This works best when we're sure the parents are imported
|
||||
# before the children, and in this case our source plugin is guaranteeing
|
||||
# that.
|
||||
migration: beer_term
|
||||
# 'style_parent' is the parent reference field from the source data. The
|
||||
# result of this plugin is that the destination 'parent' field is populated
|
||||
# with the Drupal term ID of the referenced style (or NULL if style_parent
|
||||
# was empty).
|
||||
source: style_parent
|
||||
|
||||
# We'll learn more about dependencies in beer_node - here, we leave them empty.
|
||||
migration_dependencies: {}
|
||||
|
||||
# By default, configuration entities (like this migration) are not automatically
|
||||
# removed when the migration which installed them is uninstalled. To have your
|
||||
# migrations uninstalled with your migration module, add an enforced dependency
|
||||
# on your module.
|
||||
dependencies:
|
||||
enforced:
|
||||
module:
|
||||
- migrate_example
|
||||
+105
@@ -0,0 +1,105 @@
|
||||
# Migration configuration for user accounts. We've described most of what goes
|
||||
# into migration configuration in migrate_plus.migration.beer_term.yml, so won't
|
||||
# repeat that here.
|
||||
id: beer_user
|
||||
label: Beer Drinkers of the world
|
||||
migration_group: beer
|
||||
source:
|
||||
plugin: beer_user
|
||||
destination:
|
||||
plugin: entity:user
|
||||
process:
|
||||
pass: password
|
||||
mail: email
|
||||
init: email
|
||||
status: status
|
||||
roles:
|
||||
plugin: default_value
|
||||
default_value: 2
|
||||
|
||||
# Here's a new process plugin - dedupe_entity. Our source site allowed there
|
||||
# to be multiple user accounts with the same username, but Drupal wants
|
||||
# usernames to be unique. This plugin allows us to automatically generate
|
||||
# unique usernames when we detect collisions.
|
||||
name:
|
||||
plugin: dedupe_entity
|
||||
# The name of the source field containing the username.
|
||||
source: username
|
||||
# These next two settings identify the destination-side field to check for
|
||||
# duplicates. They say "see if the incoming 'name' matches any existing
|
||||
# 'name' field in any 'user' entity".
|
||||
entity_type: user
|
||||
field: name
|
||||
# Finally, this specifies a string to use between the original value and the
|
||||
# sequence number appended to make the value unique. Thus, the first 'alice'
|
||||
# account gets the name 'alice' in Drupal, and the second one gets the name
|
||||
# 'alice_1'.
|
||||
postfix: _
|
||||
|
||||
# Another new process plugin - callback. This allows us to filter an incoming
|
||||
# source value through an arbitrary PHP function. The function called must
|
||||
# have one required argument.
|
||||
created:
|
||||
plugin: callback
|
||||
# The 'registered' timestamp in the source data is a string of the form
|
||||
# 'yyyy-mm-dd hh:mm:ss', but Drupal wants a UNIX timestamp for 'created'.
|
||||
source: registered
|
||||
callable: strtotime
|
||||
|
||||
# Our source data only has a single timestamp value, 'registered', which we
|
||||
# want to use for all four of Drupal's user timestamp fields. We could
|
||||
# duplicate the callback plugin we used for 'created' above - but we have a
|
||||
# shortcut. Putting an @ sign at the beginning of the source value indicates
|
||||
# that it is to be interpreted as a *destination* field name instead of a
|
||||
# *source* field name. Thus, if a value we need in more than one place
|
||||
# requires some processing beyond simply copying it directly, we can perform
|
||||
# that processing a single time and use the result in multiple places.
|
||||
changed: '@created'
|
||||
access: '@created'
|
||||
login: '@created'
|
||||
|
||||
# Yet another new process plugin - static_map. We're making a transformation
|
||||
# in how we represent gender data - formerly it was integer values 0 for male
|
||||
# and 1 for female, but in our modern Drupal site we will be making this a
|
||||
# free-form text field, so we want to replace the obscure integers with
|
||||
# simple strings.
|
||||
field_migrate_example_gender:
|
||||
plugin: static_map
|
||||
# Specify the source field we're reading (containing 0's and 1's).
|
||||
source: sex
|
||||
# Tell it to transform 0 to 'Male', and 1 to 'Female'.
|
||||
map:
|
||||
0: Male
|
||||
1: Female
|
||||
# If the input is missing, leave the field empty. Without this, an empty
|
||||
# or invalid source value would cause the user record to be skipped
|
||||
# entirely.
|
||||
bypass: true
|
||||
|
||||
# This looks like a simple migration process plugin, but there's magic
|
||||
# happening here. We import nodes after terms and users, because they have
|
||||
# references to terms and users, so of course the terms and users must be
|
||||
# migrated first - right? However, the favbeers field is a reference to the
|
||||
# beer nodes which haven't yet been migrated - we have a circular relationship
|
||||
# between users and nodes. The way the migration system resolves this
|
||||
# situation is by creating "stubs". In this case, because no beer nodes have
|
||||
# been created, each time a beer is looked up against the beer_node migration
|
||||
# nothing is found, and by default the migration process plugin creates an
|
||||
# empty stub node as a placeholder so the favbeers reference field has
|
||||
# something to point to. The stub is recorded in the beer_node map table, so
|
||||
# when that migration runs it knows that each incoming beer should overwrite
|
||||
# its stub instead of creating a new node.
|
||||
field_migrate_example_favbeers:
|
||||
plugin: migration
|
||||
source: beers
|
||||
migration: beer_node
|
||||
|
||||
migration_dependencies: {}
|
||||
|
||||
# When a module is creating a custom content type it needs to add an
|
||||
# enforced dependency to itself, otherwise the content type will persist
|
||||
# after the module is disabled. See: https://www.drupal.org/node/2629516.
|
||||
dependencies:
|
||||
enforced:
|
||||
module:
|
||||
- migrate_example
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
# A "migration group" is - surprise! - a group of migrations. It is used to
|
||||
# group migrations for display by our tools, and to perform operations on a
|
||||
# specific set of migrations. It can also be used to hold any configuration
|
||||
# common to those migrations, so it doesn't have to be duplicated in each one.
|
||||
|
||||
# The machine name of the group, by which it is referenced in individual
|
||||
# migrations.
|
||||
id: beer
|
||||
|
||||
# A human-friendly label for the group.
|
||||
label: Beer Imports
|
||||
|
||||
# More information about the group.
|
||||
description: A few simple beer-related imports, to demonstrate how to implement migrations.
|
||||
|
||||
# Short description of the type of source, e.g. "Drupal 6" or "WordPress".
|
||||
source_type: Custom tables
|
||||
|
||||
# Here we add any default configuration settings to be shared among all
|
||||
# migrations in the group. For this example, the source tables are in the
|
||||
# Drupal (default) database, but usually if your source data is in a
|
||||
# database it will be external.
|
||||
shared_configuration:
|
||||
# Specifying 'source' here means that this configuration will be merged into
|
||||
# the 'source' configuration of each migration.
|
||||
source:
|
||||
# A better practice for real-world migrations would be to add a database
|
||||
# connection to your external database in settings.php and reference its
|
||||
# key here.
|
||||
key: default
|
||||
|
||||
# As with the migration configuration (see beer_term), we add an enforced
|
||||
# dependency so the migration_group configuration will be removed on module
|
||||
# uninstall.
|
||||
dependencies:
|
||||
enforced:
|
||||
module:
|
||||
- migrate_example
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
type: module
|
||||
name: Migrate Example
|
||||
description: 'Examples of how Drupal 8 migration compares to previous versions.'
|
||||
package: Examples
|
||||
# core: 8.x
|
||||
dependencies:
|
||||
- drupal:migrate
|
||||
- migrate_plus:migrate_example_setup
|
||||
- migrate_plus:migrate_plus
|
||||
|
||||
# Information added by Drupal.org packaging script on 2017-05-10
|
||||
version: '8.x-4.0-beta1'
|
||||
core: '8.x'
|
||||
project: 'migrate_plus'
|
||||
datestamp: 1494450189
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies: { }
|
||||
id: node_comments
|
||||
label: 'Node comments'
|
||||
target_entity_type_id: node
|
||||
description: ''
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
config:
|
||||
- comment.type.node_comments
|
||||
- field.field.comment.node_comments.comment_body
|
||||
module:
|
||||
- text
|
||||
id: comment.node_comments.default
|
||||
targetEntityType: comment
|
||||
bundle: node_comments
|
||||
mode: default
|
||||
content:
|
||||
author:
|
||||
weight: -2
|
||||
comment_body:
|
||||
type: text_textarea
|
||||
weight: 11
|
||||
settings:
|
||||
rows: 5
|
||||
placeholder: ''
|
||||
third_party_settings: { }
|
||||
subject:
|
||||
type: string_textfield
|
||||
weight: 10
|
||||
settings:
|
||||
size: 60
|
||||
placeholder: ''
|
||||
third_party_settings: { }
|
||||
hidden: { }
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
config:
|
||||
- field.field.node.migrate_example_beer.body
|
||||
- field.field.node.migrate_example_beer.field_comments
|
||||
- field.field.node.migrate_example_beer.field_migrate_example_beer_style
|
||||
- field.field.node.migrate_example_beer.field_migrate_example_country
|
||||
- field.field.node.migrate_example_beer.field_migrate_example_image
|
||||
- node.type.migrate_example_beer
|
||||
module:
|
||||
- comment
|
||||
- image
|
||||
- text
|
||||
id: node.migrate_example_beer.default
|
||||
targetEntityType: node
|
||||
bundle: migrate_example_beer
|
||||
mode: default
|
||||
content:
|
||||
body:
|
||||
type: text_textarea_with_summary
|
||||
weight: 6
|
||||
settings:
|
||||
rows: 9
|
||||
summary_rows: 3
|
||||
placeholder: ''
|
||||
third_party_settings: { }
|
||||
created:
|
||||
type: datetime_timestamp
|
||||
weight: 2
|
||||
settings: { }
|
||||
third_party_settings: { }
|
||||
field_comments:
|
||||
weight: 10
|
||||
settings: { }
|
||||
third_party_settings: { }
|
||||
type: comment_default
|
||||
field_migrate_example_beer_style:
|
||||
weight: 7
|
||||
settings:
|
||||
match_operator: CONTAINS
|
||||
size: 60
|
||||
placeholder: ''
|
||||
third_party_settings: { }
|
||||
type: entity_reference_autocomplete
|
||||
field_migrate_example_country:
|
||||
weight: 8
|
||||
settings:
|
||||
size: 60
|
||||
placeholder: ''
|
||||
third_party_settings: { }
|
||||
type: string_textfield
|
||||
field_migrate_example_image:
|
||||
weight: 9
|
||||
settings:
|
||||
progress_indicator: throbber
|
||||
preview_image_style: thumbnail
|
||||
third_party_settings: { }
|
||||
type: image_image
|
||||
promote:
|
||||
type: boolean_checkbox
|
||||
settings:
|
||||
display_label: true
|
||||
weight: 3
|
||||
third_party_settings: { }
|
||||
sticky:
|
||||
type: boolean_checkbox
|
||||
settings:
|
||||
display_label: true
|
||||
weight: 4
|
||||
third_party_settings: { }
|
||||
title:
|
||||
type: string_textfield
|
||||
weight: 0
|
||||
settings:
|
||||
size: 60
|
||||
placeholder: ''
|
||||
third_party_settings: { }
|
||||
uid:
|
||||
type: entity_reference_autocomplete
|
||||
weight: 1
|
||||
settings:
|
||||
match_operator: CONTAINS
|
||||
size: 60
|
||||
placeholder: ''
|
||||
third_party_settings: { }
|
||||
hidden: { }
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
config:
|
||||
- comment.type.node_comments
|
||||
- field.field.comment.node_comments.comment_body
|
||||
module:
|
||||
- text
|
||||
id: comment.node_comments.default
|
||||
targetEntityType: comment
|
||||
bundle: node_comments
|
||||
mode: default
|
||||
content:
|
||||
comment_body:
|
||||
label: hidden
|
||||
type: text_default
|
||||
weight: 0
|
||||
settings: { }
|
||||
third_party_settings: { }
|
||||
links:
|
||||
weight: 100
|
||||
hidden: { }
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
config:
|
||||
- field.field.node.migrate_example_beer.body
|
||||
- field.field.node.migrate_example_beer.field_comments
|
||||
- field.field.node.migrate_example_beer.field_migrate_example_beer_style
|
||||
- field.field.node.migrate_example_beer.field_migrate_example_country
|
||||
- field.field.node.migrate_example_beer.field_migrate_example_image
|
||||
- node.type.migrate_example_beer
|
||||
module:
|
||||
- comment
|
||||
- image
|
||||
- text
|
||||
- user
|
||||
id: node.migrate_example_beer.default
|
||||
targetEntityType: node
|
||||
bundle: migrate_example_beer
|
||||
mode: default
|
||||
content:
|
||||
body:
|
||||
label: hidden
|
||||
type: text_default
|
||||
weight: 2
|
||||
settings: { }
|
||||
third_party_settings: { }
|
||||
field_comments:
|
||||
weight: 5
|
||||
label: above
|
||||
settings:
|
||||
pager_id: 0
|
||||
third_party_settings: { }
|
||||
type: comment_default
|
||||
field_migrate_example_beer_style:
|
||||
weight: 3
|
||||
label: above
|
||||
settings:
|
||||
link: true
|
||||
third_party_settings: { }
|
||||
type: entity_reference_label
|
||||
field_migrate_example_country:
|
||||
weight: 4
|
||||
label: above
|
||||
settings:
|
||||
link_to_entity: false
|
||||
third_party_settings: { }
|
||||
type: string
|
||||
field_migrate_example_image:
|
||||
weight: 1
|
||||
label: above
|
||||
settings:
|
||||
image_style: ''
|
||||
image_link: ''
|
||||
third_party_settings: { }
|
||||
type: image
|
||||
links:
|
||||
weight: 0
|
||||
settings: { }
|
||||
third_party_settings: { }
|
||||
hidden: { }
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
config:
|
||||
- core.entity_view_mode.node.teaser
|
||||
- field.field.node.migrate_example_beer.body
|
||||
- field.field.node.migrate_example_beer.field_comments
|
||||
- field.field.node.migrate_example_beer.field_migrate_example_beer_style
|
||||
- field.field.node.migrate_example_beer.field_migrate_example_country
|
||||
- field.field.node.migrate_example_beer.field_migrate_example_image
|
||||
- node.type.migrate_example_beer
|
||||
module:
|
||||
- text
|
||||
- user
|
||||
id: node.migrate_example_beer.teaser
|
||||
targetEntityType: node
|
||||
bundle: migrate_example_beer
|
||||
mode: teaser
|
||||
content:
|
||||
body:
|
||||
label: hidden
|
||||
type: text_summary_or_trimmed
|
||||
weight: 1
|
||||
settings:
|
||||
trim_length: 600
|
||||
third_party_settings: { }
|
||||
links:
|
||||
weight: 0
|
||||
settings: { }
|
||||
third_party_settings: { }
|
||||
hidden:
|
||||
field_comments: true
|
||||
field_migrate_example_beer_style: true
|
||||
field_migrate_example_country: true
|
||||
field_migrate_example_image: true
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
config:
|
||||
- comment.type.node_comments
|
||||
- field.storage.comment.comment_body
|
||||
module:
|
||||
- text
|
||||
id: comment.node_comments.comment_body
|
||||
field_name: comment_body
|
||||
entity_type: comment
|
||||
bundle: node_comments
|
||||
label: Comment
|
||||
description: ''
|
||||
required: true
|
||||
translatable: true
|
||||
default_value: { }
|
||||
default_value_callback: ''
|
||||
settings: { }
|
||||
field_type: text_long
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
config:
|
||||
- field.storage.node.body
|
||||
- node.type.migrate_example_beer
|
||||
module:
|
||||
- text
|
||||
id: node.migrate_example_beer.body
|
||||
field_name: body
|
||||
entity_type: node
|
||||
bundle: migrate_example_beer
|
||||
label: Body
|
||||
description: ''
|
||||
required: false
|
||||
translatable: true
|
||||
default_value: { }
|
||||
default_value_callback: ''
|
||||
settings:
|
||||
display_summary: true
|
||||
field_type: text_with_summary
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
config:
|
||||
- field.storage.node.field_comments
|
||||
- node.type.migrate_example_beer
|
||||
module:
|
||||
- comment
|
||||
id: node.migrate_example_beer.field_comments
|
||||
field_name: field_comments
|
||||
entity_type: node
|
||||
bundle: migrate_example_beer
|
||||
label: Comments
|
||||
description: ''
|
||||
required: false
|
||||
translatable: false
|
||||
default_value:
|
||||
-
|
||||
status: 2
|
||||
cid: 0
|
||||
last_comment_timestamp: 0
|
||||
last_comment_name: null
|
||||
last_comment_uid: 0
|
||||
comment_count: 0
|
||||
default_value_callback: ''
|
||||
settings:
|
||||
default_mode: 1
|
||||
per_page: 50
|
||||
anonymous: 0
|
||||
form_location: true
|
||||
preview: 1
|
||||
field_type: comment
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
config:
|
||||
- field.storage.node.field_migrate_example_beer_style
|
||||
- node.type.migrate_example_beer
|
||||
- taxonomy.vocabulary.migrate_example_beer_styles
|
||||
id: node.migrate_example_beer.field_migrate_example_beer_style
|
||||
field_name: field_migrate_example_beer_style
|
||||
entity_type: node
|
||||
bundle: migrate_example_beer
|
||||
label: 'Migrate Example Beer Styles'
|
||||
description: ''
|
||||
required: false
|
||||
translatable: false
|
||||
default_value: { }
|
||||
default_value_callback: ''
|
||||
settings:
|
||||
handler: 'default:taxonomy_term'
|
||||
handler_settings:
|
||||
target_bundles:
|
||||
migrate_example_beer_styles: migrate_example_beer_styles
|
||||
sort:
|
||||
field: _none
|
||||
auto_create: false
|
||||
field_type: entity_reference
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
config:
|
||||
- field.storage.node.field_migrate_example_country
|
||||
- node.type.migrate_example_beer
|
||||
id: node.migrate_example_beer.field_migrate_example_country
|
||||
field_name: field_migrate_example_country
|
||||
entity_type: node
|
||||
bundle: migrate_example_beer
|
||||
label: Countries
|
||||
description: ''
|
||||
required: false
|
||||
translatable: false
|
||||
default_value: { }
|
||||
default_value_callback: ''
|
||||
settings: { }
|
||||
field_type: string
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
config:
|
||||
- field.storage.node.field_migrate_example_image
|
||||
- node.type.migrate_example_beer
|
||||
module:
|
||||
- image
|
||||
id: node.migrate_example_beer.field_migrate_example_image
|
||||
field_name: field_migrate_example_image
|
||||
entity_type: node
|
||||
bundle: migrate_example_beer
|
||||
label: Image
|
||||
description: ''
|
||||
required: false
|
||||
translatable: false
|
||||
default_value: { }
|
||||
default_value_callback: ''
|
||||
settings:
|
||||
file_directory: ''
|
||||
file_extensions: 'png gif jpg jpeg'
|
||||
max_filesize: ''
|
||||
max_resolution: ''
|
||||
min_resolution: ''
|
||||
alt_field: true
|
||||
alt_field_required: false
|
||||
title_field: false
|
||||
title_field_required: false
|
||||
default_image:
|
||||
uuid: ''
|
||||
alt: ''
|
||||
title: ''
|
||||
width: null
|
||||
height: null
|
||||
handler: 'default:file'
|
||||
handler_settings: { }
|
||||
field_type: image
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
config:
|
||||
- field.storage.user.field_migrate_example_favbeers
|
||||
- node.type.migrate_example_beer
|
||||
module:
|
||||
- user
|
||||
id: user.user.field_migrate_example_favbeers
|
||||
field_name: field_migrate_example_favbeers
|
||||
entity_type: user
|
||||
bundle: user
|
||||
label: 'Favorite Beers'
|
||||
description: ''
|
||||
required: false
|
||||
translatable: false
|
||||
default_value: { }
|
||||
default_value_callback: ''
|
||||
settings:
|
||||
handler: 'default:node'
|
||||
handler_settings:
|
||||
target_bundles:
|
||||
migrate_example_beer: migrate_example_beer
|
||||
sort:
|
||||
field: title
|
||||
direction: ASC
|
||||
field_type: entity_reference
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
config:
|
||||
- field.storage.user.field_migrate_example_gender
|
||||
module:
|
||||
- user
|
||||
id: user.user.field_migrate_example_gender
|
||||
field_name: field_migrate_example_gender
|
||||
entity_type: user
|
||||
bundle: user
|
||||
label: Gender
|
||||
description: ''
|
||||
required: false
|
||||
translatable: false
|
||||
default_value: { }
|
||||
default_value_callback: ''
|
||||
settings: { }
|
||||
field_type: string
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
module:
|
||||
- comment
|
||||
- node
|
||||
id: node.field_comments
|
||||
field_name: field_comments
|
||||
entity_type: node
|
||||
type: comment
|
||||
settings:
|
||||
comment_type: node_comments
|
||||
module: comment
|
||||
locked: false
|
||||
cardinality: 1
|
||||
translatable: true
|
||||
indexes: { }
|
||||
persist_with_no_fields: false
|
||||
custom_storage: false
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
module:
|
||||
- node
|
||||
- taxonomy
|
||||
id: node.field_migrate_example_beer_style
|
||||
field_name: field_migrate_example_beer_style
|
||||
entity_type: node
|
||||
type: entity_reference
|
||||
settings:
|
||||
target_type: taxonomy_term
|
||||
module: core
|
||||
locked: false
|
||||
cardinality: -1
|
||||
translatable: true
|
||||
indexes: { }
|
||||
persist_with_no_fields: false
|
||||
custom_storage: false
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
module:
|
||||
- node
|
||||
id: node.field_migrate_example_country
|
||||
field_name: field_migrate_example_country
|
||||
entity_type: node
|
||||
type: string
|
||||
settings:
|
||||
max_length: 255
|
||||
is_ascii: false
|
||||
case_sensitive: false
|
||||
module: core
|
||||
locked: false
|
||||
cardinality: -1
|
||||
translatable: true
|
||||
indexes: { }
|
||||
persist_with_no_fields: false
|
||||
custom_storage: false
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
module:
|
||||
- file
|
||||
- image
|
||||
- node
|
||||
id: node.field_migrate_example_image
|
||||
field_name: field_migrate_example_image
|
||||
entity_type: node
|
||||
type: image
|
||||
settings:
|
||||
uri_scheme: public
|
||||
default_image:
|
||||
uuid: ''
|
||||
alt: ''
|
||||
title: ''
|
||||
width: null
|
||||
height: null
|
||||
target_type: file
|
||||
display_field: false
|
||||
display_default: false
|
||||
module: image
|
||||
locked: false
|
||||
cardinality: 1
|
||||
translatable: true
|
||||
indexes: { }
|
||||
persist_with_no_fields: false
|
||||
custom_storage: false
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
module:
|
||||
- node
|
||||
- user
|
||||
id: user.field_migrate_example_favbeers
|
||||
field_name: field_migrate_example_favbeers
|
||||
entity_type: user
|
||||
type: entity_reference
|
||||
settings:
|
||||
target_type: node
|
||||
module: core
|
||||
locked: false
|
||||
cardinality: -1
|
||||
translatable: true
|
||||
indexes: { }
|
||||
persist_with_no_fields: false
|
||||
custom_storage: false
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
module:
|
||||
- user
|
||||
id: user.field_migrate_example_gender
|
||||
field_name: field_migrate_example_gender
|
||||
entity_type: user
|
||||
type: string
|
||||
settings:
|
||||
max_length: 255
|
||||
is_ascii: false
|
||||
case_sensitive: false
|
||||
module: core
|
||||
locked: false
|
||||
cardinality: 1
|
||||
translatable: true
|
||||
indexes: { }
|
||||
persist_with_no_fields: false
|
||||
custom_storage: false
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
langcode: en
|
||||
status: true
|
||||
name: Beer
|
||||
type: migrate_example_beer
|
||||
description: 'Beer is what we drink.'
|
||||
help: ''
|
||||
new_revision: false
|
||||
preview_mode: 1
|
||||
display_submitted: true
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies: { }
|
||||
name: 'Migrate Example Beer Styles'
|
||||
vid: migrate_example_beer_styles
|
||||
description: 'Use tags to group beers on similar topics into categories.'
|
||||
hierarchy: 0
|
||||
weight: 0
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
type: module
|
||||
name: Migrate Example Setup
|
||||
description: 'Separate site configuration for the example from the actual migration.'
|
||||
package: Migration
|
||||
# core: 8.x
|
||||
hidden: 1
|
||||
dependencies:
|
||||
- drupal:comment
|
||||
- drupal:image
|
||||
- drupal:text
|
||||
- drupal:options
|
||||
- drupal:taxonomy
|
||||
|
||||
# Information added by Drupal.org packaging script on 2017-05-10
|
||||
version: '8.x-4.0-beta1'
|
||||
core: '8.x'
|
||||
project: 'migrate_plus'
|
||||
datestamp: 1494450189
|
||||
+345
@@ -0,0 +1,345 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Set up source data and destination configuration for the migration example
|
||||
* module. We do this in a separate module so migrate_example itself is a pure
|
||||
* migration module.
|
||||
*/
|
||||
|
||||
function migrate_example_setup_schema() {
|
||||
$schema['migrate_example_beer_account'] = migrate_example_beer_schema_account();
|
||||
$schema['migrate_example_beer_node'] = migrate_example_beer_schema_node();
|
||||
$schema['migrate_example_beer_comment'] = migrate_example_beer_schema_comment();
|
||||
$schema['migrate_example_beer_topic'] = migrate_example_beer_schema_topic();
|
||||
$schema['migrate_example_beer_topic_node'] = migrate_example_beer_schema_topic_node();
|
||||
|
||||
return $schema;
|
||||
}
|
||||
|
||||
function migrate_example_setup_install() {
|
||||
// Populate our tables.
|
||||
migrate_example_beer_data_account();
|
||||
migrate_example_beer_data_node();
|
||||
migrate_example_beer_data_comment();
|
||||
migrate_example_beer_data_topic();
|
||||
migrate_example_beer_data_topic_node();
|
||||
}
|
||||
|
||||
function migrate_example_beer_schema_node() {
|
||||
return array(
|
||||
'description' => 'Beers of the world.',
|
||||
'fields' => array(
|
||||
'bid' => array(
|
||||
'type' => 'serial',
|
||||
'not null' => TRUE,
|
||||
'description' => 'Beer ID.',
|
||||
),
|
||||
'name' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => TRUE,
|
||||
),
|
||||
'body' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Full description of the beer.',
|
||||
),
|
||||
'excerpt' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Abstract for this beer.',
|
||||
),
|
||||
'countries' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Countries of origin. Multiple values, delimited by pipe',
|
||||
),
|
||||
'aid' => array(
|
||||
'type' => 'int',
|
||||
'not null' => FALSE,
|
||||
'description' => 'Account Id of the author.',
|
||||
),
|
||||
'image' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Image path',
|
||||
),
|
||||
'image_alt' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Image ALT',
|
||||
),
|
||||
'image_title' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Image title',
|
||||
),
|
||||
'image_description' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Image description',
|
||||
),
|
||||
),
|
||||
'primary key' => array('bid'),
|
||||
);
|
||||
}
|
||||
|
||||
function migrate_example_beer_schema_topic() {
|
||||
return array(
|
||||
'description' => 'Categories',
|
||||
'fields' => array(
|
||||
'style' => array(
|
||||
'type' => 'varchar_ascii',
|
||||
'length' => 255,
|
||||
'not null' => TRUE,
|
||||
),
|
||||
'details' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
),
|
||||
'style_parent' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Parent topic, if any',
|
||||
),
|
||||
'region' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Region first associated with this style',
|
||||
),
|
||||
'hoppiness' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Relative hoppiness of the beer',
|
||||
),
|
||||
),
|
||||
'primary key' => array('style'),
|
||||
);
|
||||
}
|
||||
|
||||
function migrate_example_beer_schema_topic_node() {
|
||||
return array(
|
||||
'description' => 'Beers topic pairs.',
|
||||
'fields' => array(
|
||||
'bid' => array(
|
||||
'type' => 'int',
|
||||
'not null' => TRUE,
|
||||
'description' => 'Beer ID.',
|
||||
),
|
||||
'style' => array(
|
||||
'type' => 'varchar_ascii',
|
||||
'length' => 255,
|
||||
'not null' => TRUE,
|
||||
'description' => 'Topic name',
|
||||
),
|
||||
),
|
||||
'primary key' => array('style', 'bid'),
|
||||
);
|
||||
}
|
||||
|
||||
function migrate_example_beer_schema_comment() {
|
||||
return array(
|
||||
'description' => 'Beers comments.',
|
||||
'fields' => array(
|
||||
'cid' => array(
|
||||
'type' => 'serial',
|
||||
'not null' => TRUE,
|
||||
'description' => 'Comment ID.',
|
||||
),
|
||||
'bid' => array(
|
||||
'type' => 'int',
|
||||
'not null' => TRUE,
|
||||
'description' => 'Beer ID that is being commented upon',
|
||||
),
|
||||
'cid_parent' => array(
|
||||
'type' => 'int',
|
||||
'not null' => FALSE,
|
||||
'description' => 'Parent comment ID in case of comment replies.',
|
||||
),
|
||||
'subject' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Comment subject',
|
||||
),
|
||||
'body' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Comment body',
|
||||
),
|
||||
'name' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Comment name (if anon)',
|
||||
),
|
||||
'mail' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Comment email (if anon)',
|
||||
),
|
||||
'aid' => array(
|
||||
'type' => 'int',
|
||||
'not null' => FALSE,
|
||||
'description' => 'Account ID (if any).',
|
||||
),
|
||||
),
|
||||
'primary key' => array('cid'),
|
||||
);
|
||||
}
|
||||
|
||||
function migrate_example_beer_schema_account() {
|
||||
return array(
|
||||
'description' => 'Beers accounts.',
|
||||
'fields' => array(
|
||||
'aid' => array(
|
||||
'type' => 'serial',
|
||||
'not null' => TRUE,
|
||||
'description' => 'Account ID',
|
||||
),
|
||||
'status' => array(
|
||||
'type' => 'int',
|
||||
'not null' => TRUE,
|
||||
'description' => 'Blocked_Allowed',
|
||||
),
|
||||
'registered' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => TRUE,
|
||||
'description' => 'Registration date',
|
||||
),
|
||||
'username' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Account name (for login)',
|
||||
),
|
||||
'nickname' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Account name (for display)',
|
||||
),
|
||||
'password' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Account password (raw)',
|
||||
),
|
||||
'email' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Account email',
|
||||
),
|
||||
'sex' => array(
|
||||
'type' => 'int',
|
||||
'not null' => FALSE,
|
||||
'description' => 'Gender (0 for male, 1 for female)',
|
||||
),
|
||||
'beers' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Favorite Beers',
|
||||
),
|
||||
),
|
||||
'primary key' => array('aid'),
|
||||
);
|
||||
}
|
||||
|
||||
function migrate_example_beer_data_node() {
|
||||
$fields = array('bid', 'name', 'body', 'excerpt', 'countries', 'aid', 'image',
|
||||
'image_alt', 'image_title', 'image_description');
|
||||
$query = db_insert('migrate_example_beer_node')
|
||||
->fields($fields);
|
||||
// Use high bid numbers to avoid overwriting an existing node id.
|
||||
$data = array(
|
||||
array(99999999, 'Heineken', 'Blab Blah Blah Green', 'Green', 'Netherlands|Belgium', 0, 'heineken.jpg', 'Heinekin alt', 'Heinekin title', 'Heinekin description'), // comes with migrate_example project.
|
||||
array(99999998, 'Miller Lite', 'We love Miller Brewing', 'Tasteless', 'USA|Canada', 1, NULL, NULL, NULL, NULL),
|
||||
array(99999997, 'Boddington', 'English occasionally get something right', 'A treat', 'United Kingdom', 1, NULL, NULL, NULL, NULL),
|
||||
);
|
||||
foreach ($data as $row) {
|
||||
$query->values(array_combine($fields, $row));
|
||||
}
|
||||
$query->execute();
|
||||
}
|
||||
|
||||
// Note that alice has duplicate username. Exercises dedupe_entity plugin.
|
||||
// @TODO duplicate email also.
|
||||
function migrate_example_beer_data_account() {
|
||||
$fields = array('status', 'registered', 'username', 'nickname', 'password', 'email', 'sex', 'beers');
|
||||
$query = db_insert('migrate_example_beer_account')
|
||||
->fields($fields);
|
||||
$data = array(
|
||||
array(1, '2010-03-30 10:31:05', 'alice', 'alice in beerland', 'alicepass', 'alice@example.com', '1', '99999999|99999998|99999997'),
|
||||
array(1, '2010-04-04 10:31:05', 'alice', 'alice in aleland', 'alicepass', 'alice2@example.com', '1', '99999999|99999998|99999997'),
|
||||
array(0, '2007-03-15 10:31:05', 'bob', 'rebob', 'bobpass', 'bob@example.com', '0', '99999999|99999997'),
|
||||
array(1, '2004-02-29 10:31:05', 'charlie', 'charlie chocolate', 'mykids', 'charlie@example.com', '0', '99999999|99999998'),
|
||||
);
|
||||
foreach ($data as $row) {
|
||||
$query->values(array_combine($fields, $row));
|
||||
}
|
||||
$query->execute();
|
||||
}
|
||||
|
||||
function migrate_example_beer_data_comment() {
|
||||
$fields = array('bid', 'cid_parent', 'subject', 'body', 'name', 'mail', 'aid');
|
||||
$query = db_insert('migrate_example_beer_comment')
|
||||
->fields($fields);
|
||||
$data = array(
|
||||
array(99999998, NULL, 'im first', 'full body', 'alice', 'alice@example.com', 0),
|
||||
array(99999998, NULL, 'im second', 'aromatic', 'alice', 'alice@example.com', 0),
|
||||
array(99999999, NULL, 'im parent', 'malty', 'alice', 'alice@example.com', 0),
|
||||
array(99999999, 1, 'im child', 'cold body', 'bob', NULL, 1),
|
||||
array(99999999, 4, 'im grandchild', 'bitter body', 'charlie@example.com', NULL, 1),
|
||||
);
|
||||
foreach ($data as $row) {
|
||||
$query->values(array_combine($fields, $row));
|
||||
}
|
||||
$query->execute();
|
||||
}
|
||||
|
||||
function migrate_example_beer_data_topic() {
|
||||
$fields = array('style', 'details', 'style_parent', 'region', 'hoppiness');
|
||||
$query = db_insert('migrate_example_beer_topic')
|
||||
->fields($fields);
|
||||
$data = array(
|
||||
array('ale', 'traditional', NULL, 'Medieval British Isles', 'Medium'),
|
||||
array('red ale', 'colorful', 'ale', NULL, NULL),
|
||||
array('pilsner', 'refreshing', NULL, 'Pilsen, Bohemia (now Czech Republic)', 'Low'),
|
||||
);
|
||||
foreach ($data as $row) {
|
||||
$query->values(array_combine($fields, $row));
|
||||
}
|
||||
$query->execute();
|
||||
}
|
||||
|
||||
function migrate_example_beer_data_topic_node() {
|
||||
$fields = array('bid', 'style');
|
||||
$query = db_insert('migrate_example_beer_topic_node')
|
||||
->fields($fields);
|
||||
$data = array(
|
||||
array(99999999, 'pilsner'),
|
||||
array(99999999, 'red ale'),
|
||||
array(99999998, 'red ale'),
|
||||
);
|
||||
foreach ($data as $row) {
|
||||
$query->values(array_combine($fields, $row));
|
||||
}
|
||||
$query->execute();
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
# Migration configuration for beer comments. No new concepts here.
|
||||
id: beer_comment
|
||||
label: Comments on beers
|
||||
migration_group: beer
|
||||
source:
|
||||
plugin: beer_comment
|
||||
destination:
|
||||
plugin: entity:comment
|
||||
process:
|
||||
pid:
|
||||
plugin: migration
|
||||
migration: beer_comment
|
||||
source: cid_parent
|
||||
entity_id:
|
||||
plugin: migration
|
||||
migration: beer_node
|
||||
source: bid
|
||||
entity_type:
|
||||
plugin: default_value
|
||||
default_value: node
|
||||
field_name:
|
||||
plugin: default_value
|
||||
default_value: field_comments
|
||||
comment_type:
|
||||
plugin: default_value
|
||||
default_value: node_comments
|
||||
subject: subject
|
||||
uid:
|
||||
plugin: migration
|
||||
migration: beer_user
|
||||
source: aid
|
||||
name: name
|
||||
mail: mail
|
||||
status:
|
||||
plugin: default_value
|
||||
default_value: 1
|
||||
'comment_body/value': body
|
||||
migration_dependencies:
|
||||
required:
|
||||
- beer_node
|
||||
- beer_user
|
||||
dependencies:
|
||||
enforced:
|
||||
module:
|
||||
- migrate_example
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\migrate_example\Plugin\migrate\source;
|
||||
|
||||
use Drupal\migrate\Plugin\migrate\source\SqlBase;
|
||||
|
||||
/**
|
||||
* Source plugin for beer comments.
|
||||
*
|
||||
* @MigrateSource(
|
||||
* id = "beer_comment"
|
||||
* )
|
||||
*/
|
||||
class BeerComment extends SqlBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function query() {
|
||||
$query = $this->select('migrate_example_beer_comment', 'mec')
|
||||
->fields('mec', ['cid', 'cid_parent', 'name', 'mail', 'aid',
|
||||
'body', 'bid', 'subject'])
|
||||
->orderBy('cid_parent', 'ASC');
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fields() {
|
||||
$fields = [
|
||||
'cid' => $this->t('Comment ID'),
|
||||
'cid_parent' => $this->t('Parent comment ID in case of comment replies'),
|
||||
'name' => $this->t('Comment name (if anon)'),
|
||||
'mail' => $this->t('Comment email (if anon)'),
|
||||
'aid' => $this->t('Account ID (if any)'),
|
||||
'bid' => $this->t('Beer ID that is being commented upon'),
|
||||
'subject' => $this->t('Comment subject'),
|
||||
];
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getIds() {
|
||||
return [
|
||||
'cid' => [
|
||||
'type' => 'integer',
|
||||
'alias' => 'mec',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
+99
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\migrate_example\Plugin\migrate\source;
|
||||
|
||||
use Drupal\migrate\Plugin\migrate\source\SqlBase;
|
||||
use Drupal\migrate\Row;
|
||||
|
||||
/**
|
||||
* Source plugin for beer content.
|
||||
*
|
||||
* @MigrateSource(
|
||||
* id = "beer_node"
|
||||
* )
|
||||
*/
|
||||
class BeerNode extends SqlBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function query() {
|
||||
/**
|
||||
* An important point to note is that your query *must* return a single row
|
||||
* for each item to be imported. Here we might be tempted to add a join to
|
||||
* migrate_example_beer_topic_node in our query, to pull in the
|
||||
* relationships to our categories. Doing this would cause the query to
|
||||
* return multiple rows for a given node, once per related value, thus
|
||||
* processing the same node multiple times, each time with only one of the
|
||||
* multiple values that should be imported. To avoid that, we simply query
|
||||
* the base node data here, and pull in the relationships in prepareRow()
|
||||
* below.
|
||||
*/
|
||||
$query = $this->select('migrate_example_beer_node', 'b')
|
||||
->fields('b', ['bid', 'name', 'body', 'excerpt', 'aid',
|
||||
'countries', 'image', 'image_alt', 'image_title',
|
||||
'image_description']);
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fields() {
|
||||
$fields = [
|
||||
'bid' => $this->t('Beer ID'),
|
||||
'name' => $this->t('Name of beer'),
|
||||
'body' => $this->t('Full description of the beer'),
|
||||
'excerpt' => $this->t('Abstract for this beer'),
|
||||
'aid' => $this->t('Account ID of the author'),
|
||||
'countries' => $this->t('Countries of origin. Multiple values, delimited by pipe'),
|
||||
'image' => $this->t('Image path'),
|
||||
'image_alt' => $this->t('Image ALT'),
|
||||
'image_title' => $this->t('Image title'),
|
||||
'image_description' => $this->t('Image description'),
|
||||
// Note that this field is not part of the query above - it is populated
|
||||
// by prepareRow() below. You should document all source properties that
|
||||
// are available for mapping after prepareRow() is called.
|
||||
'terms' => $this->t('Applicable styles'),
|
||||
];
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getIds() {
|
||||
return [
|
||||
'bid' => [
|
||||
'type' => 'integer',
|
||||
'alias' => 'b',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function prepareRow(Row $row) {
|
||||
/**
|
||||
* As explained above, we need to pull the style relationships into our
|
||||
* source row here, as an array of 'style' values (the unique ID for
|
||||
* the beer_term migration).
|
||||
*/
|
||||
$terms = $this->select('migrate_example_beer_topic_node', 'bt')
|
||||
->fields('bt', ['style'])
|
||||
->condition('bid', $row->getSourceProperty('bid'))
|
||||
->execute()
|
||||
->fetchCol();
|
||||
$row->setSourceProperty('terms', $terms);
|
||||
|
||||
// As we did for favorite beers in the user migration, we need to explode
|
||||
// the multi-value country names.
|
||||
if ($value = $row->getSourceProperty('countries')) {
|
||||
$row->setSourceProperty('countries', explode('|', $value));
|
||||
}
|
||||
return parent::prepareRow($row);
|
||||
}
|
||||
|
||||
}
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\migrate_example\Plugin\migrate\source;
|
||||
|
||||
use Drupal\migrate\Plugin\migrate\source\SqlBase;
|
||||
|
||||
/**
|
||||
* This is an example of a simple SQL-based source plugin. Source plugins are
|
||||
* classes which deliver source data to the processing pipeline. For SQL
|
||||
* sources, the SqlBase class provides most of the functionality needed - for
|
||||
* a specific migration, you are required to implement the three simple public
|
||||
* methods you see below.
|
||||
*
|
||||
* This annotation tells Drupal that the name of the MigrateSource plugin
|
||||
* implemented by this class is "beer_term". This is the name that the migration
|
||||
* configuration references with the source "plugin" key.
|
||||
*
|
||||
* @MigrateSource(
|
||||
* id = "beer_term"
|
||||
* )
|
||||
*/
|
||||
class BeerTerm extends SqlBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function query() {
|
||||
/**
|
||||
* The most important part of a SQL source plugin is the SQL query to
|
||||
* retrieve the data to be imported. Note that the query is not executed
|
||||
* here - the migration process will control execution of the query. Also
|
||||
* note that it is constructed from a $this->select() call - this ensures
|
||||
* that the query is executed against the database configured for this
|
||||
* source plugin.
|
||||
*/
|
||||
return $this->select('migrate_example_beer_topic', 'met')
|
||||
->fields('met', ['style', 'details', 'style_parent', 'region', 'hoppiness'])
|
||||
// We sort this way to ensure parent terms are imported first.
|
||||
->orderBy('style_parent', 'ASC');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fields() {
|
||||
/**
|
||||
* This method simply documents the available source fields provided by
|
||||
* the source plugin, for use by front-end tools. It returns an array keyed
|
||||
* by field/column name, with the value being a translated string explaining
|
||||
* to humans what the field represents. You should always
|
||||
*/
|
||||
$fields = [
|
||||
'style' => $this->t('Account ID'),
|
||||
'details' => $this->t('Blocked/Allowed'),
|
||||
'style_parent' => $this->t('Registered date'),
|
||||
// These values are not currently migrated - it's OK to skip fields you
|
||||
// don't need.
|
||||
'region' => $this->t('Region the style is associated with'),
|
||||
'hoppiness' => $this->t('Hoppiness of the style'),
|
||||
];
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getIds() {
|
||||
/**
|
||||
* This method indicates what field(s) from the source row uniquely identify
|
||||
* that source row, and what their types are. This is critical information
|
||||
* for managing the migration. The keys of the returned array are the field
|
||||
* names from the query which comprise the unique identifier. The values are
|
||||
* arrays indicating the type of the field, used for creating compatible
|
||||
* columns in the map tables that track processed items.
|
||||
*/
|
||||
return [
|
||||
'style' => [
|
||||
'type' => 'string',
|
||||
// 'alias' is the alias for the table containing 'style' in the query
|
||||
// defined above. Optional in this case, but necessary if the same
|
||||
// column may occur in multiple tables in a join.
|
||||
'alias' => 'met',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\migrate_example\Plugin\migrate\source;
|
||||
|
||||
use Drupal\migrate\Plugin\migrate\source\SqlBase;
|
||||
use Drupal\migrate\Row;
|
||||
|
||||
/**
|
||||
* Source plugin for beer user accounts.
|
||||
*
|
||||
* @MigrateSource(
|
||||
* id = "beer_user"
|
||||
* )
|
||||
*/
|
||||
class BeerUser extends SqlBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function query() {
|
||||
return $this->select('migrate_example_beer_account', 'mea')
|
||||
->fields('mea', ['aid', 'status', 'registered', 'username', 'nickname',
|
||||
'password', 'email', 'sex', 'beers']);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fields() {
|
||||
$fields = [
|
||||
'aid' => $this->t('Account ID'),
|
||||
'status' => $this->t('Blocked/Allowed'),
|
||||
'registered' => $this->t('Registered date'),
|
||||
'username' => $this->t('Account name (for login)'),
|
||||
'nickname' => $this->t('Account name (for display)'),
|
||||
'password' => $this->t('Account password (raw)'),
|
||||
'email' => $this->t('Account email'),
|
||||
'sex' => $this->t('Gender'),
|
||||
'beers' => $this->t('Favorite beers, pipe-separated'),
|
||||
];
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getIds() {
|
||||
return [
|
||||
'aid' => [
|
||||
'type' => 'integer',
|
||||
'alias' => 'mea',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function prepareRow(Row $row) {
|
||||
/**
|
||||
* prepareRow() is the most common place to perform custom run-time
|
||||
* processing that isn't handled by an existing process plugin. It is called
|
||||
* when the raw data has been pulled from the source, and provides the
|
||||
* opportunity to modify or add to that data, creating the canonical set of
|
||||
* source data that will be fed into the processing pipeline.
|
||||
*
|
||||
* In our particular case, the list of a user's favorite beers is a pipe-
|
||||
* separated list of beer IDs. The processing pipeline deals with arrays
|
||||
* representing multi-value fields naturally, so we want to explode that
|
||||
* string to an array of individual beer IDs.
|
||||
*/
|
||||
if ($value = $row->getSourceProperty('beers')) {
|
||||
$row->setSourceProperty('beers', explode('|', $value));
|
||||
}
|
||||
/**
|
||||
* Always call your parent! Essential processing is performed in the base
|
||||
* class. Be mindful that prepareRow() returns a boolean status - if FALSE
|
||||
* that indicates that the item being processed should be skipped. Unless
|
||||
* we're deciding to skip an item ourselves, let the parent class decide.
|
||||
*/
|
||||
return parent::prepareRow($row);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
INTRODUCTION
|
||||
------------
|
||||
The migrate_example_advanced module demonstrates some techniques for Drupal 8
|
||||
migrations beyond the basics in migrate_example. It includes a group of
|
||||
migrations with a wine theme.
|
||||
|
||||
SETUP
|
||||
-----
|
||||
To demonstrate XML migrations as realistically as possible, the setup module
|
||||
provides the source data as REST services. So the migrations' references to these
|
||||
services can be set up accurately, if you install migrate_example_advanced via
|
||||
drush be sure to use the --uri parameter, e.g.
|
||||
|
||||
drush en -y migrate_example_advanced --uri=http://d8.local:8083/
|
||||
|
||||
THE WINE SITE
|
||||
-------------
|
||||
In this scenario, we have a wine aficionado site which stores data in SQL tables
|
||||
as well is pulling in additional data from XML services.
|
||||
|
||||
To make the example as simple as to run as possible, the SQL data is placed in
|
||||
tables directly in your Drupal database - in most real-world scenarios, your
|
||||
source data will be in an external database. The migrate_example_advanced_setup
|
||||
submodule creates and populates these tables, as well as configuring your Drupal
|
||||
8 site (creating node types, vocabularies, fields, etc.) to receive the data,
|
||||
and providing service endpoints for XML data.
|
||||
|
||||
STRUCTURE
|
||||
---------
|
||||
As with most custom migrations, there are two primary components to this
|
||||
example:
|
||||
|
||||
1. Migration configuration, in the config/install directory. These YAML files
|
||||
describe the migration process and provide the mappings from the source data
|
||||
to Drupal's destination entities.
|
||||
|
||||
2. Source plugins, in src/Plugin/migrate/source. These are referenced from the
|
||||
configuration files, and provide the source data to the migration processing
|
||||
pipeline, as well as manipulating that data where necessary to put it into
|
||||
a canonical form for migrations.
|
||||
|
||||
UNDERSTANDING THE MIGRATIONS
|
||||
----------------------------
|
||||
Basic techniques demonstrated in the migrate_example module are not rehashed
|
||||
here - it is expected that if you are learning Drupal 8 migration, you will
|
||||
study and understand those examples first, and use migrate_example_advanced to
|
||||
learn about specific techniques beyond those basics. This example doesn't have
|
||||
the narrative form of migrate_example - it's more of a grab-bag demonstrating
|
||||
varous features, and is more of a reference for, say, copying the code to set
|
||||
up an XML migration. An index of things demonstrated by this module:
|
||||
|
||||
Multiple vocabularies populated in one migration
|
||||
------------------------------------------------
|
||||
See migrate_plus.migration.wine_terms.yml.
|
||||
|
||||
Importing from XML services
|
||||
---------------------------
|
||||
See migrate_plus.migration.wine_role_xml.yml.
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
# This migration demonstrates importing from SOAP/WSDL.
|
||||
id: weather_soap
|
||||
label: SOAP service providing weather.
|
||||
migration_group: wine
|
||||
source:
|
||||
# We use the SOAP parser source plugin.
|
||||
plugin: url
|
||||
data_fetcher_plugin: http # Ignored - SoapClient does the fetching.
|
||||
data_parser_plugin: soap
|
||||
# URL of a WSDL endpoint.
|
||||
urls: http://www.webservicex.net/globalweather.asmx?WSDL
|
||||
# The function to call on the service, and the parameters to pass. See
|
||||
# http://www.webservicex.net/New/Home/ServiceDetail/56 for the XML structure
|
||||
# of this feed - how CountryName is passed within the GetCitiesByCountry
|
||||
# XML element.
|
||||
function: GetCitiesByCountry
|
||||
parameters:
|
||||
CountryName: Spain
|
||||
# Responses may be returned as an XML string, an object, or an array - specify
|
||||
# the type of response here.
|
||||
response_type: xml
|
||||
# Looking at the XML response at http://www.webservicex.net/globalweather.asmx/GetCitiesByCountry,
|
||||
# we see that the data items we want are within <NewDataSet><Table>.
|
||||
item_selector: /NewDataSet/Table
|
||||
# For each field, 'name' is the source property name to be used in the process
|
||||
# steps below, 'label' is optional (to document the property), and selector
|
||||
# is an xpath (-like, for array and object returns) string relative to the
|
||||
# item_selector for retrieving that data value.
|
||||
fields:
|
||||
-
|
||||
name: Country
|
||||
label: Country
|
||||
selector: Country
|
||||
-
|
||||
name: City
|
||||
label: City
|
||||
selector: City
|
||||
# 'ids' tells us what source property ('City') holds the unique identifying
|
||||
# value for each imported item, and what schema type to use to hold that
|
||||
# value in the migration map an message tables.
|
||||
ids:
|
||||
City:
|
||||
type: string
|
||||
process:
|
||||
vid:
|
||||
plugin: default_value
|
||||
default_value: migrate_example_wine_varieties
|
||||
name: City
|
||||
destination:
|
||||
plugin: entity:taxonomy_term
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
# This migration demonstrates importing from a monolithic JSON file.
|
||||
id: wine_role_json
|
||||
label: JSON feed of roles (positions)
|
||||
migration_group: wine
|
||||
source:
|
||||
# We use the JSON source plugin.
|
||||
plugin: url
|
||||
data_fetcher_plugin: http
|
||||
data_parser_plugin: json
|
||||
# The data_parser normally limits the fields passed on to the source plugin
|
||||
# to fields configured to be used as part of the migration. To support more
|
||||
# dynamic migrations, the JSON data parser supports including the original
|
||||
# data for the current row. Simply include the 'include_raw_data' flag set
|
||||
# to `true` to enable this. This option is disabled by default to minimize
|
||||
# memory footprint for migrations that do not need this capability.
|
||||
# include_raw_data: true
|
||||
# Normally, this is one or more fully-qualified URLs or file paths. Because
|
||||
# we can't hardcode your local URL, we provide a relative path here which
|
||||
# hook_install() will rewrite to a full URL for the current site.
|
||||
urls: /migrate_example_advanced_position?_format=json
|
||||
# An xpath-like selector corresponding to the items to be imported.
|
||||
item_selector: position
|
||||
# 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 xpath for retrieving that value. It's important to note that this xpath
|
||||
# is relative to the elements retrieved by item_selector.
|
||||
fields:
|
||||
-
|
||||
name: machine_name
|
||||
label: 'Unique position identifier'
|
||||
selector: sourceid
|
||||
-
|
||||
name: friendly_name
|
||||
label: 'Position name'
|
||||
selector: name
|
||||
# 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:
|
||||
machine_name:
|
||||
type: string
|
||||
process:
|
||||
# Note that the source field names here (machine_name and friendly_name) were
|
||||
# defined by the 'fields' configuration for the source plugin above.
|
||||
id: machine_name
|
||||
label: friendly_name
|
||||
destination:
|
||||
plugin: entity:user_role
|
||||
migration_dependencies: {}
|
||||
dependencies:
|
||||
enforced:
|
||||
module:
|
||||
- migrate_example_advanced
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
# This migration demonstrates importing from a monolithic XML file.
|
||||
id: wine_role_xml
|
||||
label: XML feed of roles (positions)
|
||||
migration_group: wine
|
||||
source:
|
||||
# We use the XML data parser plugin.
|
||||
plugin: url
|
||||
data_fetcher_plugin: http
|
||||
data_parser_plugin: xml
|
||||
# Normally, this is one or more fully-qualified URLs or file paths. Because
|
||||
# we can't hardcode your local URL, we provide a relative path here which
|
||||
# hook_install() will rewrite to a full URL for the current site.
|
||||
urls: /migrate_example_advanced_position?_format=xml
|
||||
# Visit the URL above (relative to your site root) and look at it. You can see
|
||||
# that <response> is the outer element, and each item we want to import is a
|
||||
# <position> element. The item_xpath value is the xpath to use to query the
|
||||
# desired elements.
|
||||
item_selector: /response/position
|
||||
# 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 xpath for retrieving that value. It's important to note that this xpath
|
||||
# is relative to the elements retrieved by item_xpath.
|
||||
fields:
|
||||
-
|
||||
name: machine_name
|
||||
label: 'Unique position identifier'
|
||||
selector: sourceid
|
||||
-
|
||||
name: friendly_name
|
||||
label: 'Position name'
|
||||
selector: name
|
||||
# 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:
|
||||
machine_name:
|
||||
type: string
|
||||
process:
|
||||
# Note that the source field names here (machine_name and friendly_name) were
|
||||
# defined by the 'fields' configuration for the source plugin above.
|
||||
id: machine_name
|
||||
label: friendly_name
|
||||
destination:
|
||||
plugin: entity:user_role
|
||||
migration_dependencies: {}
|
||||
dependencies:
|
||||
enforced:
|
||||
module:
|
||||
- migrate_example_advanced
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
id: wine_terms
|
||||
label: Migrate all categories into Drupal taxonomy terms
|
||||
migration_group: wine
|
||||
source:
|
||||
plugin: wine_term
|
||||
destination:
|
||||
plugin: entity:taxonomy_term
|
||||
process:
|
||||
name: name
|
||||
description: details
|
||||
# Usually, one wants to have a separate migration for each entity_type/bundle
|
||||
# combination - e.g., separate migrations for articles and blog posts, as
|
||||
# opposed to a single monolithic node migration. This affords maximum
|
||||
# control - the ability to import just one bundle at a time, and most
|
||||
# importantly to have distinct field mappings (because different node types
|
||||
# usually have different fields). In this case, though, because all of the
|
||||
# vocabularies we're importing come from a common table, and on the Drupal
|
||||
# side there are no distinct custom fields, we are able to import them all in
|
||||
# one migration. The static_map tells the migration in which vocabulary to
|
||||
# place each term, based on the incoming 'type' column.
|
||||
vid:
|
||||
plugin: static_map
|
||||
source: type
|
||||
map:
|
||||
best_with: migrate_example_wine_best_with
|
||||
region: migrate_example_wine_regions
|
||||
variety: migrate_example_wine_varieties
|
||||
parent:
|
||||
plugin: migration
|
||||
migration: wine_terms
|
||||
source: category_parent
|
||||
weight: ordering
|
||||
migration_dependencies: {}
|
||||
dependencies:
|
||||
enforced:
|
||||
module:
|
||||
- migrate_example_advanced
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
# This migration demonstrates importing from an endpoint listing other endpoints
|
||||
# containing individual item data.
|
||||
id: wine_variety_list
|
||||
label: XML feed of varieties
|
||||
migration_group: wine
|
||||
source:
|
||||
# We use the XML source plugin.
|
||||
plugin: xml
|
||||
# Normally, this is one or more fully-qualified URLs or file paths. Because
|
||||
# we can't hardcode your local URL, we provide a relative path here which
|
||||
# hook_install() will rewrite to a full URL for the current site.
|
||||
urls: /migrate_example_advanced_variety_list?_format=xml
|
||||
item_url: /migrate_example_advanced_variety_list/:id?_format=xml
|
||||
id_selector: /response/items
|
||||
# Visit the URL above (relative to your site root) and look at it. You can see
|
||||
# that <response> is the outer element, and each item we want to import is a
|
||||
# <position> element. The item_xpath value is the xpath to use to query the
|
||||
# desired elements.
|
||||
item_selector: /response/variety
|
||||
# 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 xpath for retrieving that value. It's important to note that this xpath
|
||||
# is relative to the elements retrieved by item_xpath.
|
||||
fields:
|
||||
category_name:
|
||||
label:
|
||||
selector: name
|
||||
category_details:
|
||||
label:
|
||||
selector: details
|
||||
category_parent:
|
||||
label: 'Unique position identifier'
|
||||
selector: parent
|
||||
# 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:
|
||||
category_name:
|
||||
type: string
|
||||
process:
|
||||
vid:
|
||||
plugin: default_value
|
||||
default_value: migrate_example_wine_varieties
|
||||
name: category_name
|
||||
description: category_details
|
||||
parent:
|
||||
plugin: migration
|
||||
migration: wine_terms
|
||||
source: category_parent
|
||||
destination:
|
||||
plugin: entity:taxonomy_term
|
||||
migration_dependencies:
|
||||
require:
|
||||
- wine_terms
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
# This migration demonstrates importing from multiple XML files.
|
||||
id: wine_variety_multi_xml
|
||||
label: XML feed of varieties
|
||||
migration_group: wine
|
||||
source:
|
||||
# We use the XML source plugin.
|
||||
plugin: url
|
||||
data_fetcher_plugin: http
|
||||
data_parser_plugin: xml
|
||||
# Normally, this is one or more fully-qualified URLs or file paths. Because
|
||||
# we can't hardcode your local URL, we provide a relative path here which
|
||||
# hook_install() will rewrite to a full URL for the current site.
|
||||
urls:
|
||||
- /migrate_example_advanced_variety_multiple/red?_format=xml
|
||||
- /migrate_example_advanced_variety_multiple/white?_format=xml
|
||||
# Visit the URL above (relative to your site root) and look at it. You can see
|
||||
# that <response> is the outer element, and each item we want to import is a
|
||||
# <position> element. The item_xpath value is the xpath to use to query the
|
||||
# desired elements.
|
||||
item_selector: /response/variety
|
||||
# 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 xpath for retrieving that value. It's important to note that this xpath
|
||||
# is relative to the elements retrieved by item_xpath.
|
||||
fields:
|
||||
-
|
||||
name: category_name
|
||||
label: Name
|
||||
selector: name
|
||||
-
|
||||
name: category_details
|
||||
label: Details
|
||||
selector: details
|
||||
-
|
||||
name: category_parent
|
||||
label: 'Unique position identifier'
|
||||
selector: parent
|
||||
-
|
||||
name: category_attributes
|
||||
label: 'List of variety attributes'
|
||||
selector: attributes
|
||||
# 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:
|
||||
category_name:
|
||||
type: string
|
||||
process:
|
||||
vid:
|
||||
plugin: default_value
|
||||
default_value: migrate_example_wine_varieties
|
||||
name: category_name
|
||||
description: category_details
|
||||
parent:
|
||||
plugin: migration
|
||||
migration: wine_terms
|
||||
source: category_parent
|
||||
field_variety_attributes: category_attributes
|
||||
destination:
|
||||
plugin: entity:taxonomy_term
|
||||
migration_dependencies:
|
||||
required:
|
||||
- wine_terms
|
||||
dependencies:
|
||||
enforced:
|
||||
module:
|
||||
- migrate_example_advanced
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
id: wine
|
||||
label: Wine Imports
|
||||
description: A few wine-related imports, demonstrating some more advanced migration techniques.
|
||||
source_type: Custom tables and XML
|
||||
shared_configuration:
|
||||
source:
|
||||
key: default
|
||||
dependencies:
|
||||
enforced:
|
||||
module:
|
||||
- migrate_example_advanced
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<producer>
|
||||
<name>Lolonis Winery</name>
|
||||
<description>Makers of Ladybug Red</description>
|
||||
<authorid>3</authorid>
|
||||
<region>Redwood Valley</region>
|
||||
</producer>
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<pr:producer xmlns:pr="http://www.wine.org/wine-producers">
|
||||
<pr:name>Château Latour</pr:name>
|
||||
<pr:description>Makers of grand vin Chateau Latour, Les Forts de Latour and Pauillac</pr:description>
|
||||
<pr:authorid>3</pr:authorid>
|
||||
<pr:region>Bordeaux</pr:region>
|
||||
</pr:producer>
|
||||
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<content>
|
||||
<sourceid>0001</sourceid>
|
||||
</content>
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<wn:content xmlns:wn="http://www.wine.org/wine">
|
||||
<wn:sourceid>0002</wn:sourceid>
|
||||
</wn:content>
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
type: module
|
||||
name: Migrate Example (Advanced)
|
||||
description: 'Specialized examples of Drupal 8 migration.'
|
||||
package: Examples
|
||||
# core: 8.x
|
||||
dependencies:
|
||||
- drupal:migrate
|
||||
- migrate_plus:migrate_example_advanced_setup
|
||||
- migrate_plus:migrate_plus
|
||||
|
||||
# Information added by Drupal.org packaging script on 2017-05-10
|
||||
version: '8.x-4.0-beta1'
|
||||
core: '8.x'
|
||||
project: 'migrate_plus'
|
||||
datestamp: 1494450189
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Install, update and uninstall functions for the migrate_example_advanced module.
|
||||
*/
|
||||
|
||||
use Drupal\migrate_plus\Entity\Migration;
|
||||
|
||||
/**
|
||||
* Implements hook_install().
|
||||
*/
|
||||
function migrate_example_advanced_install() {
|
||||
// We need the urls to be absolute for the XML source plugin to read them, but
|
||||
// the static configuration files on disk can't know the server and port to
|
||||
// use. So, in the .yml files we provide the REST resources relative to the
|
||||
// site root and here rewrite them to fully-qualified paths.
|
||||
|
||||
/** @var \Drupal\migrate_plus\Entity\MigrationInterface $wine_role_xml_migration */
|
||||
$wine_role_xml_migration = Migration::load('wine_role_xml');
|
||||
if ($wine_role_xml_migration) {
|
||||
$source = $wine_role_xml_migration->get('source');
|
||||
$request = \Drupal::request();
|
||||
$source['urls'] = 'http://' . $request->getHttpHost() . $source['urls'];
|
||||
$wine_role_xml_migration->set('source', $source);
|
||||
$wine_role_xml_migration->save();
|
||||
}
|
||||
/** @var \Drupal\migrate_plus\Entity\MigrationInterface $wine_role_json_migration */
|
||||
$wine_role_json_migration = Migration::load('wine_role_json');
|
||||
if ($wine_role_json_migration) {
|
||||
$source = $wine_role_json_migration->get('source');
|
||||
$request = \Drupal::request();
|
||||
$source['urls'] = 'http://' . $request->getHttpHost() . $source['urls'];
|
||||
$wine_role_json_migration->set('source', $source);
|
||||
$wine_role_json_migration->save();
|
||||
}
|
||||
/** @var \Drupal\migrate_plus\Entity\MigrationInterface $wine_variety_multi_xml_migration */
|
||||
$wine_variety_multi_xml_migration = Migration::load('wine_variety_multi_xml');
|
||||
if ($wine_variety_multi_xml_migration) {
|
||||
$source = $wine_variety_multi_xml_migration->get('source');
|
||||
$request = \Drupal::request();
|
||||
$urls = [];
|
||||
foreach ($source['urls'] as $url) {
|
||||
$urls[] = 'http://' . $request->getHttpHost() . $url;
|
||||
}
|
||||
$source['urls'] = $urls;
|
||||
$wine_variety_multi_xml_migration->set('source', $source);
|
||||
$wine_variety_multi_xml_migration->save();
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies: { }
|
||||
id: migrate_example_advanced_comment
|
||||
label: 'Node comments'
|
||||
target_entity_type_id: node
|
||||
description: ''
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
config:
|
||||
- comment.type.migrate_example_advanced_comment
|
||||
- field.field.comment.migrate_example_advanced_comment.comment_body
|
||||
module:
|
||||
- text
|
||||
id: comment.migrate_example_advanced_comment.default
|
||||
targetEntityType: comment
|
||||
bundle: migrate_example_advanced_comment
|
||||
mode: default
|
||||
content:
|
||||
author:
|
||||
weight: -2
|
||||
comment_body:
|
||||
type: text_textarea
|
||||
weight: 11
|
||||
settings:
|
||||
rows: 5
|
||||
placeholder: ''
|
||||
third_party_settings: { }
|
||||
subject:
|
||||
type: string_textfield
|
||||
weight: 10
|
||||
settings:
|
||||
size: 60
|
||||
placeholder: ''
|
||||
third_party_settings: { }
|
||||
hidden: { }
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
config:
|
||||
- field.field.node.migrate_example_producer.body
|
||||
- field.field.node.migrate_example_producer.field_migrate_example_wine_regio
|
||||
- node.type.migrate_example_producer
|
||||
module:
|
||||
- path
|
||||
- text
|
||||
id: node.migrate_example_producer.default
|
||||
targetEntityType: node
|
||||
bundle: migrate_example_producer
|
||||
mode: default
|
||||
content:
|
||||
body:
|
||||
type: text_textarea_with_summary
|
||||
weight: 31
|
||||
settings:
|
||||
rows: 9
|
||||
summary_rows: 3
|
||||
placeholder: ''
|
||||
third_party_settings: { }
|
||||
created:
|
||||
type: datetime_timestamp
|
||||
weight: 10
|
||||
settings: { }
|
||||
third_party_settings: { }
|
||||
field_migrate_example_wine_regio:
|
||||
weight: 32
|
||||
settings:
|
||||
match_operator: CONTAINS
|
||||
size: 60
|
||||
placeholder: ''
|
||||
third_party_settings: { }
|
||||
type: entity_reference_autocomplete
|
||||
path:
|
||||
type: path
|
||||
weight: 30
|
||||
settings: { }
|
||||
third_party_settings: { }
|
||||
promote:
|
||||
type: boolean_checkbox
|
||||
settings:
|
||||
display_label: true
|
||||
weight: 15
|
||||
third_party_settings: { }
|
||||
sticky:
|
||||
type: boolean_checkbox
|
||||
settings:
|
||||
display_label: true
|
||||
weight: 16
|
||||
third_party_settings: { }
|
||||
title:
|
||||
type: string_textfield
|
||||
weight: -5
|
||||
settings:
|
||||
size: 60
|
||||
placeholder: ''
|
||||
third_party_settings: { }
|
||||
uid:
|
||||
type: entity_reference_autocomplete
|
||||
weight: 5
|
||||
settings:
|
||||
match_operator: CONTAINS
|
||||
size: 60
|
||||
placeholder: ''
|
||||
third_party_settings: { }
|
||||
hidden: { }
|
||||
+117
@@ -0,0 +1,117 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
config:
|
||||
- field.field.node.migrate_example_wine.body
|
||||
- field.field.node.migrate_example_wine.field_migrate_example_comments
|
||||
- field.field.node.migrate_example_wine.field_migrate_example_adv_image
|
||||
- field.field.node.migrate_example_wine.field_migrate_example_top_vintag
|
||||
- field.field.node.migrate_example_wine.field_migrate_example_wine_best
|
||||
- field.field.node.migrate_example_wine.field_migrate_example_wine_ratin
|
||||
- field.field.node.migrate_example_wine.field_migrate_example_wine_regio
|
||||
- field.field.node.migrate_example_wine.field_migrate_example_wine_var
|
||||
- node.type.migrate_example_wine
|
||||
module:
|
||||
- comment
|
||||
- image
|
||||
- path
|
||||
- text
|
||||
id: node.migrate_example_wine.default
|
||||
targetEntityType: node
|
||||
bundle: migrate_example_wine
|
||||
mode: default
|
||||
content:
|
||||
body:
|
||||
type: text_textarea_with_summary
|
||||
weight: 31
|
||||
settings:
|
||||
rows: 9
|
||||
summary_rows: 3
|
||||
placeholder: ''
|
||||
third_party_settings: { }
|
||||
created:
|
||||
type: datetime_timestamp
|
||||
weight: 10
|
||||
settings: { }
|
||||
third_party_settings: { }
|
||||
field_migrate_example_comments:
|
||||
weight: 38
|
||||
settings: { }
|
||||
third_party_settings: { }
|
||||
type: comment_default
|
||||
field_migrate_example_adv_image:
|
||||
weight: 35
|
||||
settings:
|
||||
progress_indicator: throbber
|
||||
preview_image_style: thumbnail
|
||||
third_party_settings: { }
|
||||
type: image_image
|
||||
field_migrate_example_top_vintag:
|
||||
weight: 37
|
||||
settings:
|
||||
placeholder: ''
|
||||
third_party_settings: { }
|
||||
type: number
|
||||
field_migrate_example_wine_best:
|
||||
weight: 34
|
||||
settings:
|
||||
match_operator: CONTAINS
|
||||
size: 60
|
||||
placeholder: ''
|
||||
third_party_settings: { }
|
||||
type: entity_reference_autocomplete_tags
|
||||
field_migrate_example_wine_ratin:
|
||||
weight: 36
|
||||
settings:
|
||||
placeholder: ''
|
||||
third_party_settings: { }
|
||||
type: number
|
||||
field_migrate_example_wine_regio:
|
||||
weight: 33
|
||||
settings:
|
||||
match_operator: CONTAINS
|
||||
size: 60
|
||||
placeholder: ''
|
||||
third_party_settings: { }
|
||||
type: entity_reference_autocomplete
|
||||
field_migrate_example_wine_var:
|
||||
weight: 32
|
||||
settings:
|
||||
match_operator: CONTAINS
|
||||
size: 60
|
||||
placeholder: ''
|
||||
third_party_settings: { }
|
||||
type: entity_reference_autocomplete
|
||||
path:
|
||||
type: path
|
||||
weight: 30
|
||||
settings: { }
|
||||
third_party_settings: { }
|
||||
promote:
|
||||
type: boolean_checkbox
|
||||
settings:
|
||||
display_label: true
|
||||
weight: 15
|
||||
third_party_settings: { }
|
||||
sticky:
|
||||
type: boolean_checkbox
|
||||
settings:
|
||||
display_label: true
|
||||
weight: 16
|
||||
third_party_settings: { }
|
||||
title:
|
||||
type: string_textfield
|
||||
weight: -5
|
||||
settings:
|
||||
size: 60
|
||||
placeholder: ''
|
||||
third_party_settings: { }
|
||||
uid:
|
||||
type: entity_reference_autocomplete
|
||||
weight: 5
|
||||
settings:
|
||||
match_operator: CONTAINS
|
||||
size: 60
|
||||
placeholder: ''
|
||||
third_party_settings: { }
|
||||
hidden: { }
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
config:
|
||||
- field.field.taxonomy_term.migrate_example_wine_varieties.field_variety_attributes
|
||||
- taxonomy.vocabulary.migrate_example_wine_varieties
|
||||
module:
|
||||
- path
|
||||
- text
|
||||
id: taxonomy_term.migrate_example_wine_varieties.default
|
||||
targetEntityType: taxonomy_term
|
||||
bundle: migrate_example_wine_varieties
|
||||
mode: default
|
||||
content:
|
||||
description:
|
||||
type: text_textarea
|
||||
weight: 1
|
||||
settings:
|
||||
placeholder: ''
|
||||
rows: 5
|
||||
third_party_settings: { }
|
||||
field_variety_attributes:
|
||||
type: string_textfield
|
||||
weight: 3
|
||||
settings:
|
||||
size: 60
|
||||
placeholder: ''
|
||||
third_party_settings: { }
|
||||
name:
|
||||
type: string_textfield
|
||||
weight: 0
|
||||
settings:
|
||||
size: 60
|
||||
placeholder: ''
|
||||
third_party_settings: { }
|
||||
path:
|
||||
type: path
|
||||
weight: 2
|
||||
settings: { }
|
||||
third_party_settings: { }
|
||||
hidden: { }
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
config:
|
||||
- comment.type.migrate_example_advanced_comment
|
||||
- field.field.comment.migrate_example_advanced_comment.comment_body
|
||||
module:
|
||||
- text
|
||||
id: comment.migrate_example_advanced_comment.default
|
||||
targetEntityType: comment
|
||||
bundle: migrate_example_advanced_comment
|
||||
mode: default
|
||||
content:
|
||||
comment_body:
|
||||
label: hidden
|
||||
type: text_default
|
||||
weight: 0
|
||||
settings: { }
|
||||
third_party_settings: { }
|
||||
links:
|
||||
weight: 100
|
||||
hidden: { }
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
config:
|
||||
- field.field.node.migrate_example_producer.body
|
||||
- field.field.node.migrate_example_producer.field_migrate_example_wine_regio
|
||||
- node.type.migrate_example_producer
|
||||
module:
|
||||
- text
|
||||
- user
|
||||
id: node.migrate_example_producer.default
|
||||
targetEntityType: node
|
||||
bundle: migrate_example_producer
|
||||
mode: default
|
||||
content:
|
||||
body:
|
||||
label: hidden
|
||||
type: text_default
|
||||
weight: 101
|
||||
settings: { }
|
||||
third_party_settings: { }
|
||||
field_migrate_example_wine_regio:
|
||||
weight: 102
|
||||
label: inline
|
||||
settings:
|
||||
link: true
|
||||
third_party_settings: { }
|
||||
type: entity_reference_label
|
||||
links:
|
||||
weight: 100
|
||||
settings: { }
|
||||
third_party_settings: { }
|
||||
hidden: { }
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
config:
|
||||
- core.entity_view_mode.node.teaser
|
||||
- field.field.node.migrate_example_producer.body
|
||||
- field.field.node.migrate_example_producer.field_migrate_example_wine_regio
|
||||
- node.type.migrate_example_producer
|
||||
module:
|
||||
- text
|
||||
- user
|
||||
id: node.migrate_example_producer.teaser
|
||||
targetEntityType: node
|
||||
bundle: migrate_example_producer
|
||||
mode: teaser
|
||||
content:
|
||||
body:
|
||||
label: hidden
|
||||
type: text_summary_or_trimmed
|
||||
weight: 101
|
||||
settings:
|
||||
trim_length: 600
|
||||
third_party_settings: { }
|
||||
links:
|
||||
weight: 100
|
||||
hidden:
|
||||
field_migrate_example_wine_regio: true
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
config:
|
||||
- field.field.node.migrate_example_wine.body
|
||||
- field.field.node.migrate_example_wine.field_migrate_example_comments
|
||||
- field.field.node.migrate_example_wine.field_migrate_example_adv_image
|
||||
- field.field.node.migrate_example_wine.field_migrate_example_top_vintag
|
||||
- field.field.node.migrate_example_wine.field_migrate_example_wine_best
|
||||
- field.field.node.migrate_example_wine.field_migrate_example_wine_ratin
|
||||
- field.field.node.migrate_example_wine.field_migrate_example_wine_regio
|
||||
- field.field.node.migrate_example_wine.field_migrate_example_wine_var
|
||||
- node.type.migrate_example_wine
|
||||
module:
|
||||
- comment
|
||||
- image
|
||||
- text
|
||||
- user
|
||||
id: node.migrate_example_wine.default
|
||||
targetEntityType: node
|
||||
bundle: migrate_example_wine
|
||||
mode: default
|
||||
content:
|
||||
body:
|
||||
label: hidden
|
||||
type: text_default
|
||||
weight: 101
|
||||
settings: { }
|
||||
third_party_settings: { }
|
||||
field_migrate_example_comments:
|
||||
weight: 108
|
||||
label: hidden
|
||||
settings:
|
||||
pager_id: 0
|
||||
third_party_settings: { }
|
||||
type: comment_default
|
||||
field_migrate_example_adv_image:
|
||||
weight: 105
|
||||
label: hidden
|
||||
settings:
|
||||
image_style: ''
|
||||
image_link: ''
|
||||
third_party_settings: { }
|
||||
type: image
|
||||
field_migrate_example_top_vintag:
|
||||
weight: 107
|
||||
label: inline
|
||||
settings:
|
||||
thousand_separator: ''
|
||||
prefix_suffix: true
|
||||
third_party_settings: { }
|
||||
type: number_integer
|
||||
field_migrate_example_wine_best:
|
||||
weight: 104
|
||||
label: inline
|
||||
settings:
|
||||
link: true
|
||||
third_party_settings: { }
|
||||
type: entity_reference_label
|
||||
field_migrate_example_wine_ratin:
|
||||
weight: 106
|
||||
label: inline
|
||||
settings:
|
||||
thousand_separator: ''
|
||||
decimal_separator: .
|
||||
scale: 2
|
||||
prefix_suffix: true
|
||||
third_party_settings: { }
|
||||
type: number_decimal
|
||||
field_migrate_example_wine_regio:
|
||||
weight: 103
|
||||
label: inline
|
||||
settings:
|
||||
link: true
|
||||
third_party_settings: { }
|
||||
type: entity_reference_label
|
||||
field_migrate_example_wine_var:
|
||||
weight: 102
|
||||
label: inline
|
||||
settings:
|
||||
link: true
|
||||
third_party_settings: { }
|
||||
type: entity_reference_label
|
||||
links:
|
||||
weight: 100
|
||||
settings: { }
|
||||
third_party_settings: { }
|
||||
hidden: { }
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
config:
|
||||
- core.entity_view_mode.node.teaser
|
||||
- field.field.node.migrate_example_wine.body
|
||||
- field.field.node.migrate_example_wine.field_migrate_example_comments
|
||||
- field.field.node.migrate_example_wine.field_migrate_example_adv_image
|
||||
- field.field.node.migrate_example_wine.field_migrate_example_top_vintag
|
||||
- field.field.node.migrate_example_wine.field_migrate_example_wine_best
|
||||
- field.field.node.migrate_example_wine.field_migrate_example_wine_ratin
|
||||
- field.field.node.migrate_example_wine.field_migrate_example_wine_regio
|
||||
- field.field.node.migrate_example_wine.field_migrate_example_wine_var
|
||||
- node.type.migrate_example_wine
|
||||
module:
|
||||
- text
|
||||
- user
|
||||
id: node.migrate_example_wine.teaser
|
||||
targetEntityType: node
|
||||
bundle: migrate_example_wine
|
||||
mode: teaser
|
||||
content:
|
||||
body:
|
||||
label: hidden
|
||||
type: text_summary_or_trimmed
|
||||
weight: 101
|
||||
settings:
|
||||
trim_length: 600
|
||||
third_party_settings: { }
|
||||
links:
|
||||
weight: 100
|
||||
hidden:
|
||||
field_migrate_example_comments: true
|
||||
field_migrate_example_adv_image: true
|
||||
field_migrate_example_top_vintag: true
|
||||
field_migrate_example_wine_best: true
|
||||
field_migrate_example_wine_ratin: true
|
||||
field_migrate_example_wine_regio: true
|
||||
field_migrate_example_wine_var: true
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
config:
|
||||
- field.field.taxonomy_term.migrate_example_wine_varieties.field_variety_attributes
|
||||
- taxonomy.vocabulary.migrate_example_wine_varieties
|
||||
module:
|
||||
- text
|
||||
id: taxonomy_term.migrate_example_wine_varieties.default
|
||||
targetEntityType: taxonomy_term
|
||||
bundle: migrate_example_wine_varieties
|
||||
mode: default
|
||||
content:
|
||||
description:
|
||||
label: hidden
|
||||
type: text_default
|
||||
weight: 0
|
||||
settings: { }
|
||||
third_party_settings: { }
|
||||
field_variety_attributes:
|
||||
type: string
|
||||
weight: 0
|
||||
label: inline
|
||||
settings:
|
||||
link_to_entity: false
|
||||
third_party_settings: { }
|
||||
hidden: { }
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
config:
|
||||
- comment.type.migrate_example_advanced_comment
|
||||
- field.storage.comment.comment_body
|
||||
module:
|
||||
- text
|
||||
id: comment.migrate_example_advanced_comment.comment_body
|
||||
field_name: comment_body
|
||||
entity_type: comment
|
||||
bundle: migrate_example_advanced_comment
|
||||
label: Comment
|
||||
description: ''
|
||||
required: true
|
||||
translatable: true
|
||||
default_value: { }
|
||||
default_value_callback: ''
|
||||
settings: { }
|
||||
field_type: text_long
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
config:
|
||||
- field.storage.node.body
|
||||
- node.type.migrate_example_producer
|
||||
module:
|
||||
- text
|
||||
id: node.migrate_example_producer.body
|
||||
field_name: body
|
||||
entity_type: node
|
||||
bundle: migrate_example_producer
|
||||
label: Body
|
||||
description: ''
|
||||
required: false
|
||||
translatable: true
|
||||
default_value: { }
|
||||
default_value_callback: ''
|
||||
settings:
|
||||
display_summary: true
|
||||
field_type: text_with_summary
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
config:
|
||||
- field.storage.node.field_migrate_example_wine_regio
|
||||
- node.type.migrate_example_producer
|
||||
- taxonomy.vocabulary.migrate_example_wine_regions
|
||||
id: node.migrate_example_producer.field_migrate_example_wine_regio
|
||||
field_name: field_migrate_example_wine_regio
|
||||
entity_type: node
|
||||
bundle: migrate_example_producer
|
||||
label: 'Migrate Example Wine Regions'
|
||||
description: 'Select the region this wine comes from'
|
||||
required: false
|
||||
translatable: true
|
||||
default_value: { }
|
||||
default_value_callback: ''
|
||||
settings:
|
||||
handler: 'default:taxonomy_term'
|
||||
handler_settings:
|
||||
target_bundles:
|
||||
migrate_example_wine_regions: migrate_example_wine_regions
|
||||
sort:
|
||||
field: _none
|
||||
auto_create: false
|
||||
field_type: entity_reference
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
config:
|
||||
- field.storage.node.body
|
||||
- node.type.migrate_example_wine
|
||||
module:
|
||||
- text
|
||||
id: node.migrate_example_wine.body
|
||||
field_name: body
|
||||
entity_type: node
|
||||
bundle: migrate_example_wine
|
||||
label: Body
|
||||
description: ''
|
||||
required: false
|
||||
translatable: true
|
||||
default_value: { }
|
||||
default_value_callback: ''
|
||||
settings:
|
||||
display_summary: true
|
||||
field_type: text_with_summary
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
config:
|
||||
- field.storage.node.field_migrate_example_adv_image
|
||||
- node.type.migrate_example_wine
|
||||
module:
|
||||
- image
|
||||
id: node.migrate_example_wine.field_migrate_example_adv_image
|
||||
field_name: field_migrate_example_adv_image
|
||||
entity_type: node
|
||||
bundle: migrate_example_wine
|
||||
label: Image
|
||||
description: 'Upload an image to go with this wine.'
|
||||
required: false
|
||||
translatable: false
|
||||
default_value: { }
|
||||
default_value_callback: ''
|
||||
settings:
|
||||
file_directory: field/migrate_example/image
|
||||
file_extensions: 'png gif jpg jpeg'
|
||||
max_filesize: ''
|
||||
max_resolution: ''
|
||||
min_resolution: ''
|
||||
alt_field: true
|
||||
alt_field_required: false
|
||||
title_field: false
|
||||
title_field_required: false
|
||||
default_image:
|
||||
uuid: ''
|
||||
alt: ''
|
||||
title: ''
|
||||
width: null
|
||||
height: null
|
||||
handler: 'default:file'
|
||||
handler_settings: { }
|
||||
field_type: image
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
config:
|
||||
- field.storage.node.field_migrate_example_comments
|
||||
- node.type.migrate_example_wine
|
||||
module:
|
||||
- comment
|
||||
id: node.migrate_example_wine.field_migrate_example_comments
|
||||
field_name: field_migrate_example_comments
|
||||
entity_type: node
|
||||
bundle: migrate_example_wine
|
||||
label: Comments
|
||||
description: ''
|
||||
required: false
|
||||
translatable: false
|
||||
default_value:
|
||||
-
|
||||
status: 2
|
||||
cid: 0
|
||||
last_comment_timestamp: 0
|
||||
last_comment_name: null
|
||||
last_comment_uid: 0
|
||||
comment_count: 0
|
||||
default_value_callback: ''
|
||||
settings:
|
||||
default_mode: 1
|
||||
per_page: 50
|
||||
anonymous: 0
|
||||
form_location: true
|
||||
preview: 1
|
||||
field_type: comment
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
config:
|
||||
- field.storage.node.field_migrate_example_top_vintag
|
||||
- node.type.migrate_example_wine
|
||||
id: node.migrate_example_wine.field_migrate_example_top_vintag
|
||||
field_name: field_migrate_example_top_vintag
|
||||
entity_type: node
|
||||
bundle: migrate_example_wine
|
||||
label: 'Recommended vintages'
|
||||
description: ''
|
||||
required: false
|
||||
translatable: false
|
||||
default_value: { }
|
||||
default_value_callback: ''
|
||||
settings:
|
||||
min: null
|
||||
max: null
|
||||
prefix: ''
|
||||
suffix: ''
|
||||
field_type: integer
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
config:
|
||||
- field.storage.node.field_migrate_example_wine_best
|
||||
- node.type.migrate_example_wine
|
||||
- taxonomy.vocabulary.migrate_example_wine_best_with
|
||||
id: node.migrate_example_wine.field_migrate_example_wine_best
|
||||
field_name: field_migrate_example_wine_best
|
||||
entity_type: node
|
||||
bundle: migrate_example_wine
|
||||
label: 'Migrate Example Wine Best With'
|
||||
description: 'Enter any foods this wine may be paired with, separated by commas'
|
||||
required: false
|
||||
translatable: false
|
||||
default_value: { }
|
||||
default_value_callback: ''
|
||||
settings:
|
||||
handler: 'default:taxonomy_term'
|
||||
handler_settings:
|
||||
target_bundles:
|
||||
migrate_example_wine_best_with: migrate_example_wine_best_with
|
||||
sort:
|
||||
field: _none
|
||||
auto_create: false
|
||||
field_type: entity_reference
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
config:
|
||||
- field.storage.node.field_migrate_example_wine_ratin
|
||||
- node.type.migrate_example_wine
|
||||
id: node.migrate_example_wine.field_migrate_example_wine_ratin
|
||||
field_name: field_migrate_example_wine_ratin
|
||||
entity_type: node
|
||||
bundle: migrate_example_wine
|
||||
label: Rating
|
||||
description: 'Rating on a 1-100 scale'
|
||||
required: false
|
||||
translatable: false
|
||||
default_value: { }
|
||||
default_value_callback: ''
|
||||
settings:
|
||||
min: !!float 1
|
||||
max: !!float 100
|
||||
prefix: ''
|
||||
suffix: ''
|
||||
field_type: decimal
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
config:
|
||||
- field.storage.node.field_migrate_example_wine_regio
|
||||
- node.type.migrate_example_wine
|
||||
- taxonomy.vocabulary.migrate_example_wine_regions
|
||||
id: node.migrate_example_wine.field_migrate_example_wine_regio
|
||||
field_name: field_migrate_example_wine_regio
|
||||
entity_type: node
|
||||
bundle: migrate_example_wine
|
||||
label: 'Migrate Example Wine Regions'
|
||||
description: 'Select the region this wine comes from'
|
||||
required: false
|
||||
translatable: false
|
||||
default_value: { }
|
||||
default_value_callback: ''
|
||||
settings:
|
||||
handler: 'default:taxonomy_term'
|
||||
handler_settings:
|
||||
target_bundles:
|
||||
migrate_example_wine_regions: migrate_example_wine_regions
|
||||
sort:
|
||||
field: _none
|
||||
auto_create: false
|
||||
field_type: entity_reference
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
config:
|
||||
- field.storage.node.field_migrate_example_wine_var
|
||||
- node.type.migrate_example_wine
|
||||
- taxonomy.vocabulary.migrate_example_wine_varieties
|
||||
id: node.migrate_example_wine.field_migrate_example_wine_var
|
||||
field_name: field_migrate_example_wine_var
|
||||
entity_type: node
|
||||
bundle: migrate_example_wine
|
||||
label: 'Migrate Example Wine Varieties'
|
||||
description: 'Select the variety of this wine'
|
||||
required: false
|
||||
translatable: false
|
||||
default_value: { }
|
||||
default_value_callback: ''
|
||||
settings:
|
||||
handler: 'default:taxonomy_term'
|
||||
handler_settings:
|
||||
target_bundles:
|
||||
migrate_example_wine_varieties: migrate_example_wine_varieties
|
||||
sort:
|
||||
field: _none
|
||||
auto_create: false
|
||||
field_type: entity_reference
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
config:
|
||||
- field.storage.taxonomy_term.field_variety_attributes
|
||||
- taxonomy.vocabulary.migrate_example_wine_varieties
|
||||
id: taxonomy_term.migrate_example_wine_varieties.field_variety_attributes
|
||||
field_name: field_variety_attributes
|
||||
entity_type: taxonomy_term
|
||||
bundle: migrate_example_wine_varieties
|
||||
label: Attributes
|
||||
description: ''
|
||||
required: false
|
||||
translatable: false
|
||||
default_value: { }
|
||||
default_value_callback: ''
|
||||
settings: { }
|
||||
field_type: string
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
module:
|
||||
- file
|
||||
- image
|
||||
- node
|
||||
id: node.field_migrate_example_adv_image
|
||||
field_name: field_migrate_example_adv_image
|
||||
entity_type: node
|
||||
type: image
|
||||
settings:
|
||||
uri_scheme: public
|
||||
default_image:
|
||||
uuid: ''
|
||||
alt: ''
|
||||
title: ''
|
||||
width: null
|
||||
height: null
|
||||
target_type: file
|
||||
display_field: false
|
||||
display_default: false
|
||||
module: image
|
||||
locked: false
|
||||
cardinality: -1
|
||||
translatable: true
|
||||
indexes: { }
|
||||
persist_with_no_fields: false
|
||||
custom_storage: false
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
module:
|
||||
- comment
|
||||
- node
|
||||
id: node.field_migrate_example_comments
|
||||
field_name: field_migrate_example_comments
|
||||
entity_type: node
|
||||
type: comment
|
||||
settings:
|
||||
comment_type: migrate_example_advanced_comment
|
||||
module: comment
|
||||
locked: false
|
||||
cardinality: 1
|
||||
translatable: true
|
||||
indexes: { }
|
||||
persist_with_no_fields: false
|
||||
custom_storage: false
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
module:
|
||||
- node
|
||||
id: node.field_migrate_example_top_vintag
|
||||
field_name: field_migrate_example_top_vintag
|
||||
entity_type: node
|
||||
type: integer
|
||||
settings:
|
||||
unsigned: false
|
||||
size: normal
|
||||
module: core
|
||||
locked: false
|
||||
cardinality: -1
|
||||
translatable: true
|
||||
indexes: { }
|
||||
persist_with_no_fields: false
|
||||
custom_storage: false
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
module:
|
||||
- node
|
||||
- taxonomy
|
||||
id: node.field_migrate_example_wine_best
|
||||
field_name: field_migrate_example_wine_best
|
||||
entity_type: node
|
||||
type: entity_reference
|
||||
settings:
|
||||
target_type: taxonomy_term
|
||||
module: core
|
||||
locked: false
|
||||
cardinality: -1
|
||||
translatable: true
|
||||
indexes: { }
|
||||
persist_with_no_fields: false
|
||||
custom_storage: false
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
module:
|
||||
- node
|
||||
id: node.field_migrate_example_wine_ratin
|
||||
field_name: field_migrate_example_wine_ratin
|
||||
entity_type: node
|
||||
type: decimal
|
||||
settings:
|
||||
precision: 10
|
||||
scale: 0
|
||||
module: core
|
||||
locked: false
|
||||
cardinality: 1
|
||||
translatable: true
|
||||
indexes: { }
|
||||
persist_with_no_fields: false
|
||||
custom_storage: false
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
module:
|
||||
- node
|
||||
- taxonomy
|
||||
id: node.field_migrate_example_wine_regio
|
||||
field_name: field_migrate_example_wine_regio
|
||||
entity_type: node
|
||||
type: entity_reference
|
||||
settings:
|
||||
target_type: taxonomy_term
|
||||
module: core
|
||||
locked: false
|
||||
cardinality: 1
|
||||
translatable: true
|
||||
indexes: { }
|
||||
persist_with_no_fields: false
|
||||
custom_storage: false
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
module:
|
||||
- node
|
||||
- taxonomy
|
||||
id: node.field_migrate_example_wine_var
|
||||
field_name: field_migrate_example_wine_var
|
||||
entity_type: node
|
||||
type: entity_reference
|
||||
settings:
|
||||
target_type: taxonomy_term
|
||||
module: core
|
||||
locked: false
|
||||
cardinality: 1
|
||||
translatable: true
|
||||
indexes: { }
|
||||
persist_with_no_fields: false
|
||||
custom_storage: false
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
module:
|
||||
- taxonomy
|
||||
id: taxonomy_term.field_variety_attributes
|
||||
field_name: field_variety_attributes
|
||||
entity_type: taxonomy_term
|
||||
type: string
|
||||
settings:
|
||||
max_length: 255
|
||||
is_ascii: false
|
||||
case_sensitive: false
|
||||
module: core
|
||||
locked: false
|
||||
cardinality: -1
|
||||
translatable: true
|
||||
indexes: { }
|
||||
persist_with_no_fields: false
|
||||
custom_storage: false
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies: { }
|
||||
name: 'Wine Producer'
|
||||
type: migrate_example_producer
|
||||
description: 'Wineries, vineyards, and large producers.'
|
||||
help: ''
|
||||
new_revision: false
|
||||
preview_mode: 1
|
||||
display_submitted: true
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies: { }
|
||||
name: Wine
|
||||
type: migrate_example_wine
|
||||
description: 'Wine is what we drink.'
|
||||
help: ''
|
||||
new_revision: false
|
||||
preview_mode: 1
|
||||
display_submitted: true
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
id: migrate_example_advanced_position
|
||||
plugin_id: 'migrate_example_advanced_position'
|
||||
granularity: method
|
||||
configuration:
|
||||
GET:
|
||||
supported_formats:
|
||||
- json
|
||||
- xml
|
||||
supported_auth:
|
||||
- cookie
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
id: migrate_example_advanced_variety_items
|
||||
plugin_id: 'migrate_example_advanced_variety_items'
|
||||
granularity: method
|
||||
configuration:
|
||||
GET:
|
||||
supported_formats:
|
||||
- json
|
||||
- xml
|
||||
supported_auth:
|
||||
- cookie
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
id: migrate_example_advanced_variety_list
|
||||
plugin_id: 'migrate_example_advanced_variety_list'
|
||||
granularity: method
|
||||
configuration:
|
||||
GET:
|
||||
supported_formats:
|
||||
- json
|
||||
- xml
|
||||
supported_auth:
|
||||
- cookie
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
id: migrate_example_advanced_variety_multiple
|
||||
plugin_id: 'migrate_example_advanced_variety_multiple'
|
||||
granularity: method
|
||||
configuration:
|
||||
GET:
|
||||
supported_formats:
|
||||
- json
|
||||
- xml
|
||||
supported_auth:
|
||||
- cookie
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies: { }
|
||||
name: 'Migrate Example Wine Best With'
|
||||
vid: migrate_example_wine_best_with
|
||||
description: 'Foods the wine goes best with'
|
||||
hierarchy: 0
|
||||
weight: 0
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies: { }
|
||||
name: 'Migrate Example Wine Regions'
|
||||
vid: migrate_example_wine_regions
|
||||
description: 'Wine regions'
|
||||
hierarchy: 0
|
||||
weight: 0
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies: { }
|
||||
name: 'Migrate Example Wine Varieties'
|
||||
vid: migrate_example_wine_varieties
|
||||
description: 'Wine varieties'
|
||||
hierarchy: 0
|
||||
weight: 0
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
type: module
|
||||
name: Migrate Advanced Example Setup
|
||||
description: 'Separate site configuration for the example from the actual migration.'
|
||||
package: Migration
|
||||
# core: 8.x
|
||||
hidden: 1
|
||||
dependencies:
|
||||
- drupal:comment
|
||||
- drupal:image
|
||||
- drupal:text
|
||||
- drupal:taxonomy
|
||||
- drupal:rest
|
||||
|
||||
# Information added by Drupal.org packaging script on 2017-05-10
|
||||
version: '8.x-4.0-beta1'
|
||||
core: '8.x'
|
||||
project: 'migrate_plus'
|
||||
datestamp: 1494450189
|
||||
+895
@@ -0,0 +1,895 @@
|
||||
<?php
|
||||
use Drupal\user\RoleInterface;
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Set up source data and destination configuration for the migration example
|
||||
* module. We do this in a separate module so migrate_example_advanced itself is
|
||||
* a pure migration module.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_schema().
|
||||
*/
|
||||
function migrate_example_advanced_setup_schema() {
|
||||
$schema['migrate_example_advanced_account'] = migrate_example_advanced_schema_account();
|
||||
$schema['migrate_example_advanced_account_updates'] = migrate_example_advanced_schema_account_updates();
|
||||
$schema['migrate_example_advanced_categories'] = migrate_example_advanced_schema_categories();
|
||||
$schema['migrate_example_advanced_vintages'] = migrate_example_advanced_schema_vintages();
|
||||
$schema['migrate_example_advanced_variety_updates'] = migrate_example_advanced_schema_variety_updates();
|
||||
$schema['migrate_example_wine'] = migrate_example_advanced_schema_wine();
|
||||
$schema['migrate_example_advanced_updates'] = migrate_example_advanced_schema_updates();
|
||||
$schema['migrate_example_advanced_producer'] = migrate_example_advanced_schema_producer();
|
||||
$schema['migrate_example_advanced_category_wine'] = migrate_example_advanced_schema_category_wine();
|
||||
$schema['migrate_example_advanced_category_producer'] = migrate_example_advanced_schema_category_producer();
|
||||
$schema['migrate_example_advanced_comment'] = migrate_example_advanced_schema_comment();
|
||||
$schema['migrate_example_advanced_comment_updates'] = migrate_example_advanced_schema_comment_updates();
|
||||
$schema['migrate_example_advanced_files'] = migrate_example_advanced_schema_files();
|
||||
$schema['migrate_example_advanced_blobs'] = migrate_example_advanced_schema_blobs();
|
||||
$schema['migrate_example_advanced_table_source'] = migrate_example_advanced_schema_table_source();
|
||||
$schema['migrate_example_advanced_table_dest'] = migrate_example_advanced_schema_table_dest();
|
||||
|
||||
return $schema;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_install().
|
||||
*/
|
||||
function migrate_example_advanced_setup_install() {
|
||||
// Populate our tables.
|
||||
migrate_example_advanced_data_account();
|
||||
migrate_example_advanced_data_account_updates();
|
||||
migrate_example_advanced_data_categories();
|
||||
migrate_example_advanced_data_vintages();
|
||||
migrate_example_advanced_data_variety_updates();
|
||||
migrate_example_advanced_data_wine();
|
||||
migrate_example_advanced_data_updates();
|
||||
migrate_example_advanced_data_producer();
|
||||
migrate_example_advanced_data_category_wine();
|
||||
migrate_example_advanced_data_category_producer();
|
||||
migrate_example_advanced_data_comment();
|
||||
migrate_example_advanced_data_comment_updates();
|
||||
migrate_example_advanced_data_files();
|
||||
migrate_example_advanced_data_blobs();
|
||||
migrate_example_advanced_data_table_source();
|
||||
}
|
||||
|
||||
function migrate_example_advanced_schema_wine() {
|
||||
return [
|
||||
'description' => 'Wines of the world',
|
||||
'fields' => [
|
||||
'wineid' => [
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
'description' => 'Wine ID',
|
||||
],
|
||||
'name' => [
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => TRUE,
|
||||
],
|
||||
'body' => [
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Full description of the wine.',
|
||||
],
|
||||
'excerpt' => [
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Abstract for this wine.',
|
||||
],
|
||||
'accountid' => [
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => FALSE,
|
||||
'description' => 'ID of the author.',
|
||||
],
|
||||
'posted' => [
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
'description' => 'Original creation date',
|
||||
],
|
||||
'last_changed' => [
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
'description' => 'Last change date',
|
||||
],
|
||||
'variety' => [
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
'description' => 'Wine variety',
|
||||
],
|
||||
'region' => [
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
'description' => 'Wine region',
|
||||
],
|
||||
'rating' => [
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Rating (100-point scale)',
|
||||
],
|
||||
],
|
||||
'primary key' => ['wineid'],
|
||||
];
|
||||
}
|
||||
|
||||
function migrate_example_advanced_schema_updates() {
|
||||
return array(
|
||||
'description' => 'Updated wine ratings',
|
||||
'fields' => [
|
||||
'wineid' => [
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
'description' => 'Wine ID',
|
||||
],
|
||||
'rating' => [
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Rating (100-point scale)',
|
||||
],
|
||||
],
|
||||
'primary key' => ['wineid'],
|
||||
);
|
||||
}
|
||||
|
||||
function migrate_example_advanced_schema_producer() {
|
||||
return array(
|
||||
'description' => 'Wine producers of the world',
|
||||
'fields' => array(
|
||||
'producerid' => array(
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
'description' => 'Producer ID',
|
||||
),
|
||||
'name' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => TRUE,
|
||||
),
|
||||
'body' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Full description of the producer.',
|
||||
),
|
||||
'excerpt' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Abstract for this producer.',
|
||||
),
|
||||
'accountid' => array(
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Account ID of the author.',
|
||||
),
|
||||
),
|
||||
'primary key' => array('producerid'),
|
||||
);
|
||||
}
|
||||
|
||||
function migrate_example_advanced_schema_categories() {
|
||||
return array(
|
||||
'description' => 'Categories',
|
||||
'fields' => array(
|
||||
'categoryid' => array(
|
||||
'type' => 'int',
|
||||
'not null' => TRUE,
|
||||
'unsigned' => TRUE,
|
||||
'description' => 'Category ID',
|
||||
),
|
||||
'type' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => TRUE,
|
||||
'description' => 'Type of category: variety, region, best_with',
|
||||
),
|
||||
'name' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => TRUE,
|
||||
),
|
||||
'details' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
),
|
||||
'category_parent' => array(
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Parent category, if any',
|
||||
),
|
||||
'ordering' => array(
|
||||
'type' => 'int',
|
||||
'unsigned' => FALSE,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Order in which to display categories',
|
||||
),
|
||||
),
|
||||
'primary key' => array('categoryid'),
|
||||
);
|
||||
}
|
||||
|
||||
function migrate_example_advanced_schema_vintages() {
|
||||
return array(
|
||||
'description' => 'Wine vintages',
|
||||
'fields' => array(
|
||||
'wineid' => array(
|
||||
'type' => 'int',
|
||||
'not null' => TRUE,
|
||||
'description' => 'Wine ID',
|
||||
),
|
||||
'vintage' => array(
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
'description' => 'Vintage (year)',
|
||||
),
|
||||
),
|
||||
'primary key' => array('wineid', 'vintage'),
|
||||
);
|
||||
}
|
||||
|
||||
function migrate_example_advanced_schema_variety_updates() {
|
||||
return array(
|
||||
'description' => 'Variety updates',
|
||||
'fields' => array(
|
||||
'categoryid' => array(
|
||||
'type' => 'int',
|
||||
'not null' => TRUE,
|
||||
'unsigned' => TRUE,
|
||||
'description' => 'Category ID',
|
||||
),
|
||||
'details' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
),
|
||||
),
|
||||
'primary key' => array('categoryid'),
|
||||
);
|
||||
}
|
||||
|
||||
function migrate_example_advanced_schema_category_wine() {
|
||||
return array(
|
||||
'description' => 'Wine category assignments',
|
||||
'fields' => array(
|
||||
'wineid' => array(
|
||||
'type' => 'int',
|
||||
'not null' => TRUE,
|
||||
'description' => 'Wine ID',
|
||||
),
|
||||
'categoryid' => array(
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
'description' => 'Category ID',
|
||||
),
|
||||
),
|
||||
'primary key' => array('categoryid', 'wineid'),
|
||||
);
|
||||
}
|
||||
|
||||
function migrate_example_advanced_schema_category_producer() {
|
||||
return array(
|
||||
'description' => 'Producer category assignments',
|
||||
'fields' => array(
|
||||
'producerid' => array(
|
||||
'type' => 'int',
|
||||
'not null' => TRUE,
|
||||
'description' => 'Producer ID',
|
||||
),
|
||||
'categoryid' => array(
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
'description' => 'Category ID',
|
||||
),
|
||||
),
|
||||
'primary key' => array('categoryid', 'producerid'),
|
||||
);
|
||||
}
|
||||
|
||||
function migrate_example_advanced_schema_comment() {
|
||||
return array(
|
||||
'description' => 'Wine comments',
|
||||
'fields' => array(
|
||||
'commentid' => array(
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
'description' => 'Comment ID',
|
||||
),
|
||||
'wineid' => array(
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
'description' => 'Wine ID that is being commented upon',
|
||||
),
|
||||
'comment_parent' => array(
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Parent comment ID in case of comment replies.',
|
||||
),
|
||||
'subject' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Comment subject',
|
||||
),
|
||||
'body' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Comment body',
|
||||
),
|
||||
'name' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Comment name (if anon)',
|
||||
),
|
||||
'mail' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Comment email (if anon)',
|
||||
),
|
||||
'accountid' => array(
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Account ID (if any).',
|
||||
),
|
||||
'commenthost' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
'description' => 'IP/domain of host posted from',
|
||||
),
|
||||
'userpage' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
'description' => 'User homepage',
|
||||
),
|
||||
'posted' => array(
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
'description' => 'Date comment posted',
|
||||
),
|
||||
'lastchanged' => array(
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
'description' => 'Date comment last changed',
|
||||
),
|
||||
),
|
||||
'primary key' => array('commentid'),
|
||||
);
|
||||
}
|
||||
|
||||
function migrate_example_advanced_schema_comment_updates() {
|
||||
return array(
|
||||
'description' => 'Wine comment updates',
|
||||
'fields' => array(
|
||||
'commentid' => array(
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
'description' => 'Comment ID',
|
||||
),
|
||||
'subject' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Comment subject',
|
||||
),
|
||||
),
|
||||
'primary key' => array('commentid'),
|
||||
);
|
||||
}
|
||||
|
||||
function migrate_example_advanced_schema_account() {
|
||||
return array(
|
||||
'description' => 'Wine accounts.',
|
||||
'fields' => array(
|
||||
'accountid' => array(
|
||||
'type' => 'serial',
|
||||
'not null' => TRUE,
|
||||
'description' => 'Account ID',
|
||||
),
|
||||
'status' => array(
|
||||
'type' => 'int',
|
||||
'not null' => TRUE,
|
||||
'description' => 'Blocked_Allowed',
|
||||
),
|
||||
'posted' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => TRUE,
|
||||
'description' => 'Registration date',
|
||||
),
|
||||
'last_access' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => TRUE,
|
||||
'description' => 'Last access date',
|
||||
),
|
||||
'last_login' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => TRUE,
|
||||
'description' => 'Last login date',
|
||||
),
|
||||
'name' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Account name (for login)',
|
||||
),
|
||||
'sex' => array(
|
||||
'type' => 'char',
|
||||
'length' => 1,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Gender',
|
||||
),
|
||||
'password' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Account password (raw)',
|
||||
),
|
||||
'mail' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Account email',
|
||||
),
|
||||
'original_mail' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Original account email',
|
||||
),
|
||||
'sig' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => TRUE,
|
||||
'description' => 'Signature for comments',
|
||||
),
|
||||
'imageid' => array(
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Image ID',
|
||||
),
|
||||
'positions' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Positions held',
|
||||
),
|
||||
),
|
||||
'primary key' => array('accountid'),
|
||||
);
|
||||
}
|
||||
|
||||
function migrate_example_advanced_schema_account_updates() {
|
||||
return array(
|
||||
'description' => 'Wine account updates',
|
||||
'fields' => array(
|
||||
'accountid' => array(
|
||||
'type' => 'serial',
|
||||
'not null' => TRUE,
|
||||
'description' => 'Account ID',
|
||||
),
|
||||
'sex' => array(
|
||||
'type' => 'char',
|
||||
'length' => 1,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Gender',
|
||||
),
|
||||
),
|
||||
'primary key' => array('accountid'),
|
||||
);
|
||||
}
|
||||
|
||||
function migrate_example_advanced_schema_blobs() {
|
||||
return array(
|
||||
'description' => 'Wine blobs to be migrated to file entities',
|
||||
'fields' => array(
|
||||
'imageid' => array(
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
'description' => 'Image ID',
|
||||
),
|
||||
'imageblob' => array(
|
||||
'type' => 'blob',
|
||||
'size' => 'normal',
|
||||
'description' => 'binary image data',
|
||||
),
|
||||
),
|
||||
'primary key' => array('imageid'),
|
||||
);
|
||||
}
|
||||
|
||||
function migrate_example_advanced_schema_files() {
|
||||
return array(
|
||||
'description' => 'Wine and account files',
|
||||
'fields' => array(
|
||||
'imageid' => array(
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
'description' => 'Image ID',
|
||||
),
|
||||
'url' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => TRUE,
|
||||
'description' => 'Image URL',
|
||||
),
|
||||
'image_alt' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Image alt',
|
||||
),
|
||||
'image_title' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Image title',
|
||||
),
|
||||
'wineid' => array(
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Wine node this is associated with',
|
||||
),
|
||||
),
|
||||
'primary key' => array('imageid'),
|
||||
);
|
||||
}
|
||||
|
||||
function migrate_example_advanced_schema_table_source() {
|
||||
return array(
|
||||
'description' => 'Source data to go into a custom Drupal table',
|
||||
'fields' => array(
|
||||
'fooid' => array(
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
'description' => 'Primary key',
|
||||
),
|
||||
'field1' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => TRUE,
|
||||
'description' => 'First field',
|
||||
),
|
||||
'field2' => array(
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
'description' => 'Second field',
|
||||
),
|
||||
),
|
||||
'primary key' => array('fooid'),
|
||||
);
|
||||
}
|
||||
|
||||
function migrate_example_advanced_schema_table_dest() {
|
||||
return array(
|
||||
'description' => 'Custom Drupal table to receive source data directly',
|
||||
'fields' => array(
|
||||
'recordid' => array(
|
||||
'type' => 'serial',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
'description' => 'Primary key',
|
||||
),
|
||||
'drupal_text' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => TRUE,
|
||||
'description' => 'First field',
|
||||
),
|
||||
'drupal_int' => array(
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
'description' => 'Second field',
|
||||
),
|
||||
),
|
||||
'primary key' => array('recordid'),
|
||||
);
|
||||
}
|
||||
|
||||
function migrate_example_advanced_data_wine() {
|
||||
$fields = array('wineid', 'name', 'body', 'excerpt', 'accountid',
|
||||
'posted', 'last_changed', 'variety', 'region', 'rating');
|
||||
$query = db_insert('migrate_example_wine')
|
||||
->fields($fields);
|
||||
$data = array(
|
||||
array(1, 'Montes Classic Cabernet Sauvignon', 'Intense ruby-red color', 'Great!', 9,
|
||||
strtotime('2010-01-02 03:04:05'), strtotime('2010-03-04 05:06:07'), 25, 17, 95),
|
||||
array(2, 'Archeo Ruggero di Tasso Nero d\'Avola', 'Lots of berry character', 'Pair with red sauced dishes', 3,
|
||||
strtotime('2010-09-03 18:23:58'), strtotime('2010-09-03 18:23:58'), 26, 2, 85),
|
||||
);
|
||||
foreach ($data as $row) {
|
||||
$query->values(array_combine($fields, $row));
|
||||
}
|
||||
$query->execute();
|
||||
}
|
||||
|
||||
function migrate_example_advanced_data_updates() {
|
||||
$fields = array('wineid', 'rating');
|
||||
$query = db_insert('migrate_example_advanced_updates')
|
||||
->fields($fields);
|
||||
$data = array(
|
||||
array(1, 93),
|
||||
array(2, NULL),
|
||||
);
|
||||
foreach ($data as $row) {
|
||||
$query->values(array_combine($fields, $row));
|
||||
}
|
||||
$query->execute();
|
||||
}
|
||||
|
||||
function migrate_example_advanced_data_producer() {
|
||||
$fields = array('producerid', 'name', 'body', 'excerpt', 'accountid');
|
||||
$query = db_insert('migrate_example_advanced_producer')
|
||||
->fields($fields);
|
||||
$data = array(
|
||||
array(1, 'Montes', 'Fine Chilean winery', 'Great!', 9),
|
||||
array(2, 'Archeo', 'Sicilia!', NULL, 3),
|
||||
);
|
||||
foreach ($data as $row) {
|
||||
$query->values(array_combine($fields, $row));
|
||||
}
|
||||
$query->execute();
|
||||
}
|
||||
|
||||
function migrate_example_advanced_data_account() {
|
||||
$fields = array('accountid', 'status', 'posted', 'last_access', 'last_login',
|
||||
'name', 'sex', 'password', 'mail', 'original_mail', 'sig', 'imageid', 'positions');
|
||||
$query = db_insert('migrate_example_advanced_account')
|
||||
->fields($fields);
|
||||
$data = array(
|
||||
array(1, 1, '2010-03-30 10:31:05', '2010-04-30 18:25:24', '2010-04-30 14:01:02',
|
||||
'darren', 'M', 'dpass', 'ddarren@example.com', 'darren@example.com',
|
||||
'All about the Australians', NULL, '5'),
|
||||
array(3, 0, '2007-03-15 10:31:05', '2007-06-10 04:11:38', '2007-06-10 04:11:38',
|
||||
'emily', 'F', 'insecure', 'emily@example.com', 'emily@example.com',
|
||||
'Sommelier to the stars', NULL, '18'),
|
||||
array(9, 1, '2004-02-29 10:31:05', '2004-02-29 10:31:05', '2004-02-29 10:31:05',
|
||||
'fonzie', NULL, 'bike', 'thefonz@example.com', 'arthur@example.com',
|
||||
'Aaay!', 1, '5,18'),
|
||||
);
|
||||
foreach ($data as $row) {
|
||||
$query->values(array_combine($fields, $row));
|
||||
}
|
||||
$query->execute();
|
||||
}
|
||||
|
||||
function migrate_example_advanced_data_account_updates() {
|
||||
$fields = array('accountid', 'sex');
|
||||
$query = db_insert('migrate_example_advanced_account_updates')
|
||||
->fields($fields);
|
||||
$data = array(
|
||||
array(1, NULL),
|
||||
array(3, 'M'),
|
||||
array(9, 'F'),
|
||||
);
|
||||
foreach ($data as $row) {
|
||||
$query->values(array_combine($fields, $row));
|
||||
}
|
||||
$query->execute();
|
||||
}
|
||||
|
||||
function migrate_example_advanced_data_comment() {
|
||||
$fields = array('commentid', 'wineid', 'comment_parent', 'subject', 'body',
|
||||
'name', 'mail', 'accountid', 'commenthost', 'userpage', 'posted', 'lastchanged');
|
||||
$query = db_insert('migrate_example_advanced_comment')
|
||||
->fields($fields);
|
||||
$data = array(
|
||||
array(1, 1, NULL, 'im first', 'Tasty', 'grace', 'grace@example.com', 0,
|
||||
'123.456.78.9', 'http:://grace.example.com/',
|
||||
strtotime('2010-01-02 03:04:05'), strtotime('2010-04-05 06:07:08')),
|
||||
array(2, 1, NULL, 'im second', 'Delicious', 'horace', 'horace@example.com', 0,
|
||||
'example.com', NULL,
|
||||
strtotime('2010-02-02 03:04:05'), strtotime('2010-05-05 06:07:08')),
|
||||
array(3, 1, NULL, 'im parent', 'Don\'t care for it', 'irene', 'irene@example.com', 0,
|
||||
'254.0.2.5', 'http:://www.example.com/irene',
|
||||
strtotime('2010-03-02 03:04:05'), strtotime('2010-03-02 03:04:05')),
|
||||
array(4, 1, 3, 'im child', 'But it\'s so good!', 'emily', NULL, 3,
|
||||
'58.29.126.1', 'http:://www.wine.com/',
|
||||
strtotime('2010-01-02 03:04:05'), strtotime('2010-01-02 03:04:05')),
|
||||
array(5, 1, 4, 'im grandchild', 'Right on, Emily!', 'thefonz@example.com', NULL, 9,
|
||||
'123.456.78.9', NULL,
|
||||
strtotime('2010-06-02 03:04:05'), strtotime('2010-06-02 03:04:05')),
|
||||
);
|
||||
foreach ($data as $row) {
|
||||
$query->values(array_combine($fields, $row));
|
||||
}
|
||||
$query->execute();
|
||||
}
|
||||
|
||||
function migrate_example_advanced_data_comment_updates() {
|
||||
$fields = array('commentid', 'subject');
|
||||
$query = db_insert('migrate_example_advanced_comment_updates')
|
||||
->fields($fields);
|
||||
$data = array(
|
||||
array(1, 'I am first'),
|
||||
array(2, 'I am second'),
|
||||
array(3, 'I am parent'),
|
||||
array(4, ''),
|
||||
array(5, 'I am Spartacus'),
|
||||
);
|
||||
foreach ($data as $row) {
|
||||
$query->values(array_combine($fields, $row));
|
||||
}
|
||||
$query->execute();
|
||||
}
|
||||
|
||||
function migrate_example_advanced_data_categories() {
|
||||
$fields = array('categoryid', 'type', 'name', 'category_parent', 'details', 'ordering');
|
||||
$query = db_insert('migrate_example_advanced_categories')
|
||||
->fields($fields);
|
||||
$data = array(
|
||||
array(1, 'variety', 'White wine', NULL, 'White wines are generally simpler and sweeter than red', 3),
|
||||
array(3, 'variety', 'Red wine', NULL, 'Red wines are generally more complex and "dry" than white', 1),
|
||||
array(8, 'variety', 'Riesling', 1, 'Associated with Germany', 2),
|
||||
array(9, 'variety', 'Chardonnay', 1, 'One of the most popular whites', 1),
|
||||
array(13, 'variety', 'Merlot', 3, 'Very drinkable', 4),
|
||||
array(14, 'variety', 'Syrah', 3, 'A.k.a. shiraz', -3),
|
||||
array(25, 'variety', 'Cabernet Sauvignon', 3, 'A basic', -5),
|
||||
array(26, 'variety', "Nero d'Avola", 3, 'Sicilian specialty', 2),
|
||||
array(2, 'region', 'Italy', NULL, 'Largest producer of wine', 5),
|
||||
array(11, 'region', 'Tuscany', 2, NULL, 2),
|
||||
array(18, 'region', 'Chianti', 11, NULL, -1),
|
||||
array(19, 'region', 'Elba', 11, NULL, 5),
|
||||
array(4, 'region', 'France', NULL, 'C\'est bon', 6),
|
||||
array(5, 'region', 'Bordeaux', 4, NULL, 1),
|
||||
array(6, 'region', 'Barsac', 5, NULL, 3),
|
||||
array(7, 'region', 'Pomerol', 5, NULL, 2),
|
||||
array(16, 'region', 'Chile', NULL, NULL, 3),
|
||||
array(17, 'region', 'Colchagua Valley', 16, NULL, 1),
|
||||
array(20, 'region', 'California', NULL, NULL, 5),
|
||||
array(21, 'region', 'Redwood Valley', 20, NULL, 1),
|
||||
array(10, 'best_with', 'Beef', NULL, NULL, 5),
|
||||
array(12, 'best_with', 'Pork', NULL, NULL, -3),
|
||||
array(15, 'best_with', 'Chicken', NULL, NULL, -5),
|
||||
);
|
||||
foreach ($data as $row) {
|
||||
$query->values(array_combine($fields, $row));
|
||||
}
|
||||
$query->execute();
|
||||
}
|
||||
|
||||
function migrate_example_advanced_data_vintages() {
|
||||
$fields = array('wineid', 'vintage');
|
||||
$query = db_insert('migrate_example_advanced_vintages')
|
||||
->fields($fields);
|
||||
$data = array(
|
||||
array(1, 2006),
|
||||
array(1, 2007),
|
||||
array(2, 2001),
|
||||
);
|
||||
foreach ($data as $row) {
|
||||
$query->values(array_combine($fields, $row));
|
||||
}
|
||||
$query->execute();
|
||||
}
|
||||
|
||||
function migrate_example_advanced_data_variety_updates() {
|
||||
$fields = array('categoryid', 'details');
|
||||
$query = db_insert('migrate_example_advanced_variety_updates')
|
||||
->fields($fields);
|
||||
$data = array(
|
||||
array(1, 'White wines are simpler and sweeter than red'),
|
||||
array(3, 'Red wines are generally more complex and dry than white'),
|
||||
array(8, 'Usually associated with Germany'),
|
||||
array(9, NULL),
|
||||
array(13, 'Common, very drinakable'),
|
||||
array(14, 'AKA Shiraz'),
|
||||
array(25, 'Basic'),
|
||||
array(26, 'A specialty of Sicily'),
|
||||
);
|
||||
foreach ($data as $row) {
|
||||
$query->values(array_combine($fields, $row));
|
||||
}
|
||||
$query->execute();
|
||||
}
|
||||
|
||||
function migrate_example_advanced_data_category_wine() {
|
||||
$fields = array('wineid', 'categoryid');
|
||||
$query = db_insert('migrate_example_advanced_category_wine')
|
||||
->fields($fields);
|
||||
$data = array(
|
||||
array(1, 12),
|
||||
array(1, 15),
|
||||
array(2, 10),
|
||||
);
|
||||
foreach ($data as $row) {
|
||||
$query->values(array_combine($fields, $row));
|
||||
}
|
||||
$query->execute();
|
||||
}
|
||||
|
||||
function migrate_example_advanced_data_category_producer() {
|
||||
$fields = array('producerid', 'categoryid');
|
||||
$query = db_insert('migrate_example_advanced_category_producer')
|
||||
->fields($fields);
|
||||
$data = array(
|
||||
array(1, 17),
|
||||
);
|
||||
foreach ($data as $row) {
|
||||
$query->values(array_combine($fields, $row));
|
||||
}
|
||||
$query->execute();
|
||||
}
|
||||
|
||||
function migrate_example_advanced_data_files() {
|
||||
$fields = array('imageid', 'url', 'image_alt', 'image_title', 'wineid');
|
||||
$query = db_insert('migrate_example_advanced_files')
|
||||
->fields($fields);
|
||||
$data = array(
|
||||
array(1, 'http://placekitten.com/200/200', NULL, NULL, NULL),
|
||||
array(2, 'http://cyrve.com/files/penguin.jpeg', 'Penguin alt', 'Penguin title', 1),
|
||||
array(3, 'http://cyrve.com/files/rioja.jpeg', 'Rioja alt', 'Rioja title', 2),
|
||||
array(4, 'http://cyrve.com/files/boutisse_0.jpeg', 'Boutisse alt', 'Boutisse title', 2),
|
||||
);
|
||||
foreach ($data as $row) {
|
||||
$query->values(array_combine($fields, $row));
|
||||
}
|
||||
$query->execute();
|
||||
}
|
||||
|
||||
function migrate_example_advanced_data_blobs() {
|
||||
$blob = file_get_contents('core/misc/druplicon.png');
|
||||
$fields = array('imageid', 'imageblob');
|
||||
$query = db_insert('migrate_example_advanced_blobs')
|
||||
->fields($fields);
|
||||
$data = array(
|
||||
array(1, $blob),
|
||||
);
|
||||
foreach ($data as $row) {
|
||||
$query->values(array_combine($fields, $row));
|
||||
}
|
||||
$query->execute();
|
||||
}
|
||||
|
||||
function migrate_example_advanced_data_table_source() {
|
||||
$fields = array('fooid', 'field1', 'field2');
|
||||
$query = db_insert('migrate_example_advanced_table_source')
|
||||
->fields($fields);
|
||||
$data = array(
|
||||
array(3, 'Some sample data', 58),
|
||||
array(15, 'Whatever', 2),
|
||||
array(646, 'More sample data', 34989),
|
||||
);
|
||||
foreach ($data as $row) {
|
||||
$query->values(array_combine($fields, $row));
|
||||
}
|
||||
$query->execute();
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\migrate_example_advanced_setup\Plugin\rest\resource;
|
||||
|
||||
use Drupal\rest\Plugin\ResourceBase;
|
||||
use Drupal\rest\ResourceResponse;
|
||||
|
||||
/**
|
||||
* Represents positions as resources.
|
||||
*
|
||||
* @RestResource(
|
||||
* id = "migrate_example_advanced_position",
|
||||
* label = @Translation("Advanced migration example - Position data"),
|
||||
* uri_paths = {
|
||||
* "canonical" = "/migrate_example_advanced_position"
|
||||
* }
|
||||
* )
|
||||
*/
|
||||
class PositionResource extends ResourceBase {
|
||||
|
||||
/**
|
||||
* Responds to GET requests.
|
||||
*
|
||||
* @return \Drupal\rest\ResourceResponse
|
||||
* The response containing the position data.
|
||||
*/
|
||||
public function get() {
|
||||
$position1 = ['sourceid' => 'wine_taster', 'name' => 'Wine Taster'];
|
||||
$position2 = ['sourceid' => 'vintner', 'name' => 'Vintner'];
|
||||
$data = ['position' => [$position1, $position2]];
|
||||
|
||||
$response = new ResourceResponse($data, 200);
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function permissions() {
|
||||
// Remove permissions so the resource is available to all.
|
||||
return [];
|
||||
}
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user