Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[gatsby-source-wordpress] Refactored featured_media map for deep nodes #2648

Merged
merged 4 commits into from
Oct 27, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5790,6 +5790,7 @@ Array [
],
},
"acf": Object {
"dummy": true,
"linked_image___NODE": "950513a1-a720-5588-b262-9533aa598624",
},
"author___NODE": "ec1fb3e3-d897-5549-b5f6-72b358fbbe83",
Expand Down Expand Up @@ -5858,7 +5859,7 @@ Array [
"date": "2017-09-02T10:36:43.000Z",
"description": "<p class=\\"attachment\\"><a href='http://dev-gatbsyjswp.pantheonsite.io/wp-content/uploads/2017/09/pexels-photo-534327.jpeg'><img width=\\"300\\" height=\\"200\\" src=\\"http://dev-gatbsyjswp.pantheonsite.io/wp-content/uploads/2017/09/pexels-photo-534327-300x200.jpeg\\" class=\\"attachment-medium size-medium\\" alt=\\"\\" srcset=\\"http://dev-gatbsyjswp.pantheonsite.io/wp-content/uploads/2017/09/pexels-photo-534327-300x200.jpeg 300w, http://dev-gatbsyjswp.pantheonsite.io/wp-content/uploads/2017/09/pexels-photo-534327-768x512.jpeg 768w, http://dev-gatbsyjswp.pantheonsite.io/wp-content/uploads/2017/09/pexels-photo-534327-1024x683.jpeg 1024w\\" sizes=\\"(max-width: 300px) 100vw, 300px\\" /></a></p>
",
"guid": "http://dev-gatbsyjswp.pantheonsite.io/wp-content/uploads/2017/09/pexels-photo-534327.jpeg",
"guid___NODE": "61ef7ef2-032f-5c90-bba3-99d04c9a1f07",
"id": "61ef7ef2-032f-5c90-bba3-99d04c9a1f07",
"link": "http://dev-gatbsyjswp.pantheonsite.io/sample-post-1/pexels-photo-534327/",
"media_details": Object {
Expand Down Expand Up @@ -5970,7 +5971,7 @@ Array [
"date": "2017-09-02T10:35:16.000Z",
"description": "<p class=\\"attachment\\"><a href='http://dev-gatbsyjswp.pantheonsite.io/wp-content/uploads/2017/09/pexels-photo-534351.jpeg'><img width=\\"300\\" height=\\"200\\" src=\\"http://dev-gatbsyjswp.pantheonsite.io/wp-content/uploads/2017/09/pexels-photo-534351-300x200.jpeg\\" class=\\"attachment-medium size-medium\\" alt=\\"\\" srcset=\\"http://dev-gatbsyjswp.pantheonsite.io/wp-content/uploads/2017/09/pexels-photo-534351-300x200.jpeg 300w, http://dev-gatbsyjswp.pantheonsite.io/wp-content/uploads/2017/09/pexels-photo-534351-768x512.jpeg 768w, http://dev-gatbsyjswp.pantheonsite.io/wp-content/uploads/2017/09/pexels-photo-534351-1024x683.jpeg 1024w\\" sizes=\\"(max-width: 300px) 100vw, 300px\\" /></a></p>
",
"guid": "http://dev-gatbsyjswp.pantheonsite.io/wp-content/uploads/2017/09/pexels-photo-534351.jpeg",
"guid___NODE": "950513a1-a720-5588-b262-9533aa598624",
"id": "950513a1-a720-5588-b262-9533aa598624",
"link": "http://dev-gatbsyjswp.pantheonsite.io/gatsby-sample-home-page/pexels-photo-534351/",
"media_details": Object {
Expand Down Expand Up @@ -11337,6 +11338,7 @@ Array [
],
},
"acf": Object {
"dummy": true,
"linked_image___NODE": "950513a1-a720-5588-b262-9533aa598624",
},
"author___NODE": "ec1fb3e3-d897-5549-b5f6-72b358fbbe83",
Expand All @@ -11355,7 +11357,7 @@ Array [
"guid": "http://dev-gatbsyjswp.pantheonsite.io/?page_id=5",
"id": "340ceded-7db7-583c-9486-120758f5d967",
"internal": Object {
"contentDigest": "bf7491f5ede200a6f3ce8db4c28e3eca",
"contentDigest": "730b646cd1ae6cd070d74956e5041fd2",
"type": "wordpress__PAGE",
},
"link": "http://dev-gatbsyjswp.pantheonsite.io/",
Expand Down Expand Up @@ -11413,10 +11415,10 @@ Array [
"date": "2017-09-02T10:36:43.000Z",
"description": "<p class=\\"attachment\\"><a href='http://dev-gatbsyjswp.pantheonsite.io/wp-content/uploads/2017/09/pexels-photo-534327.jpeg'><img width=\\"300\\" height=\\"200\\" src=\\"http://dev-gatbsyjswp.pantheonsite.io/wp-content/uploads/2017/09/pexels-photo-534327-300x200.jpeg\\" class=\\"attachment-medium size-medium\\" alt=\\"\\" srcset=\\"http://dev-gatbsyjswp.pantheonsite.io/wp-content/uploads/2017/09/pexels-photo-534327-300x200.jpeg 300w, http://dev-gatbsyjswp.pantheonsite.io/wp-content/uploads/2017/09/pexels-photo-534327-768x512.jpeg 768w, http://dev-gatbsyjswp.pantheonsite.io/wp-content/uploads/2017/09/pexels-photo-534327-1024x683.jpeg 1024w\\" sizes=\\"(max-width: 300px) 100vw, 300px\\" /></a></p>
",
"guid": "http://dev-gatbsyjswp.pantheonsite.io/wp-content/uploads/2017/09/pexels-photo-534327.jpeg",
"guid___NODE": "61ef7ef2-032f-5c90-bba3-99d04c9a1f07",
"id": "61ef7ef2-032f-5c90-bba3-99d04c9a1f07",
"internal": Object {
"contentDigest": "345cd9205939fd066a98ad92bce14d60",
"contentDigest": "e34c3e03101d1305788a27f283e90c6b",
"type": "wordpress__wp_media",
},
"link": "http://dev-gatbsyjswp.pantheonsite.io/sample-post-1/pexels-photo-534327/",
Expand Down Expand Up @@ -11532,10 +11534,10 @@ Array [
"date": "2017-09-02T10:35:16.000Z",
"description": "<p class=\\"attachment\\"><a href='http://dev-gatbsyjswp.pantheonsite.io/wp-content/uploads/2017/09/pexels-photo-534351.jpeg'><img width=\\"300\\" height=\\"200\\" src=\\"http://dev-gatbsyjswp.pantheonsite.io/wp-content/uploads/2017/09/pexels-photo-534351-300x200.jpeg\\" class=\\"attachment-medium size-medium\\" alt=\\"\\" srcset=\\"http://dev-gatbsyjswp.pantheonsite.io/wp-content/uploads/2017/09/pexels-photo-534351-300x200.jpeg 300w, http://dev-gatbsyjswp.pantheonsite.io/wp-content/uploads/2017/09/pexels-photo-534351-768x512.jpeg 768w, http://dev-gatbsyjswp.pantheonsite.io/wp-content/uploads/2017/09/pexels-photo-534351-1024x683.jpeg 1024w\\" sizes=\\"(max-width: 300px) 100vw, 300px\\" /></a></p>
",
"guid": "http://dev-gatbsyjswp.pantheonsite.io/wp-content/uploads/2017/09/pexels-photo-534351.jpeg",
"guid___NODE": "950513a1-a720-5588-b262-9533aa598624",
"id": "950513a1-a720-5588-b262-9533aa598624",
"internal": Object {
"contentDigest": "60e31d4f0302cc6cae5c7021444ff564",
"contentDigest": "7bb20caef5bf65715b92b109cbfae7b9",
"type": "wordpress__wp_media",
},
"link": "http://dev-gatbsyjswp.pantheonsite.io/gatsby-sample-home-page/pexels-photo-534351/",
Expand Down
136 changes: 79 additions & 57 deletions packages/gatsby-source-wordpress/src/normalize.js
Original file line number Diff line number Diff line change
Expand Up @@ -239,20 +239,10 @@ exports.mapEntitiesToMedia = entities => {

return entities.map(e => {
// Map featured_media to its media node
let featuredMedia
if (e.featured_media) {
featuredMedia = media.find(m => m.wordpress_id === e.featured_media)
}

if (featuredMedia) {
e.featured_media___NODE = featuredMedia.id
}

// Always delete even if we can't find a featuredMedia as WordPress' API sets
// featured_media to 0 when there isn't one which is useless to us.
delete e.featured_media

const isPhoto = field =>
// Check if it's value of ACF Image field, that has 'Return value' set to
// 'Image Object' ( https://www.advancedcustomfields.com/resources/image/ )
const isPhotoObject = field =>
_.isObject(field) &&
field.wordpress_id &&
field.url &&
Expand All @@ -262,61 +252,93 @@ exports.mapEntitiesToMedia = entities => {
: false

const photoRegex = /\.(gif|jpg|jpeg|tiff|png)$/i
const isPhotoUrl = filename => photoRegex.test(filename)
const replacePhoto = field =>
media.find(m => m.wordpress_id === field.wordpress_id).id

const replaceFieldsInObject = object => {
_.each(object, (value, key) => {
if (_.isArray(value)) {
value.forEach(v => replaceFieldsInObject(v))
}
if (isPhoto(value)) {
object[`${key}___NODE`] = replacePhoto(value)
delete object[key]
const isPhotoUrl = filename =>
_.isString(filename) && photoRegex.test(filename)
const isPhotoUrlAlreadyProcessed = key => key == `source_url`
const isFeaturedMedia = (value, key) =>
(_.isNumber(value) || _.isBoolean(value)) && key === `featured_media`
// ACF Gallery and similarly shaped arrays
const isArrayOfPhotoObject = field =>
_.isArray(field) && field.length > 0 && isPhotoObject(field[0])
const getMediaItemID = mediaItem => (mediaItem ? mediaItem.id : null)

// Try to get media node from value:
// - special case - check if key is featured_media and value is photo ID
// - check if value is photo url
// - check if value is ACF Image Object
// - check if value is ACF Gallery
const getMediaFromValue = (value, key) => {
if (isFeaturedMedia(value, key)) {
return {
mediaNodeID: _.isNumber(value)
? getMediaItemID(media.find(m => m.wordpress_id === value))
: null,
deleteField: true,
}

// featured_media can be nested inside ACF fields
if (_.isObject(value) && value.featured_media) {
featuredMedia = media.find(
m => m.wordpress_id === value.featured_media
)
if (featuredMedia) {
value.featured_media___NODE = featuredMedia.id
}
delete value.featured_media
} else if (isPhotoUrl(value) && !isPhotoUrlAlreadyProcessed(key)) {
const mediaNodeID = getMediaItemID(
media.find(m => m.source_url === value)
)
return {
mediaNodeID,
deleteField: !!mediaNodeID,
}
if (_.isNumber(value) && key == `featured_media`) {
featuredMedia = media.find(m => m.wordpress_id === value)
if (featuredMedia) {
object[`${key}___NODE`] = featuredMedia.id
}
delete object[key]
} else if (isPhotoObject(value)) {
const mediaNodeID = getMediaItemID(
media.find(m => m.source_url === value.url)
)
return {
mediaNodeID,
deleteField: !!mediaNodeID,
}
if (_.isBoolean(value) && key == `featured_media`) {
delete object[key]
} else if (isArrayOfPhotoObject(value)) {
return {
mediaNodeID: value
.map(item => getMediaFromValue(item, key).mediaNodeID)
.filter(id => id !== null),
deleteField: true,
}
})
}
return {
mediaNodeID: null,
deleteField: false,
}
}

if (e.acf) {
_.each(e.acf, (value, key) => {
if (_.isString(value) && isPhotoUrl(value)) {
const me = media.find(m => m.source_url === value)
if (me) {
e.acf[`${key}___NODE`] = me.id
delete e.acf[key]
}
const replaceFieldsInObject = object => {
let deletedAllFields = true
_.each(object, (value, key) => {
const { mediaNodeID, deleteField } = getMediaFromValue(value, key)
if (mediaNodeID) {
object[`${key}___NODE`] = mediaNodeID
}
if (deleteField) {
delete object[key]
// We found photo node (even if it has no image),
// We can end processing this path
return
} else {
deletedAllFields = false
}

if (_.isArray(value) && value[0] && value[0].acf_fc_layout) {
e.acf[key] = e.acf[key].map(f => {
replaceFieldsInObject(f)
return f
})
if (_.isArray(value)) {
value.forEach(v => replaceFieldsInObject(v))
} else if (_.isObject(value)) {
replaceFieldsInObject(value)
}
})

// Deleting fields and replacing them with links to different nodes
// can cause build errors if object will have only linked properites:
// https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby/src/schema/infer-graphql-input-fields.js#L205
// Hacky workaround:
// Adding dummy field with concrete value (not link) fixes build
if (deletedAllFields && object && _.isObject(object)) {
object[`dummy`] = true
}
}
replaceFieldsInObject(e)

return e
})
}
Expand Down