Hello web interface

This commit is contained in:
markseu 2013-04-15 00:41:04 +02:00
parent 9355317b5e
commit 2474166d27
16 changed files with 1471 additions and 641 deletions

View file

@ -4,10 +4,14 @@ RewriteEngine on
# RewriteBase /yellow
RewriteRule ^content/(.*) error [R=301,L]
RewriteRule ^system/(.*) error [R=301,L]
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^(content|system)/ error404 [L]
RewriteCond %{REQUEST_URI} \.(css|js|png)$
RewriteRule ^media/plugins/(core_.+) system/core/$1 [L]
RewriteCond %{REQUEST_URI} \.(css|js|png)$
RewriteRule ^media/plugins/(.+) system/plugins/$1 [L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.+) index.php [L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.php [L]
</IfModule>

View file

@ -1,4 +1,16 @@
Yellow
======
Yellow is a CMS for people, it's web-based and flat-file.
Yellow is a CMS for people, it's web-based and flat-file.
How do I install this?
----------------------
[Download Yellow](https://github.com/markseu/yellowcms/archive/master.zip) and unzip it.
Copy all files to your web server hosting.
Open your website in a browser, that's it!
Installation requirements are Apache, mod_rewrite and PHP 5.3.
Need help? Have a question?
---------------------------
Visit [Yellow on Reddit](http://www.reddit.com/r/yellowcms/), follow [Yellow on Twitter](https://twitter.com/yellowcms).

View file

@ -2,6 +2,6 @@
Title: Home
---
Yes, it works! Your Yellow installation was successful.
You can now [edit this page](wiki/) or use your favorite text editor.
You can now [edit this page](@baselocation/wiki/) or use your favorite text editor.
[Visit Yellow on Github](https://github.com/markseu/yellowcms).
Visit [Yellow on Github](https://github.com/markseu/yellowcms).

View file

@ -1,5 +1,5 @@
// Yellow CMS configuration
// All directories and locations have to end with a slash
// Yellow site configuration
// All locations and directories have to end with a slash
sitename = Website
author = Website
@ -10,7 +10,6 @@ template = default
stylesLocation = /media/styles/
imagesLocation = /media/images/
pluginsLocation = /media/plugins/
systemDir = system/
configDir = system/config/
pluginDir = system/plugins/
@ -18,7 +17,9 @@ snippetDir = system/snippets/
templateDir = system/templates/
contentDir = content/
contentHomeDir = 1-home/
contentDefaultFile = page
contentDefaultFile = page.txt
contentExtension = .txt
configExtension = .ini
systemExtension = .php
systemExtension = .php
errorPageFile = error(.*).txt
textStringFile = text_(.*).ini

View file

@ -0,0 +1,4 @@
---
Title: Unauthorised
---
You are not authorised on this server. Please log in.

View file

@ -0,0 +1,4 @@
---
Title: Page does not exist
---
You can [create this page](javascript:showPane('cmspaneeditor');).

View file

@ -0,0 +1,19 @@
// Yellow text strings
// Format: key = text string
language = en
languageDescription = English
languageAuthor = Mark Seuffert
webinterfaceLoginText = Yellow login
webinterfaceLoginEmail = Email:
webinterfaceLoginPassword = Password:
webinterfaceLoginButton = Login
webinterfaceSaveButton = Save
webinterfaceCancelButton = Cancel
webinterfaceEdit = Edit
webinterfaceShow = Show
webinterfaceUser = User
webinterfaceUserLogout = Logout
webinterface424Title = New page
webinterface424Text = Write text here

4
system/config/user.ini Normal file
View file

@ -0,0 +1,4 @@
// Yellow user accounts
// Format: Email, password (sha256 with email prefix as salt), name, language
// user@user.com,e1e2f704225259e91c44fb259c7db595e6cfd1a2e85a2b56508ab5aa9217d265,User,en

File diff suppressed because it is too large Load diff

View file

@ -5,51 +5,60 @@
// Markdown parser core plugin
class Yellow_Markdown
{
var $markdown; //markdown parser
var $html; //generated HTML
// Initialise plugin
const Version = "0.1.1";
var $markdown; //markdown parser
var $html; //generated HTML
// Initialise plugin
function initPlugin($yellow)
{
$this->markdown = new Yellow_MarkdownExtraParser($yellow);
}
// Parse text
// Parse text
function parse($text)
{
return $this->html = $this->markdown->transform($text);
}
}
require("markdown.php");
class Yellow_MarkdownExtraParser extends MarkdownExtra_Parser
{
var $yellow; //access to API
var $yellow; //access to API
function __construct($yellow)
{
$this->yellow = $yellow;
parent::__construct();
}
// Handle images
function __construct($yellow)
{
$this->yellow = $yellow;
parent::__construct();
}
// Transform text
function transform($text)
{
$baseLocation = $this->yellow->config->get("baseLocation");
$text = preg_replace("/@baseLocation/i", $baseLocation, $text);
return parent::transform($text);
}
// Handle images
function _doImages_inline_callback($matches)
{
{
$path = $matches[3]=="" ? $matches[4] : $matches[3];
$src = $this->yellow->config->get("baseLocation").$this->yellow->config->get("imagesLocation").$path;
list($width, $height) = $this->yellow->toolbox->detectImageDimensions(".".$this->yellow->config->get("imagesLocation").$path);
$src = $this->yellow->config->get("baseLocation").$this->yellow->config->get("imagesLocation").$path;
list($width, $height) = $this->yellow->toolbox->detectImageDimensions(".".$this->yellow->config->get("imagesLocation").$path);
$alt = $matches[2];
$title =& $matches[7];
$title = $matches[7];
$result = "<img src=\"".$this->encodeAttribute($src)."\"";
if($width && $height) $result .= " width=\"$width\" height=\"$height\"";
if(isset($alt)) $result .= " alt=\"".$this->encodeAttribute($alt)."\"";
if($width && $height) $result .= " width=\"$width\" height=\"$height\"";
if(isset($alt)) $result .= " alt=\"".$this->encodeAttribute($alt)."\"";
if(isset($title)) $result .= " title=\"".$this->encodeAttribute($title)."\"";
$result .= $this->empty_element_suffix;
return $this->hashPart($result);
}
}
$yellow->registerPlugin("markdown", "Yellow_Markdown", "0.1.0");
$yellow->registerPlugin("markdown", "Yellow_Markdown", Yellow_Markdown::Version);
?>

View file

@ -5,14 +5,15 @@
// Raw HTML parser core plugin
class Yellow_RawHtml
{
var $html; //generated HTML
const Version = "0.1.1";
var $html; //generated HTML
// Parse text, dummy transformation
// Parse text, dummy transformation
function parse($text)
{
return $this->html = $text;
}
}
$yellow->registerPlugin("rawhtml", "Yellow_RawHtml", "0.1.0");
$yellow->registerPlugin("rawhtml", "Yellow_RawHtml", Yellow_RawHtml::Version);
?>

View file

@ -0,0 +1,25 @@
.yellowlogin { width:600px; position:absolute; top:5px; padding:30px; border:1px solid #ccc; background:#fff; color:#000; }
.yellowlogin h1 { margin:0px; padding:0px; }
.yellowlogin p { margin:0.5em; text-align:right; }
.yellowbar { width:600px; position:absolute; top:1px; background:#fff; color:#000; }
.yellowbar img { vertical-align:top; }
.yellowbar button { color:#05d; padding-left:0.5em; padding-right:0.5em; }
.yellowbar button:hover { color:#f00; }
.yellowbarleft { margin-left:0px; display:block; float:left; height:100%; }
.yellowbarright { margin-right:0px; display:block; float:right; height:100%; }
.yellowbarlink { cursor:pointer; font:inherit; background:none; border:none; margin:0px padding:0px; }
.yellowbubble { -webkit-border-radius:4px; -moz-border-radius:4px; border-radius:4px; }
.yellowpane { position:absolute; display:none; margin:0px; padding:5px; border:solid 1px #ccc; background:#fff; color:#000; z-index:10; }
.yellowpane a { text-decoration:none; color:#000; }
.yellowpane a:hover { text-decoration:none; color:#f00; }
.yellowpane p { margin:0.5em; }
.yellowpane ul { list-style:none; margin:0em 0.5em; padding:0px; }
#yellowpaneedit { }
#yellowpaneshow { min-width:250px; overflow:auto; }
#yellowpaneuser { }
#yellowedittext { margin:0px; margin-bottom:5px; padding:5px; border:solid 1px #ccc; resize:none; font-size:0.9em }
#yelloweditbuttons { margin-bottom:5px; width:100%; }
#yelloweditbuttons input { margin-left:5px; }

View file

@ -0,0 +1,243 @@
// Copyright (c) 2013 Datenstrom, http://www.datenstrom.se
// This file may be used and distributed under the terms of the public license.
// Yellow main API
var yellow =
{
version: "0.0.0", //Hello web interface!
onClick: function(e) { yellow.webinterface.hidePanesOnClick(e); },
onShow: function(id) { yellow.webinterface.showPane(id); },
onReset: function(id) { yellow.webinterface.resetPane(id); },
onResize: function() { yellow.webinterface.resizePanes(); },
webinterface:{}, page:{}, pages:{}, toolbox:{}, config:{}, text:{}
}
// Yellow web interface
yellow.webinterface =
{
created: false, //interface created? (boolean)
timerId: 0, //interface timer ID
heightOld: 0, //height of big panes
// Initialise web interface
init: function()
{
this.intervalId = window.setInterval("yellow.webinterface.create()", 1);
window.onresize = yellow.onResize;
window.onclick = yellow.onClick;
},
// Create action bar and panes
create: function()
{
var body = document.getElementsByTagName("body")[0];
if(!body || !body.firstChild || this.created) return;
if(yellow.debug) console.log("yellow.webinterface.create email:"+yellow.config.userEmail+" "+yellow.config.userName);
if(yellow.config.userEmail)
{
var location = yellow.config.baseLocation+yellow.config.pluginsLocation;
var element = document.createElement("div");
element.className = "yellowbar";
element.setAttribute("id", "yellowbar");
element.innerHTML =
"<div class=\"yellowbarleft\">"+
"<img src=\""+location+"core_webinterface.png\" width=\"16\" height=\"16\"> Yellow"+
"<button class=\"yellowbarlink\" onclick=\"yellow.onShow('yellowpaneedit');\">"+this.getText("Edit")+"</button>"+
"<button class=\"yellowbarlink\" onclick=\"yellow.onShow('yellowpaneshow');\">"+this.getText("Show")+"</button>"+
"</div>"+
"<div class=\"yellowbarright\">"+
"<button class=\"yellowbarlink\" onclick=\"yellow.onShow('yellowpaneuser');\" id=\"yellowusername\">"+this.getText("User")+"</button>"+
"</div>";
body.insertBefore(element, body.firstChild);
yellow.toolbox.insertAfter(this.createPane("yellowpaneedit"), body.firstChild);
yellow.toolbox.insertAfter(this.createPane("yellowpaneshow", yellow.pages), body.firstChild);
yellow.toolbox.insertAfter(this.createPane("yellowpaneuser"), body.firstChild);
yellow.toolbox.setText(document.getElementById("yellowusername"), yellow.config.userName+" ↓");
yellow.toolbox.setText(document.getElementById("yellowedittext"), yellow.page.rawData);
} else {
var element = document.createElement("div");
element.className = "yellowlogin yellowbubble";
element.setAttribute("id", "yellowlogin");
element.innerHTML =
"<form method=\"post\" name=\"formlogin\">"+
"<input type=\"hidden\" name=\"action\" value=\"login\"/>"+
"<h1>"+this.getText("LoginText")+"</h1>"+
"<p>"+this.getText("LoginEmail")+" <input name=\"email\" maxlength=\"64\" /></p>"+
"<p>"+this.getText("LoginPassword")+" <input type=\"password\" name=\"password\" maxlength=\"64\" /></p>"+
"<p><input type=\"submit\" value=\""+this.getText("LoginButton")+"\"/></p>"+
"</form>";
body.insertBefore(element, body.firstChild);
}
window.clearInterval(this.intervalId);
this.created = true;
this.resizePanes(true);
},
// Create pane
createPane: function (id, data)
{
if(yellow.debug) console.log("yellow.webinterface.createPane id:"+id);
var outDiv = document.createElement("div");
if(id == "yellowpaneedit")
{
outDiv.innerHTML =
"<p>Editing page...</p>"+
"<form method=\"post\" name=\"formeditor\">"+
"<input type=\"hidden\" name=\"action\" value=\"edit\"/>"+
"<textarea id=\"yellowedittext\" name=\"rawdata\"></textarea>"+
"<div id=\"yelloweditbuttons\">"+
"<input type=\"submit\" value=\""+this.getText("SaveButton")+"\"/>"+
"<input type=\"button\" value=\""+this.getText("CancelButton")+"\" onclick=\"yellow.onReset('yellowpaneedit');\"/>"+
"</div>"+
"</form>";
} else if(id == "yellowpaneshow") {
outDiv.innerHTML = "<p>Showing files...</p>";
for(var n in data)
{
var outUl = document.createElement("ul");
var outLi = document.createElement("li");
var outA = document.createElement("a");
outA.setAttribute("href", data[n]["location"]);
yellow.toolbox.setText(outA, data[n]["title"]);
outLi.appendChild(outA);
outUl.appendChild(outLi);
outDiv.appendChild(outUl);
}
} else if(id == "yellowpaneuser") {
outDiv.innerHTML =
"<p>"+yellow.config.userEmail+"</p>"+
"<form method=\"post\" name=\"formlogout\">"+
"<input type=\"hidden\" name=\"action\" value=\"logout\"/>"+
"<p><a href=\"javascript:document.formlogout.submit();\">"+this.getText("UserLogout")+"</a></p> "+
"</form>";
}
var element = document.createElement("div");
element.className = "yellowpane yellowbubble";
element.setAttribute("id", id);
element.appendChild(outDiv);
return element;
},
// Reset pane
resetPane: function(id)
{
if(id == "yellowpaneedit")
{
document.formeditor.reset();
yellow.toolbox.setText(document.getElementById("yellowedittext"), yellow.page.rawData);
this.hidePane(id);
}
},
// Show pane
showPane: function(id)
{
if(document.getElementById(id).style.display == "block")
{
this.hidePanes();
} else {
this.hidePanes();
if(yellow.debug) console.log("yellow.webinterface.showPane id:"+id);
document.getElementById(id).style.display = "block";
this.resizePanes(true);
}
},
// Hide pane
hidePane: function(id)
{
if(document.getElementById(id)) document.getElementById(id).style.display = "none";
},
// Hide all panes
hidePanes: function ()
{
for(var element=document.getElementById("yellowbar"); element; element=element.nextSibling)
{
if(element.className && element.className.indexOf("yellowpane")>=0)
{
this.hidePane(element.getAttribute("id"));
}
}
},
// Hide all panes on mouse click
hidePanesOnClick: function(e)
{
var element = e.target || e.srcElement;
while(element = element.parentNode)
{
if(element.className)
{
if(element.className.indexOf("yellowpane")>=0 || element.className.indexOf("yellowbar")>=0) return;
}
}
this.hidePanes();
},
// Resize panes, recalculate height and width where needed
resizePanes: function(force)
{
var interfaceHeight = Number(window.innerHeight);
if((interfaceHeight!=this.heightOld || force) && document.getElementById("yellowbar"))
{
this.heightOld = interfaceHeight;
var elementBar = document.getElementById("yellowbar");
var borderRadius = 6;
var panePadding = 5;
var editPadding = 5;
var interfaceTop = elementBar.offsetHeight + 1;
interfaceHeight -= interfaceTop + borderRadius*2;
if(yellow.debug) console.log("yellow.webinterface.resizePanes windowY:"+interfaceHeight+" actionbarY:"+document.getElementById("yellowbar").offsetHeight+" buttonsY:"+document.getElementById("yelloweditbuttons").offsetHeight+" editorX:"+document.getElementById("yellowpaneedit").offsetWidth);
this.setPaneHeight(document.getElementById("yellowpaneedit"), interfaceHeight, null, interfaceTop);
this.setPaneHeight(document.getElementById("yellowpaneshow"), null, interfaceHeight, interfaceTop);
this.setPaneHeight(document.getElementById("yellowpaneuser"), null, null, interfaceTop);
var editTextHeight = interfaceHeight - panePadding*2 - editPadding*2 - 10
- (document.getElementById("yellowedittext").offsetTop-document.getElementById("yellowpaneedit").getElementsByTagName("p")[0].offsetTop)
- document.getElementById("yelloweditbuttons").offsetHeight;
document.getElementById("yellowpaneedit").style.width = (elementBar.offsetWidth - panePadding*2).toString()+"px";
document.getElementById("yellowedittext").style.height = editTextHeight.toString()+"px";
document.getElementById("yellowedittext").style.width = (document.getElementById("yellowpaneedit").offsetWidth - 2 - panePadding*2 - editPadding*2).toString()+"px";
document.getElementById("yellowpaneuser").style.marginLeft = (elementBar.offsetWidth - document.getElementById("yellowpaneuser").offsetWidth).toString()+"px";
}
},
// Set pane height
setPaneHeight: function(element, height, maxHeight, top)
{
if(maxHeight)
{
element.style.maxHeight = maxHeight.toString()+"px";
} else if(height) {
element.style.height = height.toString()+"px";
}
element.style.top = top+"px";
},
// Return text string
getText: function(key)
{
return ("webinterface"+key in yellow.text) ? yellow.text["webinterface"+key] : "[webinterface"+key+"]";
}
}
// Yellow toolbox with helpers
yellow.toolbox =
{
// Set element text
setText: function(element, text)
{
while(element.firstChild!==null) element.removeChild(element.firstChild);
element.appendChild(document.createTextNode(text));
},
// Insert element after element
insertAfter: function(newElement, referenceElement)
{
referenceElement.parentNode.insertBefore(newElement, referenceElement.nextSibling);
}
}
yellow.webinterface.init();

317
system/core/core_webinterface.php Executable file
View file

@ -0,0 +1,317 @@
<?php
// Copyright (c) 2013 Datenstrom, http://www.datenstrom.se
// This file may be used and distributed under the terms of the public license.
// Web interface core plugin
class Yellow_Webinterface
{
const Version = "0.0.0"; //Hello web interface!
var $yellow; //access to API
var $users; //web interface users
var $activeLocation; //web interface location? (boolean)
var $activeUserFail; //web interface login failed (boolean)
var $activeUserEmail; //web interface user currently logged in
// Initialise plugin
function initPlugin($yellow)
{
$this->yellow = $yellow;
$this->yellow->config->setDefault("webinterfaceLocation", "/wiki/");
$this->yellow->config->setDefault("webinterfaceUserFile", "user.ini");
$this->users = new Yellow_WebinterfaceUsers();
$this->users->load($this->yellow->config->get("configDir").$this->yellow->config->get("webinterfaceUserFile"));
}
// Handle web interface location
function onRequest($baseLocation, $location, $fileName)
{
$statusCode = 0;
if($this->checkWebinterfaceLocation($location))
{
$baseLocation .= rtrim($this->yellow->config->get("webinterfaceLocation"), '/');
$location = $this->yellow->getRelativeLocation($baseLocation);
$fileName = $this->yellow->getContentFileName($location);
if($this->checkUser()) $statusCode = $this->processRequestAction($baseLocation, $location, $fileName);
if($statusCode == 0) $statusCode = $this->yellow->processRequestFile($baseLocation, $location, $fileName,
$this->activeUserFail ? 401 : 0, false);
} else {
if($this->yellow->config->get("webinterfaceLocation") == "$location/")
{
$statusCode = 301;
$this->yellow->sendStatus($statusCode, "Location: http://$_SERVER[SERVER_NAME]$baseLocation$location/");
}
}
return $statusCode;
}
// Handle extra HTML header lines
function onHeaderExtra()
{
$header = "";
if($this->isWebinterfaceLocation())
{
$location = $this->yellow->config->getHtml("baseLocation").$this->yellow->config->getHtml("pluginsLocation");
$language = $this->isUser() ? $this->users->getLanguage($this->activeUserEmail) : $this->yellow->page->get("language");
$header .= "<link href=\"{$location}core_webinterface.css\" rel=\"styleSheet\" media=\"all\" type=\"text/css\" />\n";
$header .= "<script type=\"text/javascript\" src=\"{$location}core_webinterface.js\"></script>\n";
$header .= "<script type=\"text/javascript\">\n";
$header .= "// <![CDATA[\n";
if($this->isUser())
{
$header .= "yellow.page.rawData = ".json_encode($this->yellow->page->rawData).";\n";
$header .= "yellow.pages = ".json_encode($this->getPagesData()).";\n";
$header .= "yellow.config = ".json_encode($this->getConfigData($this->activeUserEmail)).";\n";
}
$header .= "yellow.text = ".json_encode($this->yellow->text->getData($language, "webinterface")).";\n";
if(defined("DEBUG")) $header .= "yellow.debug = ".json_encode(DEBUG).";\n";
$header .= "// ]]>\n";
$header .= "</script>\n";
}
return $header;
}
// Handle page before parser
function onParseBefore($text, $statusCode)
{
if($this->isWebinterfaceLocation() && $this->isUser())
{
if($statusCode == 424)
{
$this->yellow->page->rawData = "---\r\n";
$this->yellow->page->rawData .= "Title: ".$this->yellow->text->get("webinterface424Title")."\r\n";
$this->yellow->page->rawData .= "Author: ".$this->users->getName($this->activeUserEmail)."\r\n";
$this->yellow->page->rawData .= "---\r\n";
$this->yellow->page->rawData .= $this->yellow->text->get("webinterface424Text");
}
}
return $text;
}
// Handle page after parser
function onParseAfter($text, $statusCode)
{
if($this->isWebinterfaceLocation() && $this->isUser())
{
$this->yellow->toolbox->timerStart($time);
$baseLocation = $this->yellow->config->get("baseLocation");
$webinterfaceLocation = rtrim($this->yellow->config->get("webinterfaceLocation"), '/');
$text = preg_replace("#<a(.*?)href=\"$baseLocation(?!$webinterfaceLocation)(.*?)\"(.*?)>#",
"<a$1href=\"$baseLocation$webinterfaceLocation$2\"$3>", $text);
}
return $text;
}
// Process request for an action
function processRequestAction($baseLocation, $location, $fileName)
{
$statusCode = 0;
if($_POST["action"] == "edit")
{
if(strlen($_POST["rawdata"]))
{
$fileHandle = @fopen($fileName, "w");
if($fileHandle)
{
fwrite($fileHandle, $_POST["rawdata"]);
fclose($fileHandle);
} else {
die("Configuration problem: Can't write page '$fileName'!");
}
}
} else if($_POST["action"]== "logout") {
$this->users->destroyCookie("login");
$this->activeUserEmail = "";
$statusCode = 302;
$newLocation = $this->yellow->config->getHtml("baseLocation").$location;
$this->yellow->sendStatus($statusCode, "Location: http://$_SERVER[SERVER_NAME]$newLocation");
} else {
if(!is_readable($fileName))
{
if($this->yellow->toolbox->isFileLocation($location) && is_dir($this->yellow->getContentDirectory("$location/")))
{
$statusCode = 301;
$this->yellow->sendStatus($statusCode, "Location: http://$_SERVER[SERVER_NAME]$baseLocation$location/");
} else {
$statusCode = $this->checkUserPermissions($location, $fileName) ? 424 : 404;
$this->yellow->processRequestFile($baseLocation, $location, $fileName, $statusCode, false);
}
}
}
return $statusCode;
}
// Check web interface location
function checkWebinterfaceLocation($location)
{
$locationLength = strlen($this->yellow->config->get("webinterfaceLocation"));
$this->activeLocation = substr($location, 0, $locationLength) == $this->yellow->config->get("webinterfaceLocation");
return $this->isWebinterfaceLocation();
}
// Check user login
function checkUser()
{
if($_POST["action"] == "login")
{
$email = $_POST["email"];
$password = $_POST["password"];
if($this->users->checkUser($email, $password))
{
$this->users->createCookie("login", $email);
$this->activeUserEmail = $email;
} else {
$this->activeUserFail = true;
}
} else if(isset($_COOKIE["login"])) {
$cookie = $_COOKIE["login"];
if($this->users->checkCookie($cookie))
{
$this->activeUserEmail = $this->users->getCookieEmail($cookie);
} else {
$this->activeUserFail = true;
}
}
return $this->isUser();
}
// Check users permissions for creating new page
function checkUserPermissions($location, $fileName)
{
$path = dirname($fileName);
return is_dir($path);
}
// Check if web interface location
function isWebinterfaceLocation()
{
return $this->activeLocation;
}
// Check if user is logged in
function isUser()
{
return !empty($this->activeUserEmail);
}
// Return page tree with content/media information
function getPagesData()
{
$data = array();
foreach($this->yellow->pages->root(true) as $page)
{
$data[$page->fileName] = array();
$data[$page->fileName]["location"] = $page->getLocation();
$data[$page->fileName]["title"] = $page->getTitle();
}
return $data;
}
// Return configuration data including user information
function getConfigData($email)
{
$data = array("userEmail" => $email,
"userName" => $this->users->getName($email),
"userLanguage" => $this->users->getLanguage($email),
"baseLocation" => $this->yellow->config->get("baseLocation"));
return array_merge($data, $this->yellow->config->getData("Location"));
}
}
// Yellow web interface users
class Yellow_WebinterfaceUsers
{
var $users; //registered users
function __construct()
{
$this->users = array();
}
// Load users from file
function load($fileName)
{
$fileData = @file($fileName);
if($fileData)
{
foreach($fileData as $line)
{
if(preg_match("/^\//", $line)) continue;
preg_match("/^(.*?)\s*,(.*?),\s*(.*?),\s*(.*?)\s*$/", $line, $matches);
if($matches[1]!="" && $matches[2]!="" && $matches[3]!="" && $matches[4]!="")
{
$this->setUser($matches[1], $matches[2], $matches[3], $matches[4]);
if(defined("DEBUG") && DEBUG>=3) echo "Yellow_WebinterfaceUsers::load email:$matches[1] $matches[3]<br/>\n";
}
}
}
}
// Set user data
function setUser($email, $password, $name, $language)
{
$this->users[$email] = array();
$this->users[$email]["email"] = $email;
$this->users[$email]["password"] = $password;
$this->users[$email]["name"] = $name;
$this->users[$email]["language"] = $language;
$this->users[$email]["session"] = hash("sha256", $email.$password.strrev($email.$password));
}
// Check user login
function checkUser($email, $password)
{
return $this->isExisting($email) && hash("sha256", $email.$password)==$this->users[$email]["password"];
}
// Create browser cookie
function createCookie($cookieName, $email)
{
if($this->isExisting($email))
{
$salt = hash("sha256", uniqid(mt_rand(), true));
$text = $email.";".$salt.";".hash("sha256", $salt.$this->users[$email]["session"]);
setcookie($cookieName, $text, time()+60*60*24*30*365*10, "/") || die("Server problem: Can't create '$cookieName' cookie!");
}
}
// Destroy browser cookie
function destroyCookie($cookieName)
{
setcookie($cookieName, "", time()-3600, "/");
}
// Check user login from browser cookie
function checkCookie($cookie)
{
list($email, $salt, $session) = explode(";", $cookie);
return $this->isExisting($email) && hash("sha256", $salt.$this->users[$email]["session"])==$session;
}
// Return user email from browser cookie
function getCookieEmail($cookie)
{
list($email, $salt, $session) = explode(";", $cookie);
return $email;
}
// Return user name
function getName($email)
{
return $this->isExisting($email) ? $this->users[$email]["name"] : "";
}
// Return user language
function getLanguage($email)
{
return $this->isExisting($email) ? $this->users[$email]["language"] : "";
}
// Check if user exists
function isExisting($email)
{
return !is_null($this->users[$email]);
}
}
$yellow->registerPlugin("webinterface", "Yellow_Webinterface", Yellow_Webinterface::Version);
?>

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

14
system/plugins/example.php Executable file
View file

@ -0,0 +1,14 @@
<?php
// Copyright (c) 2013 Datenstrom, http://www.datenstrom.se
// This file may be used and distributed under the terms of the public license.
// Example plugin
class Yellow_ExamplePlugin
{
//You can download plugins and extensions from Github.
//See https://github.com/markseu/yellowcms-extensions
const Version = "0.0.0";
}
$yellow->registerPlugin("example", "Yellow_ExamplePlugin", Yellow_ExamplePlugin::Version);
?>