New features

This commit is contained in:
Diego Najar 2015-05-05 01:00:01 +00:00
parent df95f7364f
commit a64d7c6370
66 changed files with 3295 additions and 809 deletions

View File

@ -2,6 +2,9 @@ AddDefaultCharset UTF-8
RewriteEngine on
DirectorySlash Off
RewriteCond %{REQUEST_FILENAME} !-f
#RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*) index.php [L]
RewriteRule ^(.*) index.php [L]

View File

@ -0,0 +1,47 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
// ============================================================================
// Functions
// ============================================================================
function addUser($args)
{
global $dbUsers;
// Check if the username already exist in db.
if( $dbUsers->userExists($args['username']) || helperText::isEmpty($args['username']) )
{
Alert::set('Username already exists or is empty');
return false;
}
// Validate password.
if( ($args['password'] != $args['confirm-password'] ) || helperText::isEmpty($args['password']) )
{
Alert::set('The password and confirmation password do not match');
return false;
}
// Add the user.
if( $dbUsers->add($args) )
{
Alert::set('User has been added successfull');
return true;
}
else
{
Alert::set('Error occurred when trying to add a new user');
return false;
}
}
// ============================================================================
// POST Method
// ============================================================================
if( $_SERVER['REQUEST_METHOD'] == 'POST' )
{
if( addUser($_POST) ) {
Redirect::page('admin', 'users');
}
}

View File

@ -0,0 +1,74 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
// ============================================================================
// Functions
// ============================================================================
function editPage($args)
{
global $dbPages;
// Page status, published or draft.
if( isset($args['publish']) ) {
$args['status'] = "published";
}
else {
$args['status'] = "draft";
}
if(!isset($args['parent'])) {
$args['parent'] = NO_PARENT_CHAR;
}
// Edit the page.
if( $dbPages->edit($args) )
{
$dbPages->regenerate();
Alert::set('The page has been saved successfully');
Redirect::page('admin', 'manage-pages');
}
else
{
Alert::set('Error occurred when trying to edit the page');
}
}
function deletePage($key)
{
global $dbPages;
if( $dbPages->delete($key) )
{
Alert::set('The page has been deleted successfully');
Redirect::page('admin', 'manage-pages');
}
else
{
Alert::set('Error occurred when trying to delete the page');
}
}
// ============================================================================
// POST Method
// ============================================================================
if( $_SERVER['REQUEST_METHOD'] == 'POST' )
{
if( isset($_POST['delete']) ) {
deletePage($_POST['key']);
}
else {
editPage($_POST);
}
}
// ============================================================================
// Main
// ============================================================================
if(!$dbPages->pageExists($layout['parameters'])) {
Redirect::page('admin', 'manage-pages');
}
$_Page = $pages[$layout['parameters']];

View File

@ -0,0 +1,68 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
// ============================================================================
// Functions
// ============================================================================
function editPost($args)
{
global $dbPosts;
// Post status, published or draft.
if( isset($args['publish']) ) {
$args['status'] = "published";
}
else {
$args['status'] = "draft";
}
// Edit the post.
if( $dbPosts->edit($args) )
{
Alert::set('The post has been saved successfull');
Redirect::page('admin', 'manage-posts');
}
else
{
Alert::set('Error occurred when trying to edit the post');
}
}
function deletePost($key)
{
global $dbPosts;
if( $dbPosts->delete($key) )
{
Alert::set('The post has been deleted successfull');
Redirect::page('admin', 'manage-posts');
}
else
{
Alert::set('Error occurred when trying to delete the post');
}
}
// ============================================================================
// POST Method
// ============================================================================
if( $_SERVER['REQUEST_METHOD'] == 'POST' )
{
if( isset($_POST['delete']) ) {
deletePost($_POST['key']);
}
else {
editPost($_POST);
}
}
// ============================================================================
// Main
// ============================================================================
if(!$dbPosts->postExists($layout['parameters'])) {
Redirect::page('admin', 'manage-posts');
}
$_Post = buildPost($layout['parameters']);

View File

@ -0,0 +1,35 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
function editUser($args)
{
global $dbUsers;
if(isset($args['password']))
{
if( ($args['password']===$args['confirm-password']) && !helperText::isEmpty($args['password']) ) {
return $dbUsers->set($args);
}
else {
Alert::set('Passwords are differents.');
return false;
}
}
else
{
return $dbUsers->set($args);
}
}
if( $_SERVER['REQUEST_METHOD'] == 'POST' )
{
if( editUser($_POST) ) {
Alert::set('User saved successfuly.');
}
}
$_user = $dbUsers->get($layout['parameters']);
// If the user doesn't exist, redirect to the users list.
if($_user===false)
Redirect::page('admin', 'users');

View File

@ -0,0 +1,30 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
function addPage($args)
{
global $dbPages;
// Page status, published or draft.
if( isset($args['publish']) ) {
$args['status'] = "published";
}
else {
$args['status'] = "draft";
}
// Add the page.
if( $dbPages->add($args) )
{
Alert::set('Page added successfuly.');
Redirect::page('admin', 'manage-pages');
}
else
{
Alert::set('Error occurred when trying to create the page.');
}
}
if( $_SERVER['REQUEST_METHOD'] == 'POST' )
{
addPage($_POST);
}

View File

@ -0,0 +1,30 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
function addPost($args)
{
global $dbPosts;
// Page status, published or draft.
if( isset($args['publish']) ) {
$args['status'] = "published";
}
else {
$args['status'] = "draft";
}
// Add the page.
if( $dbPosts->add($args) )
{
Alert::set('Post added successfuly.');
Redirect::page('admin', 'manage-posts');
}
else
{
Alert::set('Error occurred when trying to create the post.');
}
}
if( $_SERVER['REQUEST_METHOD'] == 'POST' )
{
addPost($_POST);
}

View File

@ -0,0 +1,30 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
// ============================================================================
// Functions
// ============================================================================
function setSettings($args)
{
global $Site;
if(!isset($args['advancedOptions'])) {
$args['advancedOptions'] = 'false';
}
if( $Site->set($args) ) {
Alert::set('Settings has been saved successfully');
}
else {
Alert::set('Error occurred when trying to saved the settings');
}
}
// ============================================================================
// POST Method
// ============================================================================
if( $_SERVER['REQUEST_METHOD'] == 'POST' )
{
setSettings($_POST);
}

View File

@ -0,0 +1,6 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
if( $_SERVER['REQUEST_METHOD'] == 'POST' )
{
$Site->set($_POST);
}

View File

@ -58,6 +58,17 @@ a:hover {
border-bottom: 1px solid #eee;
}
/* ----------- ALERT ----------- */
#alert {
top: 0 !important;
right: 0 !important;
left: 0 !important;
width: 100% !important;
padding: 20px 0px !important;
max-width: 100% !important;
text-align: center;
}
/* ----------- CONTENT ----------- */
#content {
overflow: auto;
@ -68,3 +79,34 @@ h2.title {
font-weight: normal;
}
/* ----------- FORMS ----------- */
form h4 {
border-bottom: 1px solid #e2e2e2;
font-weight: 300;
margin: 33px 0 20px;
padding-bottom: 10px;
width: 60%;
}
#advancedOptions {
}
p.advOptions {
color: #777;
font-size: 0.8em;
}
/* ----------- SUB-NAVBAR ----------- */
.sublinks a {
color: #2672ec;
}
.sublinks a:hover {
color: #333 !important;
}
li.active {
border-bottom: 2px solid #ccc;
}

View File

@ -11,39 +11,63 @@
<link rel="stylesheet" href="./css/default.css">
<link rel="stylesheet" href="./css/css/font-awesome.css">
<script src="./js/jquery.min.js"></script>
<script src="./js/kube.min.js"></script>
</head>
<body>
<!-- ALERT -->
<script>
$(document).ready(function() {
<?php
if( !Alert::displayed() ) {
echo '$("#alert").message();';
}
?>
});
</script>
<div id="alert" class="tools-message tools-message-blue">
<?php echo Alert::get() ?>
</div>
<!-- HEAD -->
<div id="head">
<nav class="navbar nav-fullwidth">
<h1>Bludit</h1>
<ul>
<li><a href="#">Home</a></li>
<li><a href="#">Dashboard</a></li>
<li><a href="#">Logout</a></li>
<li><a href="<?php echo HTML_PATH_ROOT ?>">Home</a></li>
<li><a href="<?php echo HTML_PATH_ADMIN_ROOT ?>dashboard">Dashboard</a></li>
<li><a href="<?php echo HTML_PATH_ADMIN_ROOT ?>logout">Logout</a></li>
</ul>
</nav>
</div>
<div class="units-row">
<!-- SIDEBAR -->
<div class="unit-20">
<div id="sidebar" class="nav">
<ul>
<li><a href="<?php echo HTML_PATH_ADMIN_ROOT ?>new-post"><i class="fa fa-pencil-square-o"></i>New post</a></li>
<li><a href="<?php echo HTML_PATH_ADMIN_ROOT ?>new-page"><i class="fa fa-file-text-o"></i>New page</a></li>
<li><a href="<?php echo HTML_PATH_ADMIN_ROOT ?>manage"><i class="fa fa-file-text-o"></i>Manage</a></li>
<li><a href="<?php echo HTML_PATH_ADMIN_ROOT ?>settings"><i class="fa fa-file-text-o"></i>Settings</a></li>
<li><a href="<?php echo HTML_PATH_ADMIN_ROOT ?>themes"><i class="fa fa-file-text-o"></i>Themes</a></li>
<li><a href="<?php echo HTML_PATH_ADMIN_ROOT ?>plugins"><i class="fa fa-file-text-o"></i>Plugins</a></li>
<li><a href="<?php echo HTML_PATH_ADMIN_ROOT ?>new-page"><i class="fa fa-pencil"></i>New page</a></li>
<li><a href="<?php echo HTML_PATH_ADMIN_ROOT ?>manage-posts"><i class="fa fa-file-text-o"></i>Manage</a></li>
<?php if($Login->role()==='admin') { ?>
<li><a href="<?php echo HTML_PATH_ADMIN_ROOT ?>settings"><i class="fa fa-cogs"></i>Settings</a></li>
<li><a href="<?php echo HTML_PATH_ADMIN_ROOT ?>users"><i class="fa fa-users"></i>Users</a></li>
<li><a href="<?php echo HTML_PATH_ADMIN_ROOT ?>themes"><i class="fa fa-adjust"></i>Themes</a></li>
<li><a href="<?php echo HTML_PATH_ADMIN_ROOT ?>plugins"><i class="fa fa-rocket"></i>Plugins</a></li>
<?php } else { ?>
<li><a href="<?php echo HTML_PATH_ADMIN_ROOT ?>edit-user/<?php echo $Login->username() ?>"><i class="fa fa-file-text-o"></i>Profile</a></li>
<?php } ?>
</ul>
</div>
</div>
<!-- CONTENT -->
<div class="unit-80">
<div id="content">
@ -58,6 +82,12 @@
</div>
</div>
<?php
include(PATH_JS.'functions.php');
?>
<?php
echo "DEBUG: Load time: ".(microtime(true) - $loadTime).'<br>';
?>
</body>
</html>

View File

@ -0,0 +1,28 @@
<?php
function makeNavbar($type)
{
global $layout;
$navbar['users'] = array(
'users'=>array('text'=>'Users'),
'add-user'=>array('text'=>'Add new user')
);
$navbar['manage'] = array(
'manage-posts'=>array('text'=>'Manage posts'),
'manage-pages'=>array('text'=>'Manage pages')
);
echo '<nav class="navbar sublinks"><ul>';
foreach($navbar[$type] as $link=>$nav)
{
if($link==$layout['view'])
echo '<li class="active">';
else
echo '<li>';
echo '<a href="'.HTML_PATH_ADMIN_ROOT.$link.'">'.$nav['text'].'</a></li>';
}
echo '</ul></nav>';
}

4
admin/themes/default/js/jquery.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -44,6 +44,8 @@
</div>
</div>
<?php
echo "DEBUG: Load time: ".(microtime(true) - $loadTime).'<br>';
?>
</body>
</html>

38
admin/views/add-user.php Normal file
View File

@ -0,0 +1,38 @@
<h2 class="title"><i class="fa fa-user-plus"></i> Add a new user</h2>
<?php makeNavbar('users'); ?>
<form method="post" action="" class="forms">
<label>
Username
<input type="text" name="username" class="width-50">
</label>
<label>
Password
<input type="password" name="password" class="width-50">
</label>
<label>
Confirm Password
<input type="password" name="confirm-password" class="width-50">
</label>
<label for="country">
Role
<select name="role" class="width-50">
<option value="editor">Editor</option>
<option value="admin">Administrator</option>
</select>
<div class="forms-desc">Where you from?</div>
</label>
<label>
Email
<input type="text" name="email" class="width-50">
<div class="forms-desc">Email will not be publicly displayed.</div>
</label>
<input type="submit" class="btn btn-blue" value="Add" name="add-user">
<a href="<?php echo HTML_PATH_ADMIN_ROOT.'users' ?>" class="btn">Cancel</a>
</form>

View File

@ -1 +1,2 @@
<h2 class="title">Dashboard</h2>
<p>Not implemented...</p>

126
admin/views/edit-page.php Normal file
View File

@ -0,0 +1,126 @@
<h2 class="title"><i class="fa fa-pencil"></i> Edit page</h2>
<form method="post" action="" class="forms">
<input type="hidden" id="key" name="key" value="<?php echo $_Page->key() ?>">
<label>
Title
<input id="title" name="title" type="text" class="width-70" value="<?php echo $_Page->title() ?>">
</label>
<label>
Content <span class="forms-desc">HTML and Markdown code supported.</span>
<textarea name="content" rows="10" class="width-70"><?php echo $_Page->contentRaw() ?></textarea>
</label>
<?php
if($Site->advancedOptions()) {
echo '<div id="advancedOptions">';
}
else
{
echo '<p class="advOptions">You can enable more features at <a href="'.HTML_PATH_ADMIN_ROOT.'settings#advanced">Settings->Advanced->Writting Settings</a></p>';
echo '<div id="advancedOptions" style="display:none">';
}
?>
<h4>Advanced options</h4>
<?php
// Remove pages parents if the page is a parent.
if(count($_Page->children())===0)
{
?>
<label for="parent">
Page parent
<select id="parent" name="parent" class="width-50">
<?php
$htmlOptions[NO_PARENT_CHAR] = '(No parent)';
$htmlOptions += $dbPages->parentKeyList();
unset($htmlOptions[$_Page->key()]);
foreach($htmlOptions as $value=>$text) {
echo '<option value="'.$value.'"'.( ($_Page->parentKey()===$value)?' selected="selected"':'').'>'.$text.'</option>';
}
?>
</select>
<div class="forms-desc">Tip/Help ???</div>
</label>
<?php } ?>
<label>
Friendly url
<div class="input-groups width-50">
<span class="input-prepend"><?php echo $Site->url() ?><span id="parentExample"></span></span>
<input id="slug" type="text" name="slug" value="<?php echo $_Page->slug() ?>">
</div>
<span class="forms-desc">Short text no more than 150 characters. Special characters not allowed.</span>
</label>
<label>
Description
<input id="description" type="text" name="description" class="width-50" value="<?php echo $_Page->description() ?>">
<span class="forms-desc">This field is for Twitter/Facebook/Google+ descriptions. No more than 150 characters.</span>
</label>
<label>
Tags
<input id="tags" name="tags" type="text" class="width-50" value="<?php echo $_Page->tags() ?>">
<span class="forms-desc">Write the tags separeted by comma. eg: tag1, tag2, tag3</span>
</label>
<label>
Position
<input id="position" name="position" type="text" class="width-20" value="<?php echo $_Page->position() ?>">
</label>
</div>
<button class="btn btn-blue" name="publish"><i class="fa fa-sun-o fa-right"></i>Save</button>
<?php if(count($_Page->children())===0) { ?>
<button class="btn" name="draft"><i class="fa fa-circle-o fa-right"></i>Draft</button>
<button class="btn" name="delete"><i class="fa fa-remove fa-right"></i>Delete</button>
<?php } ?>
</form>
<script>
$(document).ready(function()
{
var key = $("#key").val();
$("#slug").keyup(function() {
var text = $(this).val();
var parent = $("#parent").val();
checkSlugPage(text, parent, key, $("#slug"));
});
$("#title").keyup(function() {
var text = $(this).val();
var parent = $("#parent").val();
checkSlugPage(text, parent, key, $("#slug"));
});
$("#parent").change(function() {
var parent = $(this).val();
var text = $("#slug").val();
if(parent==NO_PARENT_CHAR) {
$("#parentExample").text("");
}
else {
$("#parentExample").text(parent+"/");
}
checkSlugPage(text, parent, key, $("#slug"));
});
});
</script>

78
admin/views/edit-post.php Normal file
View File

@ -0,0 +1,78 @@
<h2 class="title"><i class="fa fa-pencil"></i> Edit post</h2>
<form method="post" action="" class="forms">
<input type="hidden" id="key" name="key" value="<?php echo $_Post->key() ?>">
<label>
Title
<input id="title" name="title" type="text" class="width-70" value="<?php echo $_Post->title() ?>">
</label>
<label>
Content <span class="forms-desc">HTML and Markdown code supported.</span>
<textarea name="content" rows="10" class="width-70"><?php echo $_Post->contentRaw() ?></textarea>
</label>
<?php
if($Site->advancedOptions()) {
echo '<div id="advancedOptions">';
}
else
{
echo '<p class="advOptions">You can enable more features at <a href="'.HTML_PATH_ADMIN_ROOT.'settings#advanced">Settings->Advanced->Writting Settings</a></p>';
echo '<div id="advancedOptions" style="display:none">';
}
?>
<h4>Advanced options</h4>
<label>
Friendly url
<div class="input-groups width-50">
<span class="input-prepend"><?php echo $Site->urlPost() ?><span id="parentExample"></span></span>
<input id="slug" type="text" name="slug" value="<?php echo $_Post->slug() ?>">
</div>
<span class="forms-desc">Short text no more than 150 characters. Special characters not allowed.</span>
</label>
<label>
Description
<input id="description" type="text" name="description" class="width-50" value="<?php echo $_Post->description() ?>">
<span class="forms-desc">This field is for Twitter/Facebook/Google+ descriptions. No more than 150 characters.</span>
</label>
<label>
Tags
<input id="tags" name="tags" type="text" class="width-50" value="<?php echo $_Post->tags() ?>">
<span class="forms-desc">Write the tags separeted by comma. eg: tag1, tag2, tag3</span>
</label>
</div>
<button class="btn btn-blue" name="publish"><i class="fa fa-sun-o fa-right"></i>Save</button>
<button class="btn" name="draft"><i class="fa fa-circle-o fa-right"></i>Draft</button>
<button class="btn" name="delete"><i class="fa fa-remove fa-right"></i>Delete</button>
</form>
<script>
$(document).ready(function()
{
var key = $("#key").val();
$("#title").keyup(function() {
var slug = $(this).val();
checkSlugPost(slug, key, $("#slug"));
});
$("#slug").keyup(function() {
var slug = $("#slug").val();
checkSlugPost(slug, key, $("#slug"));
});
});
</script>

86
admin/views/edit-user.php Normal file
View File

@ -0,0 +1,86 @@
<h2 class="title"><i class="fa fa-user"></i> Edit User</h2>
<nav class="navbar nav-pills sublinks" data-tools="tabs" data-active="#profile">
<ul>
<li><a href="#profile">Profile</a></li>
<li><a href="#email">Email</a></li>
<li><a href="#password">Password</a></li>
</ul>
</nav>
<!-- ===================================== -->
<!-- Profile -->
<!-- ===================================== -->
<div id="profile">
<form method="post" action="" class="forms">
<input type="hidden" name="username" value="<?php echo $_user['username'] ?>">
<label>
First name
<input type="text" name="firstName" class="width-50" value="<?php echo $_user['firstName'] ?>">
</label>
<label>
Last name
<input type="text" name="lastName" class="width-50" value="<?php echo $_user['lastName'] ?>">
</label>
<label for="country">
Role
<select name="role" class="width-50">
<?php
$htmlOptions = array('admin'=>'Administrator', 'editor'=>'Editor');
foreach($htmlOptions as $value=>$text) {
echo '<option value="'.$value.'"'.( ($_user['role']===$value)?' selected="selected"':'').'>'.$text.'</option>';
}
?>
</select>
</label>
<input type="submit" class="btn btn-blue" value="Save" name="user-profile">
<a href="<?php echo HTML_PATH_ADMIN_ROOT.'users' ?>" class="btn">Cancel</a>
</form>
</div>
<!-- ===================================== -->
<!-- E-mail -->
<!-- ===================================== -->
<div id="email">
<form method="post" action="" class="forms">
<input type="hidden" name="username" value="<?php echo $_user['username'] ?>">
<label>
Email
<input type="text" name="email" class="width-50" value="<?php echo $_user['email'] ?>">
<div class="forms-desc">Email will not be publicly displayed.</div>
</label>
<input type="submit" class="btn btn-blue" value="Save" name="user-email">
<a href="<?php echo HTML_PATH_ADMIN_ROOT.'users' ?>" class="btn">Cancel</a>
</form>
</div>
<!-- ===================================== -->
<!-- Password -->
<!-- ===================================== -->
<div id="password">
<form method="post" action="" class="forms">
<input type="hidden" name="username" value="<?php echo $_user['username'] ?>">
<label>
New Password
<input type="password" name="password" class="width-50">
</label>
<label>
Confirm the new Password
<input type="password" name="confirm-password" class="width-50">
</label>
<input type="submit" class="btn btn-blue" value="Save" name="user-password">
<a href="<?php echo HTML_PATH_ADMIN_ROOT.'users' ?>" class="btn">Cancel</a>
</form>
</div>

View File

@ -1,6 +1,6 @@
<h2 class="title">Login</h2>
<form method="post" action="<?php echo HTML_PATH_ROOT.'admin/login' ?>" class="forms" autocomplete="">
<form method="post" action="<?php echo HTML_PATH_ADMIN_ROOT.'login' ?>" class="forms" autocomplete="">
<label>
<input type="text" name="username" placeholder="Username" class="width-100">
</label>

View File

@ -0,0 +1,35 @@
<h2 class="title"><i class="fa fa-file-text-o"></i> Manage Pages</h2>
<?php makeNavbar('manage'); ?>
<table class="table-bordered table-stripped">
<thead>
<tr>
<th>Title</th>
<th>Parent</th>
</tr>
</thead>
<tbody>
<?php
foreach($pagesParents as $parentKey=>$pageList)
{
foreach($pageList as $Page)
{
if($parentKey!==NO_PARENT_CHAR) {
$parentTitle = $pages[$Page->parentKey()]->title();
}
else {
$parentTitle = '';
}
echo '<tr>';
echo '<td>'.($Page->parentKey()?NO_PARENT_CHAR:'').'<a href="'.HTML_PATH_ADMIN_ROOT.'edit-page/'.$Page->key().'">'.(empty($Page->published())?'[DRAFT] ':'').$Page->title().'</a></td>';
echo '<td>'.$parentTitle.'</td>';
echo '</tr>';
}
}
?>
</tbody>
</table>

View File

@ -0,0 +1,27 @@
<h2 class="title"><i class="fa fa-file-text-o"></i> Manage Posts</h2>
<?php makeNavbar('manage'); ?>
<table class="table-bordered table-stripped">
<thead>
<tr>
<th>Title</th>
<th>Published date</th>
<th>Modified date</th>
</tr>
</thead>
<tbody>
<?php
foreach($posts as $Post)
{
echo '<tr>';
echo '<td><a href="'.HTML_PATH_ADMIN_ROOT.'edit-post/'.$Post->key().'">'.(empty($Post->published())?'[DRAFT] ':'').(empty($Post->title())?'[Empty title] ':$Post->title()).'</a></td>';
echo '<td>'.$Post->date().'</td>';
echo '<td>'.$Post->timeago().'</td>';
echo '</tr>';
}
?>
</tbody>
</table>

View File

@ -1,28 +1,110 @@
<h2 class="title">New page</h2>
<h2 class="title"><i class="fa fa-pencil"></i> New page</h2>
<form method="post" action="" class="forms">
<label>
Title <span class="forms-desc">Always nice to feel important.</span>
<input type="text" name="user-name" class="width-50">
</label>
<label for="text">
Text
<textarea rows="4" class="width-80"></textarea>
Title
<input id="title" name="title" type="text" class="width-70">
</label>
<label>
Description <span class="forms-desc">Short description no more than 150 characters.</span>
<input type="text" name="user-name" class="width-50" />
Content <span class="forms-desc">HTML and Markdown code supported.</span>
<textarea name="content" rows="10" class="width-70"></textarea>
</label>
<?php
if($Site->advancedOptions()) {
echo '<div id="advancedOptions">';
}
else
{
echo '<p class="advOptions">You can enable more features at <a href="'.HTML_PATH_ADMIN_ROOT.'settings#advanced">Settings->Advanced->Writting Settings</a></p>';
echo '<div id="advancedOptions" style="display:none">';
}
?>
<h4>Advanced options</h4>
<label for="parent">
Page parent
<select id="parent" name="parent" class="width-50">
<?php
$htmlOptions[NO_PARENT_CHAR] = '(No parent)';
$htmlOptions += $dbPages->parentKeyList();
foreach($htmlOptions as $value=>$text) {
echo '<option value="'.$value.'">'.$text.'</option>';
}
?>
</select>
<div class="forms-desc">Tip/Help ???</div>
</label>
<label>
Tags <span class="forms-desc">Separeted by commas. E.g. tag1, tag2, tag3</span>
<input type="text" name="user-name" class="width-50" />
Friendly url
<div class="input-groups width-50">
<span class="input-prepend"><?php echo $Site->urlPage() ?><span id="parentExample"></span></span>
<input id="slug" name="slug" type="text">
</div>
<span class="forms-desc">Short text no more than 150 characters. Special characters not allowed.</span>
</label>
<button class="btn btn-blue"><i class="fa fa-sun-o fa-right"></i>Publish now</button>
<button class="btn"><i class="fa fa-circle-o fa-right"></i>Draft</button>
<label>
Description
<input id="description" name="description" type="text" class="width-50">
<span class="forms-desc">This field is for Twitter/Facebook/Google+ descriptions. No more than 150 characters.</span>
</label>
</form>
<label>
Tags
<input id="tags" name="tags" type="text" class="width-50">
<span class="forms-desc">Write the tags separeted by comma. eg: tag1, tag2, tag3</span>
</label>
<label>
Position
<input id="position" name="position" type="text" class="width-20" value="0">
</label>
</div>
<button class="btn btn-blue" name="publish"><i class="fa fa-sun-o fa-right"></i>Publish now</button>
<button class="btn" name="draft"><i class="fa fa-circle-o fa-right"></i>Draft</button>
</form>
<script>
$(document).ready(function()
{
$("#slug").keyup(function() {
var text = $(this).val();
var parent = $("#parent").val();
checkSlugPage(text, parent, "", $("#slug"));
});
$("#title").keyup(function() {
var text = $(this).val();
var parent = $("#parent").val();
checkSlugPage(text, parent, "", $("#slug"));
});
$("#parent").change(function() {
var parent = $(this).val();
var text = $("#slug").val();
if(parent==NO_PARENT_CHAR) {
$("#parentExample").text("");
}
else {
$("#parentExample").text(parent+"/");
}
checkSlugPage(text, parent, "", $("#slug"));
});
});
</script>

75
admin/views/new-post.php Normal file
View File

@ -0,0 +1,75 @@
<h2 class="title"><i class="fa fa-pencil"></i> New post</h2>
<form method="post" action="" class="forms">
<label>
Title
<input id="title" name="title" type="text" class="width-70">
</label>
<label>
Content <span class="forms-desc">HTML and Markdown code supported.</span>
<textarea name="content" rows="10" class="width-70"></textarea>
</label>
<?php
if($Site->advancedOptions()) {
echo '<div id="advancedOptions">';
}
else
{
echo '<p class="advOptions">You can enable more features at <a href="'.HTML_PATH_ADMIN_ROOT.'settings#advanced">Settings->Advanced->Writting Settings</a></p>';
echo '<div id="advancedOptions" style="display:none">';
}
?>
<h4>Advanced options</h4>
<label>
Friendly url
<div class="input-groups width-50">
<span class="input-prepend"><?php echo $Site->urlPost() ?><span id="parentExample"></span></span>
<input id="slug" name="slug" type="text">
</div>
<span class="forms-desc">Short text no more than 150 characters. Special characters not allowed.</span>
</label>
<label>
Description
<input id="description" name="description" type="text" class="width-50">
<span class="forms-desc">This field is for Twitter/Facebook/Google+ descriptions. No more than 150 characters.</span>
</label>
<label>
Tags
<input id="tags" name="tags" type="text" class="width-50">
<span class="forms-desc">Write the tags separeted by comma. eg: tag1, tag2, tag3</span>
</label>
</div>
<button class="btn btn-blue" name="publish"><i class="fa fa-sun-o fa-right"></i>Publish now</button>
<button class="btn" name="draft"><i class="fa fa-circle-o fa-right"></i>Draft</button>
</form>
<script>
$(document).ready(function()
{
$("#title").keyup(function() {
var slug = $(this).val();
checkSlugPost(slug, "", $("#slug"));
});
$("#slug").keyup(function() {
var slug = $("#slug").val();
checkSlugPost(slug, "", $("#slug"));
});
});
</script>

2
admin/views/plugins.php Normal file
View File

@ -0,0 +1,2 @@
<h2 class="title"><i class="fa fa-rocket"></i> Plugins</h2>
<p>Not implemented...</p>

139
admin/views/settings.php Normal file
View File

@ -0,0 +1,139 @@
<h2 class="title"><i class="fa fa-cogs"></i> Settings</h2>
<nav class="navbar nav-pills sublinks" data-tools="tabs" data-active="#general">
<ul>
<li class="active"><a href="#general">General</a></li>
<li><a href="#advanced">Advanced</a></li>
<li><a href="#regional">Regional</a></li>
<li><a href="#about">About</a></li>
</ul>
</nav>
<!-- ===================================== -->
<!-- General Settings -->
<!-- ===================================== -->
<div id="general">
<form method="post" action="" class="forms">
<label>
Site title
<input type="text" name="title" class="width-50" value="<?php echo $Site->title() ?>">
</label>
<label>
Site description
<input type="text" name="description" class="width-50" value="<?php echo $Site->description() ?>">
</label>
<label>
Footer text
<input type="text" name="footer" class="width-50" value="<?php echo $Site->footer() ?>">
</label>
<input type="submit" class="btn" value="Save" name="form-general">
</form>
</div>
<!-- ===================================== -->
<!-- Advanced Settings -->
<!-- ===================================== -->
<div id="advanced">
<form method="post" action="" class="forms">
<label for="postsperpage">
Posts per page
<select name="postsperpage" class="width-50">
<?php
$htmlOptions = array('1'=>'1','2'=>'2','3'=>'3','4'=>'4','5'=>'5','6'=>'6','7'=>'7','8'=>'8');
foreach($htmlOptions as $text=>$value) {
echo '<option value="'.$value.'"'.( ($Site->postsPerPage()===$value)?' selected="selected"':'').'>'.$text.'</option>';
}
?>
</select>
<div class="forms-desc">Number of posts you want to show on the home page.</div>
</label>
<label>
Site URL
<input type="text" name="url" class="width-50" value="<?php echo $Site->url() ?>">
</label>
<h4>Writting Settings</h4>
<ul class="forms-list">
<li>
<input type="checkbox" name="advancedOptions" id="advancedOptions" value="true" <?php echo $Site->advancedOptions()?'checked':'' ?>>
<label for="advancedOptions">Advanced options when writing.</label>
<div class="forms-desc">Add/edit friendly URL, description and tags.</div>
</li>
</ul>
<h4>URL Filters</h4>
<label>
<div class="input-groups width-50">
<span class="input-prepend">Post</span><input type="text" name="uriPost" value="<?php echo $Site->uriFilters('post') ?>">
</div>
</label>
<label>
<div class="input-groups width-50">
<span class="input-prepend">Page</span><input type="text" name="uriPage" value="<?php echo $Site->uriFilters('page') ?>">
</div>
</label>
<label>
<div class="input-groups width-50">
<span class="input-prepend">Tag</span><input type="text" name="uriTag" value="<?php echo $Site->uriFilters('tag') ?>">
</div>
</label>
<input type="submit" class="btn" value="Save" name="form-advanced">
</form>
</div>
<!-- ===================================== -->
<!-- Regional Settings -->
<!-- ===================================== -->
<div id="regional">
<form method="post" action="" class="forms" name="form-regional">
<label for="language">
Language
<select name="language" class="width-50">
<?php
$htmlOptions = array('English'=>'english', 'Español'=>'espanol');
foreach($htmlOptions as $text=>$value) {
echo '<option value="'.$value.'"'.( ($Site->language()===$value)?' selected="selected"':'').'>'.$text.'</option>';
}
?>
</select>
<div class="forms-desc">Select a language for your site.</div>
</label>
<label for="timezone">
Timezone
<select name="timezone" class="width-50">
<option value="America/Argentina/Buenos_Aires">America/Argentina/Buenos_Aires</option>
</select>
<div class="forms-desc">Select a timezone for a correct date/time display on your site.</div>
</label>
<label>
Locale
<input type="text" name="locale" class="width-50" value="<?php echo $Site->locale() ?>">
</label>
<input type="submit" class="btn" value="Save" name="form-regional">
</form>
</div>
<!-- ===================================== -->
<!-- About -->
<!-- ===================================== -->
<div id="about">
<p><i class="fa fa-pencil-square-o"></i> Bludit version 0.1</p>
</div>

2
admin/views/themes.php Normal file
View File

@ -0,0 +1,2 @@
<h2 class="title"><i class="fa fa-adjust"></i> Themes</h2>
<p>Not implemented...</p>

32
admin/views/users.php Normal file
View File

@ -0,0 +1,32 @@
<h2 class="title"><i class="fa fa-users"></i> Users</h2>
<?php makeNavbar('users'); ?>
<table class="table-bordered table-stripped">
<thead>
<tr>
<th>Username</th>
<th>First Name</th>
<th>Last Name</th>
<th>Role</th>
<th>Email</th>
<th>Registered</th>
</tr>
</thead>
<tbody>
<?php
$users = $dbUsers->getAll();
foreach($users as $username=>$field)
{
echo '<tr>';
echo '<td><a href="'.HTML_PATH_ADMIN_ROOT.'edit-user/'.$username.'">'.$username.'</a></td>';
echo '<td>'.$field['firstName'].'</td>';
echo '<td>'.$field['lastName'].'</td>';
echo '<td>'.$field['role'].'</td>';
echo '<td>'.$field['email'].'</td>';
echo '<td>'.$field['registered'].'</td>';
echo '</tr>';
}
?>
</tbody>
</table>

View File

@ -1,123 +1,12 @@
<?php defined('BLUDIT') or die('Bludit CMS.'); ?>
{
"autoincrement": 1,
"pages": {
"content\/how-to-make-a-page": {
"title": "",
"content": "",
"username": "",
"status": "published",
"author": "",
"unixstamp": 1425608797,
"date": "",
"timeago": "",
"slug": "",
"permalink": "",
"parent": "content"
},
"content\/how-to-make-a-post": {
"title": "",
"content": "",
"username": "",
"status": "published",
"author": "",
"unixstamp": 1425608797,
"date": "",
"timeago": "",
"slug": "",
"permalink": "",
"parent": "content"
},
"error": {
"title": "",
"content": "",
"username": "",
"status": "published",
"author": "",
"unixstamp": 1425608797,
"date": "",
"timeago": "",
"slug": "",
"permalink": "",
"parent": ""
},
"getting-started\/installation-guide": {
"title": "",
"content": "",
"username": "",
"status": "published",
"author": "",
"unixstamp": 1425608797,
"date": "",
"timeago": "",
"slug": "",
"permalink": "",
"parent": "getting-started"
},
"getting-started\/requirements": {
"title": "",
"content": "",
"username": "",
"status": "published",
"author": "",
"unixstamp": 1425608797,
"date": "",
"timeago": "",
"slug": "",
"permalink": "",
"parent": "getting-started"
},
"index": {
"title": "",
"content": "",
"username": "",
"status": "published",
"author": "",
"unixstamp": 1425608797,
"date": "",
"timeago": "",
"slug": "",
"permalink": "",
"parent": ""
},
"themes\/variables": {
"title": "",
"content": "",
"username": "",
"status": "published",
"author": "",
"unixstamp": 1425608797,
"date": "",
"timeago": "",
"slug": "",
"permalink": "",
"parent": "themes"
},
"troubleshooting": {
"title": "",
"content": "",
"username": "",
"status": "published",
"author": "",
"unixstamp": 1425608797,
"date": "",
"timeago": "",
"slug": "",
"permalink": "",
"parent": ""
},
"content\/variables-for-posts-and-pages": {
"title": "",
"content": "",
"username": "",
"status": "published",
"author": "",
"unixstamp": 1425770059,
"date": "",
"timeago": "",
"slug": "",
"permalink": "",
"parent": "content"
}
"error": {
"description": "Error page",
"username": "admin",
"tags": "",
"status": "published",
"unixTimeCreated": 1430686755,
"unixTimeModified": 0,
"position": 0
}
}

View File

@ -1,50 +1,2 @@
<?php defined('BLUDIT') or die('Bludit CMS.'); ?>
{
"autoincrement": 1,
"posts": {
"lorem-text": {
"allow_comments": true,
"unixstamp": 1425343829,
"description": "111111",
"hash": "asdasd23r32r23rqwda",
"status": "published",
"related_post": [
"loremTest"
],
"tags": [
"lorem",
"impusm",
"lala"
],
"username": "admin"
},
"lorem\u6307\u51fa": {
"allow_comments": true,
"unixstamp": 1422836401,
"description": "2222222",
"hash": "asdasd23r32r23rqwda",
"status": "published",
"related_post": [],
"tags": [
"lorem",
"impusm",
"lala"
],
"username": "diego"
},
"loremTest": {
"allow_comments": true,
"unixstamp": 1422836401,
"description": "2222222",
"hash": "asdasd23r32r23rqwda",
"status": "published",
"related_post": [],
"tags": [
"lorem",
"impusm",
"lala"
],
"username": "diego"
}
}
}
[]

View File

@ -1,22 +1,18 @@
<?php defined('BLUDIT') or die('Bludit CMS.'); ?>
{
"title": "Bludit CMS",
"slogan": "Another content management system",
"footer": "Copyright lala",
"language": "en",
"description": "",
"footer": "Footer text - 2015",
"language": "english",
"locale": "en_EN",
"timezone": "America\/Argentina\/Buenos_Aires",
"theme": "pure",
"adminTheme": "default",
"homepage": "index",
"metaTags": {
"title": "",
"description": ""
},
"urlFilters": {
"admin": "\/admin\/",
"post": "\/post\/",
"tag": "\/tag\/",
"page": "\/"
}
}
"homepage": "",
"postsperpage": "6",
"uriPost": "\/post\/",
"uriPage": "\/",
"uriTag": "\/tag\/",
"advancedOptions": "false",
"url": "http:\/localhost\/cms\/bludit-bitbucket\/"
}

View File

@ -1,24 +1,13 @@
<?php defined('BLUDIT') or die('Bludit CMS.'); ?>
{
"autoincrement": 1,
"users": {
"admin": {
"first_name": "Admin",
"last_name": "User",
"twitter": "",
"role": "admin",
"password": "7607d34033344d9a4615a8795d865ec4a47851e7",
"salt": "adr32t",
"email": ""
},
"diego": {
"first_name": "Diego",
"last_name": "Najar",
"twitter": "",
"role": "editor",
"password": "3r3fasfasf",
"salt": "adr32t",
"email": ""
}
"admin": {
"firstName": "",
"lastName": "",
"twitter": "",
"role": "admin",
"password": "7607d34033344d9a4615a8795d865ec4a47851e7",
"salt": "adr32t",
"email": "",
"registered": 1430686755
}
}
}

4
content/pages/error/index.txt Executable file → Normal file
View File

@ -1,4 +1,2 @@
Title: Error
Content:
The page has not been found.
Content: The page has not been found.

View File

@ -10,6 +10,12 @@ Implementar
- Dashboard, parecido a Nibbleblog, me gusta.
- iPhone app
- Cloud
- Usuarios de lectura ?, no vale la pena, y hay que hacer mas controles a nivel de administracion.
- Implementar algun limpiador**
—————————
**LIMPIADOR
- Recorrer directorios content/posts/, Si el post no tiene el archivo index.txt quiere decir que ese directorio no debe existir y debe ser eliminado
—————————
@ -31,9 +37,30 @@ helperUrl::
find . -type f -name "*.php" -print0 | xargs -0 sed -i 's/Text/helperText/g'
find . -type f -name "*.php" -print0 | xargs -0 sed -i 's/Url/helperUrl/g'
————
Editar una pagina
1- Usuario logueado
Si cambia el slug
verificar slug nuevo
mover el directorio
Si cambia el parent
verificar parent
mover directorio adentro del parent
Editar usuario
1- Usuario logueado
2- Ver si el usuario es administrador o si es el mismo usuario que se esta editando.
—————————
- Las URL son Case sensitive.
- Las Friendly URL son Case sensitive.
—————————
Editando a mano

View File

@ -3,82 +3,30 @@
// DEBUG:
$loadTime = microtime(true);
// SECURITY CONSTANT
// Security constant
define('BLUDIT', true);
// PHP PATHS
define('PATH_ROOT', __DIR__.'/');
define('PATH_LANGUAGES', PATH_ROOT.'languages/');
define('PATH_THEMES', PATH_ROOT.'themes/');
define('PATH_PLUGINS', PATH_ROOT.'plugins/');
// PHP paths
define('PATH_ROOT', __DIR__.'/');
define('PATH_BOOT', PATH_ROOT.'kernel/boot/');
define('PATH_KERNEL', PATH_ROOT.'kernel/');
define('PATH_ABSTRACT', PATH_ROOT.'kernel/abstract/');
define('PATH_BOOT', PATH_ROOT.'kernel/boot/');
define('PATH_RULES', PATH_ROOT.'kernel/boot/rules/');
define('PATH_HELPERS', PATH_ROOT.'kernel/helpers/');
define('PATH_CONTENT', PATH_ROOT.'content/');
define('PATH_POSTS', PATH_CONTENT.'posts/');
define('PATH_PAGES', PATH_CONTENT.'pages/');
define('PATH_DATABASES', PATH_CONTENT.'databases/');
define('PATH_PLUGINS_DATABASES', PATH_CONTENT.'databases/plugins/');
define('PATH_ADMIN_THEMES', PATH_ROOT.'admin/themes/');
define('PATH_ADMIN_CONTROLLERS', PATH_ROOT.'admin/controllers/');
define('PATH_ADMIN_VIEWS', PATH_ROOT.'admin/views/');
// BOOT
require(PATH_BOOT.'site.php');
// Init
require(PATH_BOOT.'init.php');
// Admin area
if($Url->whereAmI()==='admin')
{
$layout = array(
'controller'=>null,
'view'=>null,
'template'=>'index.php'
);
$layout['controller'] = $layout['view'] = $Url->slug();
if($Url->notFound() || !$Login->isLogged() || ($Url->slug()==='login') )
{
$layout['controller'] = 'login';
$layout['view'] = 'login';
$layout['template'] = 'login.php';
}
// Admin theme init.php
if( Sanitize::pathFile(PATH_ADMIN_THEMES, $Site->adminTheme().'/init.php') )
include(PATH_ADMIN_THEMES.$Site->adminTheme().'/init.php');
// Load controller
if( Sanitize::pathFile(PATH_ADMIN_CONTROLLERS, $layout['controller'].'.php') )
include(PATH_ADMIN_CONTROLLERS.$layout['controller'].'.php');
// Load view and theme
if( Sanitize::pathFile(PATH_ADMIN_THEMES, $Site->adminTheme().'/'.$layout['template']) )
include(PATH_ADMIN_THEMES.$Site->adminTheme().'/'.$layout['template']);
require(PATH_BOOT.'admin.php');
}
// Site
else
{
if($Url->notFound())
{
$Url->setWhereAmI('page');
$Page = new Page('error');
}
// Theme init.php
if( Sanitize::pathFile(PATH_THEMES, $Site->theme().'/init.php') )
include(PATH_THEMES.$Site->theme().'/init.php');
// Theme HTML
if( Sanitize::pathFile(PATH_THEMES, $Site->theme().'/index.php') )
include(PATH_THEMES.$Site->theme().'/index.php');
require(PATH_BOOT.'site.php');
}
// DEBUG:
echo "Load time: ".(microtime(true) - $loadTime);
// Print all variables/objects
//print_r(get_defined_vars());
//var_dump($_SESSION);
//var_dump($Login->fingerPrint());

View File

@ -1,169 +1,105 @@
<?php
// SECURITY CONSTANT
// Security constant
define('BLUDIT', true);
// PHP PATHS
// PATHs
define('PATH_ROOT', __DIR__.'/');
define('PATH_KERNEL', PATH_ROOT.'kernel/');
define('PATH_LANGUAGES', PATH_ROOT.'languages/');
define('PATH_ABSTRACT', PATH_ROOT.'kernel/abstract/');
define('PATH_BOOT', PATH_ROOT.'kernel/boot/');
define('PATH_RULES', PATH_ROOT.'kernel/boot/rules/');
define('PATH_CONTENT', PATH_ROOT.'content/');
define('PATH_POSTS', PATH_ROOT.'content/posts/');
define('PATH_PAGES', PATH_ROOT.'content/pages/');
define('PATH_DATABASES', PATH_ROOT.'content/databases/');
define('PATH_PLUGINS_DATABASES', PATH_ROOT.'content/databases/plugins/');
define('PATH_HELPERS', PATH_ROOT.'kernel/helpers/');
define('PATH_THEMES', PATH_ROOT.'themes/');
define('PATH_PLUGINS', PATH_ROOT.'plugins/');
// BOOT
require(PATH_BOOT.'site.php');
define('PATH_POSTS', PATH_CONTENT.'posts/');
define('PATH_PAGES', PATH_CONTENT.'pages/');
define('PATH_DATABASES', PATH_CONTENT.'databases/');
define('PATH_PLUGINS_DATABASES', PATH_CONTENT.'databases/plugins/');
unset($db);
$db = new DB_SERIALIZE(PATH_DATABASES.'posts.php');
//
// Create directories
//
// 7=read,write,execute | 5=read,execute
$dirpermissions = 0755;
if(mkdir(PATH_POSTS, $dirpermissions, true))
{
$errorText = 'Error when trying to created the directory=>'.PATH_POSTS;
error_log($errorText, 0);
}
if(mkdir(PATH_PAGES.'error', $dirpermissions, true))
{
$errorText = 'Error when trying to created the directory=>'.PATH_PAGES;
error_log($errorText, 0);
}
if(mkdir(PATH_PLUGINS_DATABASES, $dirpermissions, true))
{
$errorText = 'Error when trying to created the directory=>'.PATH_PLUGINS_DATABASES;
error_log($errorText, 0);
}
//
// Create files
//
$dataHead = "<?php defined('BLUDIT') or die('Bludit CMS.'); ?>".PHP_EOL;
// File pages.php
$data = array(
'error'=>array(
"description"=>"Error page",
"username"=>"admin",
"tags"=>"",
"status"=>"published",
"unixTimeCreated"=>1430686755,
"unixTimeModified"=>0,
"position"=>0
)
);
file_put_contents(PATH_DATABASES.'pages.php', $dataHead.json_encode($data, JSON_PRETTY_PRINT), LOCK_EX);
// File posts.php
$data = array();
$data['lorem-text'] =
array(
'allow_comments'=>true,
'unixstamp'=>Date::unixstamp(),
'description'=>'111111',
'hash'=>'asdasd23r32r23rqwda',
'status'=>'published',
'related_post'=>array('loremTest'),
'tags'=>array('lorem','impusm','lala'),
'username'=>'admin'
file_put_contents(PATH_DATABASES.'posts.php', $dataHead.json_encode($data, JSON_PRETTY_PRINT), LOCK_EX);
// File site.php
$data = array(
"title"=>"Bludit CMS",
"description"=>"",
"footer"=>"Footer text - 2015",
"language"=>"english",
"locale"=>"en_EN",
"timezone"=>"America/Argentina/Buenos_Aires",
"theme"=>"pure",
"adminTheme"=>"default",
"homepage"=>"",
"postsperpage"=>"6",
"uriPost"=>"/post/",
"uriPage"=>"/",
"uriTag"=>"/tag/",
"advancedOptions"=>"false",
"url"=>"http:/localhost/cms/bludit-bitbucket/"
);
$data['lorem指出'] =
array(
'allow_comments'=>true,
'unixstamp'=>1422836401,
'description'=>'2222222',
'hash'=>'asdasd23r32r23rqwda',
'status'=>'published',
'related_post'=>array(),
'tags'=>array('lorem','impusm','lala'),
'username'=>'diego'
file_put_contents(PATH_DATABASES.'site.php', $dataHead.json_encode($data, JSON_PRETTY_PRINT), LOCK_EX);
// File users.php
$data = array(
'admin'=>array(
"firstName"=>"",
"lastName"=>"",
"twitter"=>"",
"role"=>"admin",
"password"=>"7607d34033344d9a4615a8795d865ec4a47851e7",
"salt"=>"adr32t",
"email"=>"",
"registered"=>1430686755
)
);
$data['loremTest'] =
array(
'allow_comments'=>true,
'unixstamp'=>1422836401,
'description'=>'2222222',
'hash'=>'asdasd23r32r23rqwda',
'status'=>'published',
'related_post'=>array(),
'tags'=>array('lorem','impusm','lala'),
'username'=>'diego'
);
file_put_contents(PATH_DATABASES.'users.php', $dataHead.json_encode($data, JSON_PRETTY_PRINT), LOCK_EX);
$db->setDb(array(
'autoincrement'=>1,
'posts'=>$data
));
// File index.txt for error page
$data = "Title: Error".PHP_EOL."Content: The page has not been found.";
file_put_contents(PATH_PAGES.'error/index.txt', $data, LOCK_EX);
unset($db);
$db = new DB_SERIALIZE(PATH_DATABASES.'pages.php');
$data = array();
$data['error'] =
array(
'unixstamp'=>Date::unixstamp(),
'description'=>'Error page',
'hash'=>'asdasd23r32r23rqwda',
'status'=>'published',
'tags'=>array('lorem','impusm','lala'),
'username'=>'diego'
);
$data['about'] =
array(
'unixstamp'=>Date::unixstamp(),
'description'=>'About page',
'hash'=>'asdasd23r32r23rqwda',
'status'=>'published',
'tags'=>array('lorem','impusm','lala'),
'username'=>'diego'
);
$data['contact'] =
array(
'unixstamp'=>Date::unixstamp(),
'description'=>'Contact page',
'hash'=>'asdasd23r32r23rqwda',
'status'=>'published',
'tags'=>array('lorem','impusm','lala'),
'username'=>'diego'
);
$db->setDb(array(
'autoincrement'=>1,
'pages'=>$data
));
unset($db);
$db = new DB_SERIALIZE(PATH_DATABASES.'users.php');
$data = array();
$data['admin'] =
array(
'first_name'=>'Admin',
'last_name'=>'User',
'twitter'=>'',
'role'=>'admin',
'password'=>'3r3fasfasf',
'salt'=>'adr32t',
'email'=>''
);
$data['diego'] =
array(
'first_name'=>'Diego',
'last_name'=>'Najar',
'twitter'=>'',
'role'=>'editor',
'password'=>'3r3fasfasf',
'salt'=>'adr32t',
'email'=>''
);
$db->setDb(array(
'autoincrement'=>1,
'users'=>$data
));
unset($db);
$db = new DB_SERIALIZE(PATH_DATABASES.'site.php');
$data = array();
$data = array(
'title'=>'Bludit CMS',
'slogan'=>'Another content management system',
'footer'=>'Copyright lala',
'language'=>'en',
'locale'=>'en_EN',
'timezone'=>'America/Argentina/Buenos_Aires',
'theme'=>'pure',
'adminTheme'=>'default',
'homepage'=>'about',
'metaTags'=>array(
'title'=>'',
'description'=>''
),
'urlFilters'=>array(
'admin'=>'/admin/',
'post'=>'/post/',
'tag'=>'/tag/',
'page'=>'/'
)
);
$db->setDb($data);
?>
?>

View File

@ -0,0 +1,80 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
class dbJSON
{
public $db;
public $file;
public $firstLine;
function __construct($file, $firstLine=true)
{
$this->file = $file;
$this->db = array();
$this->firstLine = $firstLine;
if(file_exists($file))
{
$lines = file($file);
if($firstLine)
{
// Remove the first line.
unset($lines[0]);
}
$implode = implode($lines);
$this->db = $this->unserialize($implode);
}
else
{
Log::set(__METHOD__.LOG_SEP.'File '.$file.' dosent exists');
}
}
public function save()
{
if($this->firstLine)
$data = "<?php defined('BLUDIT') or die('Bludit CMS.'); ?>".PHP_EOL;
else
$data = '';
$data .= $this->serialize($this->db);
// LOCK_EX flag to prevent anyone else writing to the file at the same time.
file_put_contents($this->file, $data, LOCK_EX);
}
private function serialize($data)
{
// DEBUG: La idea es siempre serializar en json, habria que ver si siempre esta cargado json_enconde y decode
if(JSON)
return json_encode($data, JSON_PRETTY_PRINT);
return serialize($data);
}
private function unserialize($data)
{
// DEBUG: La idea es siempre serializar en json, habria que ver si siempre esta cargado json_enconde y decode
if(JSON)
return json_decode($data, true);
return unserialize($data);
}
// DEBUG, ver si sirve para la instalacion, sino borrar
public function setDb($db)
{
$this->db = $db;
return $this->save();
}
// DEBUG, se puede borrar
public function show()
{
var_dump($this->db);
}
}

View File

@ -0,0 +1,92 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
class fileContent
{
public $vars;
public $path;
function __construct($pathSlug)
{
if($this->build($pathSlug)===false)
$this->vars = false;
}
// Return true if valid
public function isValid()
{
return($this->vars!==false);
}
public function getField($field)
{
if(isset($this->vars[$field])) {
return $this->vars[$field];
}
return false;
}
// $notoverwrite true if you don't want to replace the value if are set previusly
public function setField($field, $value, $overwrite=true)
{
if($overwrite || empty($this->vars[$field])) {
$this->vars[$field] = $value;
}
return true;
}
private function build($pathSlug)
{
if( !Sanitize::pathFile($this->path.$pathSlug.'/', 'index.txt') ) {
return false;
}
// Path
//$this->setField('path', $this->path);
// Database Key
$this->setField('key', $pathSlug);
$tmp = 0;
$lines = file($this->path.$pathSlug.'/index.txt');
foreach($lines as $lineNumber=>$line)
{
$parts = array_map('trim', explode(':', $line, 2));
// Lowercase variable
$parts[0] = helperText::lowercase($parts[0]);
// If variables is content then break the foreach and process the content after.
if($parts[0]==='content')
{
$tmp = $lineNumber;
break;
}
if( !empty($parts[0]) && !empty($parts[1]) ) {
// Sanitize all fields, except Content.
$this->vars[$parts[0]] = Sanitize::html($parts[1]);
}
}
// Process the content.
if($tmp!==0)
{
// Next line after "Content:" variable
$tmp++;
// Remove lines after Content
$output = array_slice($lines, $tmp);
if(!empty($parts[1])) {
array_unshift($output, "\n");
array_unshift($output, $parts[1]);
}
$this->vars['content'] = implode($output);
}
}
}

View File

@ -1,13 +1,13 @@
<?php
<?php defined('BLUDIT') or die('Bludit CMS.');
class Plugin {
// (string) Plugin's directory
public $directoryName;
// (string) Database path and filename
public $fileDb;
// (array) Database
public $db;
@ -34,8 +34,8 @@ class Plugin {
// If the plugin installed then get the database.
if($this->installed())
{
$Tmp = new DB_SERIALIZE($this->fileDb);
$this->db = $Tmp->vars;
$Tmp = new dbJSON($this->fileDb);
$this->db = $Tmp->db;
}
}
@ -51,7 +51,7 @@ class Plugin {
if( !empty($this->dbFields) )
{
$Tmp = new DB_SERIALIZE($this->fileDb);
$Tmp = new dbJSON($this->fileDb);
$Tmp->setDb($this->dbFields);
}
@ -70,8 +70,8 @@ class Plugin {
public function init()
{
}
}
// DEBUG: Ver si se usa
public function showdb()
@ -112,15 +112,12 @@ class Plugin {
public function onSiteBody()
{
return false;
return false;
}
public function onSidebar()
{
return false;
return false;
}
}
?>
}

26
kernel/ajax/slug.php Normal file
View File

@ -0,0 +1,26 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
header('Content-Type: application/json');
// Request $_POST
// type: page or post.
// text: Slug to valid.
// parent: Page parent, if you are checking a slug for a page.
// Response JSON
// text: valid slug text
$text = isset($_POST['text']) ? $_POST['text'] : '';
$parent = isset($_POST['parent']) ? $_POST['parent'] : NO_PARENT_CHAR;
$key = isset($_POST['key']) ? $_POST['key'] : '';
if( $_POST['type']==='page' ) {
$slug = $dbPages->generateKey($text, $parent, true, $key);
}
elseif( $_POST['type']==='post' ) {
$slug = $dbPosts->generateKey($text, $key);
}
echo json_encode( array('slug'=>$slug) );
?>

54
kernel/boot/admin.php Normal file
View File

@ -0,0 +1,54 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
$layout = array(
'controller'=>null,
'view'=>null,
'template'=>'index.php',
'slug'=>null,
'parameters'=>null
);
// Get the view, controller, and the parameters from the URL.
$explodeSlug = $Url->explodeSlug();
$layout['controller'] = $layout['view'] = $layout['slug'] = $explodeSlug[0];
unset($explodeSlug[0]);
$layout['parameters'] = implode('/', $explodeSlug);
// AJAX
if( $Login->isLogged() && ($layout['slug']==='ajax') )
{
// Boot rules
// Ajax doesn't needs load rules
// Load AJAX file
if( Sanitize::pathFile(PATH_AJAX, $layout['parameters'].'.php') )
include(PATH_AJAX.$layout['parameters'].'.php');
}
// ADMIN AREA
else
{
// Boot rules
include(PATH_RULES.'70.build_posts.php');
include(PATH_RULES.'70.build_pages.php');
include(PATH_RULES.'80.plugins.php');
include(PATH_RULES.'99.header.php');
if($Url->notFound() || !$Login->isLogged() || ($Url->slug()==='login') )
{
$layout['controller'] = 'login';
$layout['view'] = 'login';
$layout['template'] = 'login.php';
}
// Admin theme init.php
if( Sanitize::pathFile(PATH_ADMIN_THEMES, $Site->adminTheme().'/init.php') )
include(PATH_ADMIN_THEMES.$Site->adminTheme().'/init.php');
// Load controller
if( Sanitize::pathFile(PATH_ADMIN_CONTROLLERS, $layout['controller'].'.php') )
include(PATH_ADMIN_CONTROLLERS.$layout['controller'].'.php');
// Load view and theme
if( Sanitize::pathFile(PATH_ADMIN_THEMES, $Site->adminTheme().'/'.$layout['template']) )
include(PATH_ADMIN_THEMES.$Site->adminTheme().'/'.$layout['template']);
}

115
kernel/boot/init.php Normal file
View File

@ -0,0 +1,115 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
// PHP PATHS
define('PATH_LANGUAGES', PATH_ROOT.'languages/');
define('PATH_THEMES', PATH_ROOT.'themes/');
define('PATH_PLUGINS', PATH_ROOT.'plugins/');
define('PATH_KERNEL', PATH_ROOT.'kernel/');
define('PATH_ABSTRACT', PATH_ROOT.'kernel/abstract/');
define('PATH_RULES', PATH_ROOT.'kernel/boot/rules/');
define('PATH_HELPERS', PATH_ROOT.'kernel/helpers/');
define('PATH_AJAX', PATH_ROOT.'kernel/ajax/');
define('PATH_JS', PATH_ROOT.'kernel/js/');
define('PATH_CONTENT', PATH_ROOT.'content/');
define('PATH_POSTS', PATH_CONTENT.'posts/');
define('PATH_PAGES', PATH_CONTENT.'pages/');
define('PATH_DATABASES', PATH_CONTENT.'databases/');
define('PATH_PLUGINS_DATABASES', PATH_CONTENT.'databases/plugins/');
define('PATH_ADMIN_THEMES', PATH_ROOT.'admin/themes/');
define('PATH_ADMIN_CONTROLLERS', PATH_ROOT.'admin/controllers/');
define('PATH_ADMIN_VIEWS', PATH_ROOT.'admin/views/');
// Log
// Log separator
define('LOG_SEP', ' | ');
//
define('NO_PARENT_CHAR', '—');
// Multibyte string / UTF-8
define('MB_STRING', extension_loaded('mbstring'));
// Check if JSON encode and decode are enabled.
define('JSON', function_exists('json_encode'));
// TRUE if new posts hand-made set published, or FALSE for draft.
define('HANDMADE_PUBLISHED', true);
if(MB_STRING)
{
// Tell PHP that we're using UTF-8 strings until the end of the script.
mb_internal_encoding('UTF-8');
// Tell PHP that we'll be outputting UTF-8 to the browser.
mb_http_output('UTF-8');
}
// Abstract Classes
include(PATH_ABSTRACT.'dbjson.class.php');
include(PATH_ABSTRACT.'filecontent.class.php');
include(PATH_ABSTRACT.'plugin.class.php');
include(PATH_KERNEL.'dbposts.class.php');
include(PATH_KERNEL.'dbpages.class.php');
include(PATH_KERNEL.'dbusers.class.php');
include(PATH_KERNEL.'dblanguage.class.php');
include(PATH_KERNEL.'dbsite.class.php');
include(PATH_KERNEL.'post.class.php');
include(PATH_KERNEL.'page.class.php');
include(PATH_KERNEL.'url.class.php');
include(PATH_KERNEL.'login.class.php');
include(PATH_KERNEL.'parsedown.class.php');
// Helpers Classes
include(PATH_HELPERS.'text.class.php');
include(PATH_HELPERS.'log.class.php');
include(PATH_HELPERS.'date.class.php');
include(PATH_HELPERS.'theme.class.php');
include(PATH_HELPERS.'session.class.php');
include(PATH_HELPERS.'redirect.class.php');
include(PATH_HELPERS.'sanitize.class.php');
include(PATH_HELPERS.'filesystem.class.php');
include(PATH_HELPERS.'alert.class.php');
// Session
Session::start();
if(Session::started()===false) {
Log::set('init.php'.LOG_SEP.'Error occurred when trying to start the session.');
exit('Bludit CMS. Failed to start session.');
}
// Objects
$dbPosts = new dbPosts();
$dbPages = new dbPages();
$dbUsers = new dbUsers();
$Site = new dbSite();
$Url = new Url();
$Parsedown = new Parsedown();
// HTML PATHs
$tmp = dirname(getenv('SCRIPT_NAME'));
if($tmp!='/') {
define('HTML_PATH_ROOT', $tmp.'/');
}
else {
define('HTML_PATH_ROOT', $tmp);
}
define('HTML_PATH_THEMES', HTML_PATH_ROOT.'themes/');
define('HTML_PATH_THEME', HTML_PATH_ROOT.'themes/'.$Site->theme().'/');
define('HTML_PATH_ADMIN_THEME', HTML_PATH_ROOT.'admin/themes/'.$Site->adminTheme().'/');
define('HTML_PATH_ADMIN_ROOT', HTML_PATH_ROOT.'admin/');
// Objects with dependency
$Language = new dbLanguage( $Site->locale() );
$Login = new Login( $dbUsers );
$Url->checkFilters( $Site->uriFilters() );
// Objects shortcuts
$L = $Language;

View File

@ -1,47 +1,68 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
$pages = array();
$pagesParents = array(NO_PARENT_CHAR=>array());
function build_page($slug)
function orderChildren($a, $b)
{
if ($a->position() == $b->position()) {
return 0;
}
return ($a->position() < $b->position()) ? -1 : 1;
}
function orderParent($array, $values, $offset) {
return ( array_slice($array, 0, $offset, true) + $values + array_slice($array, $offset, NULL, true) );
}
function build_page($key)
{
global $dbPages;
global $dbUsers;
global $Parsedown;
if( !$dbPages->validPage($slug) )
// Page object.
$Page = new Page($key);
if( !$Page->isValid() ) {
return false;
}
$Page = new Page($slug);
if( !$Page->valid() )
// Page database.
$db = $dbPages->getDb($key);
if( !$db ) {
return false;
}
// Get post's database
$db = $dbPages->getDb($slug);
foreach($db as $key=>$value)
// Foreach field from database.
foreach($db as $field=>$value)
{
if($key=='unixstamp')
if($field=='unixTimeCreated')
{
// Not overwrite
$Page->setField('unixstamp', $value, false);
$Page->setField('date', Date::format($value, '%d %B'), false);
$Page->setField('timeago', Date::timeago($value), false);
// Format dates, not overwrite from file fields.
$Page->setField('unixTimeCreated', $value, false);
$Page->setField('date', Date::format($value, '%d %B'), false);
$Page->setField('timeago', Date::timeago($value), false);
}
else
{
// Not overwrite
$Page->setField($key, $value, false);
// Other fields, not overwrite from file fields.
$Page->setField($field, $value, false);
}
}
// Parse the content
// Content in raw format
$Page->setField('contentRaw', $Page->content(), true);
// Parse markdown content.
$content = $Parsedown->text( $Page->content() );
$Page->setField('content', $content, true);
if( $dbUsers->validUsername( $Page->username() ) )
// Parse username for the page.
if( $dbUsers->userExists( $Page->username() ) )
{
$user = $dbUsers->get( $Page->username() );
$Page->setField('author', $user['first_name'].', '.$user['last_name']);
$Page->setField('author', $user['firstName'].', '.$user['lastName']);
}
return $Page;
@ -50,22 +71,63 @@ function build_page($slug)
function build_all_pages()
{
global $pages;
global $pagesParents;
global $dbPages;
$list = $dbPages->getAll();
unset($list['error']);
foreach($list as $slug=>$db)
foreach($list as $key=>$db)
{
$Page = build_page($slug);
$Page = build_page($key);
if($Page!==false)
{
if( $Page->published() )
array_push($pages, $Page);
// Generate all posible parents.
if( $Page->parentKey()===false )
{
$dbPages->addParentKey($Page->key());
$pagesParents[NO_PARENT_CHAR][$Page->key()] = $Page;
}
else
{
$pagesParents[$Page->parentKey()][$Page->key()] = $Page;
}
// $pages array
$pages[$Page->key()] = $Page;
}
}
// ======== Order pages ========
// DEBUG: No me gusta esta forma de ordenar
// Order children
$tmp = array();
foreach($pagesParents as $parentKey=>$childrenPages)
{
$tmp[$parentKey] = $childrenPages;
uasort($tmp[$parentKey], 'orderChildren');
}
if(isset($tmp[NO_PARENT_CHAR]))
{
$tmpNoParents = $tmp[NO_PARENT_CHAR];
unset($tmp[NO_PARENT_CHAR]);
}
$pagesParents = $tmp;
// Order parents.
foreach($pagesParents as $parentKey=>$childrenPages)
{
$tmp = orderParent($tmp, array($parentKey=>$childrenPages), $pages[$parentKey]->position());
}
$pagesParents = array(NO_PARENT_CHAR=>$tmpNoParents) + $tmp;
}
// Filter by page, then build it
@ -93,7 +155,7 @@ if($Url->notFound()===false)
$Url->setWhereAmI('page');
$Page = build_page( $Site->homepage() );
if($Page===false)
{
$Url->setWhereAmI('home');

View File

@ -2,67 +2,71 @@
$posts = array();
function build_post($slug)
function buildPost($key)
{
global $dbPosts;
global $dbUsers;
global $Parsedown;
if( !$dbPosts->validPost($slug) )
// Post object.
$Post = new Post($key);
if( !$Post->isValid() ) {
return false;
}
$Post = new Post($slug);
if( !$Post->valid() )
// Page database.
$db = $dbPosts->getDb($key);
if( !$db ) {
return false;
}
// Get post's database
$db = $dbPosts->getDb($slug);
foreach($db as $key=>$value)
// Foreach field from database.
foreach($db as $field=>$value)
{
if($key=='unixstamp')
if($field=='unixTimeCreated')
{
// Not overwrite
$Post->setField('unixstamp', $value, false);
$Post->setField('date', Date::format($value, '%d %B'), false);
$Post->setField('timeago', Date::timeago($value), false);
// Format dates, not overwrite from file fields.
$Post->setField('unixTimeCreated', $value, false);
$Post->setField('date', Date::format($value, '%d %B'), false);
$Post->setField('timeago', Date::timeago($value), false);
}
else
{
// Not overwrite
$Post->setField($key, $value, false);
// Other fields, not overwrite from file fields.
$Post->setField($field, $value, false);
}
}
// Content in raw format
$Post->setField('contentRaw', $Post->content(), true);
// Parse the content
$content = $Parsedown->text( $Post->content() );
$Post->setField('content', $content, true);
// User / Author
if( $dbUsers->validUsername( $Post->username() ) )
if( $dbUsers->userExists( $Post->username() ) )
{
$user = $dbUsers->get( $Post->username() );
$Post->setField('author', $user['first_name'].', '.$user['last_name'], false);
$Post->setField('author', $user['firstName'].', '.$user['lastName'], false);
}
return $Post;
}
function build_posts_per_page()
function build_posts_per_page($draftPosts=false)
{
global $dbPosts;
global $posts;
$list = $dbPosts->getPage(0, 5);
$list = $dbPosts->getPage(0, 5, $draftPosts);
foreach($list as $slug=>$db)
{
$Post = build_post($slug);
$Post = buildPost($slug);
if($Post!==false)
{
if($Post!==false) {
array_push($posts, $Post);
}
}
@ -71,7 +75,7 @@ function build_posts_per_page()
// Filter by post, then build it
if( ($Url->whereAmI()==='post') && ($Url->notFound()===false) )
{
$Post = build_post( $Url->slug() );
$Post = buildPost( $Url->slug() );
if($Post===false)
{
@ -92,5 +96,12 @@ if( ($Url->whereAmI()==='post') && ($Url->notFound()===false) )
// Build post per page
else
{
build_posts_per_page();
if($Url->whereAmI()==='admin') {
// Build post for admin area with drafts
build_posts_per_page(true);
}
else
{
build_posts_per_page();
}
}

View File

@ -1,85 +1,21 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
// Multibyte string / UTF-8
define('MB_STRING', extension_loaded('mbstring'));
// Check if JSON encode and decode are enabled.
define('JSON', function_exists('json_encode'));
// TRUE if new posts hand-made set published, or FALSE for draft.
define('HANDMADE_PUBLISHED', true);
if(MB_STRING)
{
// Tell PHP that we're using UTF-8 strings until the end of the script.
mb_internal_encoding('UTF-8');
// Tell PHP that we'll be outputting UTF-8 to the browser.
mb_http_output('UTF-8');
}
// Abstract Classes
include(PATH_ABSTRACT.'db_serialize.class.php');
include(PATH_ABSTRACT.'db_content.class.php');
include(PATH_ABSTRACT.'plugin.class.php');
include(PATH_KERNEL.'db_posts.class.php');
include(PATH_KERNEL.'db_pages.class.php');
include(PATH_KERNEL.'db_users.class.php');
include(PATH_KERNEL.'post.class.php');
include(PATH_KERNEL.'page.class.php');
include(PATH_KERNEL.'site.class.php');
include(PATH_KERNEL.'url.class.php');
include(PATH_KERNEL.'login.class.php');
include(PATH_KERNEL.'language.class.php');
include(PATH_KERNEL.'parsedown.class.php');
// Helpers Classes
include(PATH_HELPERS.'text.class.php');
//include(PATH_HELPERS.'url.class.php');
include(PATH_HELPERS.'date.class.php');
include(PATH_HELPERS.'theme.class.php');
include(PATH_HELPERS.'session.class.php');
include(PATH_HELPERS.'redirect.class.php');
include(PATH_HELPERS.'sanitize.class.php');
include(PATH_HELPERS.'filesystem.class.php');
// Session
Session::start();
if(Session::started()===false)
exit('Bludit CMS. Failed to start session.');
// Objects
$dbPosts = new dbPosts();
$dbPages = new dbPages();
$dbUsers = new dbUsers();
$Site = new Site();
$Url = new Url();
$Parsedown = new Parsedown();
// HTML PATHs
$tmp = dirname(getenv('SCRIPT_NAME'));
if($tmp!='/')
define('HTML_PATH_ROOT', $tmp.'/');
else
define('HTML_PATH_ROOT', $tmp);
define('HTML_PATH_THEMES', HTML_PATH_ROOT.'themes/');
define('HTML_PATH_THEME', HTML_PATH_ROOT.'themes/'.$Site->theme().'/');
define('HTML_PATH_ADMIN_THEME', HTML_PATH_ROOT.'admin/themes/'.$Site->adminTheme().'/');
define('HTML_PATH_ADMIN_ROOT', HTML_PATH_ROOT.'admin/');
// Objects with dependency
$Language = new Language( $Site->locale() );
$Login = new Login( $dbUsers );
$Url->checkFilters( $Site->urlFilters() );
// Objects shortcuts
$L = $Language;
// Boot rules
include(PATH_RULES.'70.build_posts.php');
include(PATH_RULES.'70.build_pages.php');
include(PATH_RULES.'80.plugins.php');
include(PATH_RULES.'99.header.php');
if($Url->notFound())
{
$Url->setWhereAmI('page');
$Page = new Page('error');
}
// Theme init.php
if( Sanitize::pathFile(PATH_THEMES, $Site->theme().'/init.php') )
include(PATH_THEMES.$Site->theme().'/init.php');
// Theme HTML
if( Sanitize::pathFile(PATH_THEMES, $Site->theme().'/index.php') )
include(PATH_THEMES.$Site->theme().'/index.php');

View File

@ -0,0 +1,34 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
class dbLanguage extends dbJSON
{
public $en_EN;
function __construct($language)
{
parent::__construct(PATH_LANGUAGES.'en_EN.json', false);
$this->en_EN = $this->db;
parent::__construct(PATH_LANGUAGES.$language.'.json', false);
}
// Return the translation, if the translation does'n exist then return the English translation.
public function get($text)
{
$key = helperText::lowercase($text);
$key = helperText::replace(' ', '-', $key);
if(isset($this->db[$key]))
return $this->db[$key];
// If the key is not translated then return the English translation.
return $this->en_EN[$key];
}
// Print the translation.
public function p($text)
{
echo $this->get($text);
}
}

354
kernel/dbpages.class.php Normal file
View File

@ -0,0 +1,354 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
class dbPages extends dbJSON
{
private $parentKeyList = array();
private $dbFields = array(
'title'=> array('inFile'=>true, 'value'=>''),
'content'=> array('inFile'=>true, 'value'=>''),
'description'=> array('inFile'=>false, 'value'=>''),
'username'=> array('inFile'=>false, 'value'=>''),
'tags'=> array('inFile'=>false, 'value'=>''),
'status'=> array('inFile'=>false, 'value'=>'draft'),
'unixTimeCreated'=> array('inFile'=>false, 'value'=>0),
'unixTimeModified'=>array('inFile'=>false, 'value'=>0),
'position'=> array('inFile'=>false, 'value'=>0)
);
function __construct()
{
parent::__construct(PATH_DATABASES.'pages.php');
}
public function add($args)
{
$dataForDb = array(); // This data will be saved in the database
$dataForFile = array(); // This data will be saved in the file
$key = $this->generateKey($args['slug'], $args['parent']);
if($key===false) {
return false;
}
// The user is always the one loggued.
$args['username'] = Session::get('username');
if( helperText::isEmpty($args['username']) ) {
return false;
}
// The current unix time stamp.
$args['unixTimeCreated'] = Date::unixTime();
// Verify arguments with the database fields.
foreach($this->dbFields as $field=>$options)
{
if( isset($args[$field]) )
{
// Sanitize if will be saved on database.
if( !$options['inFile'] ) {
$tmpValue = Sanitize::html($args[$field]);
}
else {
$tmpValue = $args[$field];
}
}
// Default value for the field.
else
{
$tmpValue = $options['value'];
}
// Check where the field will be written, in file or database.
if($options['inFile']) {
$dataForFile[$field] = $field.':'.$tmpValue;
}
else
{
// Set type
settype($tmpValue, gettype($options['value']));
// Save on database
$dataForDb[$field] = $tmpValue;
}
}
// Make the directory. Recursive.
if( helperFilesystem::mkdir(PATH_PAGES.$key, true) === false ) {
Log::set(__METHOD__.LOG_SEP.'Error occurred when trying to create the directory '.PATH_PAGES.$key);
return false;
}
// Make the index.txt and save the file.
$data = implode("\n", $dataForFile);
if( file_put_contents(PATH_PAGES.$key.'/index.txt', $data) === false ) {
Log::set(__METHOD__.LOG_SEP.'Error occurred when trying to put the content in the file index.txt');
return false;
}
// Save the database
$this->db[$key] = $dataForDb;
if( $this->save() === false ) {
Log::set(__METHOD__.LOG_SEP.'Error occurred when trying to save the database file.');
return false;
}
return true;
}
public function edit($args)
{
$dataForDb = array();
$dataForFile = array();
$newKey = $this->generateKey($args['slug'], $args['parent'], false, $args['key']);
// The user is always the one loggued.
$args['username'] = Session::get('username');
if( helperText::isEmpty($args['username']) ) {
return false;
}
// Unix time created and modified.
$args['unixTimeCreated'] = $this->db[$args['key']]['unixTimeCreated'];
$args['unixTimeModified'] = Date::unixTime();
// Verify arguments with the database fields.
foreach($this->dbFields as $field=>$options)
{
if( isset($args[$field]) )
{
// Sanitize if will be saved on database.
if( !$options['inFile'] ) {
$tmpValue = Sanitize::html($args[$field]);
}
else {
$tmpValue = $args[$field];
}
}
// Default value for the field.
else
{
$tmpValue = $options['value'];
}
// Check where the field will be written, if in the file or in the database.
if($options['inFile']) {
$dataForFile[$field] = $field.':'.$tmpValue;
}
else
{
// Set type
settype($tmpValue, gettype($options['value']));
// Save on database
$dataForDb[$field] = $tmpValue;
}
}
// Make the directory. Recursive.
if($newKey!==$args['key'])
{
if( helperFilesystem::mv(PATH_PAGES.$args['key'], PATH_PAGES.$newKey) === false ) {
Log::set(__METHOD__.LOG_SEP.'Error occurred when trying to move the directory to '.PATH_PAGES.$newKey);
return false;
}
}
// Make the index.txt and save the file.
$data = implode("\n", $dataForFile);
if( file_put_contents(PATH_PAGES.$newKey.'/index.txt', $data) === false ) {
Log::set(__METHOD__.LOG_SEP.'Error occurred when trying to put the content in the file index.txt');
return false;
}
// Remove the old key.
unset($this->db[$args['key']]);
// Save the database
$this->db[$newKey] = $dataForDb;
if( $this->save() === false ) {
Log::set(__METHOD__.LOG_SEP.'Error occurred when trying to save the database file.');
return false;
}
return true;
}
public function delete($key)
{
// Page doesn't exist in database.
if(!$this->pageExists($key)) {
Log::set(__METHOD__.LOG_SEP.'The page does not exist. Key: '.$key);
}
// Delete the index.txt file.
if( helperFilesystem::rmfile(PATH_PAGES.$key.'/index.txt') === false ) {
Log::set(__METHOD__.LOG_SEP.'Error occurred when trying to delete the file index.txt');
}
// Delete the directory.
if( helperFilesystem::rmdir(PATH_PAGES.$key) === false ) {
Log::set(__METHOD__.LOG_SEP.'Error occurred when trying to delete the directory '.PATH_PAGES.$key);
}
// Remove from database.
unset($this->db[$key]);
// Save the database.
if( $this->save() === false ) {
Log::set(__METHOD__.LOG_SEP.'Error occurred when trying to save the database file.');
}
return true;
}
// Return an array with the database for a page, FALSE otherwise.
public function getDb($key)
{
if($this->pageExists($key)) {
return $this->db[$key];
}
return false;
}
// Return TRUE if the page exists, FALSE otherwise.
public function pageExists($key)
{
return isset($this->db[$key]);
}
public function parentKeyList()
{
return $this->parentKeyList;
}
public function parentKeyExists($key)
{
return isset($this->parentKeyList[$key]);
}
public function addParentKey($key)
{
$this->parentKeyList[$key] = $key;
}
// Generate a valid Key/Slug.
public function generateKey($text, $parent=NO_PARENT_CHAR, $returnSlug=false, $oldKey='')
{
if(helperText::isEmpty($text)) {
$text = 'empty';
}
if( helperText::isEmpty($parent) || ($parent==NO_PARENT_CHAR) ) {
$newKey = helperText::cleanUrl($text);
}
else {
$newKey = helperText::cleanUrl($parent).'/'.helperText::cleanUrl($text);
}
if($newKey===$oldKey) {
return $newKey;
}
// Verify if the key is already been used.
if( isset($this->db[$newKey]) )
{
if( !helperText::endsWithNumeric($newKey) ) {
$newKey = $newKey.'-0';
}
while( isset($this->db[$newKey]) ) {
$newKey++;
}
}
if($returnSlug)
{
$explode = explode('/', $newKey);
if(isset($explode[1])) {
return $explode[1];
}
return $explode[0];
}
return $newKey;
}
// Return an array with all page's databases.
public function getAll()
{
return $this->db;
}
public function regenerate()
{
$db = $this->db;
$paths = array();
$fields = array();
// Complete $fields with the default values.
foreach($this->dbFields as $field=>$options) {
if(!$options['inFile']) {
$fields[$field] = $options['value'];
}
}
// Foreach new page set the unix time stamp.
$fields['unixTimeCreated'] = Date::unixTime();
// Foreach new page set the owner admin.
$fields['username'] = 'admin';
// Foreach new page set the status.
if(HANDMADE_PUBLISHED) {
$fields['status']='published';
}
// Get the pages from the first level of directories
$tmpPaths = glob(PATH_PAGES.'*', GLOB_ONLYDIR);
foreach($tmpPaths as $directory)
{
$key = basename($directory);
if(file_exists($directory.'/index.txt')){
// The key is the directory name
$paths[$key] = true;
}
// Recovery pages from subdirectories
$subPaths = glob($directory.'/*', GLOB_ONLYDIR);
foreach($subPaths as $subDirectory)
{
$subKey = basename($subDirectory);
if(file_exists($subDirectory.'/index.txt')) {
// The key is composed by the directory/subdirectory
$paths[$key.'/'.$subKey] = true;
}
}
}
// Remove old posts from db
foreach( array_diff_key($db, $paths) as $slug=>$data ) {
unset($this->db[$slug]);
}
// Insert new posts to db
foreach( array_diff_key($paths, $db) as $slug=>$data ) {
$this->db[$slug] = $fields;
}
// Save the database.
if( $this->save() === false ) {
Log::set(__METHOD__.LOG_SEP.'Error occurred when trying to save the database file.');
return false;
}
return true;
}
}

285
kernel/dbposts.class.php Normal file
View File

@ -0,0 +1,285 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
class dbPosts extends dbJSON
{
private $dbFields = array(
'title'=> array('inFile'=>true, 'value'=>''),
'content'=> array('inFile'=>true, 'value'=>''),
'description'=> array('inFile'=>false, 'value'=>''),
'username'=> array('inFile'=>false, 'value'=>''),
'status'=> array('inFile'=>false, 'value'=>'draft'),
'tags'=> array('inFile'=>false, 'value'=>''),
'allowComments'=> array('inFile'=>false, 'value'=>false),
'unixTimeCreated'=> array('inFile'=>false, 'value'=>0),
'unixTimeModified'=>array('inFile'=>false, 'value'=>0)
);
function __construct()
{
parent::__construct(PATH_DATABASES.'posts.php');
}
// Return an array with the database for a post.
public function getDb($slug)
{
return $this->db[$slug];
}
// Generate a valid Key/Slug.
public function generateKey($text, $oldKey='')
{
if(helperText::isEmpty($text)) {
$text = 'empty';
}
$newKey = helperText::cleanUrl($text);
if($newKey===$oldKey) {
return $newKey;
}
// Verify if the key is already been used.
if( isset($this->db[$newKey]) )
{
if( !helperText::endsWithNumeric($newKey) ) {
$newKey = $newKey.'-0';
}
while( isset($this->db[$newKey]) ) {
$newKey++;
}
}
return $newKey;
}
public function add($args)
{
$dataForDb = array(); // This data will be saved in the database
$dataForFile = array(); // This data will be saved in the file
// Generate the database key.
$key = $this->generateKey($args['slug']);
// The user is always the one loggued.
$args['username'] = Session::get('username');
if( helperText::isEmpty($args['username']) ) {
return false;
}
// The current unix time stamp.
if(empty($args['unixTimeCreated'])) {
$args['unixTimeCreated'] = Date::unixTime();
}
// Verify arguments with the database fields.
foreach($this->dbFields as $field=>$options)
{
if( isset($args[$field]) )
{
// Sanitize if will be saved on database.
if( !$options['inFile'] ) {
$tmpValue = Sanitize::html($args[$field]);
}
else {
$tmpValue = $args[$field];
}
}
// Default value for the field.
else
{
$tmpValue = $options['value'];
}
// Check where the field will be written, if in the file or in the database.
if($options['inFile']) {
$dataForFile[$field] = $field.':'.$tmpValue;
}
else
{
// Set type
settype($tmpValue, gettype($options['value']));
// Save on database
$dataForDb[$field] = $tmpValue;
}
}
// Make the directory.
if( helperFilesystem::mkdir(PATH_POSTS.$key) === false ) {
Log::set(__METHOD__.LOG_SEP.'Error occurred when trying to create the directory '.PATH_POSTS.$key);
return false;
}
// Make the index.txt and save the file.
$data = implode("\n", $dataForFile);
if( file_put_contents(PATH_POSTS.$key.'/index.txt', $data) === false ) {
Log::set(__METHOD__.LOG_SEP.'Error occurred when trying to put the content in the file index.txt');
return false;
}
// Save the database
$this->db[$key] = $dataForDb;
if( $this->save() === false ) {
Log::set(__METHOD__.LOG_SEP.'Error occurred when trying to save the database file.');
return false;
}
return true;
}
public function edit($args)
{
// Unix time created and modified.
$args['unixTimeCreated'] = $this->db[$args['key']]['unixTimeCreated'];
$args['unixTimeModified'] = Date::unixTime();
if( $this->delete($args['key']) ) {
return $this->add($args);
}
Log::set(__METHOD__.LOG_SEP.'Error occurred when trying to delete the post.');
return false;
}
public function delete($key)
{
// Post doesn't exist in database.
if(!$this->postExists($key)) {
Log::set(__METHOD__.LOG_SEP.'The post does not exist. Key: '.$key);
}
// Delete the index.txt file.
if( helperFilesystem::rmfile(PATH_POSTS.$key.'/index.txt') === false ) {
Log::set(__METHOD__.LOG_SEP.'Error occurred when trying to delete the file index.txt');
}
// Delete the directory.
if( helperFilesystem::rmdir(PATH_POSTS.$key) === false ) {
Log::set(__METHOD__.LOG_SEP.'Error occurred when trying to delete the directory '.PATH_POSTS.$key);
}
// Remove from database.
unset($this->db[$key]);
// Save the database.
if( $this->save() === false ) {
Log::set(__METHOD__.LOG_SEP.'Error occurred when trying to save the database file.');
}
return true;
}
// Return TRUE if the post exists, FALSE otherwise.
public function postExists($key)
{
return isset($this->db[$key]);
}
public function regenerate()
{
$db = $this->db;
$paths = array();
$fields = array();
// Default fields and value
foreach($this->dbFields as $field=>$options) {
if(!$options['inFile']) {
$fields[$field] = $options['value'];
}
}
// Unix time stamp
$fields['unixTimeCreated'] = Date::unixTime();
// Username
$fields['username'] = 'admin';
if(HANDMADE_PUBLISHED)
$fields['status']='published';
// Recovery pages from the first level of directories
$tmpPaths = glob(PATH_POSTS.'*', GLOB_ONLYDIR);
foreach($tmpPaths as $directory)
{
$key = basename($directory);
if(file_exists($directory.'/index.txt')) {
// The key is the directory name
$paths[$key] = true;
}
}
// Remove old posts from db
foreach( array_diff_key($db, $paths) as $slug=>$data ) {
unset($this->db[$slug]);
}
// Insert new posts to db
foreach( array_diff_key($paths, $db) as $slug=>$data ) {
$this->db[$slug] = $fields;
}
$this->save();
}
public function getPage($pageNumber, $postPerPage, $draftPosts=false)
{
$init = (int) $postPerPage * $pageNumber;
$end = (int) min( ($init + $postPerPage - 1), count($this->db) - 1 );
$outrange = $init<0 ? true : $init > $end;
// DEBUG: Ver una mejor manera de eliminar draft post antes de ordenarlos
// DEBUG: Se eliminan antes de ordenarlos porque sino los draft cuentan como publicados en el PostPerPage.
if(!$draftPosts){
$this->removeUnpublished();
}
$tmp = $this->sortByDate();
if(!$outrange) {
return array_slice($tmp, $init, $end+1, true);
}
return array();
}
// DEBUG: Ver una mejor manera de eliminar draft post antes de ordenarlos
private function removeUnpublished()
{
$tmp = array();
foreach($this->db as $key=>$value)
{
if($value['status']==='published') {
$tmp[$key]=$value;
}
}
$this->db = $tmp;
}
private function sortByDate($low_to_high=false)
{
// high to low
function high_to_low($a, $b) {
return $a['unixTimeCreated']<$b['unixTimeCreated'];
}
// low to high
function low_to_high($a, $b) {
return $a['unixTimeCreated']>$b['unixTimeCreated'];
}
$tmp = $this->db;
if($low_to_high)
uasort($tmp, 'low_to_high');
else
uasort($tmp, 'high_to_low');
return $tmp;
}
}

180
kernel/dbsite.class.php Normal file
View File

@ -0,0 +1,180 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
class dbSite extends dbJSON
{
private $dbFields = array(
'title'=> array('inFile'=>false, 'value'=>''),
'description'=> array('inFile'=>false, 'value'=>''),
'footer'=> array('inFile'=>false, 'value'=>''),
'postsperpage'=>array('inFile'=>false, 'value'=>''),
'language'=> array('inFile'=>false, 'value'=>'en'),
'locale'=> array('inFile'=>false, 'value'=>'en_EN'),
'timezone'=> array('inFile'=>false, 'value'=>'America/Argentina/Buenos_Aires'),
'theme'=> array('inFile'=>false, 'value'=>'pure'),
'adminTheme'=> array('inFile'=>false, 'value'=>'kure'),
'homepage'=> array('inFile'=>false, 'value'=>''),
'uriPage'=> array('inFile'=>false, 'value'=>'/'),
'uriPost'=> array('inFile'=>false, 'value'=>'/post/'),
'uriTag'=> array('inFile'=>false, 'value'=>'/tag/'),
'url'=> array('inFile'=>false, 'value'=>''),
'advancedOptions'=> array('inFile'=>false, 'value'=>'false')
);
function __construct()
{
parent::__construct(PATH_DATABASES.'site.php');
// Set timezone
$this->setTimezone( $this->timezone() );
// Set locale
$this->setLocale( $this->locale() );
}
// Returns an array with site configuration.
function get()
{
return $this->db;
}
public function set($args)
{
foreach($args as $field=>$value)
{
if( isset($this->dbFields[$field]) )
{
$this->db[$field] = Sanitize::html($value);
}
}
if( $this->save() === false ) {
Log::set(__METHOD__.LOG_SEP.'Error occurred when trying to save the database file.');
return false;
}
return true;
}
// Returns an array with the filters for the url.
public function uriFilters($filter='')
{
$filters['admin'] = '/admin/';
$filters['post'] = $this->db['uriPost'];
$filters['page'] = $this->db['uriPage'];
$filters['tag'] = $this->db['uriTag'];
if(empty($filter))
return $filters;
return $filters[$filter];
}
public function urlPost()
{
return $this->url().ltrim($this->db['uriPost'], '/');
}
public function urlPage()
{
return $this->url().ltrim($this->db['uriPage'], '/');
}
public function urlTag()
{
return $this->url().ltrim($this->db['uriTag'], '/');
}
// Returns the site title.
public function title()
{
return $this->db['title'];
}
public function advancedOptions()
{
if($this->db['advancedOptions']==='true') {
return true;
}
return false;
}
// Returns the site description.
public function description()
{
return $this->db['description'];
}
// Returns the site theme name.
public function theme()
{
return $this->db['theme'];
}
// Returns the admin theme name.
public function adminTheme()
{
return $this->db['adminTheme'];
}
// Returns the footer text.
public function footer()
{
return $this->db['footer'];
}
// Returns the url site.
public function url()
{
return $this->db['url'];
}
// Returns the timezone.
public function timezone()
{
return $this->db['timezone'];
}
// Returns posts per page.
public function postsPerPage()
{
return $this->db['postsperpage'];
}
// Returns the current language.
public function language()
{
return $this->db['language'];
}
// Returns the current locale.
public function locale()
{
return $this->db['locale'];
}
// Returns the current homepage.
public function homepage()
{
return $this->db['homepage'];
}
// Set the locale.
public function setLocale($locale)
{
if(setlocale(LC_ALL, $locale.'.UTF-8')!==false)
return true;
if(setlocale(LC_ALL, $locale.'.UTF8')!==false)
return true;
return setlocale(LC_ALL, $locale);
}
// Set the timezone.
public function setTimezone($timezone)
{
return date_default_timezone_set($timezone);
}
}

117
kernel/dbusers.class.php Normal file
View File

@ -0,0 +1,117 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
class dbUsers extends dbJSON
{
private $dbFields = array(
'firstName'=> array('inFile'=>false, 'value'=>''),
'lastName'=> array('inFile'=>false, 'value'=>''),
'username'=> array('inFile'=>false, 'value'=>''),
'role'=> array('inFile'=>false, 'value'=>''),
'password'=> array('inFile'=>false, 'value'=>''),
'salt'=> array('inFile'=>false, 'value'=>''),
'email'=> array('inFile'=>false, 'value'=>''),
'registered'=> array('inFile'=>false, 'value'=>0)
);
function __construct()
{
parent::__construct(PATH_DATABASES.'users.php');
}
// Return an array with the username databases
public function get($username)
{
if($this->userExists($username))
{
$user = $this->db[$username];
$user['username'] = $username;
return $user;
}
return false;
}
// Return TRUE if the user exists, FALSE otherwise.
public function userExists($username)
{
return isset($this->db[$username]);
}
public function getAll()
{
return $this->db;
}
public function set($args)
{
$username = Sanitize::html($args['username']);
foreach($args as $field=>$value)
{
if( isset($this->dbFields[$field]) )
{
// Sanitize or not.
if($this->dbFields[$field]['sanitize']=='html') {
$tmpValue = Sanitize::html($value);
}
else {
$tmpValue = $value;
}
$this->db[$username][$field] = $tmpValue;
}
}
$this->save();
return true;
}
public function add($args)
{
$dataForDb = array();
// Verify arguments with the database fields.
foreach($this->dbFields as $field=>$options)
{
// If the user send the field.
if( isset($args[$field]) )
{
// Sanitize or not.
if($options['sanitize']=='html') {
$tmpValue = Sanitize::html($args[$field]);
}
else {
$tmpValue = $args[$field];
}
}
// Uses a default value for the field.
else
{
$tmpValue = $options['value'];
}
$dataForDb[$field] = $tmpValue;
}
// Check if the user alredy exists.
if( $this->userExists($dataForDb['username']) ) {
return false;
}
// The current unix time stamp.
$dataForDb['registered'] = Date::unixTime();
// Password
$dataForDb['salt'] = helperText::randomText(8);
$dataForDb['password'] = sha1($dataForDb['password'].$dataForDb['salt']);
// Save the database
$this->db[$dataForDb['username']] = $dataForDb;
$this->save();
return true;
}
}

View File

@ -1,19 +1,25 @@
<?php
<?php defined('BLUDIT') or die('Bludit CMS.');
class Alert {
// new
public static function set($value, $key='alert')
{
Session::set('displayed', false);
Session::set($key, $value);
}
public static function get($key='alert')
{
Session::set('displayed', true);
return Session::get($key);
}
public static function displayed()
{
return Session::get('displayed');
}
}
?>

View File

@ -1,9 +1,9 @@
<?php
<?php defined('BLUDIT') or die('Bludit CMS.');
class Date {
// Return current Unix timestamp, GMT+0
public static function unixstamp()
public static function unixTime()
{
return time();
}
@ -100,5 +100,3 @@ class Date {
}
}
?>

View File

@ -1,4 +1,4 @@
<?php
<?php defined('BLUDIT') or die('Bludit CMS.');
class helperFilesystem {
@ -8,7 +8,28 @@ class helperFilesystem {
return glob($path.$regex, GLOB_ONLYDIR);
}
// OLD
public static function mkdir($pathname, $recursive=false)
{
// DEBUG: Ver permisos si son correctos
return mkdir($pathname, 0755, $recursive);
}
public static function rmdir($pathname)
{
return rmdir($pathname);
}
public static function mv($oldname, $newname)
{
return rename($oldname, $newname);
}
public static function rmfile($filename)
{
return unlink($filename);
}
// OLD
public static function get_images($regex)
{
return self::ls(PATH_UPLOAD, $regex, '*', false, false, false);
@ -55,5 +76,3 @@ class helperFilesystem {
return $files;
}
}
?>

View File

@ -0,0 +1,10 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
class Log {
public static function set($text, $type=0)
{
error_log($text, $type);
}
}

View File

@ -17,4 +17,4 @@ class Redirect {
{
self::url(HTML_PATH_ROOT.$base.'/'.$page);
}
}
}

View File

@ -1,4 +1,4 @@
<?php
<?php defined('BLUDIT') or die('Bludit CMS.');
class Session {
@ -8,8 +8,34 @@ class Session {
{
if(self::$started)
return true;
self::$started = session_start();
// DEBUG: Ver un nombre con alguna llave random al momentode instalar.
$session_name = 'Bludit-KEY';
// If TRUE cookie will only be sent over secure connections.
$secure = false;
// If set to TRUE then PHP will attempt to send the httponly flag when setting the session cookie.
$httponly = true;
// Gets current cookies params.
$cookieParams = session_get_cookie_params();
session_set_cookie_params($cookieParams["lifetime"],
$cookieParams["path"],
$cookieParams["domain"],
$secure,
$httponly
);
// Sets the session name to the one set above.
session_name($session_name);
// Start session.
self::$started = session_start();
// Regenerated the session, delete the old one. There are problems with AJAX.
//session_regenerate_id(true);
}
public static function started()
@ -43,5 +69,3 @@ class Session {
return false;
}
}
?>

View File

@ -4,6 +4,51 @@ class helperText {
// New
public static function endsWith($string, $endsString)
{
$endsPosition = (-1)*self::length($endsString);
if(MB_STRING) {
return( mb_substr($string, $endsPosition)===$endsString );
}
return( substr($string, $endsPosition)===$endsString );
}
public static function endsWithNumeric($string)
{
$endsPosition = (-1)*self::length($string);
if(MB_STRING) {
return( is_numeric(mb_substr($string, -1, 1)) );
}
return( is_numeric(substr($string, -1, 1)) );
}
public static function randomText($length)
{
$characteres = "1234567890abcdefghijklmnopqrstuvwxyz!@#%^&*";
$text = '';
for($i=0; $i<$length; $i++) {
$text .= $characteres{rand(0,41)};
}
return $text;
}
public static function cleanUrl($string, $separator = '-')
{
$accents_regex = '~&([a-z]{1,2})(?:acute|cedil|circ|grave|lig|orn|ring|slash|th|tilde|uml);~i';
$special_cases = array( '&' => 'and');
$string = mb_strtolower( trim( $string ), 'UTF-8' );
$string = str_replace( array_keys($special_cases), array_values( $special_cases), $string );
$string = preg_replace( $accents_regex, '$1', htmlentities( $string, ENT_QUOTES, 'UTF-8' ) );
$string = preg_replace("/[^a-z0-9]/u", "$separator", $string);
$string = preg_replace("/[$separator]+/u", "$separator", $string);
return $string;
}
// Replace all occurrences of the search string with the replacement string.
public static function replace($search, $replace, $string)
{
@ -18,20 +63,20 @@ class helperText {
return strtolower($string);
}
// Find position of first occurrence of substring in a string
// Find position of first occurrence of substring in a string.
public static function strpos($string, $substring)
{
if(MB_STRING)
return mb_strpos($string, $substring, 0, 'UTF-8');
return strpos($string, $substring);
}
}
// Return part of string
public static function cut($string, $start, $end)
// Returns the portion of string specified by the start and length parameters.
public static function cut($string, $start, $length)
{
if(MB_STRING)
return mb_substr($string, $start, $end, 'UTF-8');
return substr($string, $start, $end);
return mb_substr($string, $start, $length, 'UTF-8');
return substr($string, $start, $length);
}
// Return string length
@ -40,7 +85,7 @@ class helperText {
if(MB_STRING)
return mb_strlen($string, 'UTF-8');
return strlen($string);
}
}
public static function isEmpty($string)
{
@ -195,16 +240,7 @@ class helperText {
public static function random_text($length)
{
$characteres = "1234567890abcdefghijklmnopqrstuvwxyz!@#%^&*";
$text = '';
for($i=0; $i<$length; $i++)
{
$text .= $characteres{rand(0,41)};
}
return $text;
}
public static function replace_assoc(array $replace, $text)
{

74
kernel/js/functions.php Normal file
View File

@ -0,0 +1,74 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
echo '<script>'."\n";
echo 'var HTML_PATH_ROOT = "'.HTML_PATH_ROOT.'";'."\n";
echo 'var HTML_PATH_ADMIN_ROOT = "'.HTML_PATH_ADMIN_ROOT.'";'."\n";
echo 'var HTML_PATH_ADMIN_THEME = "'.HTML_PATH_ADMIN_THEME.'";'."\n";
echo 'var NO_PARENT_CHAR = "'.NO_PARENT_CHAR.'";'."\n";
echo '</script>';
?>
<script>
var ajaxRequest;
function checkSlugPage(text, parent, oldKey, writeResponse)
{
parent = typeof parent !== 'undefined' ? parent : NO_PARENT_CHAR;
oldKey = typeof oldKey !== 'undefined' ? oldKey : "";
checkSlug("page", text, parent, oldKey, writeResponse);
}
function checkSlugPost(text, oldKey, writeResponse)
{
checkSlug("post", text, null, oldKey, writeResponse);
}
function checkSlug(type, text, parentPage, key, writeResponse)
{
if(ajaxRequest) {
ajaxRequest.abort();
}
if(type=="page")
{
ajaxRequest = $.ajax({
type: "POST",
data:{ type: "page", text: text, parent: parentPage, key: key },
url: "<?php echo HTML_PATH_ADMIN_ROOT.'ajax/slug' ?>"
});
}
else
{
ajaxRequest = $.ajax({
type: "POST",
data:{ type: "post", text: text, key: key },
url: "<?php echo HTML_PATH_ADMIN_ROOT.'ajax/slug' ?>"
});
}
// Callback handler that will be called on success
ajaxRequest.done(function (response, textStatus, jqXHR){
writeResponse.val(response["slug"]);
console.log("DEBUG: AJAX Done function");
});
// Callback handler that will be called on failure
ajaxRequest.fail(function (jqXHR, textStatus, errorThrown){
console.log("DEBUG: AJAX error function");
});
// Callback handler that will be called regardless
// if the request failed or succeeded
ajaxRequest.always(function () {
console.log("DEBUG: AJAX always function");
});
}
</script>

View File

@ -9,9 +9,20 @@ class Login {
$this->dbUsers = $dbUsers;
}
public function setLogin($username)
public function username()
{
return Session::get('username');
}
public function role()
{
return Session::get('role');
}
public function setLogin($username, $role)
{
Session::set('username', $username);
Session::set('role', $role);
Session::set('fingerPrint', $this->fingerPrint());
Session::set('sessionTime', time());
}
@ -20,7 +31,8 @@ class Login {
{
if(Session::get('fingerPrint')===$this->fingerPrint())
{
if(!empty(Session::get('username'))) {
$username = Session::get('username');
if(!empty($username)) {
return true;
}
}
@ -30,7 +42,10 @@ class Login {
public function verifyUser($username, $password)
{
if(empty(trim($username)) || empty(trim($password)))
$username = trim($username);
$password = trim($password);
if(empty($username) || empty($password))
return false;
$user = $this->dbUsers->get($username);
@ -38,9 +53,10 @@ class Login {
return false;
$passwordHash = sha1($password.$user['salt']);
if($passwordHash === $user['password'])
{
$this->setLogin($username);
$this->setLogin($username, $user['role']);
return true;
}
@ -48,7 +64,7 @@ class Login {
return false;
}
private function fingerPrint($random=false)
public function fingerPrint($random=false)
{
// User agent
$agent = getenv('HTTP_USER_AGENT');
@ -66,7 +82,8 @@ class Login {
if($random)
return sha1(mt_rand().$agent.$ip);
return sha1($agent.$ip);
// DEBUG: Ver CLIENT IP, hay veces que retorna la ip ::1 y otras 127.0.0.1
return sha1($agent);
}
}

View File

@ -1,93 +1,149 @@
<?php
<?php defined('BLUDIT') or die('Bludit CMS.');
class Page extends Content
class Page extends fileContent
{
function __construct($slug)
function __construct($key)
{
$this->path = PATH_PAGES;
parent::__construct($slug);
parent::__construct($key);
}
// Returns the post title.
function title()
public function title()
{
return $this->get_field('title');
return $this->getField('title');
}
// Returns the post content.
function content()
public function content()
{
return $this->get_field('content');
return $this->getField('content');
}
public function contentRaw()
{
return $this->getField('contentRaw');
}
public function description()
{
return $this->getField('description');
}
public function tags()
{
return $this->getField('tags');
}
public function position()
{
return $this->getField('position');
}
// Returns the post date in unix timestamp format, UTC-0.
function unixstamp()
public function unixTimeCreated()
{
return $this->get_field('unixstamp');
return $this->getField('unixTimeCreated');
}
public function unixTimeModified()
{
return $this->getField('unixTimeModified');
}
// Returns the post date according to locale settings and format settings.
function date($format = false)
public function date($format = false)
{
if($format!==false)
{
$unixstamp = $this->unixstamp();
return Date::format($unixstamp, $format);
$unixTimeCreated = $this->unixTimeCreated();
return Date::format($unixTimeCreated, $format);
}
return $this->get_field('date');
return $this->getField('date');
}
// Returns the time ago
function timeago()
public function timeago()
{
return $this->get_field('timeago');
return $this->getField('timeago');
}
// Returns the page slug.
function slug()
public function slug()
{
return $this->get_field('slug');
$explode = explode('/', $this->getField('key'));
if(!empty($explode[1]))
return $explode[1];
return $explode[0];
}
public function key()
{
return $this->getField('key');
}
// Returns TRUE if the page is published, FALSE otherwise.
function published()
public function published()
{
return ($this->get_field('status')==='published');
return ($this->getField('status')==='published');
}
// Returns the page permalink.
function permalink()
public function permalink()
{
global $Url;
$path = '';
$slug = $this->slug();
$parent = $this->parent();
$filter = ltrim($Url->filters('page'), '/');
if($Url->filters('page')==HTML_PATH_ROOT)
return HTML_PATH_ROOT.$this->slug();
if($Url->filters('page')==HTML_PATH_ROOT) {
$path = HTML_PATH_ROOT;
}
else {
$path = HTML_PATH_ROOT.$filter.'/';
}
return HTML_PATH_ROOT.$filter.$this->slug();
if($parent===false) {
return $path.$slug;
}
return $path.$parent.'/'.$slug;
}
function parent()
public function parentKey()
{
if(!empty($this->get_field('parent')))
return $this->get_field('parent');
$explode = explode('/', $this->getField('key'));
if(isset($explode[1])) {
return $explode[0];
}
return false;
}
function username()
public function children()
{
return $this->get_field('username');
$tmp = array();
$paths = glob(PATH_PAGES.$this->getField('key').'/*', GLOB_ONLYDIR);
foreach($paths as $path) {
array_push($tmp, basename($path));
}
return $tmp;
}
function author()
public function username()
{
return $this->get_field('author');
return $this->getField('username');
}
public function author()
{
return $this->getField('author');
}
}
?>

View File

@ -17,7 +17,7 @@ class Parsedown
{
# ~
const version = '1.5.1';
const version = '1.5.3';
# ~
@ -1212,7 +1212,7 @@ class Parsedown
{
if (preg_match('/^\s*\[(.*?)\]/', $remainder, $matches))
{
$definition = $matches[1] ? $matches[1] : $Element['text'];
$definition = strlen($matches[1]) ? $matches[1] : $Element['text'];
$definition = strtolower($definition);
$extent += strlen($matches[0]);

View File

@ -1,6 +1,6 @@
<?php
<?php defined('BLUDIT') or die('Bludit CMS.');
class Post extends Content
class Post extends fileContent
{
function __construct($slug)
{
@ -9,64 +9,89 @@ class Post extends Content
parent::__construct($slug);
}
// Return the post title
function title()
// Returns the post title.
public function title()
{
return $this->get_field('title');
return $this->getField('title');
}
// Return the post content
function content()
// Returns the post content.
public function content()
{
return $this->get_field('content');
return $this->getField('content');
}
function username()
public function contentRaw()
{
return $this->get_field('username');
return $this->getField('contentRaw');
}
// Return TRUE if the post is published, FALSE otherwise.
function published()
public function key()
{
return ($this->get_field('status')==='published');
return $this->getField('key');
}
function author()
public function username()
{
return $this->get_field('author');
return $this->getField('username');
}
function unixstamp()
// Returns TRUE if the post is published, FALSE otherwise.
public function published()
{
return $this->get_field('unixstamp');
return ($this->getField('status')==='published');
}
function date($format = false)
public function author()
{
return $this->getField('author');
}
public function description()
{
return $this->getField('description');
}
public function unixTimeCreated()
{
return $this->getField('unixTimeCreated');
}
public function unixTimeModified()
{
return $this->getField('unixTimeModified');
}
public function date($format = false)
{
if($format!==false)
{
$unixstamp = $this->unixstamp();
return Date::format($unixstamp, $format);
$unixTimeCreated = $this->unixTimeCreated();
return Date::format($unixTimeCreated, $format);
}
return $this->get_field('date');
return $this->getField('date');
}
function timeago()
public function timeago()
{
return $this->get_field('timeago');
return $this->getField('timeago');
}
function slug()
public function tags()
{
return $this->get_field('slug');
return $this->getField('tags');
}
function permalink()
public function slug()
{
return $this->getField('key');
}
public function permalink()
{
global $Url;
$filter = ltrim($Url->filters('post'), '/');
if($Url->filters('post')==HTML_PATH_ROOT)
@ -76,5 +101,3 @@ class Post extends Content
}
}
?>

View File

@ -36,7 +36,7 @@ class Url
// Get the admin filter
$adminFilter['admin'] = $filters['admin'];
unset($filters['admin']);
// Sort by filter length
uasort($filters, array($this, 'sortByLength'));
@ -72,6 +72,11 @@ class Url
return $this->slug;
}
public function explodeSlug($delimiter="/")
{
return explode($delimiter, $this->slug);
}
public function uri()
{
return $this->uri;
@ -104,93 +109,41 @@ class Url
$this->notFound = $error;
}
/*
public function is_tag($filter)
public function getDomain()
{
$slug = $this->getSlugAfterFilter($filter);
if(!empty($_SERVER['HTTPS'])) {
$protocol = 'https://';
}
else {
$protocol = 'http://';
}
// Check if the filter doesn't match in the uri.
if($slug===false)
return false;
$domain = $_SERVER['HTTP_HOST'];
// Check if the slug is empty.
if(empty($slug))
$this->setNotFound(true);
return true;
return $protocol.$domain.HTML_PATH_ROOT;
}
public function is_post($filter)
{
$slug = $this->getSlugAfterFilter($filter);
// Check if the filter doesn't match in the uri.
if($slug===false)
return false;
// Check if the slug is empty.
if(empty($slug))
$this->setNotFound(true);
$this->whereAmI = 'post';
return true;
}
public function is_page($filter)
{
$slug = $this->getSlugAfterFilter($filter);
// Check if the filter doesn't match in the uri.
if($slug===false)
return false;
// Check if the slug is empty.
if(empty($slug))
$this->setNotFound(true);
$this->whereAmI = 'page';
return true;
}
public function isAdmin($filter)
{
$slug = $this->getSlugAfterFilter($filter);
// Check if the filter doesn't match in the uri.
if($slug===false)
return false;
// Check if the slug is empty.
if(empty($slug))
$this->setNotFound(true);
$this->whereAmI = 'admin';
return true;
}
*/
// Return the slug after the $filter
// If the filter is not contain in the uri, returns FALSE
// If the filter is contain in the uri and the slug is not empty, returns the slug
// ex: http://domain.com/cms/$filter/slug123 => slug123
private function getSlugAfterFilter($filter)
{
if($filter=='/')
if($filter=='/') {
$filter = HTML_PATH_ROOT;
}
// Check if the filter is in the uri.
$position = helperText::strpos($this->uri, $filter);
if($position===false)
if($position===false) {
return false;
}
$start = $position + helperText::length($filter);
$end = $this->uriStrlen;
$slug = helperText::cut($this->uri, $start, $end);
$this->slug = trim($slug);
$this->slug = trim($slug, '/');
return $slug;
}

View File

@ -6,7 +6,7 @@
a {
text-decoration: none;
color: rgb(61, 146, 201);
color: #2672ec;
}
a:hover,
@ -26,6 +26,11 @@ p {
padding: 0;
}
.header {
margin: 60px 30px;
text-align: left;
}
.sidebar {
background-color: #fff;
}
@ -33,11 +38,47 @@ p {
.sidebar ul {
display: block;
list-style-type: none;
margin: 5px 0 10px 0;
margin: 5px 0 30px;
padding: 0 0 0 10px;
}
.sidebar .h1 {
.sidebar h1 {
font-weight: lighter;
margin: 0;
padding: 0;
font-size: 3.2em;
}
.sidebar h2 {
font-weight: lighter;
margin: -15px 0 20px;
padding: 0;
font-size: 2.2em;
}
.sidebar div.links {
margin: 20px 0;
}
.sidebar p.about {
margin: 10px 0 40px 0;
color: #555;
}
.sidebar a.homelink {
margin: 15px 0;
display: block-inline;
}
.sidebar a.parent {
display: block;
color: #333;
margin-bottom: 0;
padding-bottom: 0;
}
.sidebar a.children {
color: #888;
}
.content {
@ -50,10 +91,7 @@ p {
height: auto;
}
.header {
margin: 0 30px;
text-align: left;
}
.brand-title,
.brand-tagline {

View File

@ -41,6 +41,9 @@
<!-- Footer -->
<div class="footer">
<?php include('php/footer.php') ?>
<?php
echo "DEBUG: Load time: ".(microtime(true) - $loadTime).'<br>';
?>
</div>
</div>
@ -48,4 +51,4 @@
</div>
</body>
</html>
</html>

View File

@ -1,36 +1,35 @@
<div class="header">
<h1>Bludit cms</h1>
<p>Getting started</p>
<ul>
<li><a href="../../getting-started/requirements">Requirements</a></li>
<li><a href="../../getting-started/installation-guide">Installation guide</a></li>
</ul>
<p>Content</p>
<ul>
<li><a href="../../content/how-to-make-a-post">How to make a post</a></li>
<li><a href="../../content/how-to-make-a-page">How to make a page</a></li>
<li><a href="../../content/variables-for-posts-and-pages">Variables for posts and pages</a></li>
</ul>
<p>Themes</p>
<ul>
<li><a href="./content/how-to-make-a-post">Making a basic theme</a></li>
<li><a href="../../themes/variables">Theme variables</a></li>
</ul>
<p>Plugins</p>
<ul>
<li><a href="./content/how-to-make-a-post">Making a basic theme</a></li>
<li><a href="./content/how-to-make-a-post">Constants and Variables</a></li>
<li><a href="./content/how-to-make-a-post">Objects for themes</a></li>
</ul>
<p>General</p>
<ul>
<li><a href="./content/how-to-make-a-post">Databases</a></li>
<li><a href="./content/how-to-make-a-post">Filesystem and structure</a></li>
<li><a href="../../troubleshooting">Troubleshooting</a></li>
<li><a href="../../troubleshooting">Troubleshooting</a></li>
<li><a href="../../troubleshooting">Troubleshooting</a></li>
</ul>
<h1>Bludit</h1>
<h2>cms</h2>
<p class="about">Simple and fast content management system, create a site in 1 minute. Created by Diego Najar @dignajar</p>
</div>
<?php
// POSTS
echo '<div class="links">';
echo '<a class="homelink" href="'.HTML_PATH_ROOT.'">Home</a>';
echo '<span> | </span>';
echo '<a class="homelink" href="'.HTML_PATH_ROOT.'">Twitter</a>';
echo '</div>';
// PAGES
unset($pagesParents[NO_PARENT_CHAR]);
foreach($pagesParents as $parentKey=>$pageList)
{
echo '<a class="parent" href="'.HTML_PATH_ROOT.$parentKey.'">'.$pages[$parentKey]->title().'</a>';
echo '<ul>';
foreach($pageList as $tmpPage)
{
echo '<li><a class="children" href="'.HTML_PATH_ROOT.$tmpPage->key().'">'.$tmpPage->title().'</a></li>';
}
echo '</ul>';
}
?>
</div>