1 // 2 // The Antville Project 3 // http://code.google.com/p/antville 4 // 5 // Copyright 2001-2007 by The Antville People 6 // 7 // Licensed under the Apache License, Version 2.0 (the ``License''); 8 // you may not use this file except in compliance with the License. 9 // You may obtain a copy of the License at 10 // 11 // http://www.apache.org/licenses/LICENSE-2.0 12 // 13 // Unless required by applicable law or agreed to in writing, software 14 // distributed under the License is distributed on an ``AS IS'' BASIS, 15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 // See the License for the specific language governing permissions and 17 // limitations under the License. 18 // 19 // $Revision$ 20 // $LastChangedBy$ 21 // $LastChangedDate$ 22 // $URL$ 23 // 24 25 /** 26 * @fileOverview Defines the Comment prototype. 27 */ 28 29 /** 30 * @see defineConstants 31 */ 32 Comment.getStatus = defineConstants(Comment, "closed", 33 "pending", "readonly", "public"); 34 35 /** 36 * @returns {String} 37 */ 38 Comment.remove = function(options) { 39 if (this.constructor !== Comment) { 40 return; 41 } 42 if (options && options.mode === "user" && options.confirm === "1") { 43 var sql = new Sql; 44 sql.retrieve("select id from content where site_id = $0 and creator_id = $1 \ 45 and prototype = 'Comment'", this.site._id, this.creator._id); 46 sql.traverse(function() { 47 Comment.remove.call(Comment.getById(this.id)); 48 }); 49 } else { 50 while (this.size() > 0) { 51 Comment.remove.call(this.get(0)); 52 } 53 // Explicitely remove comment from aggressively cached collections: 54 (this.parent || this).removeChild(this); 55 this.story.comments.removeChild(this); 56 this.remove(); 57 } 58 return this.parent.href(); 59 } 60 61 /** 62 * @name Comment 63 * @constructor 64 * @param {Object} parent 65 * @property {Comment[]} _children 66 * @property {String} name 67 * @property {Story|Comment} parent 68 * @property {Story} story 69 * @extends Story 70 */ 71 Comment.prototype.constructor = function(parent) { 72 this.name = String.EMPTY; 73 this.site = parent.site; 74 this.story = parent.story || parent; 75 this.parent = parent; 76 // FIXME: Correct parent_type (Helma bug?) 77 this.parent_type = parent._prototype; 78 this.status = Story.PUBLIC; 79 this.creator = this.modifier = session.user; 80 this.created = this.modified = new Date; 81 return this; 82 } 83 84 /** 85 * 86 * @param {Object} action 87 * @returns {Boolean} 88 */ 89 Comment.prototype.getPermission = function(action) { 90 switch (action) { 91 case ".": 92 case "main": 93 case "comment": 94 // FIXME: temporary fix for lost stories due to shrunk database 95 if (!this.story) { 96 return false; 97 } 98 return this.site.commentMode === Site.ENABLED && 99 this.story.getPermission(action) && 100 this.status !== Comment.CLOSED && 101 this.status !== Comment.PENDING; 102 case "delete": 103 case "edit": 104 return this.story.getPermission.call(this, "delete"); 105 } 106 return false; 107 } 108 109 /** 110 * 111 * @param {Object} action 112 * @returns {String} 113 */ 114 Comment.prototype.href = function(action) { 115 var buffer = []; 116 switch (action) { 117 case null: 118 case undefined: 119 case "": 120 case ".": 121 case "main": 122 buffer.push(this.story.href(), "#", this._id); 123 break; 124 default: 125 buffer.push(this.story.comments.href(), this._id, "/", action); 126 } 127 return buffer.join(String.EMPTY); 128 } 129 130 Comment.prototype.edit_action = function() { 131 if (req.postParams.save) { 132 try { 133 this.update(req.postParams); 134 delete session.data.backup; 135 res.message = gettext("The comment was successfully updated.");; 136 res.redirect(this.story.href() + "#" + this._id); 137 } catch (ex) { 138 res.message = ex; 139 app.log(ex); 140 } 141 } 142 143 res.handlers.parent = this.parent; 144 res.data.action = this.href(req.action); 145 res.data.title = gettext("Edit Comment"); 146 res.data.body = this.renderSkinAsString("Comment#edit"); 147 this.site.renderSkin("Site#page"); 148 return; 149 } 150 151 /** 152 * 153 * @param {Object} data 154 */ 155 Comment.prototype.update = function(data) { 156 if (!data.title && !data.text) { 157 throw Error(gettext("Please enter at least something into the “title” or “text” field.")); 158 } 159 // Get difference to current content before applying changes 160 var delta = this.getDelta(data); 161 this.title = data.title; 162 this.text = data.text; 163 this.setMetadata(data); 164 165 if (this.story.commentMode === Story.MODERATED) { 166 this.mode = Comment.PENDING; 167 } else if (delta > 50) { 168 this.modified = new Date; 169 if (this.story.status !== Story.CLOSED) { 170 this.site.modified = this.modified; 171 } 172 // We need persistence for adding the callback 173 this.isTransient() && this.persist(); 174 res.handlers.site.callback(this); 175 // Notification is sent in Story.comment_action() 176 } 177 this.clearCache(); 178 this.modifier = session.user; 179 return; 180 } 181 182 /** 183 * 184 * @param {String} name 185 * @returns {HopObject} 186 */ 187 Comment.prototype.getMacroHandler = function(name) { 188 if (name === "related") { 189 return this.creator.comments; 190 } 191 return null; 192 } 193