654c0d587652392ffa36f4c886f79114b63d5a44
[atutor.git] / mods / wiki / plugins / admin / control.php
1 <?php
2
3 /*
4   This plugin provides per-page administrative functions, for easier access
5   to some settings and tools. Currently supports page renaming and page flag
6   setting.
7   requires _PROTECTED_MODE, see ewiki_auth() in README, and $ewiki_ring==0
8
9   The functions have following ring permission level equirements:
10      delete: ring<=1 moderators
11      rename: ring<=1 moderators
12      meta:   ring=0 admins
13      flags:  ring=0 admins, moderators may change just some flags
14
15   For styling purposes following CSS selectors could be used:
16     .wiki.control  .flags  {...}
17     .wiki.control  .rename  {...}
18     .wiki.control  .meta  {...}
19     .wiki.control  .delete  {...}
20 */
21
22
23 #-- which flags moderators may change
24 define("EWIKI_DB_F_MODERATORFLAGS",  0x0070 | 0x0004 | 0x0008);
25                              # == EWIKI_DB_F_ACCESS | EWIKI_DB_F_DISABLED | EWIKI_DB_F_HTML
26
27
28 #-- glue
29 $ewiki_plugins["action"]["control"] = "ewiki_action_control_page";
30 $ewiki_config["action_links"]["view"]["control"] = "Page Control";
31
32
33 #-- implementation
34 function ewiki_action_control_page($id, &$data, $action) {
35    global $ewiki_ring, $ewiki_config, $ewiki_plugins;
36
37    $a_flagnames = array(
38       "_TEXT", "_BINARY", "_DISABLED", "_HTML", "_READONLY", "_WRITEABLE",
39       "_APPENDONLY", "_SYSTEM", "_PART", "_MINOR", "_HIDDEN", "_ARCHIVE",
40       "_UU12", "_UU13", "_UU14", "_UU15", "_UU16", "_EXEC", "_UU18", "_UU19",
41    );
42    
43
44    $o = ewiki_make_title($id, "control $id", 2);
45
46    #-- admin requ. ---------------------------------------------------------
47    if (!ewiki_auth($id,$data,$action, $ring=0, "_FORCE_LOGIN=1") || !isset($ewiki_ring) || ($ewiki_ring > 1)) {
48
49       if (is_array($data)) {
50          $data = "You'll need to be admin. See ewiki_auth() and _PROTECTED_MODE in the README.";
51       }
52       $o .= $data;
53      
54    }
55
56    #-- page flags ---------------------------------------------------------
57    elseif (@$_REQUEST["pgc_setflags"]) {
58
59       #-- setted new flags
60       $new_f = 0;
61       foreach ($_REQUEST["sflag"] as $n=>$b) {
62          if ($b) {
63             $new_f |= (1 << $n);
64          }
65       }
66       #-- administrator may change all flags
67       if ($ewiki_ring==0) {
68          $data["flags"] = $new_f;
69       }
70       #-- moderators only a few
71       else {
72          $data["flags"] = ($data["flags"] & ( ~ EWIKI_DB_F_MODERATORFLAGS))
73                         | ($new_f & EWIKI_DB_F_MODERATORFLAGS);
74       }
75       $data["lastmodified"] = time();
76       $data["version"]++;
77
78       if (ewiki_db::WRITE($data)) {
79          $o .= "Page flags were updated correctly.";
80          ewiki_log("page flags of '$id' were set to $data[flags]");
81       }
82       else {
83          $o .= "A database error occoured.";
84       }
85    }
86
87    #-- renaming -----------------------------------------------------------
88    elseif  (@$_REQUEST["pgc_rename"] && strlen($new_id = $_REQUEST["mv_to"])) {
89
90       $old_id = $id;
91       $report = "";
92
93       $preg_id = "/". addcslashes($old_id, ".+*?|/\\()$[]^#") ."/"
94                  . ($_REQUEST["mv_cr1"] ? "i" : "");
95
96       #-- check if new name does not already exist in database
97       $exists = ewiki_db::GET($new_id);
98       if ($exists || !empty($exists)) {
99          return($o .= "Cannot overwrite an existing database entry.");
100       }
101
102       #-- copy from old name to new name
103       $max_ver = $data["version"];
104       $data = array();
105       for ($v=1; $v<=$max_ver; $v++) {
106
107          $row = ewiki_db::GET($old_id, $v);
108          $row["id"] = $new_id;
109          $row["lastmodified"] = time();
110          $row["content"] = preg_replace($preg_id, $new_id, $row["content"]);
111          ewiki_scan_wikiwords($row["content"], $links, "_STRIP_EMAIL=1");
112          $row["refs"] = "\n\n".implode("\n", array_keys($links))."\n\n";
113          $row["author"] = ewiki_author("control/");
114
115          if (!ewiki_db::WRITE($row)) {
116             $report .= "error while copying version $v,<br />\n";
117               
118          }
119       }
120
121       #-- proceed if previous actions error_free
122       if (empty($report)) {
123
124          #-- deleting old versions
125          for ($v=1; $v<=$max_ver; $v++) {
126             ewiki_db::DELETE($old_id, $v);
127          }
128
129          #-- adjust links/references to old page name
130          if ($_REQUEST["mv_cr0"]) {
131
132             $result = ewiki_db::SEARCH("refs", $old_id);
133             while ($result && ($row = $result->get())) {
134
135                $row = ewiki_db::GET($row["id"]);
136
137                if (preg_match($preg_id, $row["content"], $uu)) {
138
139                   $row["content"] = preg_replace($preg_id, $new_id, $row["content"]);
140                   $row["lastmodified"] = time();
141                   $row["version"]++;
142                   ewiki_scan_wikiwords($row["content"], $links, "_STRIP_EMAIL=1");
143                   $row["refs"] = "\n\n".implode("\n", array_keys($links))."\n\n";
144                   $row["author"] = ewiki_author("control/");
145
146                   if (!ewiki_db::WRITE($row)) {
147                      $report .= "could not update references in ".$row['id'].",<br />\n";
148                   } 
149                   else {
150                      $report .= "updated references in ".$row['id'].",<br />\n";
151                   }
152                }
153
154             }
155
156          }
157
158          $o .= "This page was correctly renamed from '$old_id' to '$new_id'.<br /><br />\n$report";
159          ewiki_log("page renamed from '$old_id' to '$new_id'", 2);
160
161       }
162       else {
163
164          $o .= "Some problems occoured while processing your request, therefor the old page still exists:<br />\n" . $report;
165       }
166
167    }
168
169    #-- meta data -----------------------------------------------------------
170    elseif (@$_REQUEST["pgc_setmeta"] && ($ewiki_ring==0) && ($set = explode("\n", $_REQUEST["pgc_meta"]))) {
171
172       $new_meta = array();
173       foreach ($set as $line) {
174          if (($line=trim($line)) && ($key=trim(strtok($line, ":"))) && ($value=trim(strtok("\000"))) ) {
175             $new_meta[$key] = $value;
176          }
177       }
178
179       $data["meta"] = $new_meta;
180       $data["lastmodified"] = time();
181       $data["version"]++;
182
183       if (ewiki_db::WRITE($data)) {
184          $o .= "The {meta} field was updated.";
185       }
186       else {
187          $o .= "A database error occoured.";
188       }
189    }
190
191    #-- deletion -----------------------------------------------------------
192    elseif (@$_REQUEST["pgc_purge"] && $_REQUEST["pgc_purge1"]) {
193
194       $loop = 3;
195       do {
196          $verZ = $data["version"];
197          while ($verZ > 0) {
198             ewiki_db::DELETE($id, $verZ);
199             $verZ--;
200          }
201       } while ($loop-- && ($data = ewiki_db::GET($id)));
202
203       if (empty($data)) {
204          $o .= "Page completely removed from database.";
205          ewiki_log("page '$id' was deleted from db", 2);
206       }
207       else {
208          $o .= "Page still here.";
209       }
210    }
211
212    #-- function list -------------------------------------------------------
213    else {
214       $o .= '<form action="'.ewiki_script("$action",$id).'" method="POST" enctype="text/html">'
215           . '<input type="hidden" name="id" value="'."$action/$id".'">';
216
217       #-- flags
218       $o .= '<div class="flags">';
219       $o .= "<h4>page flags</h4>\n";
220       foreach ($a_flagnames as $n=>$s) {
221          $disabled = (($ewiki_ring==1) && !((1<<$n) & EWIKI_DB_F_MODERATORFLAGS)) ? ' disabled="disabled"' : "";
222          $checked = $data["flags"] & (1<<$n) ? ' checked="checked"': "";
223          $a[$n] = '<input type="checkbox" name="sflag['.$n.']" value="1"'.
224                $checked . $disabled .'> ' . $s;
225       }
226       $o .= '<table border="0" class="list">' . "\n";
227       for ($n=0; $n<count($a_flagnames); $n++) {
228          $y = $n >> 2;
229          $x = $n & 0x03;
230          if ($x==0) $o .= "<tr>";
231          $o .= "<td>" . $a[4*$y + $x] . "</td>";
232          if ($x==3) $o .= "</tr>\n";
233       }
234       $o .= '</table>';
235       $o .= '<input type="submit" name="pgc_setflags" value="chmod">';
236       $o .= "\n<br /><br /><hr></div>\n"; 
237
238       #-- rename
239       $o .= '<div class="rename">';
240       $o .= "<h4>rename page</h4>\n";
241       $o .= 'new page name: <input type="text" size="30" name="mv_to" value="'.htmlentities($id).'">'
242           . '<br />'
243           . '<input type="checkbox" name="mv_cr0" value="1" checked> also try to change all references from other pages accordingly '
244           . '(<input type="checkbox" name="mv_cr1" value="1" checked> and act case-insensitive when doing so) ';
245       $o .= '<br /><input type="submit" name="pgc_rename" value="mv">';
246       $o .= "\n<br /><br /><hr></div>\n"; 
247
248       #-- meta
249       if (isset($ewiki_ring) && ($ewiki_ring==0)) {
250       $o .= '<div class="meta">';
251       $o .= "<h4>meta data</h4>\n";
252       $o .= '<textarea cols="40" rows="6" name="pgc_meta">';
253       if (($uu = @$data["meta"]) && is_array($uu))
254       foreach ($uu as $key=>$value) {
255          if (is_array($value)) { $value = serialize($array); }
256          $o .= htmlentities($key.": ".trim($value)) . "\n";
257       }
258       $o .= "</textarea>\n";
259       $o .= '<br /><input type="submit" name="pgc_setmeta" value="set">';
260       $o .= "\n<br /><br /><hr></div>\n"; 
261       }
262
263       #-- delete
264       $o .= '<div class="delete">';
265       $o .= "<h4>delete page</h4>\n";
266       $o .= '<input type="checkbox" name="pgc_purge1" value="1"> I\'m sure';
267       $o .= '<br /><input type="submit" name="pgc_purge" value="rm">';
268       $o .= "\n<br /><br /><hr></div>\n"; 
269
270       $o .= '</form>';
271    }
272
273    return($o);
274 }
275
276
277
278 ?>