diff --git a/api/src/constants/index.ts b/api/src/constants/index.ts index f7d0377e..09806a3b 100644 --- a/api/src/constants/index.ts +++ b/api/src/constants/index.ts @@ -326,3 +326,6 @@ export const RESERVED_FIELD_MAPPINGS: Record = { locale: 'cm_locale', // Add other reserved fields if needed }; + +export const MEDIA_BLOCK_NAMES = ['core/image', 'core/video', 'core/audio', 'core/file']; +export const WORDPRESS_MISSSING_BLOCKS = 'core/missing'; \ No newline at end of file diff --git a/api/src/services/wordpress.service.ts b/api/src/services/wordpress.service.ts index 5bd6058d..bfaac3f3 100644 --- a/api/src/services/wordpress.service.ts +++ b/api/src/services/wordpress.service.ts @@ -14,6 +14,7 @@ import { orgService } from "./org.service.js"; import * as cheerio from 'cheerio'; import { setupWordPressBlocks, stripHtmlTags } from "../utils/wordpressParseUtil.js"; import { getMimeTypeFromExtension } from "../utils/mimeTypes.js"; +import { MEDIA_BLOCK_NAMES, WORDPRESS_MISSSING_BLOCKS } from "../constants/index.js"; const { JSDOM } = jsdom; @@ -124,6 +125,16 @@ function getLastUid(uid : string) { return uid?.split?.('.')?.[uid?.split?.('.')?.length - 1]; } + +const resolvedBlockName = (block: any) => { + if (block?.attrs?.metadata?.name) return block?.attrs?.metadata?.name; + if (block?.blockName === WORDPRESS_MISSSING_BLOCKS) { + return block?.attrs?.originalName || 'body'; + } + if (MEDIA_BLOCK_NAMES?.includes?.(block?.blockName)) return 'media'; + return block?.blockName; +} + async function createSchema(fields: any, blockJson : any, title: string, uid: string, assetData: any, duplicateBlockMappings?: Record) { const schema : any = { title: title, @@ -159,13 +170,13 @@ async function createSchema(fields: any, blockJson : any, title: string, uid: st // Process each block in blockJson to see if it matches any modular block child for (const block of blockJson) { try { - const blockName = (block?.attrs?.metadata?.name?.toLowerCase() || getFieldName(block?.blockName?.toLowerCase())); + const blockName = getFieldName(resolvedBlockName(block)); // Find which modular block child this block matches let matchingChildField = fields.find((childField: any) => { - const fieldName = childField?.otherCmsField?.toLowerCase() ; - - return (childField?.contentstackFieldType !== 'modular_blocks_child') && (blockName === fieldName) + const fieldName = childField?.otherCmsField?.toLowerCase(); + const fieldType = childField?.otherCmsType?.toLowerCase(); + return (childField?.contentstackFieldType !== 'modular_blocks_child') && (blockName === fieldName || blockName === fieldType) }); let matchingModularBlockChild = modularBlockChildren.find((childField: any) => { @@ -187,7 +198,8 @@ async function createSchema(fields: any, blockJson : any, title: string, uid: st //if (!matchingChildField) { matchingChildField = fields.find((childField: any) => { const fieldName = childField?.otherCmsField?.toLowerCase(); - return (childField?.contentstackFieldType !== 'modular_blocks_child') && (mappedName === fieldName); + const fieldType = childField?.otherCmsType?.toLowerCase(); + return (childField?.contentstackFieldType !== 'modular_blocks_child') && (mappedName === fieldName || mappedName === fieldType); }); // } @@ -206,12 +218,13 @@ async function createSchema(fields: any, blockJson : any, title: string, uid: st const childFieldUid = matchingModularBlockChild?.contentstackFieldUid || getLastUid(matchingModularBlockChild?.contentstackUid); const childField = fields.find((f: any) => { const fUid = f?.contentstackFieldUid || ''; - const fOtherCmsField = f?.otherCmsType?.toLowerCase(); - const childBlockName = matchingChildField ? matchingChildField?.otherCmsField?.toLowerCase() : (child?.attrs?.metadata?.name?.toLowerCase() || getFieldName(child?.blockName?.toLowerCase())); + const fOtherCmsType = f?.otherCmsType?.toLowerCase(); + const fOtherCmsField = f?.otherCmsField?.toLowerCase(); + const childBlockName = matchingChildField ? matchingChildField?.otherCmsField?.toLowerCase() : (getFieldName(resolvedBlockName(child))?.toLowerCase() || getFieldName(resolvedBlockName(child)?.toLowerCase())); const childKey = getLastUid(f?.contentstackFieldUid); const alreadyPopulated = childrenObject[childKey] !== undefined && childrenObject[childKey] !== null; return fUid.startsWith(childFieldUid + '.') && - (fOtherCmsField === childBlockName) && (!alreadyPopulated || f?.advanced?.multiple === true); + (fOtherCmsType === childBlockName || fOtherCmsField === childBlockName) && (!alreadyPopulated || f?.advanced?.multiple === true); }); if (childField) { @@ -313,8 +326,9 @@ function processNestedGroup(child: any, childField: any, allFields: any[]): Reco child?.innerBlocks?.forEach((nestedChild: any, nestedIndex: number) => { try { + const nestedBlockName = (getFieldName(resolvedBlockName(nestedChild))?.toLowerCase() ?? getFieldName(resolvedBlockName(nestedChild)?.toLowerCase()))?.toLowerCase(); const nestedChildField = nestedFields?.find((field: any) => - field?.otherCmsType?.toLowerCase() === (nestedChild?.attrs?.metadata?.name?.toLowerCase() ?? getFieldName(nestedChild?.blockName?.toLowerCase()))?.toLowerCase() && !nestedChildrenObject[getLastUid(field?.contentstackFieldUid)]?.length + (field?.otherCmsType?.toLowerCase() === nestedBlockName || field?.otherCmsField?.toLowerCase() === nestedBlockName) && !nestedChildrenObject[getLastUid(field?.contentstackFieldUid)]?.length ); if (!nestedChildField) { @@ -387,7 +401,7 @@ function formatChildByType(child: any, field: any, assetData: any) { // Process attributes based on field type configuration //if (child?.attributes && typeof child.attributes === 'object') { - const attrKey = getFieldName(child?.attr?.metadata?.name?.toLowerCase() || child?.blockName?.toLowerCase()); + const attrKey = getFieldName(getFieldName(resolvedBlockName(child))?.toLowerCase() || getFieldName(resolvedBlockName(child)?.toLowerCase())); try { const attrValue = child?.attrs?.innerHTML; @@ -477,6 +491,10 @@ function formatChildByType(child: any, field: any, assetData: any) { formatted = asset; break; } + + case 'markdown': + formatted = stripHtmlTags(child?.innerHTML); + break; default: // Default formatting - preserve original structure with null check formatted = attrValue; @@ -580,6 +598,7 @@ async function saveEntry(fields: any, entry: any, file_path: string, assetData // Extract individual content encoded for this specific item const contentEncoded = $(xmlItem)?.find("content\\:encoded")?.text() || ''; const blocksJson = await setupWordPressBlocks(contentEncoded); + customLogger(project?.id, destinationStackId,'info', `Processed blocks for entry ${uid}`); diff --git a/upload-api/migration-wordpress/libs/extractItems.ts b/upload-api/migration-wordpress/libs/extractItems.ts index e368720e..da0948bf 100644 --- a/upload-api/migration-wordpress/libs/extractItems.ts +++ b/upload-api/migration-wordpress/libs/extractItems.ts @@ -15,7 +15,9 @@ const MEDIA_BLOCK_NAMES = ['core/image', 'core/video', 'core/audio', 'core/file' function resolveBlockName(field: any): string { if (field?.attributes?.metadata?.name) return field.attributes.metadata.name; - if (field?.name === 'core/missing') return 'body'; + if (field?.name === 'core/missing') { + return field?.attributes?.originalName || 'body'; + } if (MEDIA_BLOCK_NAMES.includes(field?.name)) return 'media'; return field?.name; } @@ -73,6 +75,12 @@ function isSameStructure(obj1: any, obj2: any): boolean { return false; } + if (obj1?.name === 'core/missing' && obj2?.name === 'core/missing') { + if (obj1?.attributes?.originalName !== obj2?.attributes?.originalName) { + return false; + } + } + if (Array?.isArray(obj1?.innerBlocks) || Array.isArray(obj2?.innerBlocks)) { if (!Array.isArray(obj1?.innerBlocks) || !Array.isArray(obj2?.innerBlocks)) { diff --git a/upload-api/migration-wordpress/libs/schemaMapper.ts b/upload-api/migration-wordpress/libs/schemaMapper.ts index 6fe01300..25328fad 100644 --- a/upload-api/migration-wordpress/libs/schemaMapper.ts +++ b/upload-api/migration-wordpress/libs/schemaMapper.ts @@ -6,7 +6,9 @@ const MEDIA_BLOCK_NAMES = ['core/image', 'core/video', 'core/audio', 'core/file' function resolveBlockName(key: any): string { if (key?.attributes?.metadata?.name) return key.attributes.metadata.name; - if (key?.name === 'core/missing') return 'body'; + if (key?.name === 'core/missing') { + return key?.attributes?.originalName || 'body'; + } if (MEDIA_BLOCK_NAMES.includes(key?.name)) return 'media'; return key?.name; } @@ -195,7 +197,7 @@ async function schemaMapper (key: WordPressBlock | WordPressBlock[], parentUid: case 'core/pullquote': case 'core/table': case 'core/columns': - case 'core/missing': + case 'core/verse': case 'core/code': { const rteUid = parentUid ? @@ -213,6 +215,35 @@ async function schemaMapper (key: WordPressBlock | WordPressBlock[], parentUid: advanced: {} }; } + case 'core/missing': + const rteUid = parentUid ? + `${parentUid}.${getFieldUid(`${key?.name}_${key?.clientId}`, affix)}` + : getFieldUid(`${key?.name}_${key?.clientId}`, affix); + if(key?.attributes?.originalName === 'jetpack/markdown'){ + return { + uid: rteUid, + otherCmsField: getFieldName(resolveBlockName(key)), + otherCmsType: getFieldName(resolveBlockName(key)), + contentstackField: fieldName , + contentstackFieldUid: rteUid, + contentstackFieldType: 'markdown', + backupFieldType: 'markdown', + backupFieldUid: rteUid, + advanced: {} + }; + }else{ + return { + uid: rteUid, + otherCmsField: getFieldName(resolveBlockName(key)), + otherCmsType:getFieldName( resolveBlockName(key) ?? resolveBlockName(key)), + contentstackField: fieldName , + contentstackFieldUid: rteUid, + contentstackFieldType: 'json', + backupFieldType: 'json', + backupFieldUid: rteUid, + advanced: {} + }; + } case 'core/image': case 'core/audio': case 'core/video': @@ -297,7 +328,7 @@ async function schemaMapper (key: WordPressBlock | WordPressBlock[], parentUid: }); if(innerBlocks?.length > 0 ){ - innerBlocks.forEach(schemaObj => { + innerBlocks?.forEach(schemaObj => { if (schemaObj) { if (Array.isArray(schemaObj)) { groupSchema.push(...schemaObj); @@ -310,13 +341,15 @@ async function schemaMapper (key: WordPressBlock | WordPressBlock[], parentUid: return groupSchema; } + break; } case 'core/search': { const searchEleUid = parentUid ? `${parentUid}.${getFieldUid(`${key?.name}_${key?.clientId}`, affix)}` : getFieldUid(`${key?.name}_${key?.clientId}`, affix); const searchEle = await processAttributes(key, searchEleUid,fieldName, affix); - searchEle.push({ + const groupSchema: Field[] = []; + searchEle?.length > 0 && groupSchema?.push({ uid: searchEleUid, otherCmsField: getFieldName(key?.name), otherCmsType: getFieldName(key?.attributes?.metadata?.name ?? key?.name), @@ -326,7 +359,16 @@ async function schemaMapper (key: WordPressBlock | WordPressBlock[], parentUid: backupFieldType: 'group', backupFieldUid: searchEleUid, }); - return searchEle; + searchEle?.length > 0 && searchEle?.forEach(schemaObj => { + if (schemaObj) { + if (Array.isArray(schemaObj)) { + groupSchema?.push?.(...schemaObj); + } else { + groupSchema?.push?.({...schemaObj}); + } + } + }); + return groupSchema; }