]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/main.php
Refactor/cleanup of login code continues.
[SourceForge/phpwiki.git] / lib / main.php
1 <?php
2 rcs_id('$Id: main.php,v 1.28 2002-01-23 05:10:22 dairiki Exp $');
3
4
5 include "lib/config.php";
6 include "lib/stdlib.php";
7 require_once('lib/Request.php');
8 require_once("lib/WikiUser.php");
9 require_once('lib/WikiDB.php');
10
11 // FIXME: move to config?
12 if (defined('THEME')) {
13     include("themes/" . THEME . "/themeinfo.php");
14 }
15 if (empty($Theme)) {
16     include("themes/default/themeinfo.php");
17 }
18 assert(!empty($Theme));
19
20 class UserPreferences {
21     function UserPreferences ($prefs = false) {
22         if (isa($prefs, 'UserPreferences'))
23             $this->_prefs = $prefs->_prefs;
24         else
25             $this->_prefs = array();
26
27         $this->sanitize();
28     }
29
30     function sanitize() {
31         // FIXME: needs cleanup.
32         
33         $LIMITS = array('edit_area.width' => array(30, 80, 150),
34                         'edit_area.height' => array(5, 22, 80));
35
36         $prefs = $this->_prefs;
37         $new = array();
38         foreach ($LIMITS as $key => $lims) {
39             list ($min, $default, $max) = $lims;
40             if (isset($prefs[$key]))
41                 $new[$key] = min($max, max($min, (int)$prefs[$key]));
42             else
43                 $new[$key] = $default;
44         }
45
46         $this->_prefs = $new;
47     }
48
49     function get($key) {
50         return $this->_prefs[$key];
51     }
52
53     function setPrefs($new_prefs) {
54         if (is_array($new_prefs)) {
55             $this->_prefs = array_merge($this->_prefs, $new_prefs);
56             $this->sanitize();
57         }
58     }
59 }
60
61
62 class WikiRequest extends Request {
63
64     function WikiRequest () {
65         $this->Request();
66
67         // Normalize args...
68         $this->setArg('pagename', $this->_deducePagename());
69         $this->setArg('action', $this->_deduceAction());
70
71         $this->_user = new WikiUser($this->getSessionVar('auth_state'));
72
73         if (!($prefs = $this->getSessionVar('user_prefs')))
74             $prefs = $this->getCookieVar('WIKI_PREFS');
75         $this->_prefs = new UserPreferences($prefs);
76     }
77
78     function getUser () {
79         return $this->_user;
80     }
81
82     function getPref ($key) {
83         return $this->_prefs->get($key);
84     }
85
86     function getDbh () {
87         if (!isset($this->_dbi)) {
88             $this->_dbi = WikiDB::open($GLOBALS['DBParams']);
89         }
90         return $this->_dbi;
91     }
92
93     /**
94      * Get requested page from the page database.
95      *
96      * This is a convenience function.
97      */
98     function getPage () {
99         if (!isset($this->_dbi))
100             $this->getDbh();
101         return $this->_dbi->getPage($this->getArg('pagename'));
102     }
103
104
105
106     function handleAuthRequest () {
107         $auth_args = $this->getArg('auth');
108         $this->setArg('auth', false);
109         
110         if (!is_array($auth_args) || !$this->isPost())
111             return;             // Ignore if not posted.
112         
113         $user = WikiUser::AuthCheck($auth_args);
114
115         if (isa($user, 'WikiUser')) {
116             // Successful login (or logout.)
117             $this->_user = $user;
118             $this->setSessionVar('auth_state', $user);
119         }
120         elseif ($user) {
121             // Login attempt failed.
122             $fail_message = $user;
123             WikiUser::PrintLoginForm($auth_args, $fail_message);
124             $this->finish();    //NORETURN
125         }
126         else {
127             // Login request cancelled.
128         }
129     }
130
131     function checkAuthority () {
132         $action = $this->getArg('action');
133         $require_level = $this->requiredAuthority($action);
134         
135         $user = $this->getUser();
136         if (! $user->hasAuthority($require_level)) {
137             // User does not have required authority.  Prompt for login.
138             $what = HTML::em($action);
139
140             if ($require_level >= WIKIAUTH_FORBIDDEN) {
141                 $this->finish(fmt("Action %s is disallowed on this wiki", $what));
142             }
143             elseif ($require_level == WIKIAUTH_BOGO)
144                 $msg = fmt("You must sign in to %s this wiki", $what);
145             elseif ($require_level == WIKIAUTH_USER)
146                 $msg = fmt("You must log in to %s this wiki", $what);
147             else
148                 $msg = fmt("You must be an administrator to %s this wiki", $what);
149         
150             WikiUser::PrintLoginForm(compact('require_level'), $msg);
151             $this->finish();    // NORETURN
152         }
153     }
154     
155     function requiredAuthority ($action) {
156         // FIXME: clean up.
157         switch ($action) {
158         case 'browse':
159         case 'diff':
160         // case ActionPage:   
161         // case 'search':
162             return WIKIAUTH_ANON;
163
164         case 'zip':
165             return WIKIAUTH_ANON;
166             
167         case 'edit':
168         case 'save':            // FIXME delete
169             return WIKIAUTH_ANON;
170             // return WIKIAUTH_BOGO;
171
172         case 'upload':
173         case 'dumpserial':
174         case 'loadfile':
175         case 'remove':
176         case 'lock':
177         case 'unlock':
178         default:
179             return WIKIAUTH_ADMIN;
180         }
181     }
182         
183     function handleSetPrefRequest () {
184         $new_prefs = $this->getArg('pref');
185         $this->setArg('pref', false);
186         if (!is_array($pref_args))
187             return;
188
189         // Update and save preferences.
190         $this->_prefs->setPrefs($new_prefs);
191         $this->setSessionVar('user_prefs', $prefs);
192         $this->setCookieVar('WIKI_PREFS', $prefs, 365);
193     }
194
195     function deflowerDatabase () {
196         if ($this->getArg('action') != 'browse')
197             return;
198         if ($this->getArg('pagename') != _("HomePage"))
199             return;
200
201         $page = $this->getPage();
202         $current = $page->getCurrentRevision();
203         if ($current->getVersion() > 0)
204             return;             // Homepage exists.
205
206         include('lib/loadsave.php');
207         SetupWiki($this);
208         $this->finish();        // NORETURN
209     }
210
211     function handleAction () {
212         $action = $this->getArg('action');
213         $method = "action_$action";
214         if (! method_exists($this, $method)) {
215             $this->finish(fmt("%s: Bad action", $action));
216         }
217         $this->{$method}();
218     }
219         
220         
221     function finish ($errormsg = false) {
222         static $in_exit = 0;
223
224         if ($in_exit)
225             exit();             // just in case CloseDataBase calls us
226         $in_exit = true;
227
228         if (!empty($this->_dbi))
229             $this->_dbi->close();
230         unset($this->_dbi);
231         
232
233         global $ErrorManager;
234         $ErrorManager->flushPostponedErrors();
235    
236         if (!empty($errormsg)) {
237             PrintXML(array(HTML::br(),
238                            HTML::hr(),
239                            HTML::h2(_("Fatal PhpWiki Error")),
240                            $errormsg));
241             // HACK:
242             echo "\n</body></html>";
243         }
244
245         Request::finish();
246         exit;
247     }
248         
249     function _deducePagename () {
250         if ($this->getArg('pagename'))
251             return $this->getArg('pagename');
252
253         if (USE_PATH_INFO) {
254             $pathinfo = $this->get('PATH_INFO');
255             $tail = substr($pathinfo, strlen(PATH_INFO_PREFIX));
256             
257             if ($tail && $pathinfo == PATH_INFO_PREFIX . $tail) {
258                 return $tail;
259             }
260         }
261
262         $query_string = $this->get('QUERY_STRING');
263         if (preg_match('/^[^&=]+$/', $query_string)) {
264             return urldecode($query_string);
265         }
266         
267     
268         return _("HomePage");
269     }
270
271     
272     function _deduceAction () {
273         if (!($action = $this->getArg('action')))
274             return 'browse';
275
276         if (! method_exists($this, "action_$action")) {
277             // unknown action.
278             trigger_error("$action: Unknown action", E_USER_NOTICE);
279             return 'browse';
280         }
281         return $action;
282     }
283
284     function action_browse () {
285         $this->compress_output();
286         include_once("lib/display.php");
287         displayPage($this);
288     }
289     
290     function action_diff () {
291         $this->compress_output();
292         include_once "lib/diff.php";
293         showDiff($this);
294     }
295
296     function action_search () {
297         // This is obsolete: reformulate URL and redirect.
298         // FIXME: this whole section should probably be deleted.
299         if ($this->getArg('searchtype') == 'full') {
300             $search_page = _("FullTextSearch");
301         }
302         else {
303             $search_page = _("TitleSearch");
304         }
305         $this->redirect(WikiURL($search_page,
306                                 array('s' => $this->getArg('searchterm')),
307                                 'absolute_url'));
308     }
309
310     function action_edit () {
311         $this->compress_output();
312         include "lib/editpage.php";
313         editPage($this);
314     }
315
316     // FIXME: combine this with edit
317     function action_save () {
318         $this->compress_output();
319         include "lib/savepage.php";
320         savePage($this);
321     }
322
323     function action_lock () {
324         $page = $this->getPage();
325         $page->set('locked', true);
326         $this->action_browse();
327     }
328
329     function action_unlock () {
330         // FIXME: This check is redundant.
331         //$user->requireAuth(WIKIAUTH_ADMIN);
332         $page = $this->getPage();
333         $page->set('locked', false);
334         $this->action_browse();
335     }
336
337     function action_remove () {
338         // FIXME: This check is redundant.
339         //$user->requireAuth(WIKIAUTH_ADMIN);
340         include('lib/removepage.php');
341     }
342
343     
344     function action_upload () {
345         include_once("lib/loadsave.php");
346         LoadPostFile($this);
347     }
348     
349     function action_zip () {
350         include_once("lib/loadsave.php");
351         MakeWikiZip($this);
352         // I don't think it hurts to add cruft at the end of the zip file.
353         echo "\n========================================================\n";
354         echo "PhpWiki " . PHPWIKI_VERSION . " source:\n$GLOBALS[RCS_IDS]\n";
355     }
356         
357     function action_dumpserial () {
358         include_once("lib/loadsave.php");
359         DumpToDir($this);
360     }
361
362     function action_loadfile () {
363         include_once("lib/loadsave.php");
364         LoadFileOrDir($this);
365     }
366 }
367
368 //FIXME: deprecated
369 function is_safe_action ($action) {
370     return WikiRequest::requiredAuthority($action) < WIKIAUTH_ADMIN;
371 }
372
373
374 function main () {
375     global $request;
376
377     $request = new WikiRequest();
378
379     
380     /* FIXME: is this needed anymore?
381     if (USE_PATH_INFO && ! $request->get('PATH_INFO')
382         && ! preg_match(',/$,', $request->get('REDIRECT_URL'))) {
383         $request->redirect(SERVER_URL
384                            . preg_replace('/(\?|$)/', '/\1',
385                                           $request->get('REQUEST_URI'),
386                                           1));
387         exit;
388     }
389     */
390
391     // Handle authentication requests
392     if ($request->getArg('auth'))
393         $request->handleAuthRequest();
394
395     // FIXME: deprecated
396     //global $user;               // FIXME: can we make this non-global?
397     //$user = $request->getUser();
398
399     // Handle adjustments to user preferences
400     if ($request->getArg('pref'))
401         $request->handleSetPrefRequest();
402
403     // Enable the output of most of the warning messages.
404     // The warnings will screw up zip files and setpref though.
405     global $ErrorManager;
406     if ($request->getArg('action') != 'zip') {
407         //$ErrorManager->setPostponedErrorMask(E_NOTICE|E_USER_NOTICE);
408         $ErrorManager->setPostponedErrorMask(0);
409     }
410
411     
412     // Ensure user has permissions for action
413     $request->checkAuthority();
414     
415     //FIXME:
416     //if ($user->is_authenticated())
417     //  $LogEntry->user = $user->getId();
418
419     $request->deflowerDatabase();
420
421     $request->handleAction();
422     $request->finish();
423 }
424
425 main();
426
427
428 // Local Variables:
429 // mode: php
430 // tab-width: 8
431 // c-basic-offset: 4
432 // c-hanging-comment-ender-p: nil
433 // indent-tabs-mode: nil
434 // End:   
435 ?>