comment.js 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. // disable no-return-await for model functions
  2. /* eslint-disable no-return-await */
  3. module.exports = function(crowi) {
  4. const debug = require('debug')('growi:models:comment');
  5. const mongoose = require('mongoose');
  6. const ObjectId = mongoose.Schema.Types.ObjectId;
  7. const commentSchema = new mongoose.Schema({
  8. page: { type: ObjectId, ref: 'Page', index: true },
  9. creator: { type: ObjectId, ref: 'User', index: true },
  10. revision: { type: ObjectId, ref: 'Revision', index: true },
  11. comment: { type: String, required: true },
  12. commentPosition: { type: Number, default: -1 },
  13. isMarkdown: { type: Boolean, default: false },
  14. replyTo: { type: ObjectId },
  15. }, {
  16. timestamps: true,
  17. });
  18. commentSchema.statics.create = function(pageId, creatorId, revisionId, comment, position, isMarkdown, replyTo) {
  19. const Comment = this;
  20. return new Promise(((resolve, reject) => {
  21. const newComment = new Comment();
  22. newComment.page = pageId;
  23. newComment.creator = creatorId;
  24. newComment.revision = revisionId;
  25. newComment.comment = comment;
  26. newComment.commentPosition = position;
  27. newComment.isMarkdown = isMarkdown || false;
  28. newComment.replyTo = replyTo;
  29. newComment.save((err, data) => {
  30. if (err) {
  31. debug('Error on saving comment.', err);
  32. return reject(err);
  33. }
  34. debug('Comment saved.', data);
  35. return resolve(data);
  36. });
  37. }));
  38. };
  39. commentSchema.statics.getCommentsByPageId = function(id) {
  40. return this.find({ page: id }).sort({ createdAt: -1 });
  41. };
  42. commentSchema.statics.getCommentsByRevisionId = function(id) {
  43. return this.find({ revision: id }).sort({ createdAt: -1 });
  44. };
  45. /**
  46. * @return {object} key: page._id, value: comments
  47. */
  48. commentSchema.statics.getPageIdToCommentMap = async function(pageIds) {
  49. const results = await this.aggregate()
  50. .match({ page: { $in: pageIds } })
  51. .group({ _id: '$page', comments: { $push: '$comment' } });
  52. // convert to map
  53. const idToCommentMap = {};
  54. results.forEach((result, i) => {
  55. idToCommentMap[result._id] = result.comments;
  56. });
  57. return idToCommentMap;
  58. };
  59. commentSchema.statics.countCommentByPageId = function(page) {
  60. const self = this;
  61. return new Promise(((resolve, reject) => {
  62. self.count({ page }, (err, data) => {
  63. if (err) {
  64. return reject(err);
  65. }
  66. return resolve(data);
  67. });
  68. }));
  69. };
  70. commentSchema.statics.removeCommentsByPageId = function(pageId) {
  71. const Comment = this;
  72. return new Promise(((resolve, reject) => {
  73. Comment.remove({ page: pageId }, (err, done) => {
  74. if (err) {
  75. return reject(err);
  76. }
  77. resolve(done);
  78. });
  79. }));
  80. };
  81. commentSchema.methods.removeWithReplies = async function() {
  82. const Comment = crowi.model('Comment');
  83. return Comment.remove({
  84. $or: (
  85. [{ replyTo: this._id }, { _id: this._id }]),
  86. });
  87. };
  88. /**
  89. * post save hook
  90. */
  91. commentSchema.post('save', (savedComment) => {
  92. const Page = crowi.model('Page');
  93. Page.updateCommentCount(savedComment.page)
  94. .then((page) => {
  95. debug('CommentCount Updated', page);
  96. })
  97. .catch(() => {
  98. });
  99. });
  100. return mongoose.model('Comment', commentSchema);
  101. };