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