Below is the current source of epiphany.php, one of three files used for this site.
<?php
/*
Epiphany library
Written by Nicolai Skovvart (http://llotus.dk)
Last updated: 06/07-2009
*/
class Epiphany{
//Initiate the Library.
//We're connecting to the database, defining the page we're on, fetching the data for said page and then fetching the website skin.
function __construct($id="status='active'"){
$this->db = $this->connect();
$this->id = $id;
$this->fetchTemplates();
$this->p = isset($_GET['p']) ? $_GET['p'] : "Blog";
$this->fetchPageData();
}
//Shutdown the library (like it's needed..)
function __destruct(){
$this->db->close();
}
//Skinning/templating functions
function Layout(){
return $this->parseFunctions($this->siteTemplate);
}
function fetchTemplates(){
$q = $this->db->query("SELECT * FROM skin WHERE ".$this->id);
$skin = $q->fetch_array();
$this->siteTemplate = $skin['siteTemplate'];
$this->css = $skin['css'];
}
//Easy connecting to our database. config.php has the variables used below and nothing else.
function connect(){
require_once "config.php";
$this->hash = $hash;
return new mysqli($host, $user, $password, $database);
}
//The functions you're using to view this with right now. Called by {{librarySource}} and {{indexSource}} in the database for this page.
function epiphanySource(){
return $this->returnSource("epiphany.php");
}
function indexSource(){
return $this->returnSource("index.php");
}
function returnSource($src){
$replace = array("<code>", "</code>");
return str_replace($replace, "", highlight_file($src, 1));
}
//I'm using so many boxes I figured it'd be slightly faster making it a function...
function box($header, $content, $class='blue'){
return "<div class='{$class}'><h3>{$header}</h3>{$content}</div>";
}
//Filler "Not Yet Implemented" function. Will be phased out when I'm done with the other functions. Also being called directly on this page.
function NYI(){
return $this->box("Under development",
"<img src='http://llotus.dk/imgs/notice.jpg' alt='Notice' class='right' />
<p>This feature hasn't been implented yet.</p>
<p>It is however an example of this site's ability to call functions from the design and content wrappers.</p>
",
"red");
}
//The tagwall function. It's not very elegant, but it seems to work so and so.
//It'll save posters as users the first time, and after validating the tag through an email, they'll be logged in and be able to skip the validation another time.
function Tagwall(){
$q = $this->db->query("SELECT content, author, date_format(time,'%H:%i %e/%c-%y') AS time from llotus WHERE type='validated tag' ORDER BY id DESC");
if(isset($_COOKIE['UserID'])){
$log = $this->db->query("SELECT name FROM llotus WHERE content='".$_COOKIE['UserID']."' AND type='user' LIMIT 1");
$r = $log->fetch_array();
if(empty($_POST['message'])){
$tagwall = $this->box("Tagwall",
"<p>Hello ".$r['name']."!</p>
<p>I remember you! You can skip the email validation and post directly.</p>",
"purple");
$tagwall .= "
<form action='http://llotus.dk/Tagwall' method='post'>
<p><label for='message'>Message: </label>
<textarea name='message' id='message' cols='20' rows='10' style='height: 200px; width: 400px;'></textarea><br />
<input type='submit' value='Add tag!' />
</p></form>";
while ($r = $q->fetch_array()) {
if($r['author'] == "Nicolai Skovvart"){
$tagwall .= $this->box($r['author'] ." [ ". $r['time'] ." ] wrote:", "<p>". nl2br(htmlspecialchars($r['content'])) ."</p>", "purple");
}
else{
$tagwall .= $this->box($r['author'] ." [ ". $r['time'] ." ] wrote:", "<p>". nl2br(htmlspecialchars($r['content'])) ."</p>", "dark");
}
}
}
else{
$this->db->query("INSERT INTO llotus (type,name,author,content) VALUES ('validated tag', 'null', '".$r['name']."', '".$_POST['message']."')");
$tagwall = $this->box("Tag posted!", "<p>Tag added!</p><p>Redirecting you back to the tagwall</p>", "green");
$this->setMetaDirect("http://llotus.dk/Tagwall");
}
}
else{
if(empty($_POST['message']) && empty($_POST['email']) && empty($_POST['name'])){
$tagwall = $this->box("Tagwall",
"<p>Below is a form you can fill out to post a tag.</p>
<p>To do so simply fill out all the fields and click the 'Add tag'-button.</p>
<p>Your email is only used to confirm you are a human being, and you should only have to do this once.</p>",
"purple");
$tagwall .= "
<form action='http://llotus.dk/Tagwall' method='post'>
<p><label for='name'>Name: </label><input type='text' name='name' id='name' /><br />
<label for='email'>Email: </label><input type='text' name='email' id='email' /><br />
<label for='message'>Message: </label><br />
<textarea name='message' id='message' cols='10' rows='10' style='height: 200px; width: 400px;'></textarea><br />
<input type='submit' value='Add tag' />
</p></form>";
while ($r = $q->fetch_array()) {
if($r['author'] == "Nicolai Skovvart"){
$tagwall .= $this->box($r['author'] ." [ ". $r['time'] ." ] wrote:", "<p>". nl2br(htmlspecialchars($r['content'])) ."</p>", "purple");
}
else{
$tagwall .= $this->box($r['author'] ." [ ". $r['time'] ." ] wrote:", "<p>". nl2br(htmlspecialchars($r['content'])) ."</p>", "dark");
}
}
}
elseif(!preg_match("/[-a-zA-Z0-9_.+]+@[a-zA-Z0-9-]+.[a-zA-Z]+/", $_POST['email'])){
$tagwall = $this->box("Tag not added!",
"<p>The email you specified does not appear to be valid. Please try again.</p>
<p>Redirecting you back to the tagwall.</p>",
"red");
$this->setMetaDirect("http://llotus.dk/Tagwall");
}
else{
$q = $this->db->query("SELECT name FROM llotus WHERE name='".$_POST['name']."' AND type='user'");
$r = $q->fetch_array();
if(!isset($r['name'])){
$this->db->query("INSERT INTO llotus (type,name,author,content) VALUES ('unvalidated tag', '".$_POST['email']."', '".$_POST['name']."', '".$_POST['message']."')");
mail($_POST['email'],
"llotus tagwall - please confirm your comment!",
"Hello ".$_POST['name']."!\n\nA message was just posted on the http://llotus.dk/Tagwall site using your emailaddress.\nTo confirm the comment please go visit the following link: http://llotus.dk/Confirm&val=".base64_encode(md5($this->hash)."/".$_POST['email']."/".$_POST['name'])."\nIf you did not post this tag, please ignore this email.\n\nIt is not possible to reply to this message.\n\nThank you,\nThe llotus mailbot",
"From: 'llotus mailbot' <noreply@llotus.dk>");
$tagwall = $this->box("Tag posted!",
"<p>A confirmation email has been sent to the specified email-address.</p>
<p>Your tag will be viewable when you press the confirmation link in the email. Thank you in advance.</p>",
"green");
$this->setMetaDirect("http://llotus.dk/Tagwall", 5);
}
else{
$tagwall = $this->box("Username taken",
"<p>The specified username has already been used.</p>
<p>Please try again with another name.</p>
<p>Redirecting you back to the tagwall in 5 seconds.</p>",
"red");
$this->setMetaDirect("http://llotus.dk/Tagwall", 5);
}
}
}
return $tagwall;
}
function Confirm(){
$val = explode("/", base64_decode($_GET['val']));
$this->db->query("UPDATE llotus SET type='validated tag' WHERE name='".$val[1]."' AND author='".$val[2]."'");
$this->db->query("INSERT INTO llotus (type, name, link, content) VALUES ('user', '".$val[2]."', '".$val[1]."', '".$_GET['val']."')");
$this->setMetaDirect("http://llotus.dk/Tagwall", 10);
setcookie("UserID", $_GET['val'], time()+60*60*24*365*20, "/", ".llotus.dk");
return $this->box("Tag validated!",
"<p>The tag posted by {$val[2]} ({$val[1]}) was validated and should now be viewable on the tagwall.</p>
<p>You should not have to validate tags in the future, nor will people be able to use your name.</p>
<p>Redirecting you back to the tagwall.</p>",
"green");
}
//Simple news/blog function
function Blog(){
$blogs = "";
$q = $this->db->query("SELECT name, content, author, date_format(time,'%H:%i %e/%c-%y') AS time from llotus WHERE type='blog' ORDER BY id DESC");
while ($r = $q->fetch_array()) {
$blogs .= $this->box($r['name'],
"<p>".nl2br($this->parseFunctions($r['content']))."</p>
<p class='byline'>". $r['author'] ." [ ". $r['time'] ." ]</p>");
}
return $blogs;
}
//Contact form function. Requires all fields to be filled to function, as well as a "valid" email (valid in this case being a simple something@something.something requirement)
function Contact(){
if(empty($_POST['name']) OR empty($_POST['message'])){
$contact = $this->box("Contact form",
"<p>Fill out the form below to send me an email.</p><p>Fields marked with (*) are required.</p><p>If you want me to reply by mail, please fill out your email address.</p>",
"purple");
$name = isset($_POST['name']) ? $_POST['name'] : "";
$email = isset($_POST['email']) ? $_POST['email'] : "";
$msg = isset($_POST['message']) ? $_POST['message'] : "";
$contact .="
<form action='http://llotus.dk/Contact' method='post'>
<p>
<label for='name'>Name (*)</label>
<input type='text' name='name' id='name' value='{$name}' />
<label for='email'>Email</label>
<input type='text' name='email' id='email' value='{$email}' /><br />
<label for='message'>Message (*)</label>
<textarea name='message' id='message' cols='10' rows='10' style='height: 200px; width: 400px;'>{$msg}</textarea><br />
<input type='submit' value='Send email!' />
</p></form>";
}
else{
mail('skovvart@gmail.com', '<llotus mail> ' . $_POST['name'] . ' ('. $_POST['email'] .')', $_POST['message'], 'From: "'.$_POST['name'].'" <'.$_POST['email'].'>\r\n" ."Reply-To: ' . $_POST['email']);
$contact = $this->box("Mail sent!", "<p>Thanks for contacting me.</p><p>I'll get back to you as soon as possible.</p><p>Redirecting you in 10 seconds.</p>", "green");
$this->setMetaDirect("http://llotus.dk/Contact", 10);
}
return $contact;
}
function TVList(){
require_once("tv.php");
$TVGuide = new TVGuide();
$return = "<p>Danish TV guide for ". strtolower(date("l \\t\h\e jS \of F o", $TVGuide->dataTime()))."</p>\n";
$return .= "<p><a href='http://llotus.dk/Channel-Select'>Change the channels shown here.</a></p>\n";
$return .= "<p><a href='http://llotus.dk/Channel-Sort'>Change the sorting of the channels shown here.</a></p>\n";
$first = true;
if(isset($_COOKIE['channels'])){
$_COOKIE['channels'] = unserialize(base64_decode($_COOKIE['channels']));
foreach($_COOKIE['channels'] as $key => $cookie){
$_COOKIE['channels'][$key] = str_replace("&", "&", $cookie);
}
foreach($_COOKIE['channels'] as $channel){
$return .= "<div class='tv-list'>".$TVGuide->channelListing($channel)."</div>\n";
}
}
else{
foreach(array("DR1", "DR2", "TV 2", "TV 2 Zulu", "TV3", "TV3+") as $channel){
$return .= "<div class='tv-list'>".$TVGuide->channelListing($channel)."</div>\n";
}
}
return $return;
}
function ChannelSelect(){
if(isset($_POST['selectedChannels'])){
setcookie("channels", base64_encode(serialize($_POST['selectedChannels'])), pow(2,31)-1, "/");
$this->setMetaDirect("http://llotus.dk/TV");
return $this->box("Channels updated", "<p>Selected channels updated. Returning you to the TV guide</p>","green");
}
require_once("tv.php");
$channels = new TVGuide();
$chocChip = isset($_COOKIE['channels']) ? unserialize(base64_decode($_COOKIE['channels'])) : array();
return $channels->channelOverview($chocChip);
}
function ChannelSort(){
$chocChip = isset($_COOKIE['channels']) ? unserialize(base64_decode($_COOKIE['channels'])) : array();
$list = "<p><a href='http://llotus.dk/TV'>Return to the TV guide.</a></p><table>";
foreach($chocChip as $key => $cookie){
$list .= "<tr><td><a href='http://llotus.dk/Channel-Sort&id={$key}&move=up'><img src='http://llotus.dk/imgs/up.png' alt='Move up' /></a><br /><a href='http://llotus.dk/Channel-Sort&id={$key}&move=down'><img src='http://llotus.dk/imgs/down.png' alt='Move down' /></a></td><td><p>{$cookie}</p></td></tr>";
}
$list .= "</table>";
if($list == "<p><a href='http://llotus.dk/TV'>Return to the TV guide.</a></p><table></table>"){
$list = $this->box("No channels selected!", "<p>No channels selected! Please visit <a href='http://llotus.dk/Channel-Select'>Channel Select</a> first and pick your desired channels!</p>", "red");
}
if(isset($_GET['id']) && isset($_GET['move'])){
if($_GET['id'] >= 0 && $_GET['id'] < count($chocChip)){
if($_GET['move'] == "up" && $_GET['id'] > 0){
$temp = $chocChip[$_GET['id']-1];
$chocChip[$_GET['id']-1] = $chocChip[$_GET['id']];
$chocChip[$_GET['id']] = $temp;
}
elseif($_GET['move'] == "down" && $_GET['id'] < count($chocChip)-1){
$temp = $chocChip[$_GET['id']+1];
$chocChip[$_GET['id']+1] = $chocChip[$_GET['id']];
$chocChip[$_GET['id']] = $temp;
}
else{
$this->setMetaDirect("http://llotus.dk/Channel-Sort");
return $this->box("Failed to alter sorting", "<p>It is not possible to move either top channel up, or the last channel down. Redirecting you back.</p>", "red");
}
}
setcookie("channels", base64_encode(serialize($chocChip)), pow(2,31)-1, "/");
header('Location: http://llotus.dk/Channel-Sort');
}
return $list;
}
//The function that helps me call library functions from the design and content wrappers of the database. Should NEVER be used on user-submitted content.
function parseFunctions($in){
//Eval doesn't like $this apparently, so using a filler variable.
$filler = $this;
return preg_replace("/\{\{(.*)\}\}/e", "\$filler->\$1()", $in);
}
//Menu-generator. Will probably be updated later to utilize a skinning engine, but it works for now.
function Menu(){
$menu = "<div id='menu'>";
$q = $this->db->query("SELECT * from llotus WHERE type='category' ORDER BY id");
while ($r = $q->fetch_array()) {
$menu .= "<h2>". $r['name'] ."</h2>\n<ul>\n";
$query = $this->db->query("SELECT * from llotus WHERE type='page' AND parentid='{$r['id']}' ORDER BY id");
while ($r = $query->fetch_array()) {
if($this->p == $r['link']){
$menu .= "<li><a href='http://llotus.dk/".$r['link']."' class='active'>".$r['name']."</a></li>\n";
}
else{
$menu .= "<li><a href='http://llotus.dk/".$r['link']."'>".$r['name']."</a></li>\n";
}
}
$menu .= "</ul>\n";
}
$menu .= "</div>";
return $menu;
}
//Fetch the page. If it doesn't exist, generate custom 404 file not found page.
function fetchPageData(){
$q = $this->db->query("SELECT * from llotus WHERE link='{$this->p}'");
$r = $q->fetch_array();
$this->title = $r['name'];
$this->content = $this->parseFunctions($r['content']);
if(empty($this->title) && empty($this->content)){
header("HTTP/1.0 404 Not Found");
$this->title = "Page not found!";
$this->content = $this->box("Page not found", "<p>The page, ".stripslashes(htmlspecialchars($this->p)).", could not be found. Redirecting you to the front page in 5 seconds.</p>", "red");
$this->setMetaDirect("http://llotus.dk/");
}
}
function setMetaDirect($url, $time=2){
$this->direct = "<meta http-equiv='refresh' content='{$time};url={$url}' />";
}
function metaDirect(){
return isset($this->direct) ? $this->direct : false;
}
//Returns the contents of the page.
function Content(){
return $this->content;
}
//Returns the title of the page.
function Title(){
return $this->title;
}
function CSS(){
header("Content-type: text/css");
die($this->css);
}
}
?>
Below is the current source of index.php, one of three files used for this site.
<?
error_reporting(E_ALL);
require_once "epiphany.php";
$epiphany = new Epiphany("id='5'");
echo $epiphany->Layout();
?>
Below is the current setup of config.php, one of three files used for this site.
<?
$host = "mysql.yoursite.com";
$user = "your_user";
$password = "your_password";
$database = "your_database";
$hash = "A_v3ry|s3cr3t/h4sh";
?>
