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;
?>