* Minor TOS change
[specialops2.git] / lib / class.Page.php
blob1c27ba4ba4c5635f32d776486839f663f5dd19b1
1 <?php
2 /**
3 * SO2 page class
4 * Handles the headers, footers and error output
6 * @author Anthony Parsons (xmpp:ant@specialops.ath.cx)
7 * @license file://../COPYING
8 * @version $Id$
9 */
10 class Page
12 public $title;
13 public $nav = array();
14 public $mtime = null;
15 public $cacheable = false;
17 private $errors = array();
19 const Pageheader = 1;
20 const Userheader = 2;
21 public $headers = 0;
23 function __construct()
25 set_error_handler(array($this, 'error_handler'));
27 if ( strpos($_SERVER['PHP_SELF'], 'index') === false ) {
28 $this->nav['Board List'] = '.';
32 public function pageheader()
34 global $user, $DB;
36 switch ( $user->theme ) {
37 case -1:
38 $css = array('default', 'Default Theme'); break;
39 case 0:
40 $css = array('u'.$user->userid, 'User Theme'); break;
41 default:
42 $css = $DB->query('SELECT `css_file`, `theme_name` FROM `themes` WHERE `themeid` = '.$user->theme)->fetch_row();
44 if ( basename($_SERVER['SCRIPT_NAME'], '.php') == 'theme' && isset($_POST['preview'], $_POST['user_css']) ) {
45 $css = array('css.php?'.base64_encode($_POST['user_css']).'#', 'Theme Preview');
48 if ( isset($_POST['login'], $_POST['u'], $_POST['p']) && ! ($user instanceof User_Authenticated) ) {
49 header('HTTP/1.1 400 Bad Request');
52 /* HTTP 1.1 caching bit: Page needs a mtime set for this to work */
53 if ( !empty($this->mtime) && strpos($user->options, 'cache') !== false && 'HTTP/1.1' == $_SERVER['SERVER_PROTOCOL'] ) {
54 $tmp = apache_request_headers();
56 $this->mtime += 3600;
58 /* only allow 304 response if the page is marked as cacheable */
59 if ( false == $this->cacheable ) {
60 header('Cache-Control: no-cache');
61 } elseif ( time() > $this->mtime ) {
62 header('Cache-Control: must-revalidate; max-age=1');
63 header('Last-Modified: '.date('r', $this->mtime));
64 header('Expires: '.date('r', $this->mtime+1));
66 if ( isset($tmp['If-Modified-Since']) && strtotime($tmp['If-Modified-Since']) == $this->mtime ) {
67 exit(header('HTTP/1.1 304 Not Modified'));
72 header('Content-Type: application/xhtml+xml; charset=UTF-8');
73 echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">',"\n",
74 '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-GB">',"\n",
75 "<head>\n",
76 ' <title>',( $this->title ? $this->title.' :: '.SITE_NAME : SITE_NAME ),"</title>\n",
77 ' <link rel="stylesheet" type="text/css" href="css/',$css[0],'.css" title="',$css[1],"\"/>\n";
79 if ( strpos($user->options, 'javascript') !== false ) {
80 // Global JS
81 echo ' <script src="js/global.js" type="application/x-javascript"/>',"\n";
83 // Page JS
84 if ( file_exists('js/'.basename($_SERVER['SCRIPT_NAME'], '.php').'.js') ) {
85 echo ' <script src="js/',basename($_SERVER['SCRIPT_NAME'], '.php'),'.js" type="application/x-javascript"/>',"\n";
89 echo
90 "</head>\n\n",
91 '<body id="so2-',basename($_SERVER['SCRIPT_NAME'], '.php'),"\">\n",
92 '<h1><span>',( $this->title ? $this->title : SITE_NAME ),"</span></h1>\n";
94 if ( isset($_POST['logout']) && $user instanceof User_Anonymous ) {
95 echo '<p class="notice">You are now logged out.</p>',"\n";
96 } elseif ( isset($_POST['login'], $_POST['u'], $_POST['p']) ) {
97 if ( $user instanceof User_Authenticated ) {
98 $DB->query('UPDATE `users` SET `last_login_ip` = INET_ATON("'.$_SERVER['REMOTE_ADDR'].'") WHERE `userid` = @userid');
99 echo '<p class="notice">You are now logged in.</p>',"\n";
100 if ( $user instanceof User_Authenticated && $user->check_nullpass() ) {
101 echo '<p class="notice">Your password is not set. You should <a href="passwd">set a new one</a>.</p>';
103 } else {
104 echo '<p class="error">Invalid login attempt.</p>',"\n";
108 if ( $this->nav ) {
109 echo '<ul id="navbar" class="nl">',"\n";
110 foreach ( $this->nav as $title => $url ) {
111 echo "\t",'<li><a href="',$url,'">',$title,"</a></li>\n";
113 echo "</ul>\n\n";
116 $this->headers |= self::Pageheader;
119 private function finish_headers()
121 if ( ! ($this->headers & self::Pageheader) ) {
122 $this->pageheader();
124 if ( ! ($this->headers & self::Userheader) ) {
125 $GLOBALS['user']->userheader();
129 public function errorfooter($type = 'login')
131 if ( !headers_sent() ) {
132 switch ( $type ) {
133 case 'level':
134 header('HTTP/1.1 403 Forbidden');
135 break;
136 default:
137 header('HTTP/1.1 400 Bad Request');
141 $this->finish_headers();
143 $messages = array(
144 'level' => 'You can\'t do this.',
145 'points' => 'You don\'t have enough points to use this feature.',
146 'login' => 'You must be logged in to do this.',
147 'logout' => 'You must be logged out to do this.',
148 'boardid' => 'Invalid board ID given.',
149 'topicid' => 'Invalid topic ID given.',
150 'messageid' => 'Invalid message ID given.',
151 'userid' => 'Invalid user ID given.',
152 'runtime' => 'A serious error has occured in the page. '.
153 'If this happens again and you don\'t think it\'s your fault, let the site owner know and they\'ll probably fix it. '.
154 'Unless the site owner is Aquatakat.', // yeah right, like he'd ever get off his ass and replace that shitty code.
155 'request' => 'Invalid request.'
158 echo '<p class="error">',$messages[$type],'</p>';
159 $this->pagefooter();
162 public function pagefooter()
164 $this->finish_headers();
166 if ( $GLOBALS['user'] instanceof User_Authenticated ) {
167 echo "\n\n",
168 '<form id="footer" action="." method="post">',"\n",
169 '<fieldset><legend>Session:</legend>',"\n",
170 ' <button type="submit" name="logout" onclick="return confirm(\'o rly?\');">Log Out</button>';
171 } else {
172 echo "\n\n",
173 '<form id="footer" action="',$_SERVER['PHP_SELF'],'?',htmlspecialchars($_SERVER['QUERY_STRING']),'" method="post">',"\n",
174 '<fieldset><legend>Login:</legend>',"\n",
175 ' <label>Username: <input type="text" name="u"/></label>',"\n",
176 ' <label>Password: <input type="password" name="p"/></label>',"\n",
177 ' <button type="submit" name="login">Log In</button>';
180 echo "\n</fieldset>\n";
182 if ( defined('DEVELOPER') && count($this->errors) ) {
183 echo "<h2>Errors on page:</h2>\n<dl>\n";
184 foreach ( $this->errors as $e ) {
185 vprintf('<dt>File %s at line <var>%s</var></dt><dd>errcode <var>%s</var>: <tt>%s</tt></dd>', $e);
187 echo "</dl>\n";
190 /* ball */
191 printf('<p><a href="//specialops.ath.cx/p/">Special Ops 2</a>'.
192 ' | <a href="COPYING" rel="copyright">© 2004-06</a> Ant P'.
193 ' | Accessed %s in %.4f sec</p></form>',
194 $GLOBALS['user']->fdate(time()),
195 microtime(1)-T_START
197 echo "\n\n</body>\n</html>";
199 exit;
202 public function error_handler($number, $string, $file, $line)
204 // If errors are being returned as unencoded text then try to fix them before they fuck the XHTML
205 if ( ! ini_get('html_errors') ) {
206 $string = new Message_Plaintext($string);
207 $string = $string->getOutput();
209 $this->errors[] = array($file, $line, $number, $string);