      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 // $Author$
     23 // $Date$
     24 // $URL$
     25
     26 /**
     27  * @fileOverview Defines the Membership prototype
     28  */
     29
     30 markgettext("Membership");
     31 markgettext("membership");
     32
     33 /**
     34  *
     35  * @param {String} name
     36  * @param {Site} site
     37  * @returns {Membership}
     38  */
     39 Membership.getByName = function(name, site) {
     40    return (site || res.handlers.site).members.get(name);
     41 }
     42
     43 /**
     44  *
     45  * @param {String} role
     46  * @returns {Boolean}
     47  */
     48 Membership.require = function(role) {
     49    if (res.handlers.membership) {
     50       return res.handlers.membership.require(role);
     51    }
     52    return false;
     53 }
     54
     55 /**
     56  * @function
     57  * @returns {String[]}
     58  * @see defineConstants
     59  */
     60 Membership.getRoles = defineConstants(Membership, markgettext("Subscriber"),
     61       markgettext("Contributor"), markgettext("Manager"), markgettext("Owner"));
     62
     63
     64 /**
     65  * @param {User} user
     66  * @param {String} role
     67  * @param {Site} site
     68  */
     69 Membership.add = function(user, role, site) {
     70    HopObject.confirmConstructor(Membership);
     71    user || (user = session.user);
     72    var membership = new Membership(user, role);
     73    membership.created = new Date;
     74    membership.touch();
     75    site.members.add(membership);
     76    return membership;
     77 }
     78 /**
     79  *
     80  * @param {Membership} membership
     81  * @param {Object} options
     82  */
     83 Membership.remove = function(options) {
     84    options || (options = {});
     85    if (this.constructor !== Membership) {
     86       return;
     87    }
     88    if (!options.force && !this.getPermission("delete")) {
     89       throw Error(gettext("Sorry, an owner of a site cannot be removed."));
     90    }
     91    var recipient = this.creator.email;
     92    this.remove();
     93    if (!options.force) {
     94       this.notify(req.action, recipient,
     95             gettext("[{0}] Notification of membership cancellation", root.title));
     96    }
     97    return;
     98 }
     99
    100 /**
    101  * @name Membership
    102  * @constructor
    103  * @param {User} user
    104  * @param {String} role
    105  * @property {Comment[]} comments
    106  * @property {Story[]} content
    107  * @property {Date} created
    108  * @property {User} creator
    109  * @property {File[]} files
    110  * @property {Image[]} images
    111  * @property {Date} modified
    112  * @property {User} modifier
    113  * @property {String} name
    114  * @property {Poll[]} polls
    115  * @property {String} role
    116  * @property {Site} site
    117  * @property {Story[]} stories
    118  * @extends HopObject
    119  */
    120 Membership.prototype.constructor = function(user, role) {
    121    HopObject.confirmConstructor(this);
    122    user || (user = session.user);
    123    if (user) {
    124       this.map({
    125          creator: user,
    126          name: user.name,
    127          role: role
    128       });
    129    }
    130    return this;
    131 }
    132
    133 /**
    134  *
    135  * @param {String} action
    136  * @return {Boolean}
    137  */
    138 Membership.prototype.getPermission = function(action) {
    139    if (!res.handlers.site.getPermission("main")) {
    140       return false;
    141    }
    142    switch (action) {
    143       case "contact":
    144       return true;
    145       case "edit":
    146       case "delete":
    147       return User.require(User.PRIVILEGED) ||
    148             this.role !== Membership.OWNER || this.creator !== session.user;
    149    }
    150    return false;
    151 }
    152
    153 /**
    154  *
    155  * @param {String} name
    156  * @returns {Object}
    157  */
    158 Membership.prototype.getFormOptions = function(name) {
    159    switch (name) {
    160       case "role":
    161       return Membership.getRoles();
    162    }
    163    return;
    164 }
    165
    166 Membership.prototype.edit_action = function() {
    167    if (req.postParams.save) {
    168       try {
    169          this.update(req.postParams);
    170          res.message = gettext("The changes were saved successfully.");
    171          res.redirect(this._parent.href());
    172       } catch(ex) {
    173          res.message = ex;
    174          app.log(ex);
    175       }
    176    }
    177
    178    res.data.action = this.href(req.action);
    179    res.data.title = gettext("Edit Membership: {0}", this.name);
    180    res.data.body = this.renderSkinAsString("$Membership#edit");
    181    this.site.renderSkin("Site#page");
    182    return;
    183 }
    184
    185 /**
    186  *
    187  * @param {Object} data
    188  */
    189 Membership.prototype.update = function(data) {
    190    if (!data.role) {
    191       throw Error(gettext("Please choose a role for this member."));
    192    } else if (this.user === session.user) {
    193       throw Error(gettext("Sorry, you are not allowed to edit your own membership."));
    194    } else if (data.role !== this.role) {
    195       this.role = data.role || Membership.SUBSCRIBER;
    196       this.touch();
    197       this.notify(req.action, this.creator.email,
    198             gettext("[{0}] Notification of membership change", root.title));
    199    }
    200    return;
    201 }
    202
    203 Membership.prototype.contact_action = function() {
    204    if (req.postParams.send) {
    205       try {
    206          if (!req.postParams.text) {
    207             throw Error(gettext("Please enter the message text."));
    208          }
    209          Feature.invoke("recaptcha", function() {
    210             return this.verify(req.postParams);
    211          });
    212          this.notify(req.action, this.creator.email, session.user ?
    213                gettext('[{0}] Message from user {1}', root.title, session.user.name) :
    214                gettext('[{0}] Message from anonymous user', root.title));
    215          res.message = gettext("Your message was sent successfully.");
    216          res.redirect(this._parent.getPermission() ?
    217                this._parent.href() : this.site.href());
    218       } catch(ex) {
    219          res.message = ex;
    220          app.log(ex);
    221       }
    222    }
    223
    224    res.data.action = this.href(req.action);
    225    res.data.title = gettext('Contact User: {0}', this.name);
    226    res.data.body = this.renderSkinAsString("$Membership#contact");
    227    this.site.renderSkin("Site#page");
    228    return;
    229 }
    230
    231 Membership.prototype.content_action = function() {
    232    res.data.list = renderList(this.content, "$Story#listItem",
    233          10, req.queryParams.page);
    234    res.data.pager = renderPager(this.content,
    235          this.href(), 10, req.queryParams.page);
    236    res.data.title = gettext("Content of User: {0}", this.name);
    237    res.data.body = this.renderSkinAsString("$Membership#content");
    238    this.site.renderSkin("Site#page");
    239 }
    240
    241 /**
    242  *
    243  * @param {String} name
    244  * @returns {HopObject}
    245  */
    246 Membership.prototype.getMacroHandler = function(name) {
    247    switch (name) {
    248       case "user":
    249       return this.creator;
    250    }
    251    return null;
    252 }
    253
    254 /**
    255  *
    256  * @param {String} role
    257  * @returns {Boolean}
    258  */
    259 Membership.prototype.require = function(role) {
    260    var roles = [Membership.SUBSCRIBER, Membership.CONTRIBUTOR,
    261          Membership.MANAGER, Membership.OWNER];
    262    if (role) {
    263       return roles.indexOf(this.role) >= roles.indexOf(role);
    264    }
    265    return false;
    266 }
    267
    268 /**
    269  *
    270  * @param {String} action
    271  * @param {String} recipient
    272  * @param {String} subject
    273  */
    274 Membership.prototype.notify = function(action, recipient, subject) {
    275    switch (action) {
    276       case "add":
    277       case "contact":
    278       case "delete":
    279       case "edit":
    280       case "register":
    281       res.handlers.sender = User.getMembership();
    282       sendMail(recipient, subject, this.renderSkinAsString("$Membership#notify_" + action),
    283             {footer: action !== "contact"});
    284       break;
    285    }
    286    return;
    287 }
    288
    289 /**
    290  * @returns {String}
    291  */
    292 Membership.prototype.getConfirmText = function() {
    293    return gettext("You are about to delete the membership of user {0}.",
    294          this.creator.name);
    295 }
    296
    297 /**
    298  * @returns {String}
    299  */
    300 Membership.prototype.toString = function() {
    301    return (this.role || "Transient") + " membership of user " + this.name;
    302 }
    303
    304 /**
    305  * @function
    306  * @see #toString
    307  */
    308 Membership.prototype.valueOf = Membership.prototype.toString;
    309
    310 /**
    311  *
    312  */
    313 Membership.prototype.status_macro = function() {
    314    this.renderSkin(session.user ? "Membership#status" : "Membership#login");
    315    return;
    316 }
    317
    318 /**
    319  *
    320  */
    321 Membership.prototype.role_macro = function() {
    322    this.role && res.write(gettext(this.role.capitalize()));
    323    return;
    324 }
    325
    326 /**
    327  *
    328  * @param {Object} value
    329  * @param {Object} param
    330  * @returns {String}
    331  * @see HopObject#link_filter
    332  */
    333 Membership.prototype.link_filter = function(value, param) {
    334    if (!session.user || !session.user.url) {
    335       return value;
    336    }
    337    return HopObject.prototype.link_filter.call(this, value,
    338          param, session.user.url); // || this.href());
    339 }
    340