Began to write version 2.0.0 of this extension. It's not finished yet.
[philipp/winterrodeln/mediawiki_extensions/wrreport.git] / wrreport.body.php
1 <?php
2 // Classes for the wrreport extension.
3
4
5 // Special page
6 // ------------
7
8 /// Specal Page to show reports
9 class SpecialWrReport extends SpecialPage {
10         function __construct() {
11                 parent::__construct('wrreport');
12         }
13
14
15         /// \param $par Possibilities:
16         /// - action == 'view' (default)
17         /// - action == 'preview': Preview new report
18         /// - action == 'store': Store new report
19         /// - action == 'deletepreview': Preview the deleted record
20         /// - action == 'delete': Delete an existing report
21         /// - action == 'showerror': Shows the error and exits
22         /// \param $override_action If not NULL (default), it overrides the action in $par
23         /// \param $errorMsg UFT-8 encoded error message (in WikiText) to show on top of the page or NULL (default):
24         function execute($par, $override_action = NULL, $errorMsg = NULL) {
25                 global $wgRequest, $wgOut;
26
27                 $this->setHeaders();
28
29                 // Get request data
30                 $action = $wgRequest->getText('action');
31                 if (!$action) {
32                         if ($wgRequest->getVal('preview')) $action = 'preview';
33                         elseif ($wgRequest->getVal('store')) $action = 'store';
34                         elseif ($wgRequest->getVal('deletepreview')) $action = 'deletepreview';
35                         elseif ($wgRequest->getVal('delete')) $action = 'delete';
36                         else $action = 'view';
37                 }
38                 if ($override_action) $action = $override_action;
39
40                 // Show error message
41                 if ($errorMsg || $action == 'showerror') {
42                         $wgOut->addWikiText('<div class="errorbox">' . $errorMsg . "</div>\n");
43                         if ($action == 'showerror') return;
44                 }
45
46                 // Action view
47                 if ($action == 'view') {                
48                         $conditions = array('date_invalid > now()');
49                         $rows = wrReportGetReports($conditions);
50                         if (count($rows) == 0) $wgOut->addWikiText("''Es wurden keine Bahnberichte in der Datenbank gefunden.''\n\n");
51                         $wgOut->addHTML(wrReportTableRender2($rows, WRREPORT_DETAIL, wrReportUserMayDelete())); 
52                 }
53
54                 // Action deletepreview or delete
55                 elseif ($action == 'deletepreview' || $action == 'delete') {
56                         $reportid = (int) $wgRequest->getText('reportid');
57                         if ($reportid == 0) {
58                                 $this->execute($par, 'showerror', utf8_encode('Es wurde kein Bericht zum Löschen ausgewählt.'));
59                                 return;
60                         }
61                         $rows = wrReportGetReports(array('id' => $reportid));
62                         if (count($rows) != 1) {
63                                 $this->execute($par, 'showerror', utf8_encode('Es wurde ein ungültiger Bericht zum Löschen ausgewählt.'));
64                                 return;
65                         }
66                         $row = $rows[0];
67                         if (!is_null($row['delete_date'])) {
68                                 $this->execute($par, 'showerror', utf8_encode('Der angegebende Bericht ist bereits gelöscht.'));
69                                 return;
70                         }
71                         $delete_reason_public = $wgRequest->getText('delete_reason_public');
72                         $delete_person_name = $wgRequest->getText('delete_person_name');
73                         $delete_invisible = $wgRequest->getText('delete_invisible') ? TRUE : FALSE;
74                         if ($action == 'delete') {
75                                 // page
76                                 $title = Title::newFromId($row['page_id']);
77
78                                 // user
79                                 global $wgUser;
80                                 $delete_person_userid = $wgUser->getId();
81                                 if ($delete_person_userid == 0) $delete_person_userid = NULL; // to store a NULL value in the database if no user is logged in instead of 0.
82                                 $delete_person_username = $wgUser->getName();
83
84                                 // Check permissions - see also function wrReportUserMayDelete, that does also check permissions but does not return an error message.
85                                 $errorMsg = NULL;
86                                 global $wgWrReportDeleteMode;
87                                 if ($wgWrReportDeleteMode == 'deny') $errorMsg = utf8_encode('Das Löschen von Rodelbahnberichten ist derzeit leider nicht erlaubt.');
88                                 elseif ($wgWrReportDeleteMode == 'loggedin' && !$wgUser->isLoggedIn()) $errorMsg = utf8_encode('Derzeit dürfen nur angemeldete Benutzer Rodelbahnberichte löschen.');
89                                 elseif (!$delete_person_name || !$delete_reason_public) $errorMsg = utf8_encode('Es müssen sowohl die Begründung als auch der Name angegeben werden.');
90                                 if ($errorMsg) {
91                                         $this->execute($par, 'deletepreview', $errorMsg);
92                                         return;
93                                 }
94                                 
95                                 // "Delete" (update) entry
96                                 $dbr = wfGetDB(DB_MASTER);
97                                 $dbr->update(
98                                         'wrreport', 
99                                         array(
100                                                 'delete_date' => date('c'),
101                                                 'delete_person_name' => $delete_person_name,
102                                                 'delete_person_ip' => $_SERVER['REMOTE_ADDR'],
103                                                 'delete_person_userid' => $delete_person_userid,
104                                                 'delete_person_username' => $delete_person_username,
105                                                 'delete_reason_public' => $delete_reason_public,
106                                                 'delete_invisible' => $delete_invisible ? 't' : 'f'
107                                         ),
108                                         array('id' => $reportid)
109                                 );
110
111                                 // Purge cache
112                                 $title->invalidateCache();
113                                 wrRecacheRegions();                             
114
115                                 // Show success message
116                                 $wgOut->addWikiText(wfMsg('wrreport-deletereport-success', '[[' . $row['page_title'] . '#' . wfMsg('wrreport-reports-sectionname') . '|' . $row['page_title'] . ']]'));
117                         }
118                         if ($action == 'deletepreview') {
119                                 $preview_msg = "Bitte nur dann einen Bericht löschen, wenn Gründe vorliegen wie\n" .
120                                 "* Beschimpfungen, Verleumdungen (wir wollen ''Rodelbahnen'' bewerten, nicht Personen)\n" .
121                                 "* Werbung oder Spam (wenn jemand allerdings ''werbend'' zu gute Noten vergibt, lieber eigenen Bericht eintragen als löschen).\n\n";
122                                 $wgOut->addWikiText(utf8_encode($preview_msg));
123                                 $wgOut->addWikiText(utf8_encode("== Schneelagebericht, um den es beim Löschen geht ==\n"));
124                                 $format = WRREPORT_COMPACT_PAGE;
125                                 $wgOut->addHTML(wrReportTableRender2(array($row), $format, FALSE));
126                                 $wgOut->addWikiText(utf8_encode("\n\n== Vorschau (derzeit noch nicht gelöscht) ==\n"));
127                                 $row['delete_date'] = date('c');
128                                 $row['delete_reason_public'] = $delete_reason_public;
129                                 $row['delete_person_name'] = $delete_person_name;
130                                 $row['delete_invisible'] = $delete_invisible;
131                                 $wgOut->addHTML(wrReportTableRender2(array($row), $format, FALSE));
132                                 $wgOut->addWikiText(utf8_encode("== Löschen ==\n"));
133                                 $wgOut->addWikiText(utf8_encode("Die Begründung und der Name scheinen nicht in den normalen Listen auf, allerdings dienen sie den Administratoren dazu, sich schnell einen Überblick zu verschaffen, wer was warum gelöscht hat.\n"));
134                                 $wgOut->addHTML(wrDeleteReportFormRender($reportid, $delete_person_name, $delete_reason_public, $delete_invisible));
135                         }
136                 }
137
138                 // Action preview or store
139                 elseif ($action == 'preview' || $action == 'store') {
140                         $page_title = $wgRequest->getText('page_title');
141                         $date_report = $wgRequest->getText('date_report');
142                         $condition = $wgRequest->getText('condition');
143                         $description = $wgRequest->getText('description');
144                         $author_name = $wgRequest->getText('author_name');
145                         
146                         // condition
147                         $condition = (int) $condition; // force to be nummeric. -1 ... "keine Bewertung", 0 ... "Bitte eingeben", 1 to 5 ... "Sehr gut" to "Geht nicht"
148                         if ($condition < -1 or $condition > 5) $condition = 0; // invalid condition: Tread like 0.
149                         $condition_sql = NULL;
150                         if ($condition >= 1 and $condition <= 5) $condition_sql = $condition;
151
152                         // author_name
153                         $author_name = trim($author_name);
154
155                         if ($action == 'store') {
156                                 // page_id
157                                 $title = Title::newFromText($page_title);
158                                 $page_id = $title->getArticleId();
159                                 if ($page_id == 0) $page_id = NULL;
160                                 
161                                 // user_id
162                                 global $wgUser;
163                                 $author_userid = $wgUser->getId();
164                                 if ($author_userid == 0) $author_userid = NULL; // to store a NULL value in the database if no user is logged in instead of 0.
165                                 $author_username = $wgUser->getName();
166
167                                 // description
168                                 $description_html = wrCommonSandboxParse($description); // this variable is used for checks of the created code (below)
169                                 
170                                 // check conditions/permissions
171                                 $errorMsg = NULL;
172                                 global $wgWrReportMode;
173                                 global $wgWrReportBlackListAll;
174                                 global $wgWrReportBlackListStrangers;
175                                 if ($wgWrReportMode == 'summer') $errorMsg = utf8_encode('Rodelbahnberichte sind in der schneefreien Zeit nicht erlaubt.');
176                                 elseif ($wgWrReportMode == 'deny') $errorMsg = utf8_encode('Rodelbahnberichte sind derzeit leider nicht erlaubt.');
177                                 elseif ($wgWrReportMode == 'loggedin' && !$wgUser->isLoggedIn()) $errorMsg = utf8_encode('Derzeit sind Rodelbahnberichte nur für angemeldete Benutzer erlaubt.');
178                                 elseif (!$page_id) $errorMsg = utf8_encode('Die angegebene Seite wurde nicht gefunden.');
179                                 elseif (in_array($page_title, $wgWrReportBlackListAll)) $errorMsg = utf8_encode('Bei der angegebenen Rodelbahn dürfen derzeit keine Rodelbahnberichte abgegeben werden.');
180                                 elseif (!$wgUser->isLoggedIn() && in_array($page_title, $wgWrReportBlackListStrangers)) $errorMsg = utf8_encode('Bei der angegebenen Rodelbahn dürfen derzeit nur angemeldete Benutzer Rodelbahnberichte abgebe.');
181                                 elseif ($condition == 0) $errorMsg = utf8_encode('Bitte einen Bahnzustand aus der Liste auswählen.');
182                                 elseif ($condition <= 0 && !$description) $errorMsg = utf8_encode('Es sind sowohl die Beschreibung als auch die Bewertung sind leer.');
183                                 elseif (!$wgUser->isLoggedIn()) {
184                                         if (!$description) $errorMsg = utf8_encode('Bitte bei der Beschreibung eine kurze Begründung für die Bewertung abgeben.');
185                                         elseif (!(stripos($description, 'http') === FALSE)) $errorMsg = utf8_encode('Der Text "http" ist leider für nicht-angemeldete Benutzer nicht erlaubt, weil wir in der Vergangenheit Fälle hatten, bei denen externe Werbelinks automatisiert eingetragen wurden.');
186                                         elseif (!$author_name) $errorMsg = utf8_encode('Bitte einen Autorennamen angeben (das kann gerne auch ein Pyseudonym, Nickname oder ein Kürzel sein).');
187                                         // We want to disallow certain types of markup. Unfortunately the mediawiki markup language parser cannot be configured therefore we have to filter the input manually.
188                                         // Disallow "<pre>":
189                                         elseif (!(stripos($description_html, '<pre>') === FALSE)) $errorMsg = utf8_encode('Es wurde eine WikiText Formatierung (pre) verwendet, die für nicht angemeldete Benutzer nicht erlaubt ist - bitte einen Eintrag ohne Wiki Formatierung verwenden - danke!');
190                                 }
191
192                                 // check author name
193                                 if (!$errorMsg) {
194                                         $author_name_id = $wgUser->idFromName(strtolower($author_name));
195                                         if ($wgUser->isLoggedIn()) {
196                                                 if ($author_name_id != 0 && $author_name_id != $wgUser->getId())
197                                                         $errorMsg = utf8_encode('Der von Ihnen verwendete Autorenname ist der Login-Name eines anderen Benutzers und kann daher nicht als Autorenname verwendet werden.');
198                                         } else {
199                                                 if ($author_name_id != 0)
200                                                         $errorMsg = utf8_encode('Der von Ihnen verwendete Autorenname ist der Login-Name eines Wiki-Benutzers und kann daher bei anonymen Berichten nicht verwendet werden. Wenn dieser Name Ihnen "gehört" dann melden Sie sich bitte an und probieren es nochmals.');
201                                         }
202                                 }
203
204                                 // Chech whether identical reports are present
205                                 if (!$errorMsg) {
206                                         $dbr = wfGetDB(DB_SLAVE);
207                                         $cond = 'condition';
208                                         global $wgDBtype;
209                                         if ($wgDBtype == "mysql") $cond = "`$cond`"; // "condition" is a reserved word in mysql
210                                         $sqlConditions = array('page_id' => $page_id, 'date_report' => $date_report, $cond => $condition_sql, 'description' => $description, 'author_name' => $author_name);
211                                         $res = $dbr->select('wrreport', 'id', $sqlConditions);
212                                         if ($res->numRows() == 1) $errorMsg = utf8_encode('Der Rodelbahnbericht wurde bereits früher gespeichert.');
213                                         $dbr->freeResult($res);
214                                 }
215
216                                 // Show error if any
217                                 if ($errorMsg) {
218                                         $this->execute($par, 'preview', $errorMsg);
219                                         return;
220                                 }
221
222                                 // Save entry
223                                 $dbr = wfGetDB(DB_MASTER);
224                                 $dbr->insert(
225                                         'wrreport', 
226                                         array(
227                                                 'page_id' => $page_id, 
228                                                 'page_title' => $page_title, 
229                                                 'date_report' => $date_report, 
230                                                 'date_entry' => date('c'),
231                                                 'date_invalid' => date('c', strtotime('+9 days')),
232                                                 $cond => $condition_sql,
233                                                 'description' => $description,
234                                                 'author_name' => $author_name,
235                                                 'author_ip' => $_SERVER['REMOTE_ADDR'],
236                                                 'author_userid' => $author_userid,
237                                                 'author_username' => $author_username
238                                                 // 'delete_*' => // use database defaults (NULL)
239                                         )
240                                 );
241
242                                 // Purge cache
243                                 $title->invalidateCache();
244                                 wrRecacheRegions();                             
245                                 wrUpdateWrReportCacheTable($page_id);
246
247                                 // Show success message
248                                 $wgOut->addWikiText(wfMsg('wrreport-newreport-success', '[[' . $page_title . '#' . wfMsg('wrreport-reports-sectionname') . '|' . $page_title . ']]'));
249                                 // We could redirect to result with the following line but we don't want to.
250                                 // $wgOut->redirect($title->getFullURL() . '#Eintr.C3.A4ge');
251                         }
252                         if ($action == 'preview') {
253                                 $wgOut->addWikiText(wfMsg('wrreport-newreport-preview-top'));
254                                 $format = WRREPORT_COMPACT_PAGE;
255                                 $row = array_fill_keys(wrReportGetColumnNames(), NULL);
256                                 $row['page_title'] = $page_title;
257                                 $row['date_report'] = $date_report;
258                                 $row['condition'] = $condition_sql;
259                                 $row['description'] = $description;
260                                 $row['author_name'] = $author_name;
261                                 $wgOut->addHTML(wrReportTableRender2(array($row), $format, FALSE));
262                                 $wgOut->addWikiText(wfMsg('wrreport-newreport-preview-middle'));
263                                 $wgOut->addHTML(wrReportFormRender(FALSE, $page_title, $date_report, $condition, $description, $author_name));
264                                 $wgOut->addWikiText(wfMsg('wrreport-newreport-preview-bottom'));
265                         } 
266                         
267                 }
268
269                 else die('Wrong action');
270         }
271 }
272
273
274 ?>