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 Tag prototype. 27 */ 28 29 /** 30 * @constant 31 */ 32 Tag.MOUNTPOINTS = { 33 Story: "tags", 34 Image: "galleries" 35 } 36 37 /** 38 * @name Tag 39 * @constructor 40 * @param {String} name 41 * @param {Site} site 42 * @param {String} type 43 * @property {TagHub[]} _children 44 * @property {Images[]} images 45 * @property {String} name 46 * @property {Site} site 47 * @property {Story[]} stories 48 * @property {String} type 49 * @extends HopObject 50 */ 51 Tag.prototype.constructor = function(name, site, type) { 52 this.name = name; 53 this.site = site; 54 this.type = type; 55 return this; 56 } 57 58 /** 59 * 60 * @param {String} action 61 * @returns {Boolean} 62 */ 63 Tag.prototype.getPermission = function(action) { 64 if (!res.handlers.site.getPermission("main")) { 65 return false; 66 } 67 switch (action) { 68 case ".": 69 case "main": 70 case "rss.xml": 71 return true; 72 case "edit": 73 case "delete": 74 case "rename": 75 return User.require(User.PRIVILEGED) || 76 Membership.require(Membership.MANAGER); 77 } 78 return false; 79 } 80 81 Tag.prototype.main_action = function() { 82 res.handlers.list = new jala.ListRenderer(this.getTagged()); 83 res.handlers.list.setPageSize(this.site.pageSize); 84 res.data.title = gettext("Tag: {0}", this.name); 85 res.data.body = this.renderSkinAsString("$Tag#main"); 86 res.handlers.site.renderSkin("Site#page"); 87 res.handlers.site.log(); 88 return; 89 } 90 91 Tag.prototype.rss_xml_action = function() { 92 res.dependsOn(this.site.modified); 93 res.digest(); 94 res.contentType = "text/xml"; 95 var tagHubs = this.getTagged().list(0, this.site.pageSize); 96 var stories = []; 97 for (var i in tagHubs) { 98 stories.push(tagHubs[i].tagged); 99 } 100 res.write(this.site.getXml(stories)); 101 return; 102 } 103 104 Tag.prototype.rename_action = function() { 105 var tag = this; 106 if (req.data.name) { 107 // Trim and remove troublesome characters (like ../.. etc.) 108 // We call getAccessName with a virgin HopObject to allow most names 109 var name = this.getAccessName.call(new HopObject, File.getName(req.data.name)); 110 tag = this.site.getTags(this.type, Tags.ALL).get(name); 111 if (!tag) { 112 tag = new Tag(name, this.site, this.type); 113 this.site.$tags.add(tag); 114 } 115 if (tag !== this) { 116 this.forEach(function() { 117 this.tag_id = tag._id; 118 }); 119 this.remove(); 120 res.commit(); 121 } 122 } 123 res.redirect(tag.href()); 124 return; 125 126 // FIXME: Actually, the method should work like this but it caused a mess: 127 if (req.data.name) { 128 var name = this.getAccessName.call(new HopObject, File.getName(req.data.name)); 129 var tag = this.site.getTags(this.type, Tags.ALL).get(name); 130 if (tag) { 131 if (tag !== this) { 132 // move tagged items to tag like above 133 } 134 } else { 135 // rename tag like: this.name = name 136 } 137 } 138 } 139 140 Tag.prototype.delete_action = function() { 141 var parent = this._parent; 142 while (this.size() > 0) { 143 this.get(0).remove(); 144 }; 145 this.remove(); 146 res.redirect(this.site[Tag.MOUNTPOINTS[this.type]].href()); 147 } 148 149 /** 150 * 151 * @param {String} action 152 * @returns {String} 153 */ 154 Tag.prototype.href = function(action) { 155 res.push(); 156 res.write(this.site[Tag.MOUNTPOINTS[this.type]].href()); 157 res.write(encodeURIComponent(this.name)); 158 res.write("/"); 159 if (action) { 160 res.write(java.net.URLEncoder.encode(action)); 161 } 162 return res.pop(); 163 } 164 165 /** 166 * 167 * @param {Object} param 168 * @param {String} type 169 */ 170 Tag.prototype.permission_macro = function(param, type) { 171 return this.getPermission(type); 172 } 173 174 /** 175 * @returns {Story[]|Image[]} 176 */ 177 Tag.prototype.getTagged = function() { 178 return this[pluralize(this.type.toLowerCase())]; 179 } 180 181 /** 182 * @returns {String} 183 */ 184 Tag.prototype.getTitle = function() { 185 return this.name; 186 } 187 188 /** 189 * @returns {String} 190 */ 191 Tag.prototype.toString = function() { 192 return "[" + this.type + " tag ``" + this.name + "'' of Site ``" + 193 this.site.alias + "'']"; 194 } 195