| 
									
										
										
										
											2022-04-26 11:23:07 +02:00
										 |  |  | 'use strict'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-20 19:25:46 +02:00
										 |  |  | const { joinBy } = require('@strapi/utils'); | 
					
						
							| 
									
										
										
										
											2022-04-26 11:23:07 +02:00
										 |  |  | const { getService } = require('../utils'); | 
					
						
							| 
									
										
										
										
											2022-05-13 16:10:18 +02:00
										 |  |  | const { ACTIONS, FOLDER_MODEL_UID, FILE_MODEL_UID } = require('../constants'); | 
					
						
							| 
									
										
										
										
											2022-05-02 16:31:27 +02:00
										 |  |  | const { | 
					
						
							|  |  |  |   validateDeleteManyFoldersFiles, | 
					
						
							|  |  |  |   validateMoveManyFoldersFiles, | 
					
						
							|  |  |  | } = require('./validation/admin/folder-file'); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-26 11:23:07 +02:00
										 |  |  | module.exports = { | 
					
						
							|  |  |  |   async deleteMany(ctx) { | 
					
						
							|  |  |  |     const { body } = ctx.request; | 
					
						
							| 
									
										
										
										
											2022-05-02 16:31:27 +02:00
										 |  |  |     const { | 
					
						
							|  |  |  |       state: { userAbility }, | 
					
						
							|  |  |  |     } = ctx; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const pmFolder = strapi.admin.services.permission.createPermissionsManager({ | 
					
						
							|  |  |  |       ability: ctx.state.userAbility, | 
					
						
							| 
									
										
										
										
											2022-05-13 16:10:18 +02:00
										 |  |  |       model: FOLDER_MODEL_UID, | 
					
						
							| 
									
										
										
										
											2022-05-02 16:31:27 +02:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const pmFile = strapi.admin.services.permission.createPermissionsManager({ | 
					
						
							|  |  |  |       ability: userAbility, | 
					
						
							|  |  |  |       action: ACTIONS.read, | 
					
						
							| 
									
										
										
										
											2022-05-13 16:10:18 +02:00
										 |  |  |       model: FILE_MODEL_UID, | 
					
						
							| 
									
										
										
										
											2022-05-02 16:31:27 +02:00
										 |  |  |     }); | 
					
						
							| 
									
										
										
										
											2022-04-26 11:23:07 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     await validateDeleteManyFoldersFiles(body); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const fileService = getService('file'); | 
					
						
							|  |  |  |     const folderService = getService('folder'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const deletedFiles = await fileService.deleteByIds(body.fileIds); | 
					
						
							| 
									
										
										
										
											2022-07-07 21:20:53 +02:00
										 |  |  |     const { | 
					
						
							|  |  |  |       folders: deletedFolders, | 
					
						
							|  |  |  |       totalFolderNumber, | 
					
						
							|  |  |  |       totalFileNumber, | 
					
						
							|  |  |  |     } = await folderService.deleteByIds(body.folderIds); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (deletedFiles.length + deletedFolders.length > 1) { | 
					
						
							|  |  |  |       strapi.telemetry.send('didBulkDeleteMediaLibraryElements', { | 
					
						
							|  |  |  |         rootFolderNumber: deletedFolders.length, | 
					
						
							|  |  |  |         rootAssetNumber: deletedFiles.length, | 
					
						
							|  |  |  |         totalFolderNumber, | 
					
						
							|  |  |  |         totalAssetNumber: totalFileNumber + deletedFiles.length, | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-04-26 11:23:07 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     ctx.body = { | 
					
						
							|  |  |  |       data: { | 
					
						
							| 
									
										
										
										
											2022-05-02 16:31:27 +02:00
										 |  |  |         files: await pmFile.sanitizeOutput(deletedFiles), | 
					
						
							|  |  |  |         folders: await pmFolder.sanitizeOutput(deletedFolders), | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |   }, | 
					
						
							|  |  |  |   async moveMany(ctx) { | 
					
						
							|  |  |  |     const { body } = ctx.request; | 
					
						
							|  |  |  |     const { | 
					
						
							| 
									
										
										
										
											2022-05-20 19:25:46 +02:00
										 |  |  |       state: { userAbility }, | 
					
						
							| 
									
										
										
										
											2022-05-02 16:31:27 +02:00
										 |  |  |     } = ctx; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const pmFolder = strapi.admin.services.permission.createPermissionsManager({ | 
					
						
							|  |  |  |       ability: ctx.state.userAbility, | 
					
						
							| 
									
										
										
										
											2022-05-13 16:10:18 +02:00
										 |  |  |       model: FOLDER_MODEL_UID, | 
					
						
							| 
									
										
										
										
											2022-05-02 16:31:27 +02:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const pmFile = strapi.admin.services.permission.createPermissionsManager({ | 
					
						
							|  |  |  |       ability: userAbility, | 
					
						
							|  |  |  |       action: ACTIONS.read, | 
					
						
							| 
									
										
										
										
											2022-05-13 16:10:18 +02:00
										 |  |  |       model: FILE_MODEL_UID, | 
					
						
							| 
									
										
										
										
											2022-05-02 16:31:27 +02:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     await validateMoveManyFoldersFiles(body); | 
					
						
							|  |  |  |     const { folderIds = [], fileIds = [], destinationFolderId } = body; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-07 21:20:53 +02:00
										 |  |  |     let totalFolderNumber = 0; | 
					
						
							|  |  |  |     let totalFileNumber = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-20 19:25:46 +02:00
										 |  |  |     const trx = await strapi.db.transaction(); | 
					
						
							|  |  |  |     try { | 
					
						
							|  |  |  |       // fetch folders
 | 
					
						
							|  |  |  |       const existingFolders = await strapi.db | 
					
						
							|  |  |  |         .queryBuilder(FOLDER_MODEL_UID) | 
					
						
							| 
									
										
										
										
											2022-06-03 16:21:52 +02:00
										 |  |  |         .select(['id', 'pathId', 'path']) | 
					
						
							| 
									
										
										
										
											2022-05-20 19:25:46 +02:00
										 |  |  |         .where({ id: { $in: folderIds } }) | 
					
						
							|  |  |  |         .transacting(trx) | 
					
						
							|  |  |  |         .forUpdate() | 
					
						
							|  |  |  |         .execute(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       // fetch files
 | 
					
						
							|  |  |  |       const existingFiles = await strapi.db | 
					
						
							|  |  |  |         .queryBuilder(FILE_MODEL_UID) | 
					
						
							|  |  |  |         .select(['id']) | 
					
						
							|  |  |  |         .where({ id: { $in: fileIds } }) | 
					
						
							|  |  |  |         .transacting(trx) | 
					
						
							|  |  |  |         .forUpdate() | 
					
						
							|  |  |  |         .execute(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       // fetch destinationFolder path
 | 
					
						
							|  |  |  |       let destinationFolderPath = '/'; | 
					
						
							|  |  |  |       if (destinationFolderId !== null) { | 
					
						
							|  |  |  |         const destinationFolder = await strapi.db | 
					
						
							|  |  |  |           .queryBuilder(FOLDER_MODEL_UID) | 
					
						
							|  |  |  |           .select('path') | 
					
						
							|  |  |  |           .where({ id: destinationFolderId }) | 
					
						
							|  |  |  |           .transacting(trx) | 
					
						
							|  |  |  |           .first() | 
					
						
							|  |  |  |           .execute(); | 
					
						
							|  |  |  |         destinationFolderPath = destinationFolder.path; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       const fileTable = strapi.getModel(FILE_MODEL_UID).collectionName; | 
					
						
							|  |  |  |       const folderTable = strapi.getModel(FOLDER_MODEL_UID).collectionName; | 
					
						
							|  |  |  |       const folderPathColName = strapi.db.metadata.get(FILE_MODEL_UID).attributes.folderPath | 
					
						
							|  |  |  |         .columnName; | 
					
						
							|  |  |  |       const pathColName = strapi.db.metadata.get(FOLDER_MODEL_UID).attributes.path.columnName; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (existingFolders.length > 0) { | 
					
						
							| 
									
										
										
										
											2022-06-07 11:16:53 +02:00
										 |  |  |         // update folders' parent relation
 | 
					
						
							| 
									
										
										
										
											2022-05-20 19:25:46 +02:00
										 |  |  |         const joinTable = strapi.db.metadata.get(FOLDER_MODEL_UID).attributes.parent.joinTable; | 
					
						
							|  |  |  |         await strapi.db | 
					
						
							|  |  |  |           .queryBuilder(joinTable.name) | 
					
						
							|  |  |  |           .transacting(trx) | 
					
						
							|  |  |  |           .delete() | 
					
						
							|  |  |  |           .where({ [joinTable.joinColumn.name]: { $in: folderIds } }) | 
					
						
							|  |  |  |           .execute(); | 
					
						
							| 
									
										
										
										
											2022-06-07 11:16:53 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (destinationFolderId !== null) { | 
					
						
							|  |  |  |           await strapi.db | 
					
						
							|  |  |  |             .queryBuilder(joinTable.name) | 
					
						
							|  |  |  |             .transacting(trx) | 
					
						
							|  |  |  |             .insert( | 
					
						
							|  |  |  |               existingFolders.map(folder => ({ | 
					
						
							|  |  |  |                 [joinTable.inverseJoinColumn.name]: destinationFolderId, | 
					
						
							|  |  |  |                 [joinTable.joinColumn.name]: folder.id, | 
					
						
							|  |  |  |               })) | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |             .execute(); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-05-02 16:31:27 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-20 19:25:46 +02:00
										 |  |  |         for (const existingFolder of existingFolders) { | 
					
						
							| 
									
										
										
										
											2022-06-07 11:16:53 +02:00
										 |  |  |           let replaceQuery; | 
					
						
							|  |  |  |           switch (strapi.db.dialect.client) { | 
					
						
							|  |  |  |             case 'sqlite': | 
					
						
							|  |  |  |               replaceQuery = '? || SUBSTRING(??, ?)'; | 
					
						
							|  |  |  |               break; | 
					
						
							|  |  |  |             case 'postgres': | 
					
						
							|  |  |  |               replaceQuery = 'CONCAT(?::TEXT, SUBSTRING(??, ?::INTEGER))'; | 
					
						
							|  |  |  |               break; | 
					
						
							|  |  |  |             default: | 
					
						
							|  |  |  |               replaceQuery = 'CONCAT(?, SUBSTRING(??, ?))'; | 
					
						
							|  |  |  |           } | 
					
						
							| 
									
										
										
										
											2022-06-03 16:21:52 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-20 19:25:46 +02:00
										 |  |  |           // update path for folders themselves & folders below
 | 
					
						
							| 
									
										
										
										
											2022-07-07 21:20:53 +02:00
										 |  |  |           totalFolderNumber = await strapi.db | 
					
						
							| 
									
										
										
										
											2022-05-20 19:25:46 +02:00
										 |  |  |             .connection(folderTable) | 
					
						
							|  |  |  |             .transacting(trx) | 
					
						
							| 
									
										
										
										
											2022-06-07 11:16:53 +02:00
										 |  |  |             .where(pathColName, existingFolder.path) | 
					
						
							|  |  |  |             .orWhere(pathColName, 'like', `${existingFolder.path}/%`) | 
					
						
							| 
									
										
										
										
											2022-05-20 19:25:46 +02:00
										 |  |  |             .update( | 
					
						
							|  |  |  |               pathColName, | 
					
						
							| 
									
										
										
										
											2022-06-03 16:21:52 +02:00
										 |  |  |               strapi.db.connection.raw(replaceQuery, [ | 
					
						
							|  |  |  |                 joinBy('/', destinationFolderPath, existingFolder.pathId), | 
					
						
							| 
									
										
										
										
											2022-05-20 19:25:46 +02:00
										 |  |  |                 pathColName, | 
					
						
							| 
									
										
										
										
											2022-06-03 16:21:52 +02:00
										 |  |  |                 existingFolder.path.length + 1, | 
					
						
							| 
									
										
										
										
											2022-05-20 19:25:46 +02:00
										 |  |  |               ]) | 
					
						
							|  |  |  |             ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           // update path of files below
 | 
					
						
							| 
									
										
										
										
											2022-07-07 21:20:53 +02:00
										 |  |  |           totalFileNumber = await strapi.db | 
					
						
							| 
									
										
										
										
											2022-05-20 19:25:46 +02:00
										 |  |  |             .connection(fileTable) | 
					
						
							|  |  |  |             .transacting(trx) | 
					
						
							| 
									
										
										
										
											2022-06-07 11:16:53 +02:00
										 |  |  |             .where(folderPathColName, existingFolder.path) | 
					
						
							|  |  |  |             .orWhere(folderPathColName, 'like', `${existingFolder.path}/%`) | 
					
						
							| 
									
										
										
										
											2022-05-20 19:25:46 +02:00
										 |  |  |             .update( | 
					
						
							|  |  |  |               folderPathColName, | 
					
						
							| 
									
										
										
										
											2022-06-03 16:21:52 +02:00
										 |  |  |               strapi.db.connection.raw(replaceQuery, [ | 
					
						
							|  |  |  |                 joinBy('/', destinationFolderPath, existingFolder.pathId), | 
					
						
							| 
									
										
										
										
											2022-05-20 19:25:46 +02:00
										 |  |  |                 folderPathColName, | 
					
						
							| 
									
										
										
										
											2022-06-03 16:21:52 +02:00
										 |  |  |                 existingFolder.path.length + 1, | 
					
						
							| 
									
										
										
										
											2022-05-20 19:25:46 +02:00
										 |  |  |               ]) | 
					
						
							|  |  |  |             ); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (existingFiles.length > 0) { | 
					
						
							|  |  |  |         // update files' folder relation (delete + insert; upsert not possible)
 | 
					
						
							|  |  |  |         const fileJoinTable = strapi.db.metadata.get(FILE_MODEL_UID).attributes.folder.joinTable; | 
					
						
							|  |  |  |         await strapi.db | 
					
						
							|  |  |  |           .queryBuilder(fileJoinTable.name) | 
					
						
							|  |  |  |           .transacting(trx) | 
					
						
							|  |  |  |           .delete() | 
					
						
							|  |  |  |           .where({ [fileJoinTable.joinColumn.name]: { $in: fileIds } }) | 
					
						
							|  |  |  |           .execute(); | 
					
						
							| 
									
										
										
										
											2022-06-07 11:16:53 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (destinationFolderId !== null) { | 
					
						
							|  |  |  |           await strapi.db | 
					
						
							|  |  |  |             .queryBuilder(fileJoinTable.name) | 
					
						
							|  |  |  |             .transacting(trx) | 
					
						
							|  |  |  |             .insert( | 
					
						
							|  |  |  |               existingFiles.map(file => ({ | 
					
						
							|  |  |  |                 [fileJoinTable.inverseJoinColumn.name]: destinationFolderId, | 
					
						
							|  |  |  |                 [fileJoinTable.joinColumn.name]: file.id, | 
					
						
							|  |  |  |               })) | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |             .execute(); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-05-20 19:25:46 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         // update files main fields (path + updatedBy)
 | 
					
						
							|  |  |  |         await strapi.db | 
					
						
							|  |  |  |           .connection(fileTable) | 
					
						
							|  |  |  |           .transacting(trx) | 
					
						
							|  |  |  |           .whereIn('id', fileIds) | 
					
						
							|  |  |  |           .update(folderPathColName, destinationFolderPath); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       await trx.commit(); | 
					
						
							|  |  |  |     } catch (e) { | 
					
						
							|  |  |  |       await trx.rollback(); | 
					
						
							|  |  |  |       throw e; | 
					
						
							| 
									
										
										
										
											2022-05-02 16:31:27 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-20 19:25:46 +02:00
										 |  |  |     const updatedFolders = await strapi.entityService.findMany(FOLDER_MODEL_UID, { | 
					
						
							|  |  |  |       filters: { id: { $in: folderIds } }, | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |     const updatedFiles = await strapi.entityService.findMany(FILE_MODEL_UID, { | 
					
						
							|  |  |  |       filters: { id: { $in: fileIds } }, | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2022-05-02 16:31:27 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-07 21:20:53 +02:00
										 |  |  |     strapi.telemetry.send('didBulkMoveMediaLibraryElements', { | 
					
						
							|  |  |  |       rootFolderNumber: updatedFolders.length, | 
					
						
							|  |  |  |       rootAssetNumber: updatedFiles.length, | 
					
						
							|  |  |  |       totalFolderNumber, | 
					
						
							|  |  |  |       totalAssetNumber: totalFileNumber + updatedFiles.length, | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-02 16:31:27 +02:00
										 |  |  |     ctx.body = { | 
					
						
							|  |  |  |       data: { | 
					
						
							|  |  |  |         files: await pmFile.sanitizeOutput(updatedFiles), | 
					
						
							|  |  |  |         folders: await pmFolder.sanitizeOutput(updatedFolders), | 
					
						
							| 
									
										
										
										
											2022-04-26 11:23:07 +02:00
										 |  |  |       }, | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |   }, | 
					
						
							|  |  |  | }; |