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} of {1}", this.name, res.handlers.site.getTitle());
 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