Skip to content

Importing data

To import data from YAML migration files into Repository, you run the ibexa:migrations:migrate command.

The ibexa:migrations:import command automatically places migration files in the correct folder.

Alternatively, you can place the files manually in the src/Migrations/Ibexa/migrations folder or in a custom folder that you configure, and specify the file name within this folder as parameter. If you do not specify the file, all files within this directory are used.

1
php bin/console ibexa:migrations:migrate --file=my_data_export.yaml

Migrations store execution metadata in the ibexa_migrations database table. This allows incremental upgrades: the ibexa:migration:migrate command ignores files that it had previously executed.

Available migrations

The following data migration steps are available:

create update delete
content
content_type
role
content_type_group
user
user_group
language
object_state_group
object_state
section
location
attribute_group
attribute
customer_group
currency
product_price
segment_group
segment
setting

Repeatable steps

You can run a set of one or more similar migration steps multiple times by using the special repeatable migration type.

A repeatable migration performs the defined migration steps as many times as the iterations setting declares.

1
2
3
4
5
-
    type: repeatable
    mode: create
    iterations: 5
    steps:

Tip

You can use repeatable migration steps, for example, to quickly generate large numbers of Content items for testing purposes.

You can vary the operations using the iteration counter.

For example, to create five Folders, with names ranging from "Folder 0" to "Folder 4", you can run the following migration using the iteration counter i:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
-
    type: repeatable
    mode: create
    iterations: 5
    steps:
        -   type: content
            mode: create
            metadata:
                contentType: folder
                mainTranslation: eng-GB
            location:
                parentLocationId: 2
            fields:
                -   fieldDefIdentifier: name
                    languageCode: eng-GB
                    value: 'Folder ###SSS i SSS###'

To vary the content name, the migration above uses Symfony expression syntax.

In the example above, the expression is enclosed in ### and the repeated string SSS.

Note

Iteration counter is assigned to i by default, but you can modify it in the iteration_counter_name setting.

Generating fake data

You can also generate fake data with the help of FakerPHP.

To use it, first install Faker on your system:

1
composer require fakerphp/faker

Then, you can use faker() in expressions, for example:

1
2
3
                -   fieldDefIdentifier: short_name
                    languageCode: eng-GB
                    value: '### faker().name() ###'

This step generates Field values with fake personal names.

Expression syntax

You can use Symfony expression syntax in data migrations. It is especially useful in repeatable steps, where you can use it to generate varied content in migration steps.

The expression syntax uses the following structure: ###<IDENTIFIER> <EXPRESSION> <IDENTIFIER>###

The IDENTIFIER can be any repeated string that encloses the actual expression.

Migration examples

The following examples show what data you can import using data migrations.

Content Types

The following example shows how to create a Content Type with two Field definitions.

The required metadata keys are: identifier, mainTranslation, contentTypeGroups and translations.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
-
    type: content_type
    mode: create
    metadata:
        identifier: blog_post
        mainTranslation: eng-GB
        contentTypeGroups:
            - Content
        translations:
            eng-GB:
                name: Blog Post
    fields:
        -   identifier: title
            type: ezstring
            required: true
            translations:
                eng-GB:
                    name: 'Title'
        -   identifier: body
            type: ezrichtext
            required: false
            translations:
                eng-GB:
                    name: 'Body'

Content items

The following example shows how to create two Content items: a folder and an article inside it.

When creating a Content item, two metadata keys are required: contentType and mainTranslation, as well as parentLocationId.

To use the Location ID of the folder, which is created automatically by the system, you can use a reference. In this case you assign the parent_folder_location_id reference name to the Location ID, and then use it when creating the article.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
-
    type: content
    mode: create
    metadata:
        contentType: folder
        mainTranslation: eng-GB
    location:
        parentLocationId: 2
    fields:
        -   fieldDefIdentifier: name
            languageCode: eng-GB
            value: 'Parent folder'
    references:
        -
            name: parent_folder_location_id
            type: location_id

-
    type: content
    mode: create
    metadata:
        contentType: article
        mainTranslation: eng-GB
    location:
        parentLocationId: 'reference:parent_folder_location_id'
    fields:
        -   fieldDefIdentifier: title
            languageCode: eng-GB
            value: 'Child article'
        -   fieldDefIdentifier: intro
            languageCode: eng-GB
            value:
                xml: |
                    <?xml version="1.0" encoding="UTF-8"?>
                    <section xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ezxhtml="http://ibexa.co/xmlns/dxp/docbook/xhtml" xmlns:ezcustom="http://ibexa.co/xmlns/dxp/docbook/custom" version="5.0-variant ezpublish-1.0"><para>This is <emphasis role="strong">article into</emphasis>.</para></section>

Roles

The following example shows how to create a Role. A Role requires the identifier metadata key.

For each Policy assigned to the Role, you select the module and function, with optional Limitations.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
-
    type: role
    mode: create
    metadata:
        identifier: Contributor
    policies:
        -
            module: content
            function: read
        -
            module: content
            function: create
            limitations:
                -
                    identifier: Class
                    values: [folder, article, blog_post]
                -
                    identifier: Section
                    values: [standard, media]
        -
            module: content
            function: edit
            limitations:
                -
                    identifier: Owner
                    values: ['1']

Users

The following example shows how to create a user.

The required metadata keys are: login, email, password, enabled, mainLanguage, and contentType. You also need to provide the user group's remote content ID.

You can use an action to assign a Role to the user.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
-
    type: user
    mode: create
    metadata:
        login: janedoe
        email: [email protected]
        password: Password123Password
        enabled: true
        mainLanguage: eng-GB
        contentType: user
    groups:
        - 3c160cca19fb135f83bd02d911f04db2
    fields:
        -
            fieldDefIdentifier: first_name
            languageCode: eng-GB
            value: John
        -
            fieldDefIdentifier: last_name
            languageCode: eng-GB
            value: Doe
    actions:
        - { action: assign_user_to_role, identifier: 'Member'}

Language

The following example shows how to create a language.

The required metadata keys are: languageCode, name, and enabled.

1
2
3
4
5
6
7
-
    type: language
    mode: create
    metadata:
        languageCode: ger-DE
        name: German
        enabled: true

Product catalog

The following example shows how to create an attribute group with two attributes:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
-   type: attribute_group
    mode: create
    identifier: hat
    names:
        eng-GB: Hat

-   type: attribute
    mode: create
    identifier: size
    attribute_type_identifier: integer
    attribute_group_identifier: hat
    names:
        eng-GB: Size

-   type: attribute
    mode: create
    identifier: color
    attribute_type_identifier: selection
    attribute_group_identifier: hat
    names:
        eng-GB: Color
    options:
        choices:
            -    value: red
             label: 
                 "eng-GB": "Red"
            -    value: white
             label: 
                 "eng-GB": "White"
            -    value: black
             label: 
                 "eng-GB": "Black"

You can also update attributes, including changing which attribute group they belong to:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
-
    type: attribute
    mode: update
    criteria:
        type: field_value
        field: identifier
        value: width
        operator: '='
    identifier: new_width
    attribute_group_identifier: size
    names:
        eng-GB: New Width

You cannot change the attribute type of an existing attribute.

Product type

The following example shows how to create a product type.

The main part of the migration file is the same as when creating a regular Content Type.

A product type must also contain the definition for an ibexa_product_specification Field. fieldSettings contains information about the product attributes.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
-   type: content_type
    mode: create
    metadata:
        identifier: hat
        mainTranslation: eng-GB
        contentTypeGroups:
            - product
        translations:
            eng-GB:
                name: Hat
    fields:
        -   identifier: name
            type: ezstring
            required: true
            translations:
                eng-GB:
                    name: Name
        -   identifier: specification
            type: ibexa_product_specification
            required: true
            translations:
                eng-GB:
                    name: Specification
            fieldSettings:
                attributes_definitions:
                    dimensions:
                        - { attributeDefinition: size, required: true, discriminator: false }
                        - { attributeDefinition: color, required: true, discriminator: true }

Customer groups

The following example shows how to create a customer group with a defined global price discount:

1
2
3
4
5
6
-   type: customer_group
    mode: create
    identifier: contractors
    names:
        eng-GB: Contractors
    global_price_rate: -20.0

Currencies

The following example shows how to create a currency:

1
2
3
4
5
-   type: currency
    mode: create
    code: TST
    subunits: 3
    enabled: true # default, optional

Prices

The following example shows how to create a price for a product identified by its code:

1
2
3
4
5
-   type: product_price
    mode: create
    product_code: 'DRESUN'
    currency_code: 'EUR'
    amount: 120

Segments

The following example shows how to create a segment group and add segments in it:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
-
    type: segment_group
    mode: create
    name: 'Contractors'
    identifier: contractors
    references:
        -
            name: contractors_group_id
            type: segment_group_id

-
    type: segment
    mode: create
    name: 'Painter'
    identifier: painter
    group:
        identifier: contractors

When updating a segment group or segment, you can match the object to update by using its numerical ID or identifier:

1
2
3
4
5
6
-
    type: segment
    mode: update
    name: 'Painter and Finish'
    matcher:
        identifier: painter

Settings

The following example shows how you can create and update a setting that is stored in the database:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
- type: setting
  mode: create
  group: test
  identifier: my_setting
  value:
      first: first_value
      second: second_value

- type: setting
  mode: update
  group: test
  identifier: my_setting
  value:
    first: first_value_modified

Criteria

When using update or delete modes, you can use criteria to identify the objects to operate on.

Caution

Criteria only work with objects related to the product catalog.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
type: currency
mode: update
criteria:
    type: field_value
    field: code
    value: EUR
    operator: '=' # default
code: EEE
subunits: 3
enabled: false

Available operators are:

  • =
  • <>
  • <
  • <=
  • >
  • >=
  • IN
  • NIN
  • CONTAINS
  • STARTS_WITH
  • ENDS_WITH

You can combine criteria by using logical criteria and and or:

1
2
3
4
5
6
7
8
9
type: or
criteria:
    -   type: field_value
        field: code
        value: EUR
    -   type: field_value
        field: code
        value: X
        operator: STARTS_WITH

Criteria can be nested.