|
@@ -527,19 +527,111 @@ module.exports = function(crowi) {
|
|
|
});
|
|
});
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
- // find page by path
|
|
|
|
|
- pageSchema.statics.findPageByPath = function(path) {
|
|
|
|
|
- var Page = this;
|
|
|
|
|
|
|
+ // check if a given page has a local and global tempalte
|
|
|
|
|
+ pageSchema.statics.checkIfTemplatesExist = function(path) {
|
|
|
|
|
+ const Page = this;
|
|
|
|
|
+ const pathList = generatePathsOnTree(path, []);
|
|
|
|
|
+ const regexpList = pathList.map(path => new RegExp(`${path}/_{1,2}template`));
|
|
|
|
|
+ let templateInfo = {
|
|
|
|
|
+ localTemplateExists: false,
|
|
|
|
|
+ globalTemplateExists: false,
|
|
|
|
|
+ };
|
|
|
|
|
|
|
|
- return new Promise(function(resolve, reject) {
|
|
|
|
|
- Page.findOne({path: path}, function(err, pageData) {
|
|
|
|
|
- if (err || pageData === null) {
|
|
|
|
|
- return reject(err);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ return Page
|
|
|
|
|
+ .find({path: {$in: regexpList}})
|
|
|
|
|
+ .then(templates => {
|
|
|
|
|
+ templateInfo.localTemplateExists = (assignTemplateByType(templates, path, '__') ? true : false);
|
|
|
|
|
+ templateInfo.globalTemplateExists = (assignGlobalTemplate(templates, path) ? true : false);
|
|
|
|
|
|
|
|
- return resolve(pageData);
|
|
|
|
|
|
|
+ return templateInfo;
|
|
|
});
|
|
});
|
|
|
- });
|
|
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * find all templates applicable to the new page
|
|
|
|
|
+ */
|
|
|
|
|
+ pageSchema.statics.findTemplate = function(path) {
|
|
|
|
|
+ const Page = this;
|
|
|
|
|
+ const templatePath = cutOffLastSlash(path);
|
|
|
|
|
+ const pathList = generatePathsOnTree(templatePath, []);
|
|
|
|
|
+ const regexpList = pathList.map(path => new RegExp(`^${path}/_{1,2}template$`));
|
|
|
|
|
+
|
|
|
|
|
+ return Page
|
|
|
|
|
+ .find({path: {$in: regexpList}})
|
|
|
|
|
+ .populate({path: 'revision', model: 'Revision'})
|
|
|
|
|
+ .then(templates => {
|
|
|
|
|
+ return fetchTemplate(templates, templatePath);
|
|
|
|
|
+ });
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ const cutOffLastSlash = path => {
|
|
|
|
|
+ const lastSlash = path.lastIndexOf('/');
|
|
|
|
|
+ return path.substr(0, lastSlash);
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ const generatePathsOnTree = (path, pathList) => {
|
|
|
|
|
+ if (path === '') {
|
|
|
|
|
+ return pathList;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ pathList.push(path);
|
|
|
|
|
+ const newPath = cutOffLastSlash(path);
|
|
|
|
|
+
|
|
|
|
|
+ return generatePathsOnTree(newPath, pathList);
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ const assignTemplateByType = (templates, path, type) => {
|
|
|
|
|
+ for (let i = 0; i < templates.length; i++) {
|
|
|
|
|
+ if (templates[i].path === `${path}/${type}template`) {
|
|
|
|
|
+ return templates[i];
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ const assignGlobalTemplate = (globalTemplates, path) => {
|
|
|
|
|
+ const globalTemplate = assignTemplateByType(globalTemplates, path, '_');
|
|
|
|
|
+ if (globalTemplate) {
|
|
|
|
|
+ return globalTemplate;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (path === '') {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const newPath = cutOffLastSlash(path);
|
|
|
|
|
+ return assignGlobalTemplate(globalTemplates, newPath);
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ const fetchTemplate = (templates, templatePath) => {
|
|
|
|
|
+ let templateBody;
|
|
|
|
|
+ /**
|
|
|
|
|
+ * get local template
|
|
|
|
|
+ * __tempate: applicable only to immediate decendants
|
|
|
|
|
+ */
|
|
|
|
|
+ const localTemplate = assignTemplateByType(templates, templatePath, '__');
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * get global templates
|
|
|
|
|
+ * _tempate: applicable to all pages under
|
|
|
|
|
+ */
|
|
|
|
|
+ const globalTemplate = assignGlobalTemplate(templates, templatePath);
|
|
|
|
|
+
|
|
|
|
|
+ if (localTemplate) {
|
|
|
|
|
+ templateBody = localTemplate.revision.body;
|
|
|
|
|
+ }
|
|
|
|
|
+ else if (globalTemplate) {
|
|
|
|
|
+ templateBody = globalTemplate.revision.body;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return templateBody;
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ // find page by path
|
|
|
|
|
+ pageSchema.statics.findPageByPath = function(path) {
|
|
|
|
|
+ if (path == null) {
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+ return this.findOne({path});
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
pageSchema.statics.findListByPageIds = function(ids, options) {
|
|
pageSchema.statics.findListByPageIds = function(ids, options) {
|
|
@@ -767,6 +859,7 @@ module.exports = function(crowi) {
|
|
|
{grant: GRANT_RESTRICTED, grantedUsers: userData._id},
|
|
{grant: GRANT_RESTRICTED, grantedUsers: userData._id},
|
|
|
{grant: GRANT_SPECIFIED, grantedUsers: userData._id},
|
|
{grant: GRANT_SPECIFIED, grantedUsers: userData._id},
|
|
|
{grant: GRANT_OWNER, grantedUsers: userData._id},
|
|
{grant: GRANT_OWNER, grantedUsers: userData._id},
|
|
|
|
|
+ {grant: GRANT_USER_GROUP},
|
|
|
], })
|
|
], })
|
|
|
.and({
|
|
.and({
|
|
|
$or: pathCondition
|
|
$or: pathCondition
|
|
@@ -917,10 +1010,11 @@ module.exports = function(crowi) {
|
|
|
grant = GRANT_PUBLIC;
|
|
grant = GRANT_PUBLIC;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- return new Promise(function(resolve, reject) {
|
|
|
|
|
- Page.findOne({path: path}, function(err, pageData) {
|
|
|
|
|
|
|
+ let savedPage = undefined;
|
|
|
|
|
+ return Page.findOne({path: path})
|
|
|
|
|
+ .then(pageData => {
|
|
|
if (pageData) {
|
|
if (pageData) {
|
|
|
- return reject(new Error('Cannot create new page to existed path'));
|
|
|
|
|
|
|
+ throw new Error('Cannot create new page to existed path');
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
var newPage = new Page();
|
|
var newPage = new Page();
|
|
@@ -935,28 +1029,22 @@ module.exports = function(crowi) {
|
|
|
newPage.grantedUsers = [];
|
|
newPage.grantedUsers = [];
|
|
|
newPage.grantedUsers.push(user);
|
|
newPage.grantedUsers.push(user);
|
|
|
|
|
|
|
|
- newPage.save(function(err, newPage) {
|
|
|
|
|
- if (err) {
|
|
|
|
|
- return reject(err);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if (newPage.grant == Page.GRANT_USER_GROUP && grantUserGroupId != null) {
|
|
|
|
|
- Page.updateGrantUserGroup(newPage, grant, grantUserGroupId, user)
|
|
|
|
|
- .catch((err) => {
|
|
|
|
|
- return reject(err);
|
|
|
|
|
- });
|
|
|
|
|
- }
|
|
|
|
|
- var newRevision = Revision.prepareRevision(newPage, body, user, {format: format});
|
|
|
|
|
- Page.pushRevision(newPage, newRevision, user).then(function(data) {
|
|
|
|
|
- resolve(data);
|
|
|
|
|
- pageEvent.emit('create', data, user);
|
|
|
|
|
- }).catch(function(err) {
|
|
|
|
|
- debug('Push Revision Error on create page', err);
|
|
|
|
|
- return reject(err);
|
|
|
|
|
- });
|
|
|
|
|
- });
|
|
|
|
|
|
|
+ return newPage.save();
|
|
|
|
|
+ })
|
|
|
|
|
+ .then((newPage) => {
|
|
|
|
|
+ savedPage = newPage;
|
|
|
|
|
+ })
|
|
|
|
|
+ .then(() => {
|
|
|
|
|
+ const newRevision = Revision.prepareRevision(savedPage, body, user, {format: format});
|
|
|
|
|
+ return Page.pushRevision(savedPage, newRevision, user);
|
|
|
|
|
+ })
|
|
|
|
|
+ .then(() => {
|
|
|
|
|
+ return Page.updateGrantUserGroup(savedPage, grant, grantUserGroupId, user);
|
|
|
|
|
+ })
|
|
|
|
|
+ .then(() => {
|
|
|
|
|
+ pageEvent.emit('create', savedPage, user);
|
|
|
|
|
+ return savedPage;
|
|
|
});
|
|
});
|
|
|
- });
|
|
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
pageSchema.statics.updatePage = function(pageData, body, user, options) {
|
|
pageSchema.statics.updatePage = function(pageData, body, user, options) {
|
|
@@ -968,14 +1056,22 @@ module.exports = function(crowi) {
|
|
|
// update existing page
|
|
// update existing page
|
|
|
var newRevision = Revision.prepareRevision(pageData, body, user);
|
|
var newRevision = Revision.prepareRevision(pageData, body, user);
|
|
|
|
|
|
|
|
|
|
+ let savedPage = undefined;
|
|
|
return Page.pushRevision(pageData, newRevision, user)
|
|
return Page.pushRevision(pageData, newRevision, user)
|
|
|
- .then(function(revision) {
|
|
|
|
|
- return Page.updateGrant(pageData, grant, user, grantUserGroupId);
|
|
|
|
|
|
|
+ .then((revision) => {
|
|
|
|
|
+ // fetch Page
|
|
|
|
|
+ return Page.findPageByPath(revision.path).populate('revision');
|
|
|
})
|
|
})
|
|
|
- .then(function(data) {
|
|
|
|
|
|
|
+ .then((page) => {
|
|
|
|
|
+ savedPage = page;
|
|
|
|
|
+ })
|
|
|
|
|
+ .then(() => {
|
|
|
|
|
+ return Page.updateGrant(savedPage, grant, user, grantUserGroupId);
|
|
|
|
|
+ })
|
|
|
|
|
+ .then((data) => {
|
|
|
debug('Page grant update:', data);
|
|
debug('Page grant update:', data);
|
|
|
- pageEvent.emit('update', data, user);
|
|
|
|
|
- return data;
|
|
|
|
|
|
|
+ pageEvent.emit('update', savedPage, user);
|
|
|
|
|
+ return savedPage;
|
|
|
});
|
|
});
|
|
|
};
|
|
};
|
|
|
|
|
|
|
@@ -984,20 +1080,13 @@ module.exports = function(crowi) {
|
|
|
, newPath = Page.getDeletedPageName(pageData.path)
|
|
, newPath = Page.getDeletedPageName(pageData.path)
|
|
|
;
|
|
;
|
|
|
if (Page.isDeletableName(pageData.path)) {
|
|
if (Page.isDeletableName(pageData.path)) {
|
|
|
- return new Promise(function(resolve, reject) {
|
|
|
|
|
- Page.updatePageProperty(pageData, {status: STATUS_DELETED, lastUpdateUser: user})
|
|
|
|
|
- .then(function(data) {
|
|
|
|
|
- pageData.status = STATUS_DELETED;
|
|
|
|
|
-
|
|
|
|
|
- // ページ名が /trash/ 以下に存在する場合、おかしなことになる
|
|
|
|
|
- // が、 /trash 以下にページが有るのは、個別に作っていたケースのみ。
|
|
|
|
|
- // 一応しばらく前から uncreatable pages になっているのでこれでいいことにする
|
|
|
|
|
- debug('Deleted the page, and rename it', pageData.path, newPath);
|
|
|
|
|
- return Page.rename(pageData, newPath, user, {createRedirectPage: true});
|
|
|
|
|
- }).then(function(pageData) {
|
|
|
|
|
- resolve(pageData);
|
|
|
|
|
- }).catch(reject);
|
|
|
|
|
- });
|
|
|
|
|
|
|
+ return Page.rename(pageData, newPath, user, {createRedirectPage: true})
|
|
|
|
|
+ .then((updatedPageData) => {
|
|
|
|
|
+ return Page.updatePageProperty(updatedPageData, {status: STATUS_DELETED, lastUpdateUser: user});
|
|
|
|
|
+ })
|
|
|
|
|
+ .then(() => {
|
|
|
|
|
+ return pageData;
|
|
|
|
|
+ });
|
|
|
}
|
|
}
|
|
|
else {
|
|
else {
|
|
|
return Promise.reject('Page is not deletable.');
|
|
return Promise.reject('Page is not deletable.');
|
|
@@ -1010,18 +1099,15 @@ module.exports = function(crowi) {
|
|
|
, options = options || {}
|
|
, options = options || {}
|
|
|
;
|
|
;
|
|
|
|
|
|
|
|
- return new Promise(function(resolve, reject) {
|
|
|
|
|
- Page
|
|
|
|
|
- .generateQueryToListWithDescendants(path, user, options)
|
|
|
|
|
|
|
+ return Page.generateQueryToListWithDescendants(path, user, options)
|
|
|
.then(function(pages) {
|
|
.then(function(pages) {
|
|
|
- Promise.all(pages.map(function(page) {
|
|
|
|
|
|
|
+ return Promise.all(pages.map(function(page) {
|
|
|
return Page.deletePage(page, user, options);
|
|
return Page.deletePage(page, user, options);
|
|
|
- }))
|
|
|
|
|
- .then(function(data) {
|
|
|
|
|
- return resolve(pageData);
|
|
|
|
|
- });
|
|
|
|
|
|
|
+ }));
|
|
|
|
|
+ })
|
|
|
|
|
+ .then(function(data) {
|
|
|
|
|
+ return pageData;
|
|
|
});
|
|
});
|
|
|
- });
|
|
|
|
|
|
|
|
|
|
};
|
|
};
|
|
|
|
|
|
|
@@ -1064,6 +1150,7 @@ module.exports = function(crowi) {
|
|
|
return new Promise(function(resolve, reject) {
|
|
return new Promise(function(resolve, reject) {
|
|
|
Page
|
|
Page
|
|
|
.generateQueryToListWithDescendants(path, user, options)
|
|
.generateQueryToListWithDescendants(path, user, options)
|
|
|
|
|
+ .exec()
|
|
|
.then(function(pages) {
|
|
.then(function(pages) {
|
|
|
Promise.all(pages.map(function(page) {
|
|
Promise.all(pages.map(function(page) {
|
|
|
return Page.revertDeletedPage(page, user, options);
|
|
return Page.revertDeletedPage(page, user, options);
|
|
@@ -1084,6 +1171,7 @@ module.exports = function(crowi) {
|
|
|
, Attachment = crowi.model('Attachment')
|
|
, Attachment = crowi.model('Attachment')
|
|
|
, Comment = crowi.model('Comment')
|
|
, Comment = crowi.model('Comment')
|
|
|
, Revision = crowi.model('Revision')
|
|
, Revision = crowi.model('Revision')
|
|
|
|
|
+ , PageGroupRelation = crowi.model('PageGroupRelation')
|
|
|
, Page = this
|
|
, Page = this
|
|
|
, pageId = pageData._id
|
|
, pageId = pageData._id
|
|
|
;
|
|
;
|
|
@@ -1103,6 +1191,8 @@ module.exports = function(crowi) {
|
|
|
return Page.removePageById(pageId);
|
|
return Page.removePageById(pageId);
|
|
|
}).then(function(done) {
|
|
}).then(function(done) {
|
|
|
return Page.removeRedirectOriginPageByPath(pageData.path);
|
|
return Page.removeRedirectOriginPageByPath(pageData.path);
|
|
|
|
|
+ }).then(function(done) {
|
|
|
|
|
+ return PageGroupRelation.removeAllByPage(pageData);
|
|
|
}).then(function(done) {
|
|
}).then(function(done) {
|
|
|
pageEvent.emit('delete', pageData, user); // update as renamed page
|
|
pageEvent.emit('delete', pageData, user); // update as renamed page
|
|
|
resolve(pageData);
|
|
resolve(pageData);
|
|
@@ -1190,25 +1280,22 @@ module.exports = function(crowi) {
|
|
|
, createRedirectPage = options.createRedirectPage || 0
|
|
, createRedirectPage = options.createRedirectPage || 0
|
|
|
, moveUnderTrees = options.moveUnderTrees || 0;
|
|
, moveUnderTrees = options.moveUnderTrees || 0;
|
|
|
|
|
|
|
|
- return new Promise(function(resolve, reject) {
|
|
|
|
|
- // pageData の path を変更
|
|
|
|
|
- Page.updatePageProperty(pageData, {updatedAt: Date.now(), path: newPagePath, lastUpdateUser: user})
|
|
|
|
|
- .then(function(data) {
|
|
|
|
|
|
|
+ return Page.updatePageProperty(pageData, {updatedAt: Date.now(), path: newPagePath, lastUpdateUser: user}) // pageData の path を変更
|
|
|
|
|
+ .then((data) => {
|
|
|
// reivisions の path を変更
|
|
// reivisions の path を変更
|
|
|
return Revision.updateRevisionListByPath(path, {path: newPagePath}, {});
|
|
return Revision.updateRevisionListByPath(path, {path: newPagePath}, {});
|
|
|
- }).then(function(data) {
|
|
|
|
|
|
|
+ })
|
|
|
|
|
+ .then(function(data) {
|
|
|
pageData.path = newPagePath;
|
|
pageData.path = newPagePath;
|
|
|
|
|
|
|
|
if (createRedirectPage) {
|
|
if (createRedirectPage) {
|
|
|
var body = 'redirect ' + newPagePath;
|
|
var body = 'redirect ' + newPagePath;
|
|
|
- Page.create(path, body, user, {redirectTo: newPagePath}).then(resolve).catch(reject);
|
|
|
|
|
- }
|
|
|
|
|
- else {
|
|
|
|
|
- resolve(data);
|
|
|
|
|
|
|
+ Page.create(path, body, user, {redirectTo: newPagePath});
|
|
|
}
|
|
}
|
|
|
pageEvent.emit('update', pageData, user); // update as renamed page
|
|
pageEvent.emit('update', pageData, user); // update as renamed page
|
|
|
|
|
+
|
|
|
|
|
+ return pageData;
|
|
|
});
|
|
});
|
|
|
- });
|
|
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
pageSchema.statics.renameRecursively = function(pageData, newPagePathPrefix, user, options) {
|
|
pageSchema.statics.renameRecursively = function(pageData, newPagePathPrefix, user, options) {
|
|
@@ -1216,20 +1303,17 @@ module.exports = function(crowi) {
|
|
|
, path = pageData.path
|
|
, path = pageData.path
|
|
|
, pathRegExp = new RegExp('^' + escapeStringRegexp(path), 'i');
|
|
, pathRegExp = new RegExp('^' + escapeStringRegexp(path), 'i');
|
|
|
|
|
|
|
|
- return new Promise(function(resolve, reject) {
|
|
|
|
|
- Page
|
|
|
|
|
- .generateQueryToListWithDescendants(path, user, options)
|
|
|
|
|
|
|
+ return Page.generateQueryToListWithDescendants(path, user, options)
|
|
|
.then(function(pages) {
|
|
.then(function(pages) {
|
|
|
- Promise.all(pages.map(function(page) {
|
|
|
|
|
- newPagePath = page.path.replace(pathRegExp, newPagePathPrefix);
|
|
|
|
|
|
|
+ return Promise.all(pages.map(function(page) {
|
|
|
|
|
+ const newPagePath = page.path.replace(pathRegExp, newPagePathPrefix);
|
|
|
return Page.rename(page, newPagePath, user, options);
|
|
return Page.rename(page, newPagePath, user, options);
|
|
|
- }))
|
|
|
|
|
- .then(function() {
|
|
|
|
|
- pageData.path = newPagePathPrefix;
|
|
|
|
|
- return resolve();
|
|
|
|
|
- });
|
|
|
|
|
|
|
+ }));
|
|
|
|
|
+ })
|
|
|
|
|
+ .then(function() {
|
|
|
|
|
+ pageData.path = newPagePathPrefix;
|
|
|
|
|
+ return pageData;
|
|
|
});
|
|
});
|
|
|
- });
|
|
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
pageSchema.statics.getHistories = function() {
|
|
pageSchema.statics.getHistories = function() {
|