Adding gitlab ci file.
This commit is contained in:
2
web/modules/custom/json_ingestion_examples/.gitignore
vendored
Normal file
2
web/modules/custom/json_ingestion_examples/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
.idea
|
||||
.idea/
|
||||
39
web/modules/custom/json_ingestion_examples/README.md
Normal file
39
web/modules/custom/json_ingestion_examples/README.md
Normal file
@@ -0,0 +1,39 @@
|
||||
## JSON Ingestion Examples
|
||||
|
||||
The data is pulled from https://jsonplaceholder.typicode.com/
|
||||
|
||||
### Approach 1: Migrate API
|
||||
#### Requirements
|
||||
- Migrate
|
||||
- Migrate Plus
|
||||
|
||||
There are 2 migrations:
|
||||
- images (5000 total)
|
||||
- json_posts_to_posts (100 total)
|
||||
|
||||
To run them you can do:
|
||||
```
|
||||
drush mim images --limit=100
|
||||
drush mim json_posts_to_posts
|
||||
```
|
||||
there are only 100 posts, so for our purposes we don't need more than 100 images.
|
||||
|
||||
Once both migrations have been run you can see the data at `/migration-posts` which is controller by a view.
|
||||
This approach has the advantage of requiring migrate API which pulls in a lot of helpful things,
|
||||
such as rollbacks, update old items, only importing new items...etc.
|
||||
### Approach 2: Custom Drush Command
|
||||
Will import the first 100 images only, followed by 100 posts.
|
||||
Also available for viewing on `/migration-posts` after import.
|
||||
```
|
||||
drush jie-posts
|
||||
```
|
||||
### Approach 3: Views JSON Source
|
||||
#### Requirements
|
||||
- views_json_source
|
||||
|
||||
Make sure `views_json_source` module is included in your codebase.
|
||||
Then visit `/views-json-source` after enabling this module which is a preconfigured view of titles and body fields from external JSON.
|
||||
|
||||
### Approach 4: Javascript Only
|
||||
1. Attach a javascript library to a page
|
||||
2. Fetch the API data and render it all client side
|
||||
16
web/modules/custom/json_ingestion_examples/composer.json
Normal file
16
web/modules/custom/json_ingestion_examples/composer.json
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"name": "drupal/json_ingestion_examples",
|
||||
"type": "drupal-module",
|
||||
"license": "GPL-2.0-or-later",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Dan Chadwick",
|
||||
"email": "dan.chadwick@acquia.com"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"drupal/core": "^9 || ^10",
|
||||
"drupal/migrate_plus": "^6.0",
|
||||
"drupal/views_json_source": "^1.4"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
config:
|
||||
- field.field.node.post.body
|
||||
- field.field.node.post.field_image
|
||||
- image.style.thumbnail
|
||||
- node.type.post
|
||||
module:
|
||||
- image
|
||||
- path
|
||||
- text
|
||||
id: node.post.default
|
||||
targetEntityType: node
|
||||
bundle: post
|
||||
mode: default
|
||||
content:
|
||||
body:
|
||||
type: text_textarea_with_summary
|
||||
weight: 121
|
||||
region: content
|
||||
settings:
|
||||
rows: 9
|
||||
summary_rows: 3
|
||||
placeholder: ''
|
||||
show_summary: false
|
||||
third_party_settings: { }
|
||||
created:
|
||||
type: datetime_timestamp
|
||||
weight: 10
|
||||
region: content
|
||||
settings: { }
|
||||
third_party_settings: { }
|
||||
field_image:
|
||||
type: image_image
|
||||
weight: 1
|
||||
region: content
|
||||
settings:
|
||||
progress_indicator: throbber
|
||||
preview_image_style: thumbnail
|
||||
third_party_settings: { }
|
||||
path:
|
||||
type: path
|
||||
weight: 30
|
||||
region: content
|
||||
settings: { }
|
||||
third_party_settings: { }
|
||||
promote:
|
||||
type: boolean_checkbox
|
||||
weight: 15
|
||||
region: content
|
||||
settings:
|
||||
display_label: true
|
||||
third_party_settings: { }
|
||||
status:
|
||||
type: boolean_checkbox
|
||||
weight: 120
|
||||
region: content
|
||||
settings:
|
||||
display_label: true
|
||||
third_party_settings: { }
|
||||
sticky:
|
||||
type: boolean_checkbox
|
||||
weight: 16
|
||||
region: content
|
||||
settings:
|
||||
display_label: true
|
||||
third_party_settings: { }
|
||||
title:
|
||||
type: string_textfield
|
||||
weight: -5
|
||||
region: content
|
||||
settings:
|
||||
size: 60
|
||||
placeholder: ''
|
||||
third_party_settings: { }
|
||||
uid:
|
||||
type: entity_reference_autocomplete
|
||||
weight: 5
|
||||
region: content
|
||||
settings:
|
||||
match_operator: CONTAINS
|
||||
match_limit: 10
|
||||
size: 60
|
||||
placeholder: ''
|
||||
third_party_settings: { }
|
||||
hidden: { }
|
||||
@@ -0,0 +1,41 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
config:
|
||||
- field.field.node.post.body
|
||||
- field.field.node.post.field_image
|
||||
- image.style.wide
|
||||
- node.type.post
|
||||
module:
|
||||
- image
|
||||
- text
|
||||
- user
|
||||
id: node.post.default
|
||||
targetEntityType: node
|
||||
bundle: post
|
||||
mode: default
|
||||
content:
|
||||
body:
|
||||
type: text_default
|
||||
label: hidden
|
||||
settings: { }
|
||||
third_party_settings: { }
|
||||
weight: 101
|
||||
region: content
|
||||
field_image:
|
||||
type: image
|
||||
label: hidden
|
||||
settings:
|
||||
image_link: ''
|
||||
image_style: wide
|
||||
image_loading:
|
||||
attribute: eager
|
||||
third_party_settings: { }
|
||||
weight: -1
|
||||
region: content
|
||||
links:
|
||||
settings: { }
|
||||
third_party_settings: { }
|
||||
weight: 100
|
||||
region: content
|
||||
hidden: { }
|
||||
@@ -0,0 +1,43 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
config:
|
||||
- core.entity_view_mode.node.teaser
|
||||
- field.field.node.post.body
|
||||
- field.field.node.post.field_image
|
||||
- image.style.medium
|
||||
- node.type.post
|
||||
module:
|
||||
- image
|
||||
- text
|
||||
- user
|
||||
id: node.post.teaser
|
||||
targetEntityType: node
|
||||
bundle: post
|
||||
mode: teaser
|
||||
content:
|
||||
body:
|
||||
type: text_summary_or_trimmed
|
||||
label: hidden
|
||||
settings:
|
||||
trim_length: 600
|
||||
third_party_settings: { }
|
||||
weight: 101
|
||||
region: content
|
||||
field_image:
|
||||
type: image
|
||||
label: hidden
|
||||
settings:
|
||||
image_link: content
|
||||
image_style: medium
|
||||
image_loading:
|
||||
attribute: lazy
|
||||
third_party_settings: { }
|
||||
weight: -1
|
||||
region: content
|
||||
links:
|
||||
settings: { }
|
||||
third_party_settings: { }
|
||||
weight: 100
|
||||
region: content
|
||||
hidden: { }
|
||||
@@ -0,0 +1,23 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
config:
|
||||
- field.storage.node.body
|
||||
- node.type.post
|
||||
module:
|
||||
- text
|
||||
id: node.post.body
|
||||
field_name: body
|
||||
entity_type: node
|
||||
bundle: post
|
||||
label: Body
|
||||
description: ''
|
||||
required: false
|
||||
translatable: true
|
||||
default_value: { }
|
||||
default_value_callback: ''
|
||||
settings:
|
||||
display_summary: true
|
||||
required_summary: false
|
||||
allowed_formats: { }
|
||||
field_type: text_with_summary
|
||||
@@ -0,0 +1,37 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
config:
|
||||
- field.storage.node.field_image
|
||||
- node.type.post
|
||||
module:
|
||||
- image
|
||||
id: node.post.field_image
|
||||
field_name: field_image
|
||||
entity_type: node
|
||||
bundle: post
|
||||
label: Image
|
||||
description: ''
|
||||
required: false
|
||||
translatable: false
|
||||
default_value: { }
|
||||
default_value_callback: ''
|
||||
settings:
|
||||
handler: 'default:file'
|
||||
handler_settings: { }
|
||||
file_directory: '[date:custom:Y]-[date:custom:m]'
|
||||
file_extensions: 'png gif jpg jpeg webp'
|
||||
max_filesize: ''
|
||||
max_resolution: ''
|
||||
min_resolution: ''
|
||||
alt_field: true
|
||||
alt_field_required: true
|
||||
title_field: false
|
||||
title_field_required: false
|
||||
default_image:
|
||||
uuid: ''
|
||||
alt: ''
|
||||
title: ''
|
||||
width: null
|
||||
height: null
|
||||
field_type: image
|
||||
@@ -0,0 +1,33 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
module:
|
||||
- file
|
||||
- image
|
||||
- node
|
||||
_core:
|
||||
default_config_hash: EymokncRIZ7SgQT2IdOQhQJicX4nNc0K89ik-LxmOHE
|
||||
id: node.field_image
|
||||
field_name: field_image
|
||||
entity_type: node
|
||||
type: image
|
||||
settings:
|
||||
target_type: file
|
||||
display_field: false
|
||||
display_default: false
|
||||
uri_scheme: public
|
||||
default_image:
|
||||
uuid: ''
|
||||
alt: ''
|
||||
title: ''
|
||||
width: null
|
||||
height: null
|
||||
module: image
|
||||
locked: false
|
||||
cardinality: 1
|
||||
translatable: true
|
||||
indexes:
|
||||
target_id:
|
||||
- target_id
|
||||
persist_with_no_fields: false
|
||||
custom_storage: false
|
||||
@@ -0,0 +1,17 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
module:
|
||||
- menu_ui
|
||||
third_party_settings:
|
||||
menu_ui:
|
||||
available_menus:
|
||||
- main
|
||||
parent: 'main:'
|
||||
name: Post
|
||||
type: post
|
||||
description: ''
|
||||
help: ''
|
||||
new_revision: true
|
||||
preview_mode: 1
|
||||
display_submitted: true
|
||||
@@ -0,0 +1,191 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
config:
|
||||
- core.entity_view_mode.node.teaser
|
||||
- node.type.post
|
||||
module:
|
||||
- node
|
||||
- user
|
||||
id: migration_based_posts
|
||||
label: 'Migration Based Posts'
|
||||
module: views
|
||||
description: ''
|
||||
tag: ''
|
||||
base_table: node_field_data
|
||||
base_field: nid
|
||||
display:
|
||||
default:
|
||||
id: default
|
||||
display_title: Default
|
||||
display_plugin: default
|
||||
position: 0
|
||||
display_options:
|
||||
title: 'Migration Based Posts'
|
||||
fields:
|
||||
title:
|
||||
id: title
|
||||
table: node_field_data
|
||||
field: title
|
||||
relationship: none
|
||||
group_type: group
|
||||
admin_label: ''
|
||||
entity_type: node
|
||||
entity_field: title
|
||||
plugin_id: field
|
||||
label: ''
|
||||
exclude: false
|
||||
alter:
|
||||
alter_text: false
|
||||
make_link: false
|
||||
absolute: false
|
||||
word_boundary: false
|
||||
ellipsis: false
|
||||
strip_tags: false
|
||||
trim: false
|
||||
html: false
|
||||
element_type: ''
|
||||
element_class: ''
|
||||
element_label_type: ''
|
||||
element_label_class: ''
|
||||
element_label_colon: true
|
||||
element_wrapper_type: ''
|
||||
element_wrapper_class: ''
|
||||
element_default_classes: true
|
||||
empty: ''
|
||||
hide_empty: false
|
||||
empty_zero: false
|
||||
hide_alter_empty: true
|
||||
click_sort_column: value
|
||||
type: string
|
||||
settings:
|
||||
link_to_entity: true
|
||||
group_column: value
|
||||
group_columns: { }
|
||||
group_rows: true
|
||||
delta_limit: 0
|
||||
delta_offset: 0
|
||||
delta_reversed: false
|
||||
delta_first_last: false
|
||||
multi_type: separator
|
||||
separator: ', '
|
||||
field_api_classes: false
|
||||
pager:
|
||||
type: mini
|
||||
options:
|
||||
offset: 0
|
||||
items_per_page: 10
|
||||
total_pages: null
|
||||
id: 0
|
||||
tags:
|
||||
next: ››
|
||||
previous: ‹‹
|
||||
expose:
|
||||
items_per_page: false
|
||||
items_per_page_label: 'Items per page'
|
||||
items_per_page_options: '5, 10, 25, 50'
|
||||
items_per_page_options_all: false
|
||||
items_per_page_options_all_label: '- All -'
|
||||
offset: false
|
||||
offset_label: Offset
|
||||
exposed_form:
|
||||
type: basic
|
||||
options:
|
||||
submit_button: Apply
|
||||
reset_button: false
|
||||
reset_button_label: Reset
|
||||
exposed_sorts_label: 'Sort by'
|
||||
expose_sort_order: true
|
||||
sort_asc_label: Asc
|
||||
sort_desc_label: Desc
|
||||
access:
|
||||
type: perm
|
||||
options:
|
||||
perm: 'access content'
|
||||
cache:
|
||||
type: tag
|
||||
options: { }
|
||||
empty: { }
|
||||
sorts:
|
||||
created:
|
||||
id: created
|
||||
table: node_field_data
|
||||
field: created
|
||||
relationship: none
|
||||
group_type: group
|
||||
admin_label: ''
|
||||
entity_type: node
|
||||
entity_field: created
|
||||
plugin_id: date
|
||||
order: DESC
|
||||
expose:
|
||||
label: ''
|
||||
field_identifier: ''
|
||||
exposed: false
|
||||
granularity: second
|
||||
arguments: { }
|
||||
filters:
|
||||
status:
|
||||
id: status
|
||||
table: node_field_data
|
||||
field: status
|
||||
entity_type: node
|
||||
entity_field: status
|
||||
plugin_id: boolean
|
||||
value: '1'
|
||||
group: 1
|
||||
expose:
|
||||
operator: ''
|
||||
type:
|
||||
id: type
|
||||
table: node_field_data
|
||||
field: type
|
||||
entity_type: node
|
||||
entity_field: type
|
||||
plugin_id: bundle
|
||||
value:
|
||||
post: post
|
||||
style:
|
||||
type: default
|
||||
row:
|
||||
type: 'entity:node'
|
||||
options:
|
||||
view_mode: teaser
|
||||
query:
|
||||
type: views_query
|
||||
options:
|
||||
query_comment: ''
|
||||
disable_sql_rewrite: false
|
||||
distinct: false
|
||||
replica: false
|
||||
query_tags: { }
|
||||
relationships: { }
|
||||
header: { }
|
||||
footer: { }
|
||||
display_extenders: { }
|
||||
cache_metadata:
|
||||
max-age: -1
|
||||
contexts:
|
||||
- 'languages:language_content'
|
||||
- 'languages:language_interface'
|
||||
- url.query_args
|
||||
- 'user.node_grants:view'
|
||||
- user.permissions
|
||||
tags: { }
|
||||
page_1:
|
||||
id: page_1
|
||||
display_title: Page
|
||||
display_plugin: page
|
||||
position: 1
|
||||
display_options:
|
||||
display_extenders: { }
|
||||
path: migration-posts
|
||||
cache_metadata:
|
||||
max-age: -1
|
||||
contexts:
|
||||
- 'languages:language_content'
|
||||
- 'languages:language_interface'
|
||||
- url.query_args
|
||||
- 'user.node_grants:view'
|
||||
- user.permissions
|
||||
tags: { }
|
||||
@@ -0,0 +1,199 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
module:
|
||||
- views_json_source
|
||||
id: views_json_source_demo
|
||||
label: 'Views JSON Source'
|
||||
module: views
|
||||
description: ''
|
||||
tag: ''
|
||||
base_table: json
|
||||
base_field: ''
|
||||
display:
|
||||
default:
|
||||
id: default
|
||||
display_title: Default
|
||||
display_plugin: default
|
||||
position: 0
|
||||
display_options:
|
||||
title: 'Views JSON Source'
|
||||
fields:
|
||||
value:
|
||||
id: value
|
||||
table: json
|
||||
field: value
|
||||
relationship: none
|
||||
group_type: group
|
||||
admin_label: ''
|
||||
entity_type: null
|
||||
entity_field: null
|
||||
plugin_id: views_json_source_field
|
||||
label: ''
|
||||
exclude: false
|
||||
alter:
|
||||
alter_text: false
|
||||
text: ''
|
||||
make_link: false
|
||||
path: ''
|
||||
absolute: false
|
||||
external: false
|
||||
replace_spaces: false
|
||||
path_case: none
|
||||
trim_whitespace: false
|
||||
alt: ''
|
||||
rel: ''
|
||||
link_class: ''
|
||||
prefix: ''
|
||||
suffix: ''
|
||||
target: ''
|
||||
nl2br: false
|
||||
max_length: 0
|
||||
word_boundary: true
|
||||
ellipsis: true
|
||||
more_link: false
|
||||
more_link_text: ''
|
||||
more_link_path: ''
|
||||
strip_tags: false
|
||||
trim: false
|
||||
preserve_tags: ''
|
||||
html: false
|
||||
element_type: h2
|
||||
element_class: ''
|
||||
element_label_type: ''
|
||||
element_label_class: ''
|
||||
element_label_colon: false
|
||||
element_wrapper_type: ''
|
||||
element_wrapper_class: ''
|
||||
element_default_classes: true
|
||||
empty: ''
|
||||
hide_empty: false
|
||||
empty_zero: false
|
||||
hide_alter_empty: true
|
||||
key: title
|
||||
trusted_html: 0
|
||||
value_1:
|
||||
id: value_1
|
||||
table: json
|
||||
field: value
|
||||
relationship: none
|
||||
group_type: group
|
||||
admin_label: ''
|
||||
plugin_id: views_json_source_field
|
||||
label: ''
|
||||
exclude: false
|
||||
alter:
|
||||
alter_text: false
|
||||
text: ''
|
||||
make_link: false
|
||||
path: ''
|
||||
absolute: false
|
||||
external: false
|
||||
replace_spaces: false
|
||||
path_case: none
|
||||
trim_whitespace: false
|
||||
alt: ''
|
||||
rel: ''
|
||||
link_class: ''
|
||||
prefix: ''
|
||||
suffix: ''
|
||||
target: ''
|
||||
nl2br: false
|
||||
max_length: 0
|
||||
word_boundary: true
|
||||
ellipsis: true
|
||||
more_link: false
|
||||
more_link_text: ''
|
||||
more_link_path: ''
|
||||
strip_tags: false
|
||||
trim: false
|
||||
preserve_tags: ''
|
||||
html: false
|
||||
element_type: ''
|
||||
element_class: ''
|
||||
element_label_type: ''
|
||||
element_label_class: ''
|
||||
element_label_colon: false
|
||||
element_wrapper_type: ''
|
||||
element_wrapper_class: ''
|
||||
element_default_classes: true
|
||||
empty: ''
|
||||
hide_empty: false
|
||||
empty_zero: false
|
||||
hide_alter_empty: true
|
||||
key: body
|
||||
trusted_html: 0
|
||||
pager:
|
||||
type: mini
|
||||
options:
|
||||
offset: 0
|
||||
items_per_page: 10
|
||||
total_pages: null
|
||||
id: 0
|
||||
tags:
|
||||
next: ››
|
||||
previous: ‹‹
|
||||
expose:
|
||||
items_per_page: false
|
||||
items_per_page_label: 'Items per page'
|
||||
items_per_page_options: '5, 10, 25, 50'
|
||||
items_per_page_options_all: false
|
||||
items_per_page_options_all_label: '- All -'
|
||||
offset: false
|
||||
offset_label: Offset
|
||||
exposed_form:
|
||||
type: basic
|
||||
options:
|
||||
submit_button: Apply
|
||||
reset_button: false
|
||||
reset_button_label: Reset
|
||||
exposed_sorts_label: 'Sort by'
|
||||
expose_sort_order: true
|
||||
sort_asc_label: Asc
|
||||
sort_desc_label: Desc
|
||||
access:
|
||||
type: none
|
||||
options: { }
|
||||
cache:
|
||||
type: tag
|
||||
options: { }
|
||||
empty: { }
|
||||
sorts: { }
|
||||
arguments: { }
|
||||
filters: { }
|
||||
style:
|
||||
type: default
|
||||
row:
|
||||
type: fields
|
||||
query:
|
||||
type: views_query
|
||||
options:
|
||||
json_file: 'https://jsonplaceholder.typicode.com/posts'
|
||||
row_apath: /
|
||||
headers: ''
|
||||
single_payload: 0
|
||||
show_errors: 1
|
||||
relationships: { }
|
||||
header: { }
|
||||
footer: { }
|
||||
display_extenders: { }
|
||||
cache_metadata:
|
||||
max-age: -1
|
||||
contexts:
|
||||
- 'languages:language_interface'
|
||||
- url.query_args
|
||||
tags: { }
|
||||
page_1:
|
||||
id: page_1
|
||||
display_title: Page
|
||||
display_plugin: page
|
||||
position: 1
|
||||
display_options:
|
||||
display_extenders: { }
|
||||
path: views-json-source
|
||||
cache_metadata:
|
||||
max-age: -1
|
||||
contexts:
|
||||
- 'languages:language_interface'
|
||||
- url.query_args
|
||||
tags: { }
|
||||
@@ -0,0 +1,5 @@
|
||||
services:
|
||||
json_ingestion_examples.commands:
|
||||
class: Drupal\json_ingestion_examples\Drush\Commands\JsonIngestionCommands
|
||||
tags:
|
||||
- { name: drush.command }
|
||||
@@ -0,0 +1,9 @@
|
||||
name: JSON Ingestion Examples
|
||||
type: module
|
||||
package: custom
|
||||
description: 'Ways to import JSON data to Drupal'
|
||||
core_version_requirement: ^9 || ^10
|
||||
dependencies:
|
||||
- drupal:migrate
|
||||
- drupal:migrate_plus
|
||||
- drupal:views_json_source
|
||||
@@ -0,0 +1,6 @@
|
||||
<?php
|
||||
|
||||
function json_ingestion_examples_install() {
|
||||
$mod_installer = \Drupal::service('module_installer');
|
||||
$mod_installer->install(['migrate', 'migrate_plus', 'views_json_source']);
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
id: images
|
||||
label: 'Import remote images.'
|
||||
source:
|
||||
plugin: url
|
||||
data_fetcher_plugin: http
|
||||
data_parser_plugin: json
|
||||
urls: 'https://jsonplaceholder.typicode.com/photos'
|
||||
item_selector: /
|
||||
constants:
|
||||
file_dest_dir: 'public://migrated-images/'
|
||||
jpeg: '.jpeg'
|
||||
ids:
|
||||
image_id:
|
||||
type: string
|
||||
fields:
|
||||
-
|
||||
name: image_id
|
||||
label: 'Image ID'
|
||||
selector: /id
|
||||
-
|
||||
name: image_title
|
||||
label: 'Image URL'
|
||||
selector: /title
|
||||
-
|
||||
name: image_url
|
||||
label: 'Image URL'
|
||||
selector: /url
|
||||
process:
|
||||
_prep_filename:
|
||||
-
|
||||
plugin: callback
|
||||
callable: basename
|
||||
source: image_url
|
||||
filename:
|
||||
plugin: concat
|
||||
source:
|
||||
- '@_prep_filename'
|
||||
- constants/jpeg
|
||||
_prep_file_destination:
|
||||
plugin: concat
|
||||
source:
|
||||
- constants/file_dest_dir
|
||||
- '@filename'
|
||||
uri:
|
||||
plugin: file_copy
|
||||
source:
|
||||
- image_url
|
||||
- '@_prep_file_destination'
|
||||
status:
|
||||
plugin: default_value
|
||||
default_value: 1
|
||||
alt: image_title
|
||||
destination:
|
||||
plugin: 'entity:file'
|
||||
@@ -0,0 +1,37 @@
|
||||
id: json_posts_to_posts
|
||||
label: 'JSON Migrate - Posts to Posts'
|
||||
migration_group: migrate_posts
|
||||
source:
|
||||
plugin: url
|
||||
data_fetcher_plugin: http
|
||||
data_parser_plugin: json
|
||||
urls: 'https://jsonplaceholder.typicode.com/posts'
|
||||
item_selector: /
|
||||
ids:
|
||||
post_id:
|
||||
type: string
|
||||
fields:
|
||||
-
|
||||
name: post_id
|
||||
label: 'Post ID'
|
||||
selector: /id
|
||||
-
|
||||
name: post_title
|
||||
label: 'Post Title'
|
||||
selector: /title
|
||||
-
|
||||
name: post_body
|
||||
label: 'Post Body'
|
||||
selector: /body
|
||||
process:
|
||||
title: post_title
|
||||
body/value: post_body
|
||||
field_image:
|
||||
plugin: migration_lookup
|
||||
migration: images
|
||||
source: post_id # this gets an image with the same ID as the post.
|
||||
|
||||
destination:
|
||||
plugin: 'entity:node'
|
||||
default_bundle: post
|
||||
migration_dependencies: { }
|
||||
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\json_ingestion_examples\Drush\Commands;
|
||||
|
||||
use Drupal\Core\File\FileSystemInterface;
|
||||
use Drupal\file\Entity\File;
|
||||
use Drupal\node\Entity\Node;
|
||||
use Drush\Commands\DrushCommands;
|
||||
|
||||
/**
|
||||
* Drush command file.
|
||||
*/
|
||||
class JsonIngestionCommands extends DrushCommands {
|
||||
|
||||
/**
|
||||
* A custom Drush command to displays the given text.
|
||||
*
|
||||
* @command json-ingestion-examples:update-posts
|
||||
* The amount to iterate over
|
||||
* @aliases jie-posts
|
||||
*/
|
||||
public function updatePosts() {
|
||||
$this->importImages();
|
||||
$this->importPosts();
|
||||
}
|
||||
|
||||
/**
|
||||
* Imports all images.
|
||||
*/
|
||||
public function importImages() {
|
||||
// Go fetch JSON for images.
|
||||
$http_client = \Drupal::httpClient();
|
||||
$images_json_url = 'https://jsonplaceholder.typicode.com/photos';
|
||||
$images_json = $http_client->request('GET', $images_json_url)->getBody()->getContents();
|
||||
// Reduce to 100 images as only have 100 posts.
|
||||
$images_array = array_slice(json_decode($images_json), 0, 100);
|
||||
$directory = 'public://drush-generated';
|
||||
/** @var \Drupal\Core\File\FileSystemInterface $file_system */
|
||||
$file_system = \Drupal::service('file_system');
|
||||
// Make sure directory exists.
|
||||
$file_system->prepareDirectory($directory, FileSystemInterface:: CREATE_DIRECTORY | FileSystemInterface::MODIFY_PERMISSIONS);
|
||||
foreach ($images_array as $img_ob) {
|
||||
// Download file, always replace.
|
||||
$file = file_get_contents($img_ob->url);
|
||||
$filename = basename($img_ob->url) . '.jpeg';
|
||||
$filepath = $directory . '/' . $filename;
|
||||
$file_system->saveData($file, $filepath, FileSystemInterface::EXISTS_REPLACE);
|
||||
// Create file entity.
|
||||
$file = File::create([
|
||||
'filename' => $filename,
|
||||
'uri' => $filepath,
|
||||
'status' => 1,
|
||||
'uid' => 1,
|
||||
]);
|
||||
if ($file->save()) {
|
||||
$this->writeln("File $filename created");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Imports all posts.
|
||||
*/
|
||||
public function importPosts() {
|
||||
// Go fetch JSON for posts.
|
||||
$http_client = \Drupal::httpClient();
|
||||
$node_storage = \Drupal::entityTypeManager()->getStorage('node');
|
||||
$posts_json_url = 'https://jsonplaceholder.typicode.com/posts';
|
||||
$posts_json = $http_client->request('GET', $posts_json_url)->getBody()->getContents();
|
||||
$posts_array = json_decode($posts_json);
|
||||
foreach ($posts_array as $post) {
|
||||
$node_check = $node_storage->loadByProperties([
|
||||
'type' => 'post',
|
||||
'title' => $post->title
|
||||
]);
|
||||
// If title already exists, skip.
|
||||
if ($node_check) {
|
||||
continue;
|
||||
}
|
||||
$new_post = Node::create(['type' => 'post']);
|
||||
$new_post->set('title', $post->title);
|
||||
$new_post->set('body', $post->body);
|
||||
$new_post->set('field_image', $post->id);
|
||||
$new_post->enforceIsNew();
|
||||
if ($new_post->save()) {
|
||||
$this->writeln("New post created: $post->title");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user