function controller_revisions($args)
{
    page_canonical($args[0][0]);
    $page = $args[0][0];
    if (!page_exists($page)) {
        hotglue_error(404);
    }
    // get all revisions of page and determine the current revision's index
    load_modules('glue');
    $a = expl('.', $page);
    $revs = revisions_info(array('pagename' => $a[0], 'sort' => 'time'));
    $revs = $revs['#data'];
    $cur_rev = false;
    for ($i = 0; $i < count($revs); $i++) {
        if ($revs[$i]['revision'] == $a[1]) {
            $cur_rev = $i;
            break;
        }
    }
    if ($cur_rev === false) {
        // we didn't find the current revision
        hotglue_error(500);
    }
    default_html(true);
    html_add_css(base_url() . 'modules/revisions_browser/revisions_browser.css');
    if (USE_MIN_FILES) {
        html_add_js(base_url() . 'modules/revisions_browser/revisions_browser.min.js');
    } else {
        html_add_js(base_url() . 'modules/revisions_browser/revisions_browser.js');
    }
    html_add_js_var('$.glue.page', $page);
    $bdy =& body();
    elem_attr($bdy, 'id', 'revisions');
    render_page(array('page' => $page, 'edit' => false));
    body_append('<div id="revisions_browser_ctrl">');
    body_append('<div id="revisions_browser_prev">');
    if ($cur_rev + 1 < count($revs)) {
        body_append('<a href="' . base_url() . '?' . htmlspecialchars(urlencode($revs[$cur_rev + 1]['page']), ENT_COMPAT, 'UTF-8') . '/revisions">prev</a>');
    }
    body_append('</div><div id="revisions_browser_cur">');
    if (substr($revs[$cur_rev]['revision'], 0, 5) == 'auto-') {
        body_append(date('d M y H:i', $revs[$cur_rev]['time']));
    } else {
        body_append(htmlspecialchars($revs[$cur_rev]['revision'], ENT_NOQUOTES, 'UTF-8'));
    }
    body_append('<br>');
    if ($a[1] == 'head') {
        body_append('<a href="' . base_url() . '?' . htmlspecialchars(urlencode($page), ENT_COMPAT, 'UTF-8') . '/edit">back to editing mode</a>');
    } else {
        body_append('<a id="revisions_browser_revert_btn" href="#">revert</a>');
    }
    body_append('</div><div id="revisions_browser_next">');
    if (0 < $cur_rev) {
        body_append('<a href="' . base_url() . '?' . htmlspecialchars(urlencode($revs[$cur_rev - 1]['page']), ENT_COMPAT, 'UTF-8') . '/revisions">next</a>');
    }
    body_append('</div>');
    body_append('</div>');
    echo html_finalize();
}
/**
 *	controller that shows a textarea for editing either a page's or the global 
 *	user-defined css file
 */
function controller_user_css_stylesheet($args)
{
    if ($args[0][1] == 'stylesheet') {
        // changing page stylesheet
        $page = $args[0][0];
        page_canonical($page);
        if (!page_exists($page)) {
            hotglue_error(404);
        }
    } else {
        // changing global stylesheet
        $page = false;
    }
    default_html(true);
    html_add_js_var('$.glue.page', $page);
    html_add_css(base_url() . 'modules/user_css/user_css.css');
    if (USE_MIN_FILES) {
        html_add_js(base_url() . 'modules/user_css/user_css.min.js');
    } else {
        html_add_js(base_url() . 'modules/user_css/user_css.js');
    }
    $bdy =& body();
    elem_attr($bdy, 'id', 'user_css');
    if ($page === false) {
        body_append('<h1>Global stylesheet</h1>' . nl());
        // try to load css
        $css = @file_get_contents(CONTENT_DIR . '/usercss');
        if ($css === false) {
            $css = '';
        }
    } else {
        body_append('<h1>' . htmlspecialchars($page, ENT_NOQUOTES, 'UTF-8') . ' stylesheet</h1>' . nl());
        load_modules('glue');
        $obj = load_object(array('name' => $page . '.usercss'));
        if ($obj['#error']) {
            $css = '';
        } else {
            $css = $obj['#data']['content'];
        }
    }
    // encoding to html must come before the replacement below
    $css = htmlspecialchars($css, ENT_NOQUOTES, 'UTF-8');
    // replace newline characters by an entity to prevent render_object()
    // from adding some indentation
    $css = str_replace("\r\n", '&#10;', $css);
    $css = str_replace("\n", '&#10;', $css);
    // why not replace tabs as well why we are at it
    $css = str_replace("\t", '&#09;', $css);
    body_append('<textarea id="user_css_text" placeholder="enter css code here">' . $css . '</textarea>' . nl());
    body_append('<br>' . nl());
    body_append('<input id="user_css_save" type="button" value="save">' . nl());
    echo html_finalize();
}
예제 #3
0
/**
 *	controller that shows a textarea for editing either a page's or the global 
 *	user-defined code files
 */
function controller_user_code_stylesheet($args)
{
    if ($args[0][1] == 'code') {
        // changing page code
        $page = $args[0][0];
        page_canonical($page);
        if (!page_exists($page)) {
            hotglue_error(404);
        }
    } else {
        // changing global code
        $page = false;
    }
    default_html(true);
    html_add_js_var('$.glue.page', $page);
    html_add_css(base_url() . 'modules/user_code/user_code.css');
    if (USE_MIN_FILES) {
        html_add_js(base_url() . 'modules/user_code/user_code.min.js');
    } else {
        html_add_js(base_url() . 'modules/user_code/user_code.js');
    }
    $bdy =& body();
    // create array with names of code elements
    $code = array('head' => '', 'body' => '');
    elem_attr($bdy, 'id', 'user_code');
    if ($page === false) {
        body_append('<h1>Global code</h1>' . nl());
        // try to load code
        foreach ($code as $x => $v) {
            $code[$x] = @file_get_contents(CONTENT_DIR . '/user' . $x);
            if ($code[$x] === false) {
                $code[$x] = '';
            }
        }
    } else {
        body_append('<h1>"' . htmlspecialchars(substr($page, 0, strpos($page, '.')), ENT_NOQUOTES, 'UTF-8') . '" page code</h1>' . nl());
        load_modules('glue');
        foreach ($code as $x => $v) {
            $obj = load_object(array('name' => $page . '.user' . $x));
            if ($obj['#error']) {
                $code[$x] = '';
            } else {
                $code[$x] = $obj['#data']['content'];
            }
        }
    }
    foreach ($code as $k => $v) {
        // encoding to html must come before the replacement below
        $v = htmlspecialchars($v, ENT_NOQUOTES, 'UTF-8');
        // replace newline characters by an entity to prevent render_object()
        // from adding some indentation
        $v = str_replace("\r\n", '&#10;', $v);
        $v = str_replace("\n", '&#10;', $v);
        // why not replace tabs as well why we are at it
        $v = str_replace("\t", '&#09;', $v);
        $code[$k] = $v;
    }
    body_append('<div id=\'text\'>add your custom code to &lt;head&gt; and &lt;body&gt; sections of this ' . ($page ? 'page.' : 'site.') . nl());
    body_append('<br>' . nl());
    body_append('be cautious - errors in the code below may render the whole ' . ($page ? 'page' : 'site') . ' unusable.</div>' . nl());
    body_append('<br>' . nl());
    body_append('<div id=\'fake_tags\'>&lt;head&gt;</div>' . nl());
    body_append('<textarea id="user_head_text" placeholder="enter code here">' . $code['head'] . '</textarea>' . nl());
    body_append('<br>' . nl());
    body_append('<div id=\'fake_tags\'>&lt;/head&gt;<br>' . nl());
    body_append('&lt;body&gt;</div>' . nl());
    body_append('<textarea id="user_body_text" placeholder="enter code here">' . $code['body'] . '</textarea>' . nl());
    body_append('<div id=\'fake_tags\'>&lt;/body&gt;</div><br>' . nl());
    body_append('<input id="user_code_save" type="button" value="save">' . nl());
    echo html_finalize();
}
예제 #4
0
/**
 *	invoke a controller based on the query arguments given
 *
 *	this function does not return in case of an error.
 *	@param array $args query-arguments array
 *	@return mixed return value of controller that was called
 */
function invoke_controller($args)
{
    global $controllers;
    // change query-arguments so that we always have a arg0 and arg1
    if (!isset($args[0])) {
        $args[0] = array('', '');
    } elseif (is_string($args[0])) {
        $args[0] = array($args[0], '');
    }
    // load all modules
    // TODO (later): fastpath for serving cached pages or files (the latter one
    // is only doable when we store in the object file which module to load)
    load_modules();
    $match = false;
    if (isset($controllers[$args[0][0] . '-' . $args[0][1]])) {
        // foo/bar would match controller for "foo/bar"
        $match = $controllers[$args[0][0] . '-' . $args[0][1]];
        $reason = $args[0][0] . '/' . $args[0][1];
    } elseif (isset($controllers[$args[0][0] . '-*'])) {
        // foo/bar would match "foo/*"
        $match = $controllers[$args[0][0] . '-*'];
        $reason = $args[0][0] . '/*';
    } elseif (isset($controllers['*-' . $args[0][1]])) {
        // foo/bar would match "*/bar"
        $match = $controllers['*-' . $args[0][1]];
        $reason = '*/' . $args[0][1];
    } elseif (isset($controllers['*-*'])) {
        // foo/bar would match "*/*"
        $match = $controllers['*-*'];
        $reason = '*/*';
    }
    if ($match !== false) {
        // check authentication for those controllers that require it
        if (isset($match['auth']) && $match['auth']) {
            if (!is_auth()) {
                prompt_auth();
            }
            // also check the referer to prevent against cross site request
            // forgery (xsrf)
            // this is not really optimal, since proxies can filter the referer
            // header, but as a first step..
            if (!empty($_SERVER['HTTP_REFERER'])) {
                $bu = base_url();
                if (substr($_SERVER['HTTP_REFERER'], 0, strlen($bu)) != $bu) {
                    log_msg('warn', 'controller: possible xsrf detected, referer is ' . quot($_SERVER['HTTP_REFERER']) . ', arguments ' . var_dump_inl($args));
                    hotglue_error(400);
                }
            }
        }
        log_msg('info', 'controller: invoking controller ' . quot($reason) . ' => ' . $match['func']);
        return $match['func']($args);
    } else {
        // normally we won't reach this as some default (*/*) controller will
        // be present
        log_msg('warn', 'controller: no match for ' . quot($args[0][0] . '/' . $args[0][1]));
        hotglue_error(400);
    }
}
예제 #5
0
/**
 *	prompt user for authentication
 *
 *	@param bool $header_only only send header information
 *	this function does not return.
 */
function prompt_auth($header_only = false)
{
    if (AUTH_METHOD == 'none') {
        // nothing to do here
    } elseif (AUTH_METHOD == 'basic') {
        header('WWW-Authenticate: Basic realm="' . str_replace("\"", '', SITE_NAME) . '"');
        header($_SERVER['SERVER_PROTOCOL'] . ' 401 Unauthorized');
    } elseif (AUTH_METHOD == 'digest') {
        http_digest_prompt(SITE_NAME);
    } else {
        log_msg('error', 'common: invalid or missing AUTH_METHOD config setting');
    }
    hotglue_error(401, true);
}