Sotaro KARASAWA 10 лет назад
Родитель
Сommit
79cf1fb5cf
6 измененных файлов с 104 добавлено и 81 удалено
  1. 41 22
      lib/models/page.js
  2. 11 3
      lib/models/revision.js
  3. 1 1
      lib/routes/index.js
  4. 37 44
      lib/routes/page.js
  5. 6 4
      lib/views/modal/widget_rename.html
  6. 8 7
      resource/js/crowi.js

+ 41 - 22
lib/models/page.js

@@ -282,6 +282,7 @@ module.exports = function(crowi) {
       /^\/\-\/.*/,
       /^\/_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).+/,
@@ -376,6 +377,21 @@ module.exports = function(crowi) {
     });
   };
 
+  // find page by path
+  pageSchema.statics.findPageByPath = function(path) {
+    var Page = this;
+
+    return new Promise(function(resolve, reject) {
+      Page.findOne({path: path}, function(err, pageData) {
+        if (err || pageData === null) {
+          return reject(err);
+        }
+
+        return resolve(pageData);
+      });
+    });
+  };
+
   pageSchema.statics.findListByPageIds = function(ids, option) {
     var Page = this;
     var User = crowi.model('User');
@@ -486,10 +502,17 @@ module.exports = function(crowi) {
     });
   };
 
-  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);
+      });
     });
   };
 
@@ -606,33 +629,29 @@ module.exports = function(crowi) {
     });
   };
 
-  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);
         }
       });
     });

+ 11 - 3
lib/models/revision.js

@@ -38,9 +38,17 @@ module.exports = function(crowi) {
     });
   };
 
-  revisionSchema.statics.updateRevisionListByPath = function(path, updateData, options, cb) {
-    this.update({path: path}, {$set: updateData}, {multi: true}, function(err, data) {
-      cb(err, data);
+  revisionSchema.statics.updateRevisionListByPath = function(path, updateData, options) {
+    var Revision = this;
+
+    return new Promise(function(resolve, reject) {
+      Revision.update({path: path}, {$set: updateData}, {multi: true}, function(err, data) {
+        if (err) {
+          return reject(err);
+        }
+
+        return resolve(data);
+      });
     });
   };
 

+ 1 - 1
lib/routes/index.js

@@ -68,7 +68,6 @@ module.exports = function(crowi, app) {
   app.get( '/_api/check_username'     , user.api.checkUsername);
   app.post('/_api/me/picture/upload'  , loginRequired(crowi, app) , me.api.uploadPicture);
   app.get( '/_api/user/bookmarks'     , loginRequired(crowi, app) , user.api.bookmarks);
-  app.post('/_api/page_rename/*'      , loginRequired(crowi, app) , page.api.rename);
   app.get( '/_api/attachment/page/:pageId', loginRequired(crowi, app) , attachment.api.list);
   app.post('/_api/attachment/page/:pageId', loginRequired(crowi, app) , attachment.api.add);
   app.post('/_api/attachment/:id/remove',loginRequired(crowi, app), attachment.api.remove);
@@ -80,6 +79,7 @@ module.exports = function(crowi, app) {
   app.get('/_api/users.list'          , accessTokenParser(crowi, app) , loginRequired(crowi, app) , user.api.list);
   app.get('/_api/pages.get'           , accessTokenParser(crowi, app) , loginRequired(crowi, app) , page.api.get);
   app.post('/_api/pages.seen'         , accessTokenParser(crowi, app) , loginRequired(crowi, app) , page.api.seen);
+  app.post('/_api/pages.rename'       , accessTokenParser(crowi, app) , loginRequired(crowi, app) , page.api.rename);
   app.get('/_api/comments.get'        , accessTokenParser(crowi, app) , loginRequired(crowi, app) , comment.api.get);
   app.post('/_api/comments.add'       , form.comment, accessTokenParser(crowi, app) , loginRequired(crowi, app) , comment.api.add);
   app.get( '/_api/bookmarks.get'      , accessTokenParser(crowi, app) , loginRequired(crowi, app) , bookmark.api.get);

+ 37 - 44
lib/routes/page.js

@@ -7,6 +7,9 @@ module.exports = function(crowi, app) {
     , Revision = crowi.model('Revision')
     , Bookmark = crowi.model('Bookmark')
     , ApiResponse = require('../util/apiResponse')
+
+    , sprintf = require('sprintf')
+
     , actions = {};
 
   function getPathFromRequest(req) {
@@ -453,61 +456,51 @@ module.exports = function(crowi, app) {
   };
 
   /**
-   * page rename
+   * @api {post} /pages.rename Rename page
+   * @apiName SeenPage
+   * @apiGroup Page
+   *
+   * @apiParam {String} page_id Page Id.
+   * @apiParam {String} path
+   * @apiParam {String} revision_id
+   * @apiParam {String} new_path
+   * @apiParam {Bool} create_redirect
    */
   api.rename = function(req, res){
-    var path = Page.normalizePath(getPathFromRequest(req));
-
-    var val = req.body;
-    var previousRevision = val.previousRevision;
-    var newPageName = Page.normalizePath(val.newPageName);
+    var pageId = req.body.page_id;
+    var previousRevision = req.body.revision_id || null;
+    var newPagePath = Page.normalizePath(req.body.new_path);
     var options = {
-      createRedirectPage: val.createRedirectPage || 0,
-      moveUnderTrees: val.moveUnderTrees || 0,
+      createRedirectPage: req.body.create_redirect || 0,
+      moveUnderTrees: req.body.move_trees || 0,
     };
+    var page = {};
 
-    if (!Page.isCreatableName(newPageName)) {
-      return res.json({
-        message: 'このページ名は作成できません (' + newPageName + ')',
-        status: false,
-      });
+    if (!Page.isCreatableName(newPagePath)) {
+      return res.json(ApiResponse.error(sprintf('このページ名は作成できません (%s)', newPagePath)));
     }
-    Page.findPage(newPageName, req.user, null, {}, function(err, checkPageData){
-      if (checkPageData) {
-        return res.json({
-          message: 'このページ名は作成できません (' + newPageName + ')。ページが存在します。',
-          status: false,
-        });
-      }
 
-      Page.findPage(path, req.user, null, {}, function(err, pageData){
+    Page.findPageByPath(newPagePath)
+    .then(function(page) {
+      // if page found, cannot cannot rename to that path
+      return res.json(ApiResponse.error(sprintf('このページ名は作成できません (%s)。ページが存在します。', newPagePath)));
+    }).catch(function(err) {
+
+      Page.findPageById(pageId)
+      .then(function(pageData) {
+        page = pageData;
         if (!pageData.isUpdatable(previousRevision)) {
-          return res.json({
-            message: '誰かが更新している可能性があります。ページを更新できません。',
-            status: false,
-          });
-        }
-        if (err) {
-          return res.json({
-            message: 'エラーが発生しました。ページを更新できません。',
-            status: false,
-          });
+          return res.json(ApiResponse.error('誰かが更新している可能性があります。ページを更新できません。'));
         }
 
-        Page.rename(pageData, newPageName, req.user, options, function(err, pageData) {
-          if (err) {
-            return res.json({
-              message: 'ページの移動に失敗しました',
-              status: false,
-            });
-          }
+        return Page.rename(pageData, newPagePath, req.user, options);
+      }).then(function() {
+        var result = {};
+        result.page = page;
 
-          return res.json({
-            message: '移動しました',
-            page: pageData,
-            status: true,
-          });
-        });
+        return res.json(ApiResponse.success(result));
+      }).catch(function(err) {
+        return res.json(ApiResponse.error('エラーが発生しました。ページを更新できません。'));
       });
     });
   };

+ 6 - 4
lib/views/modal/widget_rename.html

@@ -21,12 +21,12 @@
               <label for="newPageName">移動先のページ名</label><br>
               <div class="input-group">
                 <span class="input-group-addon">{{ config.crowi['app:url'] }}</span>
-                <input type="text" class="form-control" name="newPageName" id="newPageName" value="{{ page.path }}">
+                <input type="text" class="form-control" name="new_path" id="newPageName" value="{{ page.path }}">
               </div>
             </div>
             <div class="checkbox">
                <label>
-                 <input name="createRedirectPage" value="1"  type="checkbox"> リダイレクトページを作成
+                 <input name="create_redirect" value="1"  type="checkbox"> リダイレクトページを作成
                </label>
                <p class="help-block">チェックを入れると、<code>{{ page.path }}</code>にアクセスされた際に自動的に新しいページにジャンプします。</p>
             </div>
@@ -40,8 +40,10 @@
         </div>
         <div class="modal-footer">
           <p><small class="pull-left" id="newPageNameCheck"></small></p>
-          <input type="hidden" name="previousRevision" value="{{ page.revision._id.toString() }}">
-          <input type="submit" class="btn btn-primary" value="実行">
+          <input type="hidden" name="path" value="{{ page.path }}">
+          <input type="hidden" name="page_id" value="{{ page._id.toString() }}">
+          <input type="hidden" name="revision_id" value="{{ page.revision._id.toString() }}">
+          <input type="submit" class="btn btn-primary" value="Rename!">
         </div>
 
       </form>

+ 8 - 7
resource/js/crowi.js

@@ -258,23 +258,24 @@ $(function() {
     $('#newPageName').focus();
   });
   $('#renamePageForm').submit(function(e) {
-    var path = $('#pagePath').html();
     $.ajax({
       type: 'POST',
-      url: '/_api/page_rename' + path,
+      url: '/_api/pages.rename',
       data: $('#renamePageForm').serialize(),
       dataType: 'json'
-    }).done(function(data) {
-      if (!data.status) {
-        $('#newPageNameCheck').html('<i class="fa fa-times-circle"></i> ' + data.message);
+    }).done(function(res) {
+      if (!res.ok) {
+        $('#newPageNameCheck').html('<i class="fa fa-times-circle"></i> ' + res.error);
         $('#newPageNameCheck').addClass('alert-danger');
       } else {
-        $('#newPageNameCheck').removeClass('alert-danger');
+        var page = res.page;
+        var path = $('#pagePath').html();
 
+        $('#newPageNameCheck').removeClass('alert-danger');
         $('#newPageNameCheck').html('<img src="/images/loading_s.gif"> 移動しました。移動先にジャンプします。');
 
         setTimeout(function() {
-          top.location.href = data.page.path + '?renamed=' + path;
+          top.location.href = page.path + '?renamed=' + path;
         }, 1000);
       }
     });