00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 @require_once('config.inc.php');
00013 require_once('common.inc.php');
00014 require_once('html.inc.php');
00015 require_once('log.inc.php');
00016 require_once('modules.inc.php');
00017
00018 require_once('util.inc.php');
00019
00020 if (!isset($controllers)) {
00021 $controllers = array();
00022 }
00023
00024
00025
00026
00027
00028
00029 function controller_create_page($args)
00030 {
00031 page_canonical($args[0][0]);
00032 $page = $args[0][0];
00033 if (page_exists($page)) {
00034 log_msg('debug', 'controller_create_page: page '.quot($page).'already exists, invoking controller_edit');
00035 controller_edit($args);
00036 return;
00037 }
00038
00039 load_modules('glue');
00040 default_html(true);
00041 html_add_css(base_url().'css/hotglue_error.css');
00042 if (USE_MIN_FILES) {
00043 html_add_js(base_url().'js/create_page.min.js');
00044 } else {
00045 html_add_js(base_url().'js/create_page.js');
00046 }
00047 html_add_js_var('$.glue.page', $page);
00048 html_add_js_var('$.glue.q', (SHORT_URLS ? '' : '?'));
00049 $bdy = &body();
00050 elem_attr($bdy, 'id', 'create_page');
00051 body_append(tab(1).'<div id="paper">'.nl());
00052 body_append(tab(2).'<div id="wrapper">'.nl());
00053 body_append(tab(3).'<div id="content">'.nl());
00054 body_append(tab(4).'<div id="left-nav">'.nl());
00055 body_append(tab(5).'<img src="'.htmlspecialchars(base_url(), ENT_COMPAT, 'UTF-8').'img/hotglue-logo.png" alt="logo">'.nl());
00056 body_append(tab(4).'</div>'.nl());
00057 body_append(tab(4).'<div id="main">'.nl());
00058 body_append(tab(5).'<h1 id="error-title">Page does not exist yet!</h1>'.nl());
00059 body_append(tab(5).'<p>'.nl());
00060 body_append(tab(6).'This page does not exist yet!<br>'.nl());
00061 body_append(tab(6).'Would you like to create the page?'.nl());
00062 body_append(tab(5).'</p>'.nl());
00063 body_append(tab(5).'<form><input id="create_page_btn" type="button" value="Create it!"></form>'.nl());
00064 body_append(tab(4).'</div>'.nl());
00065 body_append(tab(3).'</div>'.nl());
00066 body_append(tab(2).'</div>'.nl());
00067 body_append(tab(2).'<div style="position: absolute; left: 200px; top: -10px; z-index: 2;">'.nl());
00068 body_append(tab(3).'<img src="'.htmlspecialchars(base_url(), ENT_COMPAT, 'UTF-8').'img/hotglue-404.png" alt="404">'.nl());
00069 body_append(tab(2).'</div>'.nl());
00070 body_append(tab(1).'</div>'.nl());
00071 echo html_finalize();
00072 }
00073
00074 register_controller('*', 'create_page', 'controller_create_page', array('auth'=>true));
00075
00076
00077
00078
00079
00080 function controller_edit($args)
00081 {
00082 handle_updates();
00083
00084 log_msg('debug', 'controller_edit: running on php version '.phpversion());
00085
00086
00087
00088 page_canonical($args[0][0]);
00089 $page = $args[0][0];
00090 if (!page_exists($page)) {
00091 log_msg('debug', 'controller_edit: page '.quot($page).' does not exist, invoking controller_create_page');
00092 controller_create_page($args);
00093 return;
00094 }
00095
00096
00097 load_modules('glue');
00098 default_html(true);
00099 html_add_js_var('$.glue.page', $page);
00100 html_add_css(base_url().'css/farbtastic.css', 2);
00101 html_add_css(base_url().'css/edit.css', 5);
00102 if (USE_MIN_FILES) {
00103 html_add_js(base_url().'js/jquery-ui-1.8.6.custom.min.js', 2);
00104 } else {
00105 html_add_js(base_url().'js/jquery-ui-1.8.6.custom.js', 2);
00106 }
00107 if (USE_MIN_FILES) {
00108 html_add_js(base_url().'js/farbtastic.min.js', 2);
00109 } else {
00110 html_add_js(base_url().'js/farbtastic.js', 2);
00111 }
00112 if (USE_MIN_FILES) {
00113 html_add_js(base_url().'js/jquery.xcolor-1.2.1.min.js', 2);
00114 } else {
00115 html_add_js(base_url().'js/jquery.xcolor-1.2.1.js', 2);
00116 }
00117 if (USE_MIN_FILES) {
00118 html_add_js(base_url().'js/edit.min.js', 4);
00119 } else {
00120 html_add_js(base_url().'js/edit.js', 4);
00121 }
00122 render_page(array('page'=>$page, 'edit'=>true));
00123 echo html_finalize();
00124
00125 log_msg('debug', 'controller_edit: invoking check_auto_snapshot');
00126 check_auto_snapshot(array('page'=>$page));
00127 }
00128
00129 register_controller('*', 'edit', 'controller_edit', array('auth'=>true));
00130
00131
00132
00133
00134
00135
00136
00137 function controller_default($args)
00138 {
00139 if (empty($args[0][0]) && empty($args[0][1])) {
00140
00141 $args[0][0] = startpage();
00142 log_msg('debug', 'controller_default: using the default page');
00143 } elseif ($args[0][0] == 'edit' && empty($args[0][1])) {
00144
00145 $args[0][0] = startpage();
00146 $args[0][1] = 'edit';
00147 log_msg('debug', 'controller_default: using the default page');
00148 invoke_controller($args);
00149 return;
00150 }
00151
00152 page_canonical($args[0][0]);
00153 $obj = expl('.', $args[0][0]);
00154 if (count($obj) == 2) {
00155
00156 if (page_exists($args[0][0])) {
00157 if (DEFAULT_TO_EDIT && is_auth()) {
00158 log_msg('debug', 'controller_default: invoking controller_edit');
00159 controller_edit($args);
00160 } else {
00161 log_msg('debug', 'controller_default: invoking controller_show');
00162 controller_show($args);
00163 }
00164 } elseif (ALWAYS_PROMPT_CREATE_PAGE || is_auth() || $args[0][0] == startpage()) {
00165 log_msg('debug', 'controller_default: invoking controller_create_page');
00166 controller_create_page($args);
00167 } else {
00168 log_msg('info', 'controller_default: page '.quot($args[0][0]).' not found, serving 404');
00169 hotglue_error(404);
00170 }
00171 } else {
00172
00173 if (object_exists($args[0][0])) {
00174
00175 if (isset($args['download']) && $args['download']) {
00176
00177 $dl = true;
00178 } else {
00179 $dl = false;
00180 }
00181 log_msg('debug', 'controller_default: invoking serve_resource');
00182 if (!serve_resource($args[0][0], $dl)) {
00183 log_msg('info', 'controller_default: object '.quot($args[0][0]).' has no associated resource, serving 404');
00184 hotglue_error(404);
00185 }
00186 } else {
00187 log_msg('info', 'controller_default: object '.quot($args[0][0]).' not found, serving 404');
00188 hotglue_error(404);
00189 }
00190 }
00191 }
00192
00193 register_controller('*', '*', 'controller_default');
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204 function controller_login($args)
00205 {
00206 if (!is_auth()) {
00207 prompt_auth();
00208 } else {
00209
00210 if (SHORT_URLS) {
00211 header('Location: '.base_url().'pages');
00212 } else {
00213 header('Location: '.base_url().'?pages');
00214 }
00215 die();
00216 }
00217 }
00218
00219 register_controller('login', '', 'controller_login');
00220
00221
00222
00223
00224
00225 function controller_show($args)
00226 {
00227
00228
00229 page_canonical($args[0][0]);
00230 $page = $args[0][0];
00231 if (!page_exists($page)) {
00232 log_msg('info', 'controller_show: page '.quot($page).' not found, serving 404');
00233 hotglue_error(404);
00234 }
00235
00236
00237 if (0 < CACHE_TIME && is_cached('page', $page, CACHE_TIME)) {
00238 serve_cached('page', $page);
00239 die();
00240 }
00241
00242
00243 load_modules('glue');
00244 default_html(false);
00245 $cache_page = true;
00246 render_page(array('page'=>$page, 'edit'=>false));
00247
00248 $html = html_finalize($cache_page);
00249 echo $html;
00250
00251
00252 if (0 < CACHE_TIME && $cache_page) {
00253 cache_output('page', $page, $html);
00254 }
00255 }
00256
00257 register_controller('*', 'show_page', 'controller_show');
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268 function invoke_controller($args)
00269 {
00270 global $controllers;
00271
00272
00273 if (!isset($args[0])) {
00274 $args[0] = array('', '');
00275 } elseif (is_string($args[0])) {
00276 $args[0] = array($args[0], '');
00277 }
00278
00279
00280
00281
00282 load_modules();
00283
00284 $match = false;
00285 if (isset($controllers[$args[0][0].'-'.$args[0][1]])) {
00286
00287 $match = $controllers[$args[0][0].'-'.$args[0][1]];
00288 $reason = $args[0][0].'/'.$args[0][1];
00289 } elseif (isset($controllers[$args[0][0].'-*'])) {
00290
00291 $match = $controllers[$args[0][0].'-*'];
00292 $reason = $args[0][0].'/*';
00293 } elseif (isset($controllers['*-'.$args[0][1]])) {
00294
00295 $match = $controllers['*-'.$args[0][1]];
00296 $reason = '*/'.$args[0][1];
00297 } elseif (isset($controllers['*-*'])) {
00298
00299 $match = $controllers['*-*'];
00300 $reason = '*/*';
00301 }
00302
00303 if ($match !== false) {
00304
00305 if (isset($match['auth']) && $match['auth']) {
00306 if (!is_auth()) {
00307 prompt_auth();
00308 }
00309
00310
00311
00312
00313
00314 if (!empty($_SERVER['HTTP_REFERER'])) {
00315 $bu = base_url();
00316 if (substr($_SERVER['HTTP_REFERER'], 0, strlen($bu)) != $bu) {
00317 log_msg('warn', 'controller: possible xsrf detected, referer is '.quot($_SERVER['HTTP_REFERER']).', arguments '.var_dump_inl($args));
00318 hotglue_error(400);
00319 }
00320 }
00321 }
00322
00323 log_msg('info', 'controller: invoking controller '.quot($reason).' => '.$match['func']);
00324 return $match['func']($args);
00325 } else {
00326
00327
00328 log_msg('warn', 'controller: no match for '.quot($args[0][0].'/'.$args[0][1]));
00329 hotglue_error(400);
00330 }
00331 }
00332
00333
00334
00335
00336
00337
00338
00339 function parse_query_string()
00340 {
00341
00342
00343 $q = $_SERVER['QUERY_STRING'];
00344 $args = array();
00345 $num_args = array();
00346
00347 if (substr($q, -1) == '/') {
00348 $q = substr($q, 0, -1);
00349 }
00350
00351
00352 $temp = expl('&', $q);
00353 foreach ($temp as $a) {
00354 if (($p = strpos($a, '=')) !== false) {
00355 $args[urldecode(substr($a, 0, $p))] = urldecode(substr($a, $p+1));
00356 } else {
00357 $num_args[] = urldecode($a);
00358 }
00359 }
00360
00361 for ($i=0; $i < count($num_args); $i++) {
00362
00363 if (($p = strpos($num_args[$i], '/')) !== false) {
00364 $args[$i] = expl('/', $num_args[$i]);
00365 } else {
00366 $args[$i] = $num_args[$i];
00367 }
00368 }
00369 return $args;
00370 }
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381 function register_controller($arg0, $arg1, $func, $args = array())
00382 {
00383 global $controllers;
00384 $controllers[$arg0.'-'.$arg1] = array_merge($args, array('func'=>$func));
00385 log_msg('debug', 'controller: registered controller '.quot($arg0.'/'.$arg1).' => '.$func);
00386 }
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397 function serve_resource($s, $dl)
00398 {
00399 load_modules('glue');
00400
00401
00402 $ret = object_get_symlink(array('name'=>$s));
00403 if ($ret['#error'] == false && $ret['#data'] !== false) {
00404 log_msg('debug', 'controller: resolved resource '.quot($s).' into '.quot($ret['#data']));
00405 $s = $ret['#data'];
00406 }
00407
00408 $obj = load_object(array('name'=>$s));
00409 if ($obj['#error']) {
00410 return false;
00411 } else {
00412 $obj = $obj['#data'];
00413 }
00414
00415 $ret = invoke_hook_while('serve_resource', false, array('obj'=>$obj, 'dl'=>$dl));
00416
00417
00418 foreach ($ret as $key=>$val) {
00419 if ($val !== false) {
00420 return true;
00421 }
00422 }
00423 return false;
00424 }
00425
00426 register_hook('serve_resource', 'serve resources associated with objects');