1 // The Antville Project 2 // http://code.google.com/p/antville 3 // 4 // Copyright 2007-2011 by Tobi Schäfer. 5 // 6 // Copyright 2001–2007 Robert Gaggl, Hannes Wallnöfer, Tobi Schäfer, 7 // Matthias & Michael Platzer, Christoph Lincke. 8 // 9 // Licensed under the Apache License, Version 2.0 (the ``License''); 10 // you may not use this file except in compliance with the License. 11 // You may obtain a copy of the License at 12 // 13 // http://www.apache.org/licenses/LICENSE-2.0 14 // 15 // Unless required by applicable law or agreed to in writing, software 16 // distributed under the License is distributed on an ``AS IS'' BASIS, 17 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 // See the License for the specific language governing permissions and 19 // limitations under the License. 20 // 21 // $Revision$ 22 // $LastChangedBy$ 23 // $LastChangedDate$ 24 // $URL$ 25 26 /** 27 * @fileOverview Defines the Tag prototype. 28 */ 29 30 markgettext("Tag"); 31 markgettext("tag"); 32 33 /** 34 * @constant 35 */ 36 Tag.MOUNTPOINTS = { 37 Story: "tags", 38 Image: "galleries" 39 } 40 41 /** 42 * @constant 43 */ 44 Tag.DELIMITER = ", "; 45 46 /** 47 * @param {String} name 48 * @param {Site} site 49 * @param {String} type 50 */ 51 Tag.add = function(name, type, site) { 52 var tag = new Tag; 53 tag.name = name; 54 tag.type = type; 55 tag.site = site; 56 site.$tags.add(tag); 57 return tag; 58 } 59 60 /** 61 * @name Tag 62 * @constructor 63 * @property {TagHub[]} _children 64 * @property {Images[]} images 65 * @property {String} name 66 * @property {Site} site 67 * @property {Story[]} stories 68 * @property {String} type 69 * @extends HopObject 70 */ 71 Tag.prototype.constructor = function() { 72 HopObject.confirmConstructor(Tag); 73 return this; 74 } 75 76 /** 77 * 78 * @param {String} action 79 * @returns {Boolean} 80 */ 81 Tag.prototype.getPermission = function(action) { 82 if (!res.handlers.site.getPermission("main")) { 83 return false; 84 } 85 switch (action) { 86 case ".": 87 case "main": 88 case "rss.xml": 89 return true; 90 case "edit": 91 case "delete": 92 case "rename": 93 return User.require(User.PRIVILEGED) || 94 Membership.require(Membership.MANAGER); 95 } 96 return false; 97 } 98 99 Tag.prototype.main_action = function() { 100 res.handlers.list = new jala.ListRenderer(this.getTagged()); 101 res.handlers.list.setPageSize(this.site.pageSize); 102 res.data.title = gettext("Tag: {0}", this.name); 103 res.data.body = this.renderSkinAsString("$Tag#main"); 104 res.handlers.site.renderSkin("Site#page"); 105 res.handlers.site.log(); 106 return; 107 } 108 109 Tag.prototype.rss_xml_action = function() { 110 res.contentType = "text/xml"; 111 res.dependsOn(this.site.modified); 112 res.digest(); 113 var tagHubs = this.getTagged().list(0, this.site.pageSize); 114 var stories = []; 115 for (var i in tagHubs) { 116 stories.push(tagHubs[i].tagged); 117 } 118 res.write(this.site.getXml(stories)); 119 return; 120 } 121 122 Tag.prototype.rename_action = function() { 123 var tag = this; 124 if (req.data.name) { 125 // Trim and remove troublesome characters (like ../.. etc.) 126 // We call getAccessName with a virgin HopObject to allow most names 127 var name = this.getAccessName.call(new HopObject, File.getName(req.data.name)); 128 tag = this.site.getTags(this.type, Tags.ALL).get(name); 129 if (!tag) { 130 tag = Tag.add(name, this.site, this.type); 131 } 132 if (tag !== this) { 133 this.forEach(function() { 134 this.tag_id = tag._id; 135 }); 136 this.remove(); 137 res.commit(); 138 } 139 } 140 res.redirect(tag.href()); 141 return; 142 143 // FIXME: Actually, the method should work like this but it caused a mess: 144 if (req.data.name) { 145 var name = this.getAccessName.call(new HopObject, File.getName(req.data.name)); 146 var tag = this.site.getTags(this.type, Tags.ALL).get(name); 147 if (tag) { 148 if (tag !== this) { 149 // move tagged items to tag like above 150 } 151 } else { 152 // rename tag like: this.name = name 153 } 154 } 155 } 156 157 Tag.prototype.delete_action = function() { 158 var parent = this._parent; 159 while (this.size() > 0) { 160 this.get(0).remove(); 161 }; 162 this.remove(); 163 res.redirect(this.site[Tag.MOUNTPOINTS[this.type]].href()); 164 } 165 166 /** 167 * 168 * @param {String} action 169 * @returns {String} 170 */ 171 Tag.prototype.href = function(action) { 172 res.push(); 173 res.write(this.site[Tag.MOUNTPOINTS[this.type]].href()); 174 res.write(encodeURIComponent(this.name)); 175 res.write("/"); 176 if (action) { 177 res.write(java.net.URLEncoder.encode(action)); 178 } 179 return res.pop(); 180 } 181 182 /** 183 * 184 * @param {Object} param 185 * @param {String} type 186 */ 187 Tag.prototype.permission_macro = function(param, type) { 188 return this.getPermission(type); 189 } 190 191 /** 192 * @returns {Story[]|Image[]} 193 */ 194 Tag.prototype.getTagged = function() { 195 return this[pluralize(this.type.toLowerCase())]; 196 } 197 198 /** 199 * @returns {String} 200 */ 201 Tag.prototype.getTitle = function() { 202 return this.name; 203 } 204 205 /** 206 * @returns {String} 207 */ 208 Tag.prototype.toString = function() { 209 return this.type + " tag " + this.name + " of Site " + this.site.alias; 210 } 211