|
|
@@ -9,24 +9,12 @@ module.exports = function(crowi) {
|
|
|
, PAGE_GRANT_ERROR = 1
|
|
|
, pageSchema;
|
|
|
|
|
|
- function populatePageData(pageData, revisionId, callback) {
|
|
|
- var Page = crowi.model('Page');
|
|
|
-
|
|
|
- pageData.latestRevision = pageData.revision;
|
|
|
- if (revisionId) {
|
|
|
- pageData.revision = revisionId;
|
|
|
+ function isPortalPath(path) {
|
|
|
+ if (path.match(/.*\/$/)) {
|
|
|
+ return true;
|
|
|
}
|
|
|
- pageData.likerCount = pageData.liker.length || 0;
|
|
|
- pageData.seenUsersCount = pageData.seenUsers.length || 0;
|
|
|
|
|
|
- pageData.populate([
|
|
|
- {path: 'creator', model: 'User'},
|
|
|
- {path: 'revision', model: 'Revision'},
|
|
|
- {path: 'liker', options: { limit: 11 }},
|
|
|
- {path: 'seenUsers', options: { limit: 11 }},
|
|
|
- ], function (err, pageData) {
|
|
|
- Page.populate(pageData, {path: 'revision.author', model: 'User'}, callback);
|
|
|
- });
|
|
|
+ return false;
|
|
|
}
|
|
|
|
|
|
pageSchema = new mongoose.Schema({
|
|
|
@@ -38,6 +26,7 @@ module.exports = function(crowi) {
|
|
|
creator: { type: ObjectId, ref: 'User', index: true },
|
|
|
liker: [{ type: ObjectId, ref: 'User', index: true }],
|
|
|
seenUsers: [{ type: ObjectId, ref: 'User', index: true }],
|
|
|
+ commentCount: { type: Number, default: 0 },
|
|
|
createdAt: { type: Date, default: Date.now },
|
|
|
updatedAt: Date
|
|
|
});
|
|
|
@@ -50,6 +39,10 @@ module.exports = function(crowi) {
|
|
|
return false;
|
|
|
};
|
|
|
|
|
|
+ pageSchema.methods.isPortal = function() {
|
|
|
+ return isPortalPath(this.path);
|
|
|
+ };
|
|
|
+
|
|
|
pageSchema.methods.isCreator = function(userData) {
|
|
|
if (this.populated('creator') && this.creator._id.toString() === userData._id.toString()) {
|
|
|
return true;
|
|
|
@@ -90,48 +83,53 @@ module.exports = function(crowi) {
|
|
|
};
|
|
|
|
|
|
pageSchema.methods.isLiked = function(userData) {
|
|
|
- if (undefined === this.populated('liker')) {
|
|
|
- if (this.liker.indexOf(userData._id.toString()) != -1) {
|
|
|
- return true;
|
|
|
- }
|
|
|
- return true;
|
|
|
- } else {
|
|
|
- return this.liker.some(function(likedUser) {
|
|
|
- return likedUser._id.equals(userData._id);
|
|
|
- });
|
|
|
- }
|
|
|
+ return this.liker.some(function(likedUser) {
|
|
|
+ return likedUser == userData._id.toString();
|
|
|
+ });
|
|
|
};
|
|
|
|
|
|
- pageSchema.methods.like = function(userData, callback) {
|
|
|
+ pageSchema.methods.like = function(userData) {
|
|
|
var self = this,
|
|
|
Page = self;
|
|
|
|
|
|
- var added = this.liker.addToSet(userData._id);
|
|
|
- if (added.length > 0) {
|
|
|
- this.save(function(err, data) {
|
|
|
- debug('liker updated!', added);
|
|
|
- return callback(err, data);
|
|
|
- });
|
|
|
- } else {
|
|
|
- debug('liker not updated');
|
|
|
- return callback(null, this);
|
|
|
- }
|
|
|
+ return new Promise(function(resolve, reject) {
|
|
|
+ var added = self.liker.addToSet(userData._id);
|
|
|
+ if (added.length > 0) {
|
|
|
+ self.save(function(err, data) {
|
|
|
+ if (err) {
|
|
|
+ return reject(err);
|
|
|
+ }
|
|
|
+ debug('liker updated!', added);
|
|
|
+ return resolve(data);
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ debug('liker not updated');
|
|
|
+ return reject(self);
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
};
|
|
|
|
|
|
pageSchema.methods.unlike = function(userData, callback) {
|
|
|
var self = this,
|
|
|
Page = self;
|
|
|
|
|
|
- var removed = this.liker.pull(userData._id);
|
|
|
- if (removed.length > 0) {
|
|
|
- this.save(function(err, data) {
|
|
|
- debug('unlike updated!', removed);
|
|
|
- return callback(err, data);
|
|
|
- });
|
|
|
- } else {
|
|
|
- debug('unlike not updated');
|
|
|
- callback(null, this);
|
|
|
- }
|
|
|
+ return new Promise(function(resolve, reject) {
|
|
|
+ var beforeCount = self.liker.length;
|
|
|
+ self.liker.pull(userData._id);
|
|
|
+ if (self.liker.length != beforeCount) {
|
|
|
+ self.save(function(err, data) {
|
|
|
+ if (err) {
|
|
|
+ return reject(err);
|
|
|
+ }
|
|
|
+ return resolve(data);
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ debug('liker not updated');
|
|
|
+ return reject(self);
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
};
|
|
|
|
|
|
pageSchema.methods.isSeenUser = function(userData) {
|
|
|
@@ -139,27 +137,119 @@ module.exports = function(crowi) {
|
|
|
Page = self;
|
|
|
|
|
|
return this.seenUsers.some(function(seenUser) {
|
|
|
- return seenUser._id.equals(userData._id);
|
|
|
+ return seenUser.equals(userData._id);
|
|
|
});
|
|
|
};
|
|
|
|
|
|
- pageSchema.methods.seen = function(userData, callback) {
|
|
|
+ pageSchema.methods.seen = function(userData) {
|
|
|
var self = this,
|
|
|
Page = self;
|
|
|
|
|
|
- if (!userData || !userData._id) {
|
|
|
- callback(new Error('User data is not valid'), null);
|
|
|
- }
|
|
|
-
|
|
|
if (this.isSeenUser(userData)) {
|
|
|
debug('seenUsers not updated');
|
|
|
- return callback(null, self);
|
|
|
+ return Promise.resolve(this);
|
|
|
}
|
|
|
|
|
|
- var added = self.seenUsers.addToSet(userData);
|
|
|
- this.save(function(err, data) {
|
|
|
- debug('seenUsers updated!', added);
|
|
|
- return callback(err, self);
|
|
|
+ return new Promise(function(resolve, reject) {
|
|
|
+ if (!userData || !userData._id) {
|
|
|
+ reject(new Error('User data is not valid'));
|
|
|
+ }
|
|
|
+
|
|
|
+ var added = self.seenUsers.addToSet(userData);
|
|
|
+ self.save(function(err, data) {
|
|
|
+ if (err) {
|
|
|
+ return reject(err);
|
|
|
+ }
|
|
|
+
|
|
|
+ debug('seenUsers updated!', added);
|
|
|
+ return resolve(self);
|
|
|
+ });
|
|
|
+ });
|
|
|
+ };
|
|
|
+
|
|
|
+ pageSchema.statics.populatePageData = function(pageData, revisionId) {
|
|
|
+ var Page = crowi.model('Page');
|
|
|
+ var User = crowi.model('User');
|
|
|
+
|
|
|
+ pageData.latestRevision = pageData.revision;
|
|
|
+ if (revisionId) {
|
|
|
+ pageData.revision = revisionId;
|
|
|
+ }
|
|
|
+ pageData.likerCount = pageData.liker.length || 0;
|
|
|
+ pageData.seenUsersCount = pageData.seenUsers.length || 0;
|
|
|
+
|
|
|
+ return new Promise(function(resolve, reject) {
|
|
|
+ pageData.populate([
|
|
|
+ {path: 'creator', model: 'User', select: User.USER_PUBLIC_FIELDS},
|
|
|
+ {path: 'revision', model: 'Revision'},
|
|
|
+ //{path: 'liker', options: { limit: 11 }},
|
|
|
+ //{path: 'seenUsers', options: { limit: 11 }},
|
|
|
+ ], function (err, pageData) {
|
|
|
+ Page.populate(pageData, {path: 'revision.author', model: 'User', select: User.USER_PUBLIC_FIELDS}, function(err, data) {
|
|
|
+ if (err) {
|
|
|
+ return reject(err);
|
|
|
+ }
|
|
|
+
|
|
|
+ return resolve(data);
|
|
|
+ });
|
|
|
+ });
|
|
|
+ });
|
|
|
+ };
|
|
|
+
|
|
|
+ pageSchema.statics.populatePageList = function(pageList) {
|
|
|
+ var Page = self;
|
|
|
+ var User = crowi.model('User');
|
|
|
+
|
|
|
+ return new Promise(function(resolve, reject) {
|
|
|
+ Page.populate(
|
|
|
+ pageList,
|
|
|
+ [
|
|
|
+ {path: 'creator', model: 'User', select: User.USER_PUBLIC_FIELDS},
|
|
|
+ {path: 'revision', model: 'Revision'}
|
|
|
+ ],
|
|
|
+ function(err, pageList) {
|
|
|
+ if (err) {
|
|
|
+ return reject(err);
|
|
|
+ }
|
|
|
+
|
|
|
+ Page.populate(pageList, {path: 'revision.author', model: 'User', select: User.USER_PUBLIC_FIELDS}, function(err, data) {
|
|
|
+ if (err) {
|
|
|
+ return reject(err);
|
|
|
+ }
|
|
|
+
|
|
|
+ resolve(data);
|
|
|
+ });
|
|
|
+ }
|
|
|
+ );
|
|
|
+ });
|
|
|
+ };
|
|
|
+
|
|
|
+
|
|
|
+ pageSchema.statics.updateCommentCount = function (page, num)
|
|
|
+ {
|
|
|
+ var self = this;
|
|
|
+
|
|
|
+ return new Promise(function(resolve, reject) {
|
|
|
+ self.update({_id: page}, {commentCount: num}, {}, function(err, data) {
|
|
|
+ if (err) {
|
|
|
+ debug('Update commentCount Error', err);
|
|
|
+ return reject(err);
|
|
|
+ }
|
|
|
+
|
|
|
+ return resolve(data);
|
|
|
+ });
|
|
|
+ });
|
|
|
+ };
|
|
|
+
|
|
|
+ pageSchema.statics.hasPortalPage = function (path, user) {
|
|
|
+ var self = this;
|
|
|
+ return new Promise(function(resolve, reject) {
|
|
|
+ self.findPage(path, user)
|
|
|
+ .then(function(page) {
|
|
|
+ resolve(page);
|
|
|
+ }).catch(function(err) {
|
|
|
+ resolve(null); // check only has portal page, through error
|
|
|
+ });
|
|
|
});
|
|
|
};
|
|
|
|
|
|
@@ -181,14 +271,20 @@ module.exports = function(crowi) {
|
|
|
return path;
|
|
|
};
|
|
|
|
|
|
+ pageSchema.statics.getUserPagePath = function(user) {
|
|
|
+ return '/user/' + user.username;
|
|
|
+ };
|
|
|
+
|
|
|
pageSchema.statics.isCreatableName = function(name) {
|
|
|
var forbiddenPages = [
|
|
|
/\^|\$|\*|\+|\#/,
|
|
|
/^\/_api\/.*/,
|
|
|
/^\/\-\/.*/,
|
|
|
/^\/_r\/.*/,
|
|
|
+ /^\/user\/[^\/]+\/(bookmarks|comments|activities|pages|recent-create|recent-edit)/, // reserved
|
|
|
+ /^http:\/\/.+$/, // avoid miss in renaming
|
|
|
/.+\/edit$/,
|
|
|
- /\/$/,
|
|
|
+ /.+\.md$/,
|
|
|
/^\/(installer|register|login|logout|admin|me|files|trash|paste|comments).+/,
|
|
|
];
|
|
|
|
|
|
@@ -213,7 +309,7 @@ module.exports = function(crowi) {
|
|
|
pageSchema.statics.findUpdatedList = function(offset, limit, cb) {
|
|
|
this
|
|
|
.find({})
|
|
|
- .sort('updatedAt', -1)
|
|
|
+ .sort({updatedAt: -1})
|
|
|
.skip(offset)
|
|
|
.limit(limit)
|
|
|
.exec(function(err, data) {
|
|
|
@@ -221,70 +317,145 @@ module.exports = function(crowi) {
|
|
|
});
|
|
|
};
|
|
|
|
|
|
- pageSchema.statics.findPageById = function(id, cb) {
|
|
|
+ pageSchema.statics.findPageById = function(id) {
|
|
|
var Page = this;
|
|
|
|
|
|
- Page.findOne({_id: id}, function(err, pageData) {
|
|
|
- if (pageData === null) {
|
|
|
- return cb(new Error('Page Not Found'), null);
|
|
|
- }
|
|
|
+ return new Promise(function(resolve, reject) {
|
|
|
+ Page.findOne({_id: id}, function(err, pageData) {
|
|
|
+ if (err) {
|
|
|
+ return reject(err);
|
|
|
+ }
|
|
|
|
|
|
- return populatePageData(pageData, null, cb);
|
|
|
+ if (pageData == null) {
|
|
|
+ return reject(new Error('Page not found'));
|
|
|
+ }
|
|
|
+ return Page.populatePageData(pageData, null).then(resolve);
|
|
|
+ });
|
|
|
});
|
|
|
};
|
|
|
|
|
|
- pageSchema.statics.findListByPageIds = function(ids) {
|
|
|
+ pageSchema.statics.findPageByIdAndGrantedUser = function(id, userData) {
|
|
|
var Page = this;
|
|
|
|
|
|
- debug('findPageByIds', ids);
|
|
|
-
|
|
|
return new Promise(function(resolve, reject) {
|
|
|
- Page.find({
|
|
|
- _id: {$in: ids},
|
|
|
- }).populate([
|
|
|
- {path: 'creator', model: 'User'},
|
|
|
- {path: 'revision', model: 'Revision'},
|
|
|
- ]).exec(function(err, docs) {
|
|
|
- debug('findPagesByIds', err, docs);
|
|
|
+ Page.findPageById(id)
|
|
|
+ .then(function(pageData) {
|
|
|
+ if (userData && !pageData.isGrantedFor(userData)) {
|
|
|
+ return reject(new Error('Page is not granted for the user')); //PAGE_GRANT_ERROR, null);
|
|
|
+ }
|
|
|
|
|
|
+ return resolve(pageData);
|
|
|
+ }).catch(function(err) {
|
|
|
+ return reject(err);
|
|
|
+ });
|
|
|
+ });
|
|
|
+ };
|
|
|
+
|
|
|
+ // find page and check if granted user
|
|
|
+ pageSchema.statics.findPage = function(path, userData, revisionId, ignoreNotFound) {
|
|
|
+ var self = this;
|
|
|
+
|
|
|
+ return new Promise(function(resolve, reject) {
|
|
|
+ self.findOne({path: path}, function(err, pageData) {
|
|
|
if (err) {
|
|
|
return reject(err);
|
|
|
}
|
|
|
|
|
|
- return resolve(docs);
|
|
|
+ if (pageData === null) {
|
|
|
+ if (ignoreNotFound) {
|
|
|
+ return resolve(null);
|
|
|
+ }
|
|
|
+
|
|
|
+ var pageNotFoundError = new Error('Page Not Found')
|
|
|
+ pageNotFoundError.name = 'Crowi:Page:NotFound';
|
|
|
+ return reject(pageNotFoundError);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!pageData.isGrantedFor(userData)) {
|
|
|
+ return reject(new Error('Page is not granted for the user')); //PAGE_GRANT_ERROR, null);
|
|
|
+ }
|
|
|
+
|
|
|
+ self.populatePageData(pageData, revisionId || null).then(resolve).catch(reject);
|
|
|
});
|
|
|
});
|
|
|
};
|
|
|
|
|
|
- pageSchema.statics.findPageByIdAndGrantedUser = function(id, userData, cb) {
|
|
|
+ // find page by path
|
|
|
+ pageSchema.statics.findPageByPath = function(path) {
|
|
|
var Page = this;
|
|
|
|
|
|
- Page.findPageById(id, function(err, pageData) {
|
|
|
- if (pageData === null) {
|
|
|
- return cb(new Error('Page Not Found'), null);
|
|
|
- }
|
|
|
+ return new Promise(function(resolve, reject) {
|
|
|
+ Page.findOne({path: path}, function(err, pageData) {
|
|
|
+ if (err || pageData === null) {
|
|
|
+ return reject(err);
|
|
|
+ }
|
|
|
|
|
|
- if (userData && !pageData.isGrantedFor(userData)) {
|
|
|
- return cb(PAGE_GRANT_ERROR, null);
|
|
|
- }
|
|
|
+ return resolve(pageData);
|
|
|
+ });
|
|
|
+ });
|
|
|
+ };
|
|
|
+
|
|
|
+ pageSchema.statics.findListByPageIds = function(ids, option) {
|
|
|
+ var Page = this;
|
|
|
+ var User = crowi.model('User');
|
|
|
+ var limit = option.limit || 50;
|
|
|
+ var offset = option.skip || 0;
|
|
|
+
|
|
|
+ return new Promise(function(resolve, reject) {
|
|
|
+ Page
|
|
|
+ .find({ _id: { $in: ids }, grant: GRANT_PUBLIC })
|
|
|
+ //.sort({createdAt: -1}) // TODO optionize
|
|
|
+ .skip(offset)
|
|
|
+ .limit(limit)
|
|
|
+ .populate([
|
|
|
+ {path: 'creator', model: 'User'},
|
|
|
+ {path: 'revision', model: 'Revision'},
|
|
|
+ ])
|
|
|
+ .exec(function(err, pages) {
|
|
|
+ if (err) {
|
|
|
+ return reject(err);
|
|
|
+ }
|
|
|
|
|
|
- return cb(null,pageData);
|
|
|
+ Page.populate(pages, {path: 'revision.author', model: 'User', select: User.USER_PUBLIC_FIELDS}, function(err, data) {
|
|
|
+ if (err) {
|
|
|
+ return reject(err);
|
|
|
+ }
|
|
|
+
|
|
|
+ return resolve(data);
|
|
|
+ });
|
|
|
+ });
|
|
|
});
|
|
|
};
|
|
|
|
|
|
- pageSchema.statics.findPage = function(path, userData, revisionId, options, cb) {
|
|
|
+ /**
|
|
|
+ * とりあえず、公開ページであり、redirectTo が無いものだけを出すためだけのAPI
|
|
|
+ */
|
|
|
+ pageSchema.statics.findListByCreator = function(user, option) {
|
|
|
var Page = this;
|
|
|
+ var User = crowi.model('User');
|
|
|
+ var limit = option.limit || 50;
|
|
|
+ var offset = option.offset || 0;
|
|
|
|
|
|
- this.findOne({path: path}, function(err, pageData) {
|
|
|
- if (pageData === null) {
|
|
|
- return cb(new Error('Page Not Found'), null);
|
|
|
- }
|
|
|
+ return new Promise(function(resolve, reject) {
|
|
|
+ Page
|
|
|
+ .find({ creator: user._id, grant: GRANT_PUBLIC, redirectTo: null })
|
|
|
+ .sort({createdAt: -1})
|
|
|
+ .skip(offset)
|
|
|
+ .limit(limit)
|
|
|
+ .populate('revision')
|
|
|
+ .exec(function(err, pages) {
|
|
|
+ if (err) {
|
|
|
+ return reject(err);
|
|
|
+ }
|
|
|
|
|
|
- if (!pageData.isGrantedFor(userData)) {
|
|
|
- return cb(PAGE_GRANT_ERROR, null);
|
|
|
- }
|
|
|
+ Page.populate(pages, {path: 'revision.author', model: 'User', select: User.USER_PUBLIC_FIELDS}, function(err, data) {
|
|
|
+ if (err) {
|
|
|
+ return reject(err);
|
|
|
+ }
|
|
|
|
|
|
- return populatePageData(pageData, revisionId, cb);
|
|
|
+ return resolve(data);
|
|
|
+ });
|
|
|
+ });
|
|
|
});
|
|
|
};
|
|
|
|
|
|
@@ -311,158 +482,217 @@ module.exports = function(crowi) {
|
|
|
.stream();
|
|
|
};
|
|
|
|
|
|
- pageSchema.statics.findListByStartWith = function(path, userData, options, cb) {
|
|
|
- if (!options) {
|
|
|
- options = {sort: 'updatedAt', desc: -1, offset: 0, limit: 50};
|
|
|
+ /**
|
|
|
+ * findListByStartWith
|
|
|
+ *
|
|
|
+ * If `path` has `/` at the end, returns '{path}/*' and '{path}' self.
|
|
|
+ * If `path` doesn't have `/` at the end, returns '{path}*'
|
|
|
+ * e.g.
|
|
|
+ */
|
|
|
+ pageSchema.statics.findListByStartWith = function(path, userData, option) {
|
|
|
+ var Page = this;
|
|
|
+ var User = crowi.model('User');
|
|
|
+ var pathCondition = [];
|
|
|
+
|
|
|
+ if (!option) {
|
|
|
+ option = {sort: 'updatedAt', desc: -1, offset: 0, limit: 50};
|
|
|
}
|
|
|
var opt = {
|
|
|
- sort: options.sort || 'updatedAt',
|
|
|
- desc: options.desc || -1,
|
|
|
- offset: options.offset || 0,
|
|
|
- limit: options.limit || 50
|
|
|
+ sort: option.sort || 'updatedAt',
|
|
|
+ desc: option.desc || -1,
|
|
|
+ offset: option.offset || 0,
|
|
|
+ limit: option.limit || 50
|
|
|
};
|
|
|
var sortOpt = {};
|
|
|
sortOpt[opt.sort] = opt.desc;
|
|
|
var queryReg = new RegExp('^' + path);
|
|
|
- var sliceOption = options.revisionSlice || {$slice: 1};
|
|
|
-
|
|
|
- var q = this.find({
|
|
|
- path: queryReg,
|
|
|
- redirectTo: null,
|
|
|
- $or: [
|
|
|
- {grant: null},
|
|
|
- {grant: GRANT_PUBLIC},
|
|
|
- {grant: GRANT_RESTRICTED, grantedUsers: userData._id},
|
|
|
- {grant: GRANT_SPECIFIED, grantedUsers: userData._id},
|
|
|
- {grant: GRANT_OWNER, grantedUsers: userData._id},
|
|
|
- ],
|
|
|
- })
|
|
|
- .populate('revision')
|
|
|
- .sort(sortOpt)
|
|
|
- .skip(opt.offset)
|
|
|
- .limit(opt.limit);
|
|
|
+ var sliceOption = option.revisionSlice || {$slice: 1};
|
|
|
|
|
|
- q.exec(function(err, data) {
|
|
|
- cb(err, data);
|
|
|
+ pathCondition.push({path: queryReg});
|
|
|
+ if (path.match(/\/$/)) {
|
|
|
+ debug('Page list by ending with /, so find also upper level page');
|
|
|
+ pathCondition.push({path: path.substr(0, path.length -1)});
|
|
|
+ }
|
|
|
+
|
|
|
+ return new Promise(function(resolve, reject) {
|
|
|
+ // FIXME: might be heavy
|
|
|
+ var q = Page.find({
|
|
|
+ redirectTo: null,
|
|
|
+ $or: [
|
|
|
+ {grant: null},
|
|
|
+ {grant: GRANT_PUBLIC},
|
|
|
+ {grant: GRANT_RESTRICTED, grantedUsers: userData._id},
|
|
|
+ {grant: GRANT_SPECIFIED, grantedUsers: userData._id},
|
|
|
+ {grant: GRANT_OWNER, grantedUsers: userData._id},
|
|
|
+ ],
|
|
|
+ })
|
|
|
+ .populate('revision')
|
|
|
+ .and({
|
|
|
+ $or: pathCondition
|
|
|
+ })
|
|
|
+ .sort(sortOpt)
|
|
|
+ .skip(opt.offset)
|
|
|
+ .limit(opt.limit);
|
|
|
+
|
|
|
+ q.exec()
|
|
|
+ .then(function(pages) {
|
|
|
+ Page.populate(pages, {path: 'revision.author', model: 'User', select: User.USER_PUBLIC_FIELDS})
|
|
|
+ .then(resolve)
|
|
|
+ .catch(reject);
|
|
|
+ })
|
|
|
});
|
|
|
};
|
|
|
|
|
|
- pageSchema.statics.updatePage = function(page, updateData, cb) {
|
|
|
- // TODO foreach して save
|
|
|
- this.update({_id: page._id}, {$set: updateData}, function(err, data) {
|
|
|
- return cb(err, data);
|
|
|
+ pageSchema.statics.updatePage = function(page, updateData) {
|
|
|
+ var Page = this;
|
|
|
+ return new Promise(function(resolve, reject) {
|
|
|
+ // TODO foreach して save
|
|
|
+ Page.update({_id: page._id}, {$set: updateData}, function(err, data) {
|
|
|
+ if (err) {
|
|
|
+ return reject(err);
|
|
|
+ }
|
|
|
+
|
|
|
+ return resolve(data);
|
|
|
+ });
|
|
|
});
|
|
|
};
|
|
|
|
|
|
- pageSchema.statics.updateGrant = function(page, grant, userData, cb) {
|
|
|
- this.update({_id: page._id}, {$set: {grant: grant}}, function(err, data) {
|
|
|
- if (grant == GRANT_PUBLIC) {
|
|
|
- page.grantedUsers = [];
|
|
|
- } else {
|
|
|
- page.grantedUsers = [];
|
|
|
- page.grantedUsers.push(userData._id);
|
|
|
- }
|
|
|
- page.save(function(err, data) {
|
|
|
- return cb(err, data);
|
|
|
+ pageSchema.statics.updateGrant = function(page, grant, userData) {
|
|
|
+ var self = this;
|
|
|
+
|
|
|
+ return new Promise(function(resolve, reject) {
|
|
|
+ self.update({_id: page._id}, {$set: {grant: grant}}, function(err, data) {
|
|
|
+ if (err) {
|
|
|
+ return reject(err);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (grant == GRANT_PUBLIC) {
|
|
|
+ page.grantedUsers = [];
|
|
|
+ } else {
|
|
|
+ page.grantedUsers = [];
|
|
|
+ page.grantedUsers.push(userData._id);
|
|
|
+ }
|
|
|
+ page.save(function(err, data) {
|
|
|
+ if (err) {
|
|
|
+ return reject(err);
|
|
|
+ }
|
|
|
+
|
|
|
+ return resolve(data);
|
|
|
+ });
|
|
|
});
|
|
|
});
|
|
|
};
|
|
|
|
|
|
// Instance method でいいのでは
|
|
|
- pageSchema.statics.pushToGrantedUsers = function(page, userData, cb) {
|
|
|
- if (!page.grantedUsers || !Array.isArray(page.grantedUsers)) {
|
|
|
- page.grantedUsers = [];
|
|
|
- }
|
|
|
- page.grantedUsers.push(userData._id);
|
|
|
- page.save(function(err, data) {
|
|
|
- return cb(err, data);
|
|
|
+ pageSchema.statics.pushToGrantedUsers = function(page, userData) {
|
|
|
+
|
|
|
+ return new Promise(function(resolve, reject) {
|
|
|
+ if (!page.grantedUsers || !Array.isArray(page.grantedUsers)) {
|
|
|
+ page.grantedUsers = [];
|
|
|
+ }
|
|
|
+ page.grantedUsers.push(userData);
|
|
|
+ page.save(function(err, data) {
|
|
|
+ if (err) {
|
|
|
+ return reject(err);
|
|
|
+ }
|
|
|
+ return resolve(data);
|
|
|
+ });
|
|
|
});
|
|
|
};
|
|
|
|
|
|
- pageSchema.statics.pushRevision = function(pageData, newRevision, user, cb) {
|
|
|
- newRevision.save(function(err, newRevision) {
|
|
|
- if (err) {
|
|
|
- debug('Error on saving revision', err);
|
|
|
- return cb(err, null);
|
|
|
- }
|
|
|
+ pageSchema.statics.pushRevision = function(pageData, newRevision, user) {
|
|
|
|
|
|
- debug('Successfully saved new revision', newRevision);
|
|
|
- pageData.revision = newRevision._id;
|
|
|
- pageData.updatedAt = Date.now();
|
|
|
- pageData.save(function(err, data) {
|
|
|
+ return new Promise(function(resolve, reject) {
|
|
|
+ newRevision.save(function(err, newRevision) {
|
|
|
if (err) {
|
|
|
- debug('Error on save page data (after push revision)', err);
|
|
|
- cb(err, null);
|
|
|
- return;
|
|
|
+ debug('Error on saving revision', err);
|
|
|
+ return reject(err);
|
|
|
}
|
|
|
- cb(err, data);
|
|
|
+
|
|
|
+ debug('Successfully saved new revision', newRevision);
|
|
|
+ pageData.revision = newRevision;
|
|
|
+ pageData.updatedAt = Date.now();
|
|
|
+ pageData.save(function(err, data) {
|
|
|
+ if (err) {
|
|
|
+ // todo: remove new revision?
|
|
|
+ debug('Error on save page data (after push revision)', err);
|
|
|
+ return reject(err);
|
|
|
+ }
|
|
|
+
|
|
|
+ resolve(data);
|
|
|
+ });
|
|
|
});
|
|
|
});
|
|
|
};
|
|
|
|
|
|
- pageSchema.statics.create = function(path, body, user, options, cb) {
|
|
|
+ pageSchema.statics.create = function(path, body, user, options) {
|
|
|
var Page = this
|
|
|
, Revision = crowi.model('Revision')
|
|
|
, format = options.format || 'markdown'
|
|
|
, grant = options.grant || GRANT_PUBLIC
|
|
|
, redirectTo = options.redirectTo || null;
|
|
|
|
|
|
- this.findOne({path: path}, function(err, pageData) {
|
|
|
- if (pageData) {
|
|
|
- cb(new Error('Cannot create new page to existed path'), null);
|
|
|
- return;
|
|
|
- }
|
|
|
+ // force public
|
|
|
+ if (isPortalPath(path)) {
|
|
|
+ grant = GRANT_PUBLIC;
|
|
|
+ }
|
|
|
|
|
|
- var newPage = new Page();
|
|
|
- newPage.path = path;
|
|
|
- newPage.creator = user;
|
|
|
- newPage.createdAt = Date.now();
|
|
|
- newPage.updatedAt = Date.now();
|
|
|
- newPage.redirectTo = redirectTo;
|
|
|
- newPage.grant = grant;
|
|
|
- newPage.grantedUsers = [];
|
|
|
- newPage.grantedUsers.push(user);
|
|
|
- newPage.save(function (err, newPage) {
|
|
|
-
|
|
|
- var newRevision = Revision.prepareRevision(newPage, body, user, {format: format});
|
|
|
- Page.pushRevision(newPage, newRevision, user, function(err, data) {
|
|
|
+ return new Promise(function(resolve, reject) {
|
|
|
+ Page.findOne({path: path}, function(err, pageData) {
|
|
|
+ if (pageData) {
|
|
|
+ return reject(new Error('Cannot create new page to existed path'));
|
|
|
+ }
|
|
|
+
|
|
|
+ var newPage = new Page();
|
|
|
+ newPage.path = path;
|
|
|
+ newPage.creator = user;
|
|
|
+ newPage.createdAt = Date.now();
|
|
|
+ newPage.updatedAt = Date.now();
|
|
|
+ newPage.redirectTo = redirectTo;
|
|
|
+ newPage.grant = grant;
|
|
|
+ newPage.grantedUsers = [];
|
|
|
+ newPage.grantedUsers.push(user);
|
|
|
+
|
|
|
+ newPage.save(function (err, newPage) {
|
|
|
if (err) {
|
|
|
- console.log('Push Revision Error on create page', err);
|
|
|
+ return reject(err);
|
|
|
}
|
|
|
- cb(err, data);
|
|
|
- return;
|
|
|
+
|
|
|
+ var newRevision = Revision.prepareRevision(newPage, body, user, {format: format});
|
|
|
+ Page.pushRevision(newPage, newRevision, user).then(function(data) {
|
|
|
+ resolve(data);
|
|
|
+ }).catch(function(err) {
|
|
|
+ debug('Push Revision Error on create page', err);
|
|
|
+ return reject(err);
|
|
|
+ });
|
|
|
});
|
|
|
});
|
|
|
});
|
|
|
};
|
|
|
|
|
|
- pageSchema.statics.rename = function(pageData, newPageName, user, options, cb) {
|
|
|
+ pageSchema.statics.rename = function(pageData, newPagePath, user, options) {
|
|
|
var Page = this
|
|
|
, Revision = crowi.model('Revision')
|
|
|
, path = pageData.path
|
|
|
, createRedirectPage = options.createRedirectPage || 0
|
|
|
, moveUnderTrees = options.moveUnderTrees || 0;
|
|
|
|
|
|
- // pageData の path を変更
|
|
|
- this.updatePage(pageData, {updatedAt: Date.now(), path: newPageName}, function(err, data) {
|
|
|
- if (err) {
|
|
|
- return cb(err, null);
|
|
|
- }
|
|
|
-
|
|
|
- // reivisions の path を変更
|
|
|
- Revision.updateRevisionListByPath(path, {path: newPageName}, {}, function(err, data) {
|
|
|
- if (err) {
|
|
|
- return cb(err, null);
|
|
|
- }
|
|
|
+ return new Promise(function(resolve, reject) {
|
|
|
+ // pageData の path を変更
|
|
|
+ Page.updatePage(pageData, {updatedAt: Date.now(), path: newPagePath})
|
|
|
+ .then(function(data) {
|
|
|
+ debug('Before ', pageData);
|
|
|
+ // reivisions の path を変更
|
|
|
+ return Revision.updateRevisionListByPath(path, {path: newPagePath}, {})
|
|
|
+ }).then(function(data) {
|
|
|
+ debug('After ', pageData);
|
|
|
+ pageData.path = newPagePath;
|
|
|
|
|
|
- pageData.path = newPageName;
|
|
|
if (createRedirectPage) {
|
|
|
- Page.create(path, 'redirect ' + newPageName, user, {redirectTo: newPageName}, function(err, data) {
|
|
|
- // @TODO error handling
|
|
|
- return cb(err, pageData);
|
|
|
- });
|
|
|
+ var body = 'redirect ' + newPagePath;
|
|
|
+ return Page.create(path, body, user, {redirectTo: newPagePath}).then(resolve).catch(reject);
|
|
|
} else {
|
|
|
- return cb(err, pageData);
|
|
|
+ return resolve(data);
|
|
|
}
|
|
|
});
|
|
|
});
|