bookmark.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. module.exports = function(crowi) {
  2. var debug = require('debug')('growi:models:bookmark')
  3. , mongoose = require('mongoose')
  4. , ObjectId = mongoose.Schema.Types.ObjectId
  5. , bookmarkSchema;
  6. bookmarkSchema = new mongoose.Schema({
  7. page: { type: ObjectId, ref: 'Page', index: true },
  8. user: { type: ObjectId, ref: 'User', index: true },
  9. createdAt: { type: Date, default: Date.now() }
  10. });
  11. bookmarkSchema.index({page: 1, user: 1}, {unique: true});
  12. bookmarkSchema.statics.populatePage = function(bookmarks, requestUser) {
  13. var Bookmark = this;
  14. var User = crowi.model('User');
  15. var Page = crowi.model('Page');
  16. requestUser = requestUser || null;
  17. // mongoose promise に置き換えてみたものの、こいつは not native promise but original promise だったので
  18. // これ以上は置き換えないことにする ...
  19. // @see http://eddywashere.com/blog/switching-out-callbacks-with-promises-in-mongoose/
  20. return Bookmark.populate(bookmarks, {path: 'page'})
  21. .then(function(bookmarks) {
  22. return Bookmark.populate(bookmarks, {path: 'page.revision', model: 'Revision'});
  23. }).then(function(bookmarks) {
  24. // hmm...
  25. bookmarks = bookmarks.filter(function(bookmark) {
  26. // requestUser を指定しない場合 public のみを返す
  27. if (requestUser === null) {
  28. return bookmark.page.isPublic();
  29. }
  30. return bookmark.page.isGrantedFor(requestUser);
  31. });
  32. return Bookmark.populate(bookmarks, {path: 'page.revision.author', model: 'User', select: User.USER_PUBLIC_FIELDS});
  33. });
  34. };
  35. // bookmark チェック用
  36. bookmarkSchema.statics.findByPageIdAndUserId = function(pageId, userId) {
  37. var Bookmark = this;
  38. return new Promise(function(resolve, reject) {
  39. return Bookmark.findOne({ page: pageId, user: userId }, function(err, doc) {
  40. if (err) {
  41. return reject(err);
  42. }
  43. return resolve(doc);
  44. });
  45. });
  46. };
  47. /**
  48. * option = {
  49. * limit: Int
  50. * offset: Int
  51. * requestUser: User
  52. * }
  53. */
  54. bookmarkSchema.statics.findByUser = function(user, option) {
  55. var User = crowi.model('User');
  56. var Bookmark = this;
  57. var requestUser = option.requestUser || null;
  58. debug('Finding bookmark with requesting user:', requestUser);
  59. var limit = option.limit || 50;
  60. var offset = option.offset || 0;
  61. var populatePage = option.populatePage || false;
  62. return new Promise(function(resolve, reject) {
  63. Bookmark
  64. .find({ user: user._id })
  65. .sort({createdAt: -1})
  66. .skip(offset)
  67. .limit(limit)
  68. .exec(function(err, bookmarks) {
  69. if (err) {
  70. return reject(err);
  71. }
  72. if (!populatePage) {
  73. return resolve(bookmarks);
  74. }
  75. return Bookmark.populatePage(bookmarks, requestUser).then(resolve);
  76. });
  77. });
  78. };
  79. bookmarkSchema.statics.add = function(page, user) {
  80. var Bookmark = this;
  81. return new Promise(function(resolve, reject) {
  82. var newBookmark = new Bookmark;
  83. newBookmark.page = page;
  84. newBookmark.user = user;
  85. newBookmark.createdAt = Date.now();
  86. newBookmark.save(function(err, bookmark) {
  87. debug('Bookmark.save', err, bookmark);
  88. if (err) {
  89. if (err.code === 11000) { // duplicate key (dummy reesponse of new object)
  90. return resolve(newBookmark);
  91. }
  92. return reject(err);
  93. }
  94. resolve(bookmark);
  95. });
  96. });
  97. };
  98. bookmarkSchema.statics.removeBookmarksByPageId = function(pageId) {
  99. var Bookmark = this;
  100. return new Promise(function(resolve, reject) {
  101. Bookmark.remove({page: pageId}, function(err, data) {
  102. if (err) {
  103. debug('Bookmark.remove failed (removeBookmarkByPage)', err);
  104. return reject(err);
  105. }
  106. return resolve(data);
  107. });
  108. });
  109. };
  110. bookmarkSchema.statics.removeBookmark = function(page, user) {
  111. var Bookmark = this;
  112. return new Promise(function(resolve, reject) {
  113. Bookmark.findOneAndRemove({page: page, user: user}, function(err, data) {
  114. if (err) {
  115. debug('Bookmark.findOneAndRemove failed', err);
  116. return reject(err);
  117. }
  118. return resolve(data);
  119. });
  120. });
  121. };
  122. return mongoose.model('Bookmark', bookmarkSchema);
  123. };