liquid_feedback_frontend

view model/member.lua @ 10:72c5e0ee7c98

Version beta6

Bugfixes:
- Security fix: Every user was able to change the discussion URL of an initiative
- Creation of new issues in areas without default policies is now possible
- Members can now be sorted in different ways
- No error when trying to compare a draft with itself
- Added missing local statement to variable initialization in app/main/delegation/new.lua
- CSS flaw in initiative action bar fixed

New features:
- Possiblity to invite other users to become initiator
- Revokation of initiatives implemented
- Number of suggestions, supporters, etc. is shown on corresponding tabs of initiative view
- Members can now be sorted by account creation (default sorting is "newest first")
- Configuration option to create an automatic discussion link for all issues
- First draft of global timeline feature (not accessible via link yet)
- Custom stylesheet URL for users marked as developers

In area listing the number of closed issues is shown too

Renamed "author" field of initiative to "last author"

Removed wrongly included file app/main/member/_show_thumb.lua.orig in the distribution

Help texts updated
author bsw
date Sun Jan 10 12:00:00 2010 +0100 (2010-01-10)
parents 0ee1e0c42d4c
children 77d58efe99fd
line source
1 Member = mondelefant.new_class()
2 Member.table = 'member'
4 Member:add_reference{
5 mode = "1m",
6 to = "MemberHistory",
7 this_key = 'id',
8 that_key = 'member_id',
9 ref = 'history_entries',
10 back_ref = 'member'
11 }
13 Member:add_reference{
14 mode = '1m',
15 to = "MemberImage",
16 this_key = 'id',
17 that_key = 'member_id',
18 ref = 'images',
19 back_ref = 'member'
20 }
22 Member:add_reference{
23 mode = '1m',
24 to = "Contact",
25 this_key = 'id',
26 that_key = 'member_id',
27 ref = 'contacts',
28 back_ref = 'member',
29 default_order = '"other_member_id"'
30 }
32 Member:add_reference{
33 mode = '1m',
34 to = "Contact",
35 this_key = 'id',
36 that_key = 'member_id',
37 ref = 'foreign_contacts',
38 back_ref = 'other_member',
39 default_order = '"member_id"'
40 }
42 Member:add_reference{
43 mode = '1m',
44 to = "Session",
45 this_key = 'id',
46 that_key = 'member_id',
47 ref = 'sessions',
48 back_ref = 'member',
49 default_order = '"ident"'
50 }
52 Member:add_reference{
53 mode = '1m',
54 to = "Draft",
55 this_key = 'id',
56 that_key = 'author_id',
57 ref = 'drafts',
58 back_ref = 'author',
59 default_order = '"id"'
60 }
62 Member:add_reference{
63 mode = '1m',
64 to = "Suggestion",
65 this_key = 'id',
66 that_key = 'author_id',
67 ref = 'suggestions',
68 back_ref = 'author',
69 default_order = '"id"'
70 }
72 Member:add_reference{
73 mode = '1m',
74 to = "Membership",
75 this_key = 'id',
76 that_key = 'member_id',
77 ref = 'memberships',
78 back_ref = 'member',
79 default_order = '"area_id"'
80 }
82 Member:add_reference{
83 mode = '1m',
84 to = "Interest",
85 this_key = 'id',
86 that_key = 'member_id',
87 ref = 'interests',
88 back_ref = 'member',
89 default_order = '"id"'
90 }
92 Member:add_reference{
93 mode = '1m',
94 to = "Initiator",
95 this_key = 'id',
96 that_key = 'member_id',
97 ref = 'initiators',
98 back_ref = 'member'
99 }
101 Member:add_reference{
102 mode = '1m',
103 to = "Supporter",
104 this_key = 'id',
105 that_key = 'member_id',
106 ref = 'supporters',
107 back_ref = 'member'
108 }
110 Member:add_reference{
111 mode = '1m',
112 to = "Opinion",
113 this_key = 'id',
114 that_key = 'member_id',
115 ref = 'opinions',
116 back_ref = 'member',
117 default_order = '"id"'
118 }
120 Member:add_reference{
121 mode = '1m',
122 to = "Delegation",
123 this_key = 'id',
124 that_key = 'truster_id',
125 ref = 'outgoing_delegations',
126 back_ref = 'truster',
127 default_order = '"id"'
128 }
130 Member:add_reference{
131 mode = '1m',
132 to = "Delegation",
133 this_key = 'id',
134 that_key = 'trustee_id',
135 ref = 'incoming_delegations',
136 back_ref = 'trustee',
137 default_order = '"id"'
138 }
140 Member:add_reference{
141 mode = '1m',
142 to = "DirectVoter",
143 this_key = 'id',
144 that_key = 'member_id',
145 ref = 'direct_voter',
146 back_ref = 'member',
147 default_order = '"issue_id"'
148 }
150 Member:add_reference{
151 mode = '1m',
152 to = "Vote",
153 this_key = 'id',
154 that_key = 'member_id',
155 ref = 'vote',
156 back_ref = 'member',
157 default_order = '"issue_id", "initiative_id"'
158 }
160 Member:add_reference{
161 mode = 'mm',
162 to = "Member",
163 this_key = 'id',
164 that_key = 'id',
165 connected_by_table = 'contact',
166 connected_by_this_key = 'member_id',
167 connected_by_that_key = 'other_member_id',
168 ref = 'saved_members',
169 }
171 Member:add_reference{
172 mode = 'mm',
173 to = "Member",
174 this_key = 'id',
175 that_key = 'id',
176 connected_by_table = 'contact',
177 connected_by_this_key = 'other_member_id',
178 connected_by_that_key = 'member_id',
179 ref = 'saved_by_members',
180 }
182 Member:add_reference{
183 mode = 'mm',
184 to = "Area",
185 this_key = 'id',
186 that_key = 'id',
187 connected_by_table = 'membership',
188 connected_by_this_key = 'member_id',
189 connected_by_that_key = 'area_id',
190 ref = 'areas'
191 }
193 Member:add_reference{
194 mode = 'mm',
195 to = "Issue",
196 this_key = 'id',
197 that_key = 'id',
198 connected_by_table = 'interest',
199 connected_by_this_key = 'member_id',
200 connected_by_that_key = 'issue_id',
201 ref = 'issues'
202 }
204 Member:add_reference{
205 mode = 'mm',
206 to = "Initiative",
207 this_key = 'id',
208 that_key = 'id',
209 connected_by_table = 'initiator',
210 connected_by_this_key = 'member_id',
211 connected_by_that_key = 'initiative_id',
212 ref = 'initiated_initiatives'
213 }
215 Member:add_reference{
216 mode = 'mm',
217 to = "Initiative",
218 this_key = 'id',
219 that_key = 'id',
220 connected_by_table = 'supporter',
221 connected_by_this_key = 'member_id',
222 connected_by_that_key = 'initiative_id',
223 ref = 'supported_initiatives'
224 }
226 function Member.object:set_password(password)
227 local hash = os.crypt(
228 password,
229 "$1$" .. multirand.string(
230 8,
231 "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz./"
232 )
233 )
234 assert(hash, "os.crypt failed")
235 self.password = hash
236 end
238 function Member.object:check_password(password)
239 if type(password) == "string" and type(self.password) == "string" then
240 return os.crypt(password, self.password) == self.password
241 else
242 return false
243 end
244 end
246 function Member.object_get:published_contacts()
247 return Member:new_selector()
248 :join('"contact"', nil, '"contact"."other_member_id" = "member"."id"')
249 :add_where{ '"contact"."member_id" = ?', self.id }
250 :add_where("public")
251 :exec()
252 end
254 function Member:by_login_and_password(login, password)
255 local selector = self:new_selector()
256 selector:add_where{'"login" = ?', login }
257 selector:add_where('"active"')
258 selector:optional_object_mode()
259 local member = selector:exec()
260 if member and member:check_password(password) then
261 return member
262 else
263 return nil
264 end
265 end
267 function Member:by_login(login)
268 local selector = self:new_selector()
269 selector:add_where{'"login" = ?', login }
270 selector:optional_object_mode()
271 return selector:exec()
272 end
274 function Member:by_name(name)
275 local selector = self:new_selector()
276 selector:add_where{'"name" = ?', name }
277 selector:optional_object_mode()
278 return selector:exec()
279 end
281 function Member:get_search_selector(search_string)
282 return self:new_selector()
283 :add_field( {'"highlight"("member"."name", ?)', search_string }, "name_highlighted")
284 :add_where{ '"member"."text_search_data" @@ "text_search_query"(?)', search_string }
285 :add_where("active")
286 end
288 function Member.object:set_notify_email(notify_email)
289 local expiry = db:query("SELECT now() + '7 days'::interval as expiry", "object").expiry
290 self.notify_email_unconfirmed = notify_email
291 self.notify_email_secret = multirand.string( 24, "23456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz" )
292 self.notify_email_secret_expiry = expiry
293 local content = slot.use_temporary(function()
294 slot.put(_"Hello " .. self.name .. ",\n\n")
295 slot.put(_"Please confirm your email address by clicking the following link:\n\n")
296 slot.put(config.absolute_base_url .. "index/confirm_notify_email.html?secret=" .. self.notify_email_secret .. "\n\n")
297 slot.put(_"If this link is not working, please open following url in your web browser:\n\n")
298 slot.put(config.absolute_base_url .. "index/confirm_notify_email.html\n\n")
299 slot.put(_"On that page please enter the confirmation code:\n\n")
300 slot.put(self.notify_email_secret .. "\n\n")
301 end)
302 local success = net.send_mail{
303 envelope_from = config.mail_envelope_from,
304 from = config.mail_from,
305 reply_to = config.mail_reply_to,
306 to = self.notify_email_unconfirmed,
307 subject = config.mail_subject_prefix .. _"Email confirmation request",
308 content_type = "text/plain; charset=UTF-8",
309 content = content
310 }
311 return success
312 end

Impressum / About Us