-
Notifications
You must be signed in to change notification settings - Fork 2
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
handle different locale #48
Changes from all commits
c292e80
723cc36
7cdfe74
f8ff7ed
d2a22ca
52d3ef0
719f8c5
c0d0df8
438245b
84786d0
4ced67d
f444864
d2c5306
88c9078
abf2f59
6baee6f
72b9512
b74a712
164b8bd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,13 +6,65 @@ const { EJSON } = require('bson'); | |
module.exports = self => { | ||
return { | ||
async import(req, moduleName) { | ||
const { | ||
docs, attachmentsInfo, exportPath, filePath | ||
} = await self.readExportFile(req); | ||
if (!req.user) { | ||
throw self.apos.error('forbidden'); | ||
} | ||
|
||
const overrideLocale = self.apos.launder.boolean(req.body.overrideLocale); | ||
let exportPath = self.apos.launder.string(req.body.exportPath); | ||
|
||
let docs; | ||
let attachmentsInfo; | ||
|
||
if (exportPath) { | ||
const filesData = await self.getFilesData(exportPath); | ||
|
||
({ docs, attachmentsInfo } = filesData); | ||
} else { | ||
const exportFile = await self.readExportFile(req); | ||
|
||
({ docs, attachmentsInfo } = exportFile); | ||
exportPath = exportFile.exportPath; | ||
|
||
await self.cleanFile(exportFile.filePath); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we now clean the archive right after having extracted it so we don't have to think about removing it at several other places |
||
} | ||
|
||
const differentDocsLocale = self.getFirstDifferentLocale(req, docs); | ||
const siteHasMultipleLocales = Object.keys(self.apos.i18n.locales).length > 1; | ||
|
||
if (differentDocsLocale) { | ||
if (siteHasMultipleLocales && !overrideLocale) { | ||
// Display confirmation modal to ask the user if he wants to | ||
// continue the import with the current locale overriding the docs one: | ||
await self.apos.notify(req, ' ', { | ||
type: 'warning', | ||
event: { | ||
name: 'import-locale-differs', | ||
data: { | ||
moduleName, | ||
exportPath, | ||
content: { | ||
heading: req.t('aposImportExport:importWithCurrentLocaleHeading'), | ||
description: req.t('aposImportExport:importWithCurrentLocaleDescription', { | ||
docsLocale: differentDocsLocale, | ||
currentLocale: req.locale | ||
}), | ||
negativeLabel: 'apostrophe:no', | ||
affirmativeLabel: 'apostrophe:yes' | ||
} | ||
} | ||
}, | ||
classes: [ 'apos-notification--hidden' ] | ||
}); | ||
|
||
return; | ||
} | ||
|
||
// Re-write if user decided to continue the import (`overrideLocale` param sent) | ||
// or if the site has only one locale configured | ||
self.rewriteDocsWithCurrentLocale(req, docs); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I suppose this method is called twice, another time with the confirmation to change locale? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This method is called only during the 2nd call (when the user chooses Yes), see the early return above |
||
} | ||
|
||
const total = docs.length + attachmentsInfo.length; | ||
const { | ||
reporting, jobId, notificationId | ||
|
@@ -21,6 +73,7 @@ module.exports = self => { | |
const { | ||
duplicatedDocs, duplicatedIds, failedIds | ||
} = await self.insertDocs(req, docs, reporting); | ||
|
||
const importedAttachments = await self.insertAttachments(req, { | ||
attachmentsInfo, | ||
reporting, | ||
|
@@ -52,7 +105,6 @@ module.exports = self => { | |
}); | ||
|
||
await self.cleanFile(exportPath); | ||
await self.cleanFile(filePath); | ||
return; | ||
} | ||
|
||
|
@@ -68,6 +120,7 @@ module.exports = self => { | |
} | ||
|
||
const results = { | ||
overrideLocale, | ||
duplicatedDocs, | ||
importedAttachments, | ||
type: moduleName, | ||
|
@@ -87,8 +140,6 @@ module.exports = self => { | |
classes: [ 'apos-notification--hidden' ] | ||
}); | ||
|
||
self.cleanFile(filePath); | ||
|
||
return results; | ||
}, | ||
|
||
|
@@ -180,6 +231,34 @@ module.exports = self => { | |
}; | ||
}, | ||
|
||
getFirstDifferentLocale(req, docs) { | ||
const doc = docs | ||
.find(doc => self.isLocaleDifferent(req, doc)); | ||
|
||
return doc && self.extractLocale(doc.aposLocale); | ||
}, | ||
|
||
rewriteDocsWithCurrentLocale(req, docs) { | ||
for (const doc of docs) { | ||
if (self.isLocaleDifferent(req, doc)) { | ||
const [ id ] = doc._id.split(':'); | ||
|
||
doc._id = [ id, req.locale, doc.aposMode ].join(':'); | ||
doc.aposLocale = [ req.locale, doc.aposMode ].join(':'); | ||
} | ||
} | ||
}, | ||
|
||
isLocaleDifferent(req, doc) { | ||
return doc.aposLocale && self.extractLocale(doc.aposLocale) !== req.locale; | ||
}, | ||
|
||
extractLocale(aposLocale) { | ||
const [ locale ] = aposLocale.split(':'); | ||
|
||
return locale; | ||
}, | ||
|
||
async insertDocs(req, docs, reporting) { | ||
const duplicatedDocs = []; | ||
const duplicatedIds = []; | ||
|
@@ -342,25 +421,26 @@ module.exports = self => { | |
} | ||
}, | ||
|
||
async cleanFile(exportPath) { | ||
async cleanFile(path) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. minor change: |
||
try { | ||
const stat = await fsp.lstat(exportPath); | ||
const stat = await fsp.lstat(path); | ||
if (stat.isDirectory()) { | ||
await fsp.rm(exportPath, { | ||
await fsp.rm(path, { | ||
recursive: true, | ||
force: true | ||
}); | ||
} else { | ||
await fsp.unlink(exportPath); | ||
await fsp.unlink(path); | ||
} | ||
} catch (err) { | ||
self.apos.util.error( | ||
`Error while trying to remove the file or folder: ${exportPath}. You might want to remove it yourself.` | ||
`Error while trying to remove the file or folder: ${path}. You might want to remove it yourself.` | ||
); | ||
} | ||
}, | ||
|
||
async overrideDuplicates(req) { | ||
const overrideLocale = self.apos.launder.boolean(req.body.overrideLocale); | ||
const exportPath = self.apos.launder.string(req.body.exportPath); | ||
const docIds = self.apos.launder.strings(req.body.docIds); | ||
const jobId = self.apos.launder.string(req.body.jobId); | ||
|
@@ -372,6 +452,16 @@ module.exports = self => { | |
|
||
const { docs, attachmentsInfo } = await self.getFilesData(exportPath, docIds); | ||
|
||
const differentDocsLocale = self.getFirstDifferentLocale(req, docs); | ||
const siteHasMultipleLocales = Object.keys(self.apos.i18n.locales).length > 1; | ||
|
||
// Re-write locale if `overrideLocale` param is passed-on from the import process | ||
// (i.e if the user chose "Yes") | ||
// or re-write locale automatically on a single-locale site | ||
if (differentDocsLocale && (!siteHasMultipleLocales || overrideLocale)) { | ||
self.rewriteDocsWithCurrentLocale(req, docs); | ||
} | ||
|
||
Comment on lines
+455
to
+464
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we also need to override the locale here! |
||
for (const doc of docs) { | ||
try { | ||
const attachmentsToOverride = self.getRelatedDocsFromSchema(req, { | ||
|
@@ -428,15 +518,15 @@ module.exports = self => { | |
const jobId = self.apos.launder.string(req.body.jobId); | ||
const notificationId = self.apos.launder.string(req.body.notificationId); | ||
|
||
const jobManager = self.apos.modules['@apostrophecms/job']; | ||
const job = await jobManager.db.findOne({ _id: jobId }); | ||
|
||
jobManager.end(job, true); | ||
if (jobId) { | ||
const jobManager = self.apos.modules['@apostrophecms/job']; | ||
const job = await jobManager.db.findOne({ _id: jobId }); | ||
jobManager.end(job, true); | ||
} | ||
if (notificationId) { | ||
self.apos.notification.dismiss(req, notificationId, 2000).catch(self.apos.util.error); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. clean job and notification only if existing There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. see |
||
|
||
self.apos.notification.dismiss(req, notificationId, 2000) | ||
.catch((error) => { | ||
self.apos.util.error(error); | ||
}); | ||
await self.cleanFile(exportPath); | ||
} | ||
}; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what means the fact that this method receives an exportPath? Does it mean that the gzip file has already been cleaned?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The gzip file is now cleaned as soon as it's extracted (cf. comment below)
This method is provided
exportPath
when the user choosesYes
(continue the import with the current locale), because is archive has already been extracted during theimport
method first call.It just early returned to display the confirmation modal.
So at the 2nd call, we simply give the method back the
exportPath
so it knows where the files were extracted during the 1st call