|
|
@@ -392,10 +392,10 @@ module.exports = function(crowi) {
|
|
|
|
|
|
pageSchema.statics.isCreatableName = function(name) {
|
|
|
var forbiddenPages = [
|
|
|
- /\^|\$|\*|\+|\#/,
|
|
|
- /^\/_.*/, // /_api/* and so on
|
|
|
- /^\/\-\/.*/,
|
|
|
+ /\^|\$|\*|\+|#/,
|
|
|
+ /^\/-\/.*/,
|
|
|
/^\/_r\/.*/,
|
|
|
+ /^\/_apix?(\/.*)?/,
|
|
|
/^\/?https?:\/\/.+$/, // avoid miss in renaming
|
|
|
/\/{2,}/, // avoid miss in renaming
|
|
|
/\s+\/\s+/, // avoid miss in renaming
|
|
|
@@ -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 children and decendants 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 = {
|
|
|
+ childrenTemplateExists: false,
|
|
|
+ decendantsTemplateExists: 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.childrenTemplateExists = (assignTemplateByType(templates, path, '_') ? true : false);
|
|
|
+ templateInfo.decendantsTemplateExists = (assignTemplateByType(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 assignDecendantsTemplate = (decendantsTemplates, path) => {
|
|
|
+ const decendantsTemplate = assignTemplateByType(decendantsTemplates, path, '__');
|
|
|
+ if (decendantsTemplate) {
|
|
|
+ return decendantsTemplate;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (path === '') {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ const newPath = cutOffLastSlash(path);
|
|
|
+ return assignDecendantsTemplate(decendantsTemplates, newPath);
|
|
|
+ };
|
|
|
+
|
|
|
+ const fetchTemplate = (templates, templatePath) => {
|
|
|
+ let templateBody;
|
|
|
+ /**
|
|
|
+ * get children template
|
|
|
+ * __tempate: applicable only to immediate decendants
|
|
|
+ */
|
|
|
+ const childrenTemplate = assignTemplateByType(templates, templatePath, '_');
|
|
|
+
|
|
|
+ /**
|
|
|
+ * get decendants templates
|
|
|
+ * _tempate: applicable to all pages under
|
|
|
+ */
|
|
|
+ const decendantsTemplate = assignDecendantsTemplate(templates, templatePath);
|
|
|
+
|
|
|
+ if (childrenTemplate) {
|
|
|
+ templateBody = childrenTemplate.revision.body;
|
|
|
+ }
|
|
|
+ else if (decendantsTemplate) {
|
|
|
+ templateBody = decendantsTemplate.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) {
|
|
|
@@ -918,6 +1010,7 @@ module.exports = function(crowi) {
|
|
|
grant = GRANT_PUBLIC;
|
|
|
}
|
|
|
|
|
|
+ let savedPage = undefined;
|
|
|
return Page.findOne({path: path})
|
|
|
.then(pageData => {
|
|
|
if (pageData) {
|
|
|
@@ -939,14 +1032,18 @@ module.exports = function(crowi) {
|
|
|
return newPage.save();
|
|
|
})
|
|
|
.then((newPage) => {
|
|
|
- const newRevision = Revision.prepareRevision(newPage, body, user, {format: format});
|
|
|
- return Page.pushRevision(newPage, newRevision, user)
|
|
|
- .then(() => {
|
|
|
- return Page.updateGrantUserGroup(newPage, grant, grantUserGroupId, user);
|
|
|
- });
|
|
|
+ savedPage = newPage;
|
|
|
})
|
|
|
- .then((data) => {
|
|
|
- pageEvent.emit('create', data, user);
|
|
|
+ .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;
|
|
|
});
|
|
|
};
|
|
|
|
|
|
@@ -959,14 +1056,22 @@ module.exports = function(crowi) {
|
|
|
// update existing page
|
|
|
var newRevision = Revision.prepareRevision(pageData, body, user);
|
|
|
|
|
|
+ let savedPage = undefined;
|
|
|
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);
|
|
|
- pageEvent.emit('update', data, user);
|
|
|
- return data;
|
|
|
+ pageEvent.emit('update', savedPage, user);
|
|
|
+ return savedPage;
|
|
|
});
|
|
|
};
|
|
|
|