Kontakt - Datenschutz

Subversion

<?php
/**
 * ydlinks
 *
 * @category  YD
 * @package   Web
 * @author    Sven Drieling <sd@sven-drieling.de>
 * @copyright 2013 Sven Drieling
 * @license   http://opensource.org/licenses/mit-license.php MIT license
 * @version   0.1.0alpha1
 */

namespace YD\Web\Links;


require_once __DIR__ . '/links_config.php';

// Improve security of session cookie
ini_set('session.use_only_cookies', 1);
ini_set('session.cookie_secure'   , $linksConfig['cookieSecure']);
ini_set('session.cookie_httponly' , 1);


session_start();
if(!isset($_SESSION['isLogin'])) {
    $_SESSION['isLogin'] = false;
}

if(!isset($_SESSION['templateName'])) {
    $_SESSION['templateName'] = 'default';
}

// Simple maintenance mode
if($linksConfig['maintenance'] and !$_SESSION['isLogin']) {
    $page['httpStatus']  = 503;
    $page['httpMessage'] = 'Service Unavailable';

    if('cgi-fcgi' === php_sapi_name()) { // TODO Check more sapis?
        header("Status: {$page['httpStatus']} {$page['httpMessage']}");
    } else {
        // TODO Check $_SERVER['SERVER_PROTOCOL']
        header("{$_SERVER['SERVER_PROTOCOL']} {$page['httpStatus']} {$page['httpMessage']}");
    }
    echo "Maintenance Mode.\n";
    exit;
}

require_once __DIR__ . '/Link.php';
require_once __DIR__ . '/Links.php';


$links = new \YD\Web\Links();
$links->viewIndex = function($link) use ($links) {
    $result = '';


    if($links->isLogin()) {
        $buttonEdit   = " <button name='_command' value='showEditForm {$link->§id}'   type='submit'>Edit</button>";
        $buttonDelete = " <button name='_command' value='delete {$link->§id}' type='submit'>Delete</button>";
    } else {
        $buttonEdit   = '';
        $buttonDelete = '';
    }

    $result .= "<article>\n";
    $result .= "<h2><a href='{$link->§uri}'>{$link->§title}</a><br />{$buttonEdit}{$buttonDelete}</h2>\n";
    $result .= "<div class='description'>{$link->description}</div>\n";
    $result .= "</article>\n";


    return $result;
};


function isSecureConnection() {
    $secureConnection = false;


    if(isset($_SERVER['HTTPS'])) {
        if('on' === $_SERVER["HTTPS"]) {
            $secureConnection = true;
        }
    }


    return $secureConnection;
}


function checkSecureConnection() {
    global $linksConfig;


    if($linksConfig['cookieSecure'] and !isSecureConnection()) {
        $GLOBALS['page']['message']['type']    = 'security';
        $GLOBALS['page']['message']['content'] = 'Admin requires secure connection.';

        return false;
    }


    return true;
}


function checkIsAdmin($links) {
    if(!$links->isAdmin()) {
        $GLOBALS['page']['message']['type']    = 'security';
        $GLOBALS['page']['message']['content'] = 'Operation requires admin login.';

        return false;
    }


    return true;
}


// Page content
$page = ['httpStatus'  => 200,
         'httpMessage' => 'OK',

         'title'       => 'Bookmarks - Sven Drieling',
         'message'     => ['type'    => 'info',
                           'content' => ''],
         'navigation'  => '',
         'content'     => '',
         'debug'       => ''];


// Command API
$command   = 'show';
$arguments = [];

$_POST = \array_map('trim', $_POST);


if(isset($_POST['_command'])) {
    $args = \explode(' ', $_POST['_command']);
    if(count($args)) { // TODO Check error
        $command   = \array_shift($args);
        $arguments = $args;
    }
}


// Debug info
if($linksConfig['debug'] or $links->isLogin()) {
    ob_start();
    echo "<h2 id='debug'>Debug</h2>\n"; // TODO HTML5 section, ...?

    echo "<pre>";
    echo "PHP: ", phpversion(), '(', php_sapi_name(), ")\n";

    echo "\$_POST\n";
    var_dump($_POST);

    echo "\$command\n";
    var_dump($command);

    echo "\$arguments\n";
    var_dump($arguments);

    echo "\$_COOKIE\n";
    var_dump($_COOKIE);

    echo "\$_SESSION\n";
    var_dump($_SESSION);
    echo "</pre>";

    echo "\$_SERVER\n";
    var_dump($_SERVER);
    echo "</pre>";

    $page['debug'] .= ob_get_contents();
    ob_end_clean();
}


try {
    switch($command) {
        case 'selectTemplate':
            if(checkIsAdmin($links)) {
                // TODO Error handling
                $_SESSION['templateName'] = isset($_POST['templateName']) ? $_POST['templateName'] : 'default';
                if(!preg_match('#^[a-z]+$#', $_SESSION['templateName'])) {
                    $_SESSION['templateName'] = 'default';
                }
            }
            // Fall through

        case 'showNewForm':
            if(checkIsAdmin($links)) {
                $links->loadTemplates();

                // TODO Check template exists
                $link = new \YD\Web\Links\Link($links->templates[$_SESSION['templateName']]);

                $page['title']      = 'Add Link';
                $page['navigation'] = $links->showNavigation();
                $page['content']    = $links->showNewForm($link);
            }
            break;


        case 'showEditForm':
            if(checkIsAdmin($links)) {
                $link = $links->readByID($arguments[0]); // TODO Error handling

                $page['title']      = 'Edit Link';
                $page['navigation'] = $links->showNavigation();
                $page['content']    = $links->showEditForm($link);
            }
            break;


        case 'updateLink':
            if(checkIsAdmin($links)) {
                $link = new \YD\Web\Links\Link($_POST); // TODO Error handling
                if($link->validate()) {
                    $links->update($link);
                    if(true === $links->saveOverviewAsHTML32()) {
                        $page['message']['type']    = 'info';
                        $page['message']['content'] = "<p>Update overview OK</p>";
                    } else {
                        $page['message']['type']    = 'error';
                        $page['message']['content'] = "<p>Update overview FAILED!</p>";
                    }
                } else {
                    $page['message']['type']    = 'error'; // TODO Cleanup
                    $page['message']['content'] = "<p>Input not valid.</p>\n<ul>\n";
                    foreach($link->messages as $message) {
                        $page['message']['content'] .= "<li>" . e($message) . "</li>\n";
                    }
                    $page['message']['content'] .= "</ul>\n";
                }

                $page['navigation'] = $links->showNavigation();
                $page['content']    = $links->showEditForm($link);
            }
            break;


        case 'addLink':
            if(checkIsAdmin($links)) {
                $link = new \YD\Web\Links\Link($_POST); // TODO Error handling
                $page['navigation'] = $links->showNavigation();

                if($link->validate() and $links->create($link)) {
                    try {
                        if(true === $links->saveOverviewAsHTML32()) {
                            $page['message']['type']    = 'info';
                            $page['message']['content'] = "<p>Update overview OK</p>";
                        } else {
                            $page['message']['type']    = 'error';
                            $page['message']['content'] = "<p>Update overview FAILED!</p>";
                        }
                    } catch (\Exception $e) {
                        $page['message']['type']    = 'error';
                        $page['message']['content'] = "<p>" . $e->getMessage() . "</p>";
                    }

                    $page['content'] = $links->showIndex();
                } else {
                    $page['title']   = 'Add Link';
                    $page['content'] = $links->showNewForm($link);

                    $page['message']['type']    = 'error';
                    $page['message']['content'] = "<p>Input not valid.</p>\n<ul>\n";
                    foreach($link->messages as $message) {
                        $page['message']['content'] .= "<li>" . e($message) . "</li>\n";
                    }
                    $page['message']['content'] .= "</ul>\n";
                }
            }
            break;


        case 'delete': // TODO 'deleteLink'
            if(checkIsAdmin($links)) {
                $links->delete($arguments[0]); // TODO Error handling

                $page['navigation'] = $links->showNavigation();
                $page['content']    = $links->showIndex();
            }
            break;


        case 'saveTemplate':
            if(checkIsAdmin($links)) {
                try {
                    $link = new \YD\Web\Links\Link($_POST); // TODO Error handling

                    $links->loadTemplates();


                    $templateName = trim($_POST['templateNameSave']);
                    if(!preg_match('#^[a-z]+$#', $templateName)) {
                        $page['message']['type']    = 'error';
                        $page['message']['content'] = "<p>Malformed template name [a-z]</p>";
                    }
                    else {
                        $links->templates[$templateName]['title']       = $link->title;
                        $links->templates[$templateName]['uri']         = $link->uri;
                        $links->templates[$templateName]['description'] = $link->description;
                        $links->saveTemplates();

                        $_SESSION['templateName'] = $templateName;

                        $page['message']['type']    = 'info';
                        $page['message']['content'] = "<p>Save Templates OK</p>";
                    }

                    $page['title']      = 'Add Link';
                    $page['navigation'] = $links->showNavigation();
                    $page['content']    = $links->showNewForm($link);
                } catch (\Exception $e) {
                    $page['message']['type']    = 'error';
                    $page['message']['content'] = "<p>" . $e->getMessage() . "</p>";
                }
            }
            break;


        case 'show':
            $page['navigation'] = $links->showNavigation();
            $page['content']    = $links->showIndex();

            if(\file_exists(__DIR__ . '/links.txt')) {
                $page['content'] .= \file_get_contents(__DIR__ . '/links.txt'); // TODO Error handling
            }
            break;


        case 'showLoginForm':
            if(checkSecureConnection()) {
                $page['title']   = 'Login';
                $page['content'] = $links->showLoginForm();
            }
            break;


        case 'updateOverview':
            if(checkIsAdmin($links)) {
                $page['navigation'] = $links->showNavigation();

                if($links->saveOverviewAsHTML32()) {
                    $GLOBALS['page']['message']['type']    = 'info';
                    $GLOBALS['page']['message']['content'] = 'Overview updated.';
                } else {
                    $GLOBALS['page']['message']['type']    = 'error';
                    $GLOBALS['page']['message']['content'] = 'Update overview failed.';
                }

                $page['content'] = $links->showIndex();
            }
            break;


        case 'login':
            if(checkSecureConnection()) {
                if($links->login()) {
                    $page['navigation'] = $links->showNavigation();
                    $page['content']    = $links->showIndex();
                } else {
                    $page['title']   = 'Login';
                    $page['content'] = $links->showLoginForm();
                }
            }
            break;


        case 'logout':
            if(checkSecureConnection()) {
                $links->logout();
                $page['navigation'] = $links->showNavigation();
                $page['content']    = $links->showIndex();
            }
            break;


        default:
            $page['title']       = 'Error';
            $page['content']     = '<p>Unknown command.</p>';
            $page['httpStatus']  = 400;
            $page['httpMessage'] = 'Bad Request';
            break;
    }
} catch(\Exception $e) {
    $page['title']       = 'Error';
    $page['content']     = e($e->getMessage()); // TODO Only login?
    $page['httpStatus']  = 500;                 // TODO Status code?
    $page['httpMessage'] = 'Internal Server Error';
}


$message = "<div id='message'>{$page['message']['content']}</div>"; // TODO Message type, CSS

$html = \str_replace('<v:title>',      $page['title'],      $linksConfig['templatePage']);
$html = \str_replace('<v:message>',    $message,            $html);
$html = \str_replace('<v:navigation>', $page['navigation'], $html);
$html = \str_replace('<v:content>',    $page['content'],    $html);
$html = \str_replace('<v:debug>',      $page['debug'],      $html);


if('cgi-fcgi' === php_sapi_name()) { // TODO Check more sapis?
    header("Status: {$page['httpStatus']} {$page['httpMessage']}");
} else {
    // TODO Check $_SERVER['SERVER_PROTOCOL']
    header("{$_SERVER['SERVER_PROTOCOL']} {$page['httpStatus']} {$page['httpMessage']}");
}

header('Content-Type: text/html; charset=utf-8');
header('Content-Length: ' . strlen($html));
echo $html;
?>