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