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