      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