Taichi Masuyama 4 лет назад
Родитель
Сommit
179e2bf637

+ 1 - 1
packages/app/src/server/models/page.ts

@@ -140,7 +140,7 @@ schema.statics.createEmptyPagesByPaths = async function(paths: string[], publicO
 };
 
 schema.statics.createEmptyPage = async function(
-    path: string, parent: any, // TODO: improve type including IPage
+    path: string, parent: any, // TODO: improve type including IPage at https://redmine.weseek.co.jp/issues/86506
 ): Promise<PageDocument & { _id: any }> {
   if (parent == null) {
     throw Error('parent must not be null');

+ 4 - 4
packages/app/src/server/routes/apiv3/pages.js

@@ -452,9 +452,9 @@ module.exports = (crowi) => {
    *          409:
    *            description: page path is already existed
    */
-  router.put('/rename', /* accessTokenParser, loginRequiredStrictly, csrf, */validator.renamePage, apiV3FormValidator, async(req, res) => {
-    const { pageId, isRecursively, revisionId } = req.body;
-    // v4 compatible validation
+  router.put('/rename', accessTokenParser, loginRequiredStrictly, csrf, validator.renamePage, apiV3FormValidator, async(req, res) => {
+    const { pageId, revisionId } = req.body;
+    // v4 compatible validation (reason: empty page does not require revisionId validation)
     const isV5Compatible = crowi.configManager.getConfig('crowi', 'app:isV5Compatible');
     if (!isV5Compatible && revisionId == null) {
       return res.apiv3Err(new ErrorV3('revisionId must be a mongoId', 'invalid_body'), 400);
@@ -492,7 +492,7 @@ module.exports = (crowi) => {
       if (!page.isEmpty && !page.isUpdatable(revisionId)) {
         return res.apiv3Err(new ErrorV3('Someone could update this page, so couldn\'t delete.', 'notfound_or_forbidden'), 409);
       }
-      page = await crowi.pageService.renamePage(page, newPagePath, req.user, options, isRecursively);
+      page = await crowi.pageService.renamePage(page, newPagePath, req.user, options);
     }
     catch (err) {
       logger.error(err);

+ 14 - 83
packages/app/src/server/service/page.ts

@@ -191,7 +191,7 @@ class PageService {
       .cursor({ batchSize: BULK_REINDEX_SIZE });
   }
 
-  // TODO: implement recursive rename
+  // TODO: rewrite recursive rename
   async renamePage(page, newPagePath, user, options) {
     // v4 compatible process
     const isV5Compatible = this.crowi.configManager.getConfig('crowi', 'app:isV5Compatible') && page.parent != null;
@@ -203,7 +203,6 @@ class PageService {
     const {
       path, grant, grantedUsers: grantedUserIds, grantedGroup: grantUserGroupId,
     } = page;
-    const createRedirectPage = options.createRedirectPage || false;
     const updateMetadata = options.updateMetadata || false;
 
     // sanitize path
@@ -232,19 +231,9 @@ class PageService {
     await this.renameDescendantsWithStream(page, newPagePath, user, options);
 
     /*
-     * replace target
+     * TODO: https://redmine.weseek.co.jp/issues/86577
+     * bulkWrite PageRedirectDocument if createRedirectPage is true
      */
-    const escapedPath = escapeStringRegexp(page.path);
-    const shouldReplaceTarget = createRedirectPage
-      || await Page.countDocuments({ path: { $regex: new RegExp(`^${escapedPath}(\\/[^/]+)\\/?$`, 'gi') }, parent: { $ne: null } }) > 0;
-    let pageToReplaceWith = null;
-    if (createRedirectPage) {
-      const body = `redirect ${newPagePath}`;
-      pageToReplaceWith = await Page.create(path, body, user, { redirectTo: newPagePath });
-    }
-    if (shouldReplaceTarget) {
-      await Page.replaceTargetWithPage(page, pageToReplaceWith);
-    }
 
     /*
      * update target
@@ -252,7 +241,6 @@ class PageService {
     const update: Partial<IPage> = {};
     // find or create parent
     const newParent = await Page.getParentAndFillAncestors(newPagePath);
-
     // update Page
     update.path = newPagePath;
     update.parent = newParent._id;
@@ -267,20 +255,19 @@ class PageService {
     return renamedPage;
   }
 
-  private async renamePageV4(page, newPagePath, user, options, isRecursively = false) {
+  // !!renaming always include descendant pages!!
+  private async renamePageV4(page, newPagePath, user, options) {
     const Page = this.crowi.model('Page');
     const Revision = this.crowi.model('Revision');
     const path = page.path;
-    const createRedirectPage = options.createRedirectPage || false;
     const updateMetadata = options.updateMetadata || false;
 
     // sanitize path
     newPagePath = this.crowi.xss.process(newPagePath); // eslint-disable-line no-param-reassign
 
     // create descendants first
-    if (isRecursively) {
-      await this.renameDescendantsWithStream(page, newPagePath, user, options);
-    }
+    await this.renameDescendantsWithStream(page, newPagePath, user, options);
+
 
     const update: any = {};
     // update Page
@@ -294,10 +281,10 @@ class PageService {
     // update Rivisions
     await Revision.updateRevisionListByPath(path, { path: newPagePath }, {});
 
-    if (createRedirectPage) {
-      const body = `redirect ${newPagePath}`;
-      await Page.create(path, body, user, { redirectTo: newPagePath });
-    }
+    /*
+     * TODO: https://redmine.weseek.co.jp/issues/86577
+     * bulkWrite PageRedirectDocument if createRedirectPage is true
+     */
 
     this.pageEvent.emit('rename', page, user);
 
@@ -305,20 +292,17 @@ class PageService {
   }
 
 
-  private async renameDescendants(pages, user, options, oldPagePathPrefix, newPagePathPrefix, isV5Compatible, grant?, grantedUsers?, grantedGroup?) {
+  private async renameDescendants(pages, user, options, oldPagePathPrefix, newPagePathPrefix, isV5Compatible) {
     // v4 compatible process
     if (!isV5Compatible) {
       return this.renameDescendantsV4(pages, user, options, oldPagePathPrefix, newPagePathPrefix);
     }
 
     const Page = this.crowi.model('Page');
-    const Revision = this.crowi.model('Revision');
 
-    const { updateMetadata, createRedirectPage } = options;
+    const { updateMetadata } = options;
 
     const updatePathOperations: any[] = [];
-    const insertRediectPageOperations: any[] = [];
-    const insertRediectRevisionOperations: any[] = [];
 
     pages.forEach((page) => {
       const newPagePath = page.path.replace(oldPagePathPrefix, newPagePathPrefix);
@@ -343,43 +327,10 @@ class PageService {
           update,
         },
       });
-
-      // create redirect page
-      if (createRedirectPage && !page.isEmpty) {
-        const revisionId = new mongoose.Types.ObjectId();
-        insertRediectPageOperations.push({
-          insertOne: {
-            document: {
-              path: page.path,
-              revision: revisionId,
-              creator: user._id,
-              lastUpdateUser: user._id,
-              status: Page.STATUS_PUBLISHED,
-              redirectTo: newPagePath,
-              grant,
-              grantedUsers,
-              grantedGroup,
-            },
-          },
-        });
-        insertRediectRevisionOperations.push({
-          insertOne: {
-            document: {
-              _id: revisionId, pageId: page._id, body: `redirected ${newPagePath}`, author: user._id, format: 'markdown',
-            },
-          },
-        });
-      }
     });
 
     try {
       await Page.bulkWrite(updatePathOperations);
-      // Execute after unorderedBulkOp to prevent duplication
-      if (createRedirectPage) {
-        await Page.bulkWrite(insertRediectPageOperations);
-        await Revision.bulkWrite(insertRediectRevisionOperations);
-        // fill ancestors(parents) of redirectPages
-      }
     }
     catch (err) {
       if (err.code !== 11000) {
@@ -394,17 +345,12 @@ class PageService {
     const Page = this.crowi.model('Page');
 
     const pageCollection = mongoose.connection.collection('pages');
-    const revisionCollection = mongoose.connection.collection('revisions');
-    const { updateMetadata, createRedirectPage } = options;
+    const { updateMetadata } = options;
 
     const unorderedBulkOp = pageCollection.initializeUnorderedBulkOp();
-    const createRediectPageBulkOp = pageCollection.initializeUnorderedBulkOp();
-    const revisionUnorderedBulkOp = revisionCollection.initializeUnorderedBulkOp();
-    const createRediectRevisionBulkOp = revisionCollection.initializeUnorderedBulkOp();
 
     pages.forEach((page) => {
       const newPagePath = page.path.replace(oldPagePathPrefix, newPagePathPrefix);
-      const revisionId = new mongoose.Types.ObjectId();
 
       if (updateMetadata) {
         unorderedBulkOp
@@ -414,25 +360,10 @@ class PageService {
       else {
         unorderedBulkOp.find({ _id: page._id }).update({ $set: { path: newPagePath } });
       }
-      if (createRedirectPage) {
-        createRediectPageBulkOp.insert({
-          path: page.path, revision: revisionId, creator: user._id, lastUpdateUser: user._id, status: Page.STATUS_PUBLISHED, redirectTo: newPagePath,
-        });
-        createRediectRevisionBulkOp.insert({
-          _id: revisionId, path: page.path, body: `redirect ${newPagePath}`, author: user._id, format: 'markdown',
-        });
-      }
-      revisionUnorderedBulkOp.find({ path: page.path }).update({ $set: { path: newPagePath } });
     });
 
     try {
       await unorderedBulkOp.execute();
-      await revisionUnorderedBulkOp.execute();
-      // Execute after unorderedBulkOp to prevent duplication
-      if (createRedirectPage) {
-        await createRediectPageBulkOp.execute();
-        await createRediectRevisionBulkOp.execute();
-      }
     }
     catch (err) {
       if (err.code !== 11000) {