//One Page CMS - written by Paul Tero 23/1/2009. This simple CMS allows you to edit
//text within HTML and PHP pages which appear between comments that look like:
// and .
//See http://www.tero.co.uk/scripts/onepagecms.php for more information
//From 7/12/2009 this editor can also handle images! From 23/6/2010, you can login from a form.
//From 25/8/2010 it uses TinyMCE's built-in image list
//Specify which files are allowed to be edited. This accepts wildcards and can be an array, eg:
//$ALLOWEDFILES = array ("home/*.php", "about/*.html");
$ALLOWEDFILES = '*.html';
//Directory where we should save backups every time a file is edited. Leave blank to disable this feature
$BACKUPDIR = 'onepagecmsbackups/';
//Directory where images should be (or are already) stored. Leave blank to disable this feature.
$IMAGEDIR = 'onepagecmsimages/';
//If we want to use the TinyMCE editor, pass in the theme. Can be blank for no editor, simple, or advanced.
//Note that this uses the Javascript files from the TinyMCE server, with some extra code to allow popups
//and inserting images to work.
$HTMLEDITOR = 'advanced'; //leave blank to disable
//User name and password. If this kind of login doesn't work, change PhpAuthLogin to FormLogin at the bottom
$USERNAME = 'onepagecms';
$PASSWORD = 'uYadfIfJa';
/////////////////////////////// Helpful functions ///////////////////////////////
//This gets all files matching $match. It looks recursively using glob or the find command.
function GetMatchingFiles ($matches) {
if (!is_array ($matches)) $matches = array ($matches); //the things to match
$files = array(); //the array of files
foreach ($matches as $match) {
//if the glob function exists
if (function_exists ("glob") && ($globfiles = glob ($match)) && is_array ($globfiles)) $files = array_merge ($files, $globfiles);
//or else use the find function
else if (function_exists ('exec') && exec ('find ' . dirname ($match) . ' -type f | grep "' . str_replace ('*', '.*', str_replace ('.', '\.', basename ($match))) . '"', $findfiles) && is_array ($findfiles)) $files = array_merge ($files, $findfiles);
//or else loop through each one as if it were a directory, added 3/10/2010
else if (preg_match ('/\*/', $match) && ($dh = opendir ($filedir = dirname ($match)))) {
$match = (str_replace ('*', '.*', str_replace ('.', '\.', "~$match~")));
while (false!==($file=readdir($dh))) if (is_file($file="$filedir/$file") && preg_match ($match,$file)) array_push ($files, $file);
}
//or else just add the file
else array_push ($files, $match);
}
return $files;
}
//Get the image files from a directory and its subdirectories
function GetImageFiles ($imagedir) {
$imageendings = array ('gif', 'jpg', 'jpeg', 'png');
$a = array(); foreach ($imageendings as $ending) $a = array_merge ($a, GetMatchingFiles ("$imagedir*.$ending"));
$images = array(); foreach ($a as $image) $images[$image] = preg_replace ("|^$imagedir|", '', $image); //with and without the directory
return $images;
}
//This gets the editable areas from a file
function GetEditableAreas ($file) {
$areas = array(); //this is an array of editable areas
$fc = file_get_contents ($file); //get the file conents
//Get all the editable areas, s is so that . matches multiline, U is for ungreedy
preg_match_all ('/(.*)/sU', $fc, $matches, PREG_SET_ORDER);
//Loop through the matches and put them into an array, also removing any \r characters that might get entered
foreach ($matches as $m) array_push ($areas, array (ucwords (str_replace ('-', ' ', $m[1])), $m[2]));
//Return the editable areas which is an array of arrays each with 2 elements for the name and text
return $areas;
}
//For saving a file
function SaveFile ($file, $areas, $backupdir='') {
//First check we can save the data
if (!$areas) return "There is no data to save";
$fc = file_get_contents ($file); //get the file conents
if (!$fc) return "Could not read the file $file";
//Now get allthe parts with tags
$parts = preg_split ('/()/', $fc, -1, PREG_SPLIT_DELIM_CAPTURE); //split by the ONEPAGECMS tags
if (count ($parts) != count ($areas) * 4 + 1) return "There are the wrong number of ONEPAGECMS tags in the file";
$newcontents = array_shift ($parts); //get the first bit before the first ONEPAGECMS tag
//For each editable area, get the START tag, the editable area, the end tag, then the part after the END tag
foreach ($areas as $i=>$area) //remove slashes and \r from the data being saved
$newcontents .= $parts[$i*4] . "\n" . trim (stripSlashes (preg_replace ("/\r\n?/", "\n", $areas[$i]))) . "\n" .
$parts[$i*4 + 2] . $parts[$i*4+3];
//Backup the file before saving it, and make the backup world writeable so it can be deleted via FTP
$backupminutes = 5; //only backup files if they were last saved more than $backupminutes ago - eg don't backup for tiny quick changes
if ($backupdir && is_file ($file) && ($backupstat = stat ($file)) && ($backupstat['mtime'] < time() - 60 * $backupminutes)) {
if (!is_dir ($backupdir)) {mkdir ($backupdir); chmod ($backupdir, 0777);}
copy ($file, $backupfile = $backupdir . '/' . str_replace ('/', '-', $file) . '.' . date ('Y-m-d-Hi') . '.backup');
if (file_exists ($backupfile)) chmod ($backupfile, 0666);
}
//Save the contents
$fw = fopen ($file, 'w'); //try to open the file for writing
if (!$fw) return "Could not write to the file $file. Please check the permissions.";
//Save the file
fwrite ($fw, $newcontents); fclose ($fw);
return "File was saved successfully.";
}
//Saving the images
function SaveImages ($imagedir) {
$imageendings = array ('gif', 'jpg', 'jpeg', 'png'); $m = array();
if (!is_dir ($imagedir)) {mkdir ($imagedir); chmod ($imagedir, 0777);}
//Check it's the right endings, etc
if (isset ($_POST['remove'])) foreach ($_POST['remove'] as $image)
if (preg_match ("~^$imagedir.+\." . join ('|', $imageendings) . '$~', $image)) {$m[] = "Removing $image"; unlink ($image);}
else $m[] = "Cannot remove $image (perhaps because of the file ending)";
foreach ($_FILES as $formfield=>$filedata) {
if (!$filedata['size']) continue; //nothing to upload
$moveto = $imagedir . $filedata['name'];
if ($filedata['error']) $m[] = "Could not upload $filedata[name] because of: $filedata[error]";
else if (!preg_match ('~\.' . join ('|', $imageendings) . '$~', $filedata['name'])) $m[] = "Cannot upload $filedata[name] (wrong ending)";
else {$m[] = "Saving $moveto"; move_uploaded_file ($filedata['tmp_name'], $moveto); chmod ($moveto, 0666);}
}
return join ('
', $m);
}
//Function for logging in using PhpAuth
function PhpAuthLogin ($username, $password) {
$u = isset ($_SERVER['PHP_AUTH_USER']) ? $_SERVER['PHP_AUTH_USER'] : '';
$p = isset ($_SERVER['PHP_AUTH_PW']) ? $_SERVER['PHP_AUTH_PW'] : '';
if ($username != $u || $password != $p) {
header ('WWW-Authenticate: Basic realm="One Page CMS"');
header ("HTTP/1.0 401 Unauthorized");
print '
You are not authorised to access this ';
print 'One Page CMS. ';
print 'Reload this page to try again,
';
print 'especially if you have just logged out, and want to log back in.';
exit;
}
}
//Function for logging in from a form
function FormLogin ($username, $password) {
if (!isset ($_SESSION)) session_start(); //start the sessions
if (isset ($_GET['logout'])) $_SESSION['AUTH_OK'] = ''; //logged out
$u = isset ($_POST['AUTH_USER']) ? $_POST['AUTH_USER'] : ''; //from posted variable
$p = isset ($_POST['AUTH_PW']) ? $_POST['AUTH_PW'] : '';
if ($username == $u && $password == $p) {$_SESSION['AUTH_OK'] = $u; return;} //successful login from the form
if (isset ($_SESSION['AUTH_OK']) && $_SESSION['AUTH_OK']==$username) return; //previous login from the session
echo '
Your login details were incorrect, please try again:
'; //previous unsuccessful login else echo 'Please enter your login details below:
'; echo '