]> git.p6c8.net - selfforum.git/blob - selfforum-cgi/shared/Posting/Admin.pm
a075f569c6c4a30df27efd50c10ecee8635be207
[selfforum.git] / selfforum-cgi / shared / Posting / Admin.pm
1 package Posting::Admin;
2
3 ################################################################################
4 # #
5 # File: shared/Posting/Admin.pm #
6 # (was: ~Handle.pm) #
7 # #
8 # Authors: Frank Schönmann <fs@tower.de> #
9 # André Malo <nd@o3media.de> #
10 # #
11 # Description: Allow administration of postings #
12 # #
13 # Todo: * Lock files before modification #
14 # * Change body in change_posting_body() #
15 # * Recursively set invisibility flag in main forum xml by #
16 # hide_posting() and recover_posting() #
17 # #
18 ################################################################################
19
20 use strict;
21 use vars qw(
22 @EXPORT
23 );
24
25 use Lock qw(:READ);
26 use Posting::_lib qw(
27 get_message_node
28 save_file
29 get_all_threads
30 create_forum_xml_string
31 );
32
33 use XML::DOM;
34
35 ################################################################################
36 #
37 # Version check
38 #
39 # last modified:
40 # $Date$ (GMT)
41 # by $Author$
42 #
43 sub VERSION {(q$Revision$ =~ /([\d.]+)\s*$/)[0] or '0.0'}
44
45 ################################################################################
46 #
47 # Export
48 #
49 use base qw(Exporter);
50
51 @EXPORT = qw(
52 hide_posting
53 recover_posting
54 modify_posting
55 add_user_vote
56 level_vote
57 );
58
59 ### add_user_vote () ###########################################################
60 #
61 # Increase number of user votes (only in thread file)
62 #
63 # Params: $forum Path and filename of forum
64 # $tpath Path to thread files
65 # \%info Hash reference: 'thread', 'posting', 'percent'
66 # Return: Status code (Bool)
67 #
68 # Todo:
69 # * Lock files before modification
70 #
71 sub add_user_vote ($$$) {
72 my ($forum, $tpath, $info) = @_;
73 my ($tid, $mid, $percent) = ($info->{'thread'},
74 $info->{'posting'},
75 $info->{'percent'});
76
77 # Thread
78 my $tfile = $tpath . '/t' . $tid . '.xml';
79
80 my $parser = new XML::DOM::Parser;
81 my $xml = $parser->parsefile($tfile);
82
83 my $mnode = get_message_node($xml, $tid, $mid);
84 my $votes = $mnode->getAttribute('votingUser') + 1;
85 $mnode->setAttribute('votingUser', $votes);
86
87 return save_file($tfile, \$xml->toString);
88 }
89
90 ### level_vote () ##############################################################
91 #
92 # Set 1st or 2nd level voting (only in thread file)
93 #
94 # Params: $forum Path and filename of forum
95 # $tpath Path to thread files
96 # \%info Hash reference: 'thread', 'posting', 'level', 'value'
97 # Return: Status code (Bool)
98 #
99 # Todo:
100 # * Lock files before modification
101 #
102 sub level_vote {
103 my ($forum, $tpath, $info´) = @_;
104 my ($tid, $mid, $level, $value) = (
105 $info->{'thread'},
106 $info->{'posting'},
107 $info->{'level'},
108 $info->{'value'}
109 );
110
111 # Thread
112 my $tfile = $tpath . '/t' . $tid . '.xml';
113
114 my $parser = new XML::DOM::Parser;
115 my $xml = $parser->parsefile($tfile);
116
117 my $mnode = get_message_node($xml, $tid, $mid);
118
119 unless (defined $value) {
120 removeAttribute($level);
121 }
122 else {
123 $mnode->setAttribute($level, $value);
124 }
125
126 return save_file($tfile, \$xml->toString);
127 }
128
129 ### hide_posting () ############################################################
130 #
131 # Hide a posting: set 'invisible' flag
132 #
133 # Params: $forum Path and filename of forum
134 # $tpath Path to thread files
135 # \%info Hash reference: 'thread', 'posting', 'indexFile'
136 # Return: -none-
137 #
138 # Todo:
139 # * set flags recursively in forum xml
140 # * lock files before modification
141 #
142 sub hide_posting ($$$) {
143 my ($forum, $tpath, $info) = @_;
144 my ($tid, $mid, $indexFile) = ($info->{'thread'},
145 $info->{'posting'},
146 $info->{'indexFile'});
147
148 # Thread
149 my $tfile = $tpath . '/t' . $tid . '.xml';
150 change_posting_visibility($tfile, 't'.$tid, 'm'.$mid, 1);
151
152 # Forum
153 my ($f, $lthread, $lmsg, $dtd, $zlev) = get_all_threads($forum, 0, 0); # filter deleted, descending
154
155 for (@{$f->{$tid}})
156 {
157 if ($_->{'mid'} == $mid)
158 {
159 $_->{'deleted'} = 1;
160 }
161 }
162
163 my %cfxs = (
164 'dtd' => $dtd,
165 'lastMessage' => $lmsg,
166 'lastThread' => $lthread
167 );
168 my $xmlstring = create_forum_xml_string($f, \%cfxs);
169 save_file($forum, $$xmlstring);
170 }
171
172 ### recover_posting() ##########################################################
173 #
174 # Recover a posting: delete 'invisible' flag
175 #
176 # Params: $forum Path and filename of forum
177 # $tpath Path to thread files
178 # \%info Hash reference: 'thread', 'posting', 'indexFile'
179 # Return: -none-
180 #
181 # Todo:
182 # * set flags recursive in forum xml
183 # * lock files before modification
184 #
185 sub recover_posting ($$$) {
186 my ($forum, $tpath, $info) = @_;
187 my ($tid, $mid, $indexFile) = ($info->{'thread'},
188 $info->{'posting'},
189 $info->{'indexFile'});
190
191 # Thread
192 my $tfile = $tpath . '/t' . $tid . '.xml';
193 change_posting_visibility($tfile, 't'.$tid, 'm'.$mid, 0);
194
195 # Forum
196 my ($f, $lthread, $lmsg, $dtd, $zlev) = get_all_threads($forum, 1, 0); # do not filter deleted, descending
197
198 for (@{$f->{$tid}})
199 {
200 if ($_->{'mid'} == $mid)
201 {
202 $_->{'deleted'} = 0;
203 }
204 }
205
206 my %cfxs = (
207 'dtd' => $dtd,
208 'lastMessage' => $lmsg,
209 'lastThread' => $lthread
210 );
211 my $xmlstring = create_forum_xml_string($f, \%cfxs);
212 save_file($forum, $$xmlstring);
213 }
214
215 ### change_posting_visibility () ###############################################
216 #
217 # Set a postings visibility flag to $invisible
218 #
219 # Params: $fname Filename
220 # $tid Thread ID
221 # $mid Message ID
222 # $invisible 1 - invisible, 0 - visible
223 # Return: Status code
224 #
225 sub change_posting_visibility ($$$$)
226 {
227 my ($fname, $tid, $mid, $invisible) = @_;
228
229 my $parser = new XML::DOM::Parser;
230 my $xml = $parser->parsefile($fname);
231
232 # Set flag in given msg
233 my $mnode = get_message_node($xml, $tid, $mid);
234 $mnode->setAttribute('invisible', $invisible);
235
236 # Set flag in sub nodes
237 for ($mnode->getElementsByTagName('Message')) {
238 $_->setAttribute('invisible', $invisible);
239 }
240
241 return save_file($fname, \$xml->toString);
242 }
243
244 ### modify_posting () ##########################################################
245 #
246 # Modify a posting (only subject and category until now!)
247 #
248 # Params: $forum Path and filename of forum
249 # $tpath Path to thread files
250 # \%info Reference: 'thread', 'posting', 'indexFile', 'data'
251 # (data = \%hashref: 'subject', 'category', 'body')
252 # Return: -none-
253 #
254 sub modify_posting($$$) {
255 my ($forum, $tpath, $info) = @_;
256 my ($tid, $mid, $indexFile, $data) = (
257 $info->{'thread'},
258 $info->{'posting'},
259 $info->{'indexFile'},
260 $info->{'data'}
261 );
262
263 my ($subject, $category, $body) = (
264 $data->{'subject'},
265 $data->{'category'},
266 $data->{'body'}
267 );
268
269 my %msgdata;
270
271 # These values may be changed by change_posting_value()
272 $subject && $msgdata{'Subject'} = $subject;
273 $category && $msgdata{'Category'} = $category;
274
275 # Thread
276 my $tfile = $tpath . '/t' . $tid . '.xml';
277 change_posting_value($tfile, 't'.$tid, 'm'.$mid, \$msgdata);
278 $body && change_posting_body($tfile, 't'.$tid, 'm'.$mid, $body);
279
280 # Forum (does not contain msg bodies)
281 if ($subject or $category) {
282 my ($f, $lthread, $lmsg, $dtd, $zlev) = get_all_threads($forum, 1, 0);
283
284 for (@{$f->{$tid}}) {
285 if ($_->{'mid'} == $mid) {
286 $subject && $_->{'subject'} = $subject;
287 $category && $_->{'cat'} = $category;
288 }
289 }
290
291 my %cfxs = (
292 'dtd' => $dtd,
293 'lastMessage' => $lmsg,
294 'lastThread' => $lthread
295 );
296 my $xmlstring = create_forum_xml_string($f, \%cfxs);
297 save_file($forum, $$xmlstring);
298 }
299
300 ### change_posting_value () ####################################################
301 #
302 # Change specific values of a posting
303 #
304 # Params: $fname Filename
305 # $tid Thread ID
306 # $mid Message ID
307 # \%values New values
308 # Return: Status code
309 #
310 sub change_posting_value($$$$) {
311 my ($fname, $tid, $mid, $values) = @_;
312
313 my $parser = new XML::DOM::Parser;
314 my $xml = $parser->parsefile($fname);
315
316 my $mnode = get_message_node($xml, $tid, $mid);
317
318 for (keys %$values)
319 {
320 # Find first direct child node with name $_
321 my $nodes = $mnode->getElementsByTagName($_, 0);
322 my $node = $nodes->item(0);
323 $node->setValue($values->{$_});
324 }
325
326 return save_file($fname, \$xml->toString);
327 }
328
329 ### change_posting_body () #####################################################
330 #
331 # Change body of a posting
332 #
333 # Params: $fname Filename
334 # $tid Thread ID (unused, for compatibility purposes)
335 # $mid Message ID
336 # $body New body
337 # Return: Status code
338 #
339 # Todo:
340 # * Change body
341 #
342 sub change_posting_body ($$$$) {
343 my ($fname, $tid, $mid, $body) = @_;
344
345 my $parser = new XML::DOM::Parser;
346 my $xml = $parser->parsefile($fname);
347
348 my $mbnody = get_message_body($xml, $mid);
349
350 # todo: change body
351
352 return save_file($fname, \$xml->toString);
353 }
354
355
356 # Let it be true
357 1;
358
359 #
360 #
361 ### end of Posting::Admin ######################################################

patrick-canterino.de