Răsfoiți Sursa

Merge pull request #3281 from weseek/imprv/gw-4776

imprv/gw-4776
Yuki Takei 5 ani în urmă
părinte
comite
e98f93be54

+ 3 - 0
src/server/events/page.js

@@ -15,5 +15,8 @@ PageEvent.prototype.onCreate = function(page, user) {
 PageEvent.prototype.onUpdate = function(page, user) {
   debug('onUpdate event fired');
 };
+PageEvent.prototype.onCreateMany = function(pages, user) {
+  debug('onCreateMany event fired');
+};
 
 module.exports = PageEvent;

+ 17 - 3
src/server/models/page.js

@@ -293,6 +293,7 @@ module.exports = function(crowi) {
     pageEvent = crowi.event('page');
     pageEvent.on('create', pageEvent.onCreate);
     pageEvent.on('update', pageEvent.onUpdate);
+    pageEvent.on('createMany', pageEvent.onCreateMany);
   }
 
   function validateCrowi() {
@@ -1200,7 +1201,7 @@ module.exports = function(crowi) {
       await Page.create(path, body, user, { redirectTo: newPagePath });
     }
 
-    pageEvent.emit('delete', pageData, user, socketClientId);
+    pageEvent.emit('delete', [pageData], user, socketClientId);
     pageEvent.emit('create', updatedPageData, user, socketClientId);
 
     return updatedPageData;
@@ -1242,8 +1243,21 @@ module.exports = function(crowi) {
       revisionUnorderedBulkOp.find({ path: page.path }).update({ $set: { path: newPagePath } }, { multi: true });
     });
 
-    await unorderedBulkOp.execute();
-    await revisionUnorderedBulkOp.execute();
+    try {
+      await unorderedBulkOp.execute();
+      await revisionUnorderedBulkOp.execute();
+    }
+    catch (err) {
+      if (err.code !== 11000) {
+        throw new Error('Failed to rename pages: ', err);
+      }
+    }
+
+    const newParentPath = path.replace(pathRegExp, newPagePathPrefix);
+    const newParentPage = await this.findByPath(newParentPath);
+    const renamedPages = await this.findManageableListWithDescendants(newParentPage, user, options);
+
+    pageEvent.emit('createMany', renamedPages, user, newParentPage);
 
     // Execute after unorderedBulkOp to prevent duplication
     if (createRedirectPage) {

+ 31 - 0
src/server/service/search-delegator/elasticsearch.js

@@ -352,6 +352,14 @@ class ElasticsearchDelegator {
     return this.updateOrInsertPages(() => Page.findById(pageId));
   }
 
+  updateOrInsertDescendantsPagesById(page, user) {
+    const Page = mongoose.model('Page');
+    const { PageQueryBuilder } = Page;
+    const builder = new PageQueryBuilder(Page.find());
+    builder.addConditionToListWithDescendants(page.path);
+    return this.updateOrInsertPages(() => builder.query);
+  }
+
   /**
    * @param {function} queryFactory factory method to generate a Mongoose Query instance
    */
@@ -959,6 +967,29 @@ class ElasticsearchDelegator {
     return this.updateOrInsertPageById(page._id);
   }
 
+  async syncDescendantsPagesUpdated(pages, user, parentPage) {
+
+    const shoudDeletePages = [];
+    pages.forEach((page) => {
+      logger.debug('SearchClient.syncPageUpdated', page.path);
+      if (!this.shouldIndexed(page)) {
+        shoudDeletePages.append(page);
+      }
+    });
+
+    // delete if page should not indexed
+    try {
+      if (shoudDeletePages.length !== 0) {
+        await this.deletePages(shoudDeletePages);
+      }
+    }
+    catch (err) {
+      logger.error('deletePages:ES Error', err);
+    }
+
+    return this.updateOrInsertDescendantsPagesById(parentPage, user);
+  }
+
   async syncPagesDeletedCompletely(pages, user) {
     for (let i = 0; i < pages.length; i++) {
       logger.debug('SearchClient.syncPageDeleted', pages[i].path);

+ 1 - 0
src/server/service/search.js

@@ -60,6 +60,7 @@ class SearchService {
     pageEvent.on('update', this.delegator.syncPageUpdated.bind(this.delegator));
     pageEvent.on('deleteCompletely', this.delegator.syncPagesDeletedCompletely.bind(this.delegator));
     pageEvent.on('delete', this.delegator.syncPageDeleted.bind(this.delegator));
+    pageEvent.on('createMany', this.delegator.syncDescendantsPagesUpdated.bind(this.delegator));
 
     const bookmarkEvent = this.crowi.event('bookmark');
     bookmarkEvent.on('create', this.delegator.syncBookmarkChanged.bind(this.delegator));