Location: PHPKode > projects > Blandware AtLeap Lite - CMS on PHP > atleaplite/index.php
<?php
/*
 *  Copyright 2008 Blandware (http://www.blandware.com)
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

/**
 * This file is main entry point. It dispatches requests.
 *
 * @package     AtleapLite
 * @author      Roman Puchkovskiy
 * @license     http://www.apache.org/licenses/LICENSE-2.0  Apache License, Version 2.0
 */

/**
 */
require 'server_options.php';

/**
 * Including common entry file header
 */
require 'include/entry_common.php';


require_once 'DB/DataObject.php'; 
require_once 'include/common.php';
require_once 'include/util/smarty_ex.php';
require_once 'HTTP.php';
require_once 'include/util/pager_ex.php';
require_once 'include/form/formbase.php';
require_once 'HTML/QuickForm/Renderer/ArraySmarty.php';

require_once 'include/grid.php';

require 'include/menus.php';


// Global variables

/**
 * Whether first button on grid exists
 */
$firstButtonExists = true;
/**
 * Array of structures that describe links to be displayed at page bottom
 */
$bottomLinks = array();


// Global functions

/**
 * Includes file with actions for a given action group.
 *
 * @param string $group         name of group
 * @param string $dir optional  directory prefix
 * @internal
 */
function includeActions($group, $dir = null)
{
    $dirStr = $dir ? "$dir/" : "";
    require_once "include/actions/$dirStr$group.php";
}

/**
 * Registers action in action mapping.
 * 
 * @global array action mapping
 * @param string $action        name of action (as in $_GET)
 * @param string $perm          name of permission to check for this action
 * @param string $include       name of group to include; if null, ignored
 * @param string $func          name of function to call (which will process
 *                              the request
 * @param string $pre optional  name of function which will be called before
 *                              permission is checked
 * @param string $altAllowed optional name of function which returns true if
 * action is allowed. If this is empty, it's ignored. Else, it's ORed with
 * a regular permission checking.
 */
function registerAction($action, $perm, $include, $func, $pre = null, $altAllowed = null) {
    global $actionMapping;

    $actionMapping[$action] = array('perm' => $perm, 'include' => $include,
            'func' => $func, 'pre' => $pre, 'altAllowed' => $altAllowed);
}

/**
 * Registers action in action mapping assuming that func has same name as
 * action.
 * 
 * @global array action mapping
 * @param string $action            name of action (as in $_GET)
 * @param string $include optional  name of group to include; if null, ignored
 * @param string $perm optional     name of permission to check for this action;
                                    if omitted, assumed to be same as action
 * @param string $pre optional      name of function which will be called before
 *                                  permission is checked
 * @param string $altAllowed optional name of function which returns true if
 * action is allowed. If this is empty, it's ignored. Else, it's ORed with
 * a regular permission checking.
 */
function registerActionSimple($action, $include = null, $perm = null,
        $pre = null, $altAllowed = null) {
    if ($perm == null) {
        $perm = $action;
    }
    registerAction($action, $perm, $include, $action, $pre, $altAllowed);
}

/**
 * Initializes action mapping.
 *
 * @global array action mapping
 */
function initController() {
    global $actionMapping;

    $actionMapping = array();

    registerActionSimple('login', null, 'login', 'preLogin');
    registerActionSimple('logout');
    registerActionSimple('showAdminConsole');

    registerActionSimple('listUsers', 'user');
    registerActionSimple('viewUser', 'user');
    registerActionSimple('callCreateUser', 'user', 'createUser');
    registerActionSimple('createUser', 'user');
    registerActionSimple('callUpdateUser', 'user', 'updateUser', null, 'editingOneself');
    registerActionSimple('updateUser', 'user', 'updateUser', null, 'editingOneself');
    registerActionSimple('deleteUser', 'user');
    registerActionSimple('massDeleteUsers', 'user', 'deleteUser');
    registerActionSimple('updateMyself', 'user');

    registerActionSimple('listRoles', 'role');
    registerActionSimple('viewRole', 'role');
    registerActionSimple('callCreateRole', 'role', 'createRole');
    registerActionSimple('createRole', 'role');
    registerActionSimple('callUpdateRole', 'role', 'updateRole');
    registerActionSimple('updateRole', 'role');
    registerActionSimple('deleteRole', 'role');
    registerActionSimple('massDeleteRoles', 'role', 'deleteRole');

    registerActionSimple('listMessageBundles', 'message');
    registerActionSimple('callUpdateMessageBundle', 'message', 'updateMessageBundle');
    registerActionSimple('updateMessageBundle', 'message', 'updateMessageBundle');

    registerActionSimple('listPages', 'page');
    registerActionSimple('viewPage', 'page');
    registerActionSimple('callCreatePage', 'page', 'createPage');
    registerActionSimple('callCreatePageFields', 'page', 'createPage');
    registerActionSimple('createPage', 'page');
    registerActionSimple('callUpdatePage', 'page', 'updatePage');
    registerActionSimple('updatePage', 'page');
    registerActionSimple('deletePage', 'page');
    registerActionSimple('massDeletePages', 'page', 'deletePage');
    registerActionSimple('showPage', 'page');

    registerActionSimple('showNewsArchive', 'news');

    registerActionSimple('listResources', 'resource');
    registerActionSimple('viewResource', 'resource');
    registerActionSimple('callCreateResource', 'resource', 'createResource');
    registerActionSimple('createResource', 'resource');
    registerActionSimple('callUpdateResource', 'resource', 'updateResource');
    registerActionSimple('updateResource', 'resource');
    registerActionSimple('deleteResource', 'resource');
    registerActionSimple('massDeleteResources', 'resource', 'deleteResource');
    registerActionSimple('showResources', 'resource');

    registerActionSimple('listCategories', 'category');
    registerActionSimple('viewCategory', 'category');
    registerActionSimple('callCreateCategory', 'category', 'createCategory');
    registerActionSimple('createCategory', 'category');
    registerActionSimple('callUpdateCategory', 'category', 'updateCategory');
    registerActionSimple('updateCategory', 'category');
    registerActionSimple('liftCategory', 'category', 'updateCategory');
    registerActionSimple('lowerCategory', 'category', 'updateCategory');
    registerActionSimple('deleteCategory', 'category');
    registerActionSimple('massDeleteCategories', 'category', 'deleteCategory');
    registerActionSimple('showCategory', 'category');

    registerActionSimple('viewCommodity', 'commodity');
    registerActionSimple('callCreateCommodity', 'commodity', 'createCommodity');
    registerActionSimple('createCommodity', 'commodity');
    registerActionSimple('callUpdateCommodity', 'commodity', 'updateCommodity');
    registerActionSimple('updateCommodity', 'commodity');
    registerActionSimple('liftCommodity', 'commodity', 'updateCommodity');
    registerActionSimple('lowerCommodity', 'commodity', 'updateCommodity');
    registerActionSimple('deleteCommodity', 'commodity');
    registerActionSimple('massDeleteCommodities', 'commodity', 'deleteCommodity');
    registerActionSimple('showCommodity', 'commodity');

    registerActionSimple('callUpdateGlobalProperties', 'global_property', 'updateGlobalProperties');
    registerActionSimple('updateGlobalProperties', 'global_property');
    registerActionSimple('flushServerCache', 'global_property', 'updateGlobalProperties');

    registerActionSimple('showImage', 'misc');
    registerActionSimple('siteMap', 'misc', 'viewSiteMap');

    registerActionSimple('browsePages', 'browser', 'listPages');
    registerActionSimple('browseImages', 'browser', 'listResources');
    registerActionSimple('browseFiles', 'browser', 'listResources');
}

/**
 * Sets up a 'forbidden' message. Used when user has no enough rights.
 *
 * @global object smarty instance
 * @global array menu items
 * @param string $reason optional   message to show; if omitted, default one
                                    will be shown
 * @param string $link optional     link to render; if omitted, no link is shown
 */
function setupForb($reason = null, $link = '')
{
    global $smarty;

    if ($reason === null) {
        $reason = getMessage('common.error.noPermissionOrBlocked');
    }

    $smarty->assign('reason', $reason);
    $smarty->assign('link', $link);
    $smarty->assign('title', getMessage('common.error'));
    $smarty->assign('template', 'error.tpl');
}

/**
 * Dispatches a request.
 *
 * @global object smarty instance
 * @global array menu items
 * @global array bottom links
 * @global array action mapping
 * @global string database URL
 */
function dispatch() 
{
    global $smarty, $actionMapping, $dsn;

    $log =& getLog();

    if ($_GET['clearFilters'] == 'yes') {
        clearFilters();
    }
    if ($_GET['resetPageId'] == 'yes') {
        unset($_SESSION[PAGE_ID_VAR]);
    }
    configurateDataObject($dsn);

    $action = $_GET['action'];
    $log->debug("dispatch(): going to process request, action is " . $action);
    if (isset($actionMapping[$action])) {
        $a = $actionMapping[$action];
        if ($a['pre'] != null) {
            $a['pre']();
        }
        $altAllowed = $a['altAllowed'];
        if ((!empty($altAllowed) && $altAllowed()) || allowed($a['perm'])) {
            $log->debug("dispatch(): the action is allowed");
            if (!empty($a['include'])) {
                includeActions($a['include']);
            }
            $a['func']();
        } else {
            $log->debug("dispatch(): the action is not allowed");
            if (isAnonymous()) {
                redirect(ADMIN_PAGE);
            } else {
                setupForb();
            }
        }
    } else {
        showDefaultPage();
    }
}

/**
 * Displays a default page.
 *
 * @global object smarty instance
 * @global array menu items
 * @global array bottom links
 */
function showDefaultPage()
{
    global $smarty, $bottomLinks;

    redirect(buildUrl(null, array('identifier' => WELCOME_PAGE_IDENTIFIER), 'page'));

    setSystemMenuItemBold('viewMainPage');

    $smarty->assign('template', 'index.tpl');
    $smarty->assign('title', getMessage('page.index.title'));
}

/**
 * Called before the login is made; used to redirect to welcome page.
 */
function preLogin() {
    if (!isAnonymous()) {
        redirect(buildUrl('showAdminConsole', array()));
    }
}

/**
 * Login action.
 *
 * @global object smarty instance
 * @global array menu items
 */
function login()
{
    global $smarty;

    // saving the language which was before the login
    $lang = getCurrentLanguage();

    destroySession();
    createSession(true);

    if (!$lang) {
        $lang = getCurrentLanguage();
    }

    // determining language again as the session was just destroyed
    setLanguageFromParameter();
    ensureCurrentLanguageIsInitialized();

    removeSystemMenuItemByPermission('login');

    $form = new FormBase('login', 'POST', buildUrl('login'));
    /* Add elements */
    $form->addTextElement('login', getMessage('login.form.login'), array('maxlength' => 20));
    $form->addPasswordElement('password', getMessage('login.form.password'), array('maxlength' => 40));
    $form->addProceedElement(getMessage('login.form.enter'));
    // Validation rules
    $form->addRequiredRule('login', getMessage('login.error.login.required'));

    if (isset($_POST['auth'])) {
        // Need to check login/password
        if (auth($_POST['login'], $_POST['password'])) {
            // User with this login/password exists
            createSession();
            $_SESSION['anonymous'] = false;
            redirect(buildUrl('showAdminConsole', array(), null, false, $lang));
        } else {
            // No such user, or bad password
            $smarty->assign('errorMessage', getMessage('common.error.wrongPassword'));
        }
    }
    showForm($smarty, $form, '', '');
    $smarty->assign('title', getMessage('login.title'));
    $smarty->assign('template', 'login.tpl');
}

/**
 * Logout action.
 *
 * @global object smarty instance
 */
function logout()
{
    global $smarty;

    $lang = getCurrentLanguage();
    destroySession();
    redirect(ADMIN_PAGE . '?language=' . $lang);
}

/**
 * Returns true if trying to edit oneself.
 */
function editingOneself() {
    if (isAnonymous()) {
        return false;
    }
    $dao =& staticGet('user', $_GET['id']);
    return $dao->login == getCurrentUser();
}

/**
 * Displays admin console - i.e. page to which any registered user is allowed
 * to go.
 *
 * @global object smarty instance
 */
function showAdminConsole() {
    global $smarty;

    $smarty->assign('title', getMessage('admin.console.title'));
    $smarty->assign('template', 'admin_console.tpl');
}

/**
 * Loads top news from DB.
 *
 * @return array news
 */
function loadTopNews() {
    $queryInfo['fields']['layout'] = 'newsItem';
    $queryInfo['fields']['language'] = getCurrentLanguage();
    $queryInfo['fields']['published'] = 1;
    $queryInfo['where'] = "('" . getNowDate() . "' BETWEEN publication_date AND expiration_date)";
    $queryInfo['orderBy'] = 'publication_date desc';
    $queryInfo['limit'] = 5;
    $partial = loadObjects('page', getPageDescriptor(), null, $queryInfo);
    return $partial['rows'];
}

/**
 * Creates a smarty instance and does initial configuration.
 *
 * @return object smarty instance
 */
function createSmartyInstance() {
    global $smarty;

    $smarty = new Smarty_Base;
    $smarty->assign('unique', rand());
    $smarty->setAdminLayout(true);
}


/**
 * Processes session: creates if not exists, checks if expired.
 */
function processSession() {
    switch (checkSession()) {
    case TAUTH_OK:
        // OK, session exists and not expired
        break;
    case TAUTH_SESSION_EXPIRED:
        // Session exists, but already expired
        destroySession();
        HTTP::redirect('index.php');
        exit;
        break;
    case TAUTH_FIRST_TIME:
        // No session yet
        // This is anonymous user
        createSession(true);
        break;
    }
}

/**
 * If HTTPS needs to be used and request came over HTTP, switches to HTTPS.
 *
 * @global bool whether HTTPS needs to be used
 */
function processHttps() {
    global $useHTTPS;

    if ($useHTTPS) {
        if (!$_SESSION['anonymous'] || $_GET['action'] == 'login') {
            if ($_SERVER['CHARSET_HTTP_METHOD'] == "http://" && strtolower($_SERVER['HTTPS']) != 'on') {
                HTTP::redirect("https://".$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI']);
            }
        }
    }
}

/**
 * Retrieves a canonical URL and puts to smarty instance.
 *
 * @global object smarty instance
 * @global string context path
 */
function setCanonicalUrl() {
    global $smarty, $contextPath;

    if (isset($_SERVER['REDIRECT_URL'])) {
        $url = $_SERVER['REDIRECT_URL'];
        if (strpos($url, $contextPath) === 0) {
            $url = substr($url, strlen($contextPath));
        }
        if (strpos($url, '/') === 0) {
            $url = substr($url, 1);
        }
        $smarty->assign('canonicalUrl', $url);
    }
}

/**
 * Converts menu keys to messages. Should be called only when the
 * current language is already determined.
 *
 * @param array $menu    the menu
 */
function resolveMenuMessages(&$menu) {
    foreach ($menu as $key => $link) {
        if ($link['messageKey']) {
            $menu[$key]['text'] = getMessage($link['messageKey']);
        }
    }
}

/**
 * Converts menu and layout keys to messages. Should be called only when the
 * current language is already determined.
 */
function resolveMenuAndLayoutMessages() {
    resolveMenuMessages(getSystemMenu());
    $layouts =& getLayouts();
    foreach ($layouts as $key => $layout) {
        if ($layout['titleKey']) {
            $layouts[$key]['title'] = getMessage($layout['titleKey']);
        }
        foreach ($layout['menus'] as $menuId => $menu) {
            $layouts[$key]['menus'][$menuId]['title'] = getMessage($menu['titleKey']);
            resolveMenuMessages($layouts[$key]['menus'][$menuId]['items']);
        }
        foreach ($layout['fields'] as $fieldId => $field) {
            $layouts[$key]['fields'][$fieldId]['title'] = getMessage($field['titleKey']);
        }
    }
}

/**
 * Determines and returns the layout which will be used to display a page.
 *
 * @global object smarty instance
 * @global array  layouts
 * @return the layout
 */
function determineLayout() {
    global $smarty, $layouts;

    if ($smarty->isDisplayLayoutSet()) {
        $layout = $smarty->getDisplayLayout();
    } else if ($smarty->isAdminLayout()) {
        $layout = $layouts[ADMIN_LAYOUT];
    } else {
        $layout = $layouts[FRONTEND_LAYOUT];
    }

    return $layout;
}

/**
 * Displays a page using the specified layout.
 *
 * @global object smarty instance
 * @param array the layout
 */
function doDisplay($layout) {
    global $smarty;

    if (!$smarty->isNoOutput()) {
        $smarty->display($layout['outerTemplate']);
    }
}

/**
 * Does main job serving the request.
 *
 * @global object   smarty instance
 * @global array    menu items
 * @global array    bottom links
 * @global array    bottom buttons
 * @global bool     whether first button exists
 * @global int      items per page
 * @global array    main menu items
 */
function processRequest() {
    global $smarty, $bottomLinks, $bottomButtons,
            $firstButtonExists, $perPage, $contextPath;

    $log =& getLog();
    $log->debug('processRequest(): beginning processing');

    unescapeGPCAll();
    createSmartyInstance();

    processSession();
    setLanguageFromParameter();
    ensureCurrentLanguageIsInitialized();
    // this should be done after the current language is determined
    resolveMenuAndLayoutMessages();

    // Maybe we need to switch to HTTPS
    processHttps();

    initController();

    dispatch();

    $log->debug('processRequest(): dispatch finished');

    checkLinks(getSystemMenu());
    checkLinks($bottomLinks);
    checkLinks(getBrowserMenu());
    formatBottomLinks();

    $layout = determineLayout();
    $menus = $layout['menus'];

    $smarty->assign('systemMenu', getSystemMenu());
    $smarty->assign('bottomLinks', $bottomLinks);
    $smarty->assign('bottomLinksAreEmpty', count($bottomLinks) == 0);
    $smarty->assign('bottomButtons', $bottomButtons);
    $smarty->assign('bottomButtonsAreEmpty', count($bottomButtons) == 0);
    $smarty->assign('firstButtonExists', $firstButtonExists);
    $smarty->assign('perPage', $perPage);
    $smarty->assign('menus', $menus);
    $smarty->assign('languages', getLanguages());
    $smarty->assign('currentLanguage', getCurrentLanguage());
    $smarty->assign('requestUri', $_SERVER['REQUEST_URI']);
    $localRequestUri = substr($_SERVER['REQUEST_URI'], strlen($contextPath), strlen($_SERVER['REQUEST_URI']) - strlen($contextPath));
    if (startsWith($localRequestUri, '/')) {
        $localRequestUri = substr($localRequestUri, 1, strlen($localRequestUri));
    }
    $smarty->assign('localRequestUri', $localRequestUri);
    $smarty->assign('contextPath', $contextPath);

    setCanonicalUrl();

    header('Content-type: text/html; charset=' . HTTP_CHARSET);

    doDisplay($layout);

    $log->debug('processRequest(): finished processing');
}



// Entry point

processRequest();


?>
Return current item: Blandware AtLeap Lite - CMS on PHP