From 9cd6e158ff541b47dd4aa327251fb4abee1fdf4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pierre=20No=C3=ABl?= Date: Fri, 2 Apr 2021 15:13:23 +0200 Subject: [PATCH] refacto --- .../controllers/content-types.js | 7 ++- .../services/content-types.js | 57 ++++++++++++------- .../services/localizations.js | 11 ++-- 3 files changed, 47 insertions(+), 28 deletions(-) diff --git a/packages/strapi-plugin-i18n/controllers/content-types.js b/packages/strapi-plugin-i18n/controllers/content-types.js index 36babb162f..898fc40312 100644 --- a/packages/strapi-plugin-i18n/controllers/content-types.js +++ b/packages/strapi-plugin-i18n/controllers/content-types.js @@ -1,6 +1,6 @@ 'use strict'; -const { pick, uniq, prop, getOr, flatten, pipe } = require('lodash/fp'); +const { pick, uniq, prop, getOr, flatten, pipe, map } = require('lodash/fp'); const { contentTypes: contentTypesUtils } = require('strapi-utils'); const { getService } = require('../utils'); const { validateGetNonLocalizedAttributesInput } = require('../validation/content-types'); @@ -10,6 +10,8 @@ const { PUBLISHED_AT_ATTRIBUTE } = contentTypesUtils.constants; const getLocalesProperty = getOr([], 'properties.locales'); const getFieldsProperty = prop('properties.fields'); +const getFirstLevelPath = map(path => path.split('.')[0]); + module.exports = { async getNonLocalizedAttributes(ctx) { const { user } = ctx.state; @@ -46,7 +48,8 @@ module.exports = { const localePermissions = permissions .filter(perm => getLocalesProperty(perm).includes(locale)) .map(getFieldsProperty); - const permittedFields = pipe(flatten, uniq)(localePermissions); + + const permittedFields = pipe(flatten, getFirstLevelPath, uniq)(localePermissions); const nonLocalizedFields = copyNonLocalizedAttributes(modelDef, entity); const sanitizedNonLocalizedFields = pick(permittedFields, nonLocalizedFields); diff --git a/packages/strapi-plugin-i18n/services/content-types.js b/packages/strapi-plugin-i18n/services/content-types.js index 366cace092..04a8f05bac 100644 --- a/packages/strapi-plugin-i18n/services/content-types.js +++ b/packages/strapi-plugin-i18n/services/content-types.js @@ -1,7 +1,7 @@ 'use strict'; const _ = require('lodash'); -const { pick, pipe, has, prop, isNil, cloneDeepWith } = require('lodash/fp'); +const { pick, pipe, has, prop, isNil, cloneDeep, isArray } = require('lodash/fp'); const { isRelationalAttribute, getVisibleAttributes, @@ -97,25 +97,41 @@ const getNonLocalizedAttributes = model => { ); }; -const cleanIds = (model, { output = true }) => entry => { - // remove ids - const processedEntry = cloneDeepWith(value => { - if (typeof value === 'object' && has('id', value)) { - delete value.id; - } - }, entry); +const removeId = value => { + if (typeof value === 'object' && has('id', value)) { + delete value.id; + } +}; - // set media ids back - if (!output) { - _.forIn(entry, (value, attrName) => { - const attr = model.attributes[attrName]; - if (isMediaAttribute(attr) && value) { - processedEntry[attrName] = has('collection', attr) ? value : value.id; - } - }); +const removeIds = model => entry => removeIdsMut(model, cloneDeep(entry)); + +const removeIdsMut = (model, entry) => { + if (isNil(entry)) { + return entry; } - return processedEntry; + removeId(entry); + + _.forEach(model.attributes, (attr, attrName) => { + const value = entry[attrName]; + if (attr.type === 'dynamiczone' && isArray(value)) { + value.forEach(compo => { + if (has('__component', compo)) { + const model = strapi.components[compo.__component]; + removeIdsMut(model, compo); + } + }); + } else if (attr.type === 'component') { + const [model] = strapi.db.getModelsByAttribute(attr); + if (isArray(value)) { + value.forEach(compo => removeIdsMut(model, compo)); + } else { + removeIdsMut(model, value); + } + } + }); + + return entry; }; /** @@ -124,10 +140,11 @@ const cleanIds = (model, { output = true }) => entry => { * @param {object} entry * @returns {object} */ -const copyNonLocalizedAttributes = (model, entry, { output = true } = {}) => { +const copyNonLocalizedAttributes = (model, entry) => { const nonLocalizedAttributes = getNonLocalizedAttributes(model); - return pipe(pick(nonLocalizedAttributes), cleanIds(model, { output }))(entry); + const res = pipe(pick(nonLocalizedAttributes), removeIds(model))(entry); + return res; }; /** @@ -154,7 +171,7 @@ const fillNonLocalizedAttributes = (entry, relatedEntry, { model }) => { } const modelDef = strapi.getModel(model); - const relatedEntryCopy = copyNonLocalizedAttributes(modelDef, relatedEntry, { output: false }); + const relatedEntryCopy = copyNonLocalizedAttributes(modelDef, relatedEntry); _.forEach(relatedEntryCopy, (value, field) => { if (isNil(entry[field])) { diff --git a/packages/strapi-plugin-i18n/services/localizations.js b/packages/strapi-plugin-i18n/services/localizations.js index acd301d354..3ff294e997 100644 --- a/packages/strapi-plugin-i18n/services/localizations.js +++ b/packages/strapi-plugin-i18n/services/localizations.js @@ -1,6 +1,6 @@ 'use strict'; -const { pick, prop, isNil } = require('lodash/fp'); +const { prop, isNil, isEmpty } = require('lodash/fp'); const { getService } = require('../utils'); @@ -43,17 +43,16 @@ const syncLocalizations = async (entry, { model }) => { * @param {Object} options.model corresponding model */ const syncNonLocalizedAttributes = async (entry, { model }) => { - const { getNonLocalizedAttributes } = getService('content-types'); + const { copyNonLocalizedAttributes } = getService('content-types'); if (Array.isArray(entry.localizations)) { - const nonLocalizedFields = getNonLocalizedAttributes(model); + const nonLocalizedAttributes = copyNonLocalizedAttributes(model, entry); - if (nonLocalizedFields.length === 0) { + if (isEmpty(nonLocalizedAttributes)) { return; } - const fieldsToUpdate = pick(nonLocalizedFields, entry); - const updateLocalization = id => strapi.query(model.uid).update({ id }, fieldsToUpdate); + const updateLocalization = id => strapi.query(model.uid).update({ id }, nonLocalizedAttributes); await Promise.all(entry.localizations.map(({ id }) => updateLocalization(id))); }