Merge pull request #11 from dignajar/master

New pull request
This commit is contained in:
Edi 2016-01-14 01:29:06 +01:00
commit c1e7caf9e3
48 changed files with 937 additions and 676 deletions

View File

@ -38,3 +38,4 @@ if($Url->whereAmI()==='admin') {
else { else {
require(PATH_BOOT.'site.php'); require(PATH_BOOT.'site.php');
} }

View File

@ -61,7 +61,7 @@ if(!defined('JSON_PRETTY_PRINT')) {
define('JSON', function_exists('json_encode')); define('JSON', function_exists('json_encode'));
// Database format date // Database format date
define('DB_DATE_FORMAT', 'Y-m-d H:i'); define('DB_DATE_FORMAT', 'Y-m-d H:i:s');
// Charset, default UTF-8. // Charset, default UTF-8.
define('CHARSET', 'UTF-8'); define('CHARSET', 'UTF-8');

View File

@ -0,0 +1,274 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
class Content {
public $vars;
function __construct($path)
{
if($this->build($path)===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($path)
{
if( !Sanitize::pathFile($path, 'index.txt') ) {
return false;
}
$tmp = 0;
$lines = file($path.'index.txt');
foreach($lines as $lineNumber=>$line)
{
$parts = array_map('trim', explode(':', $line, 2));
// Lowercase variable
$parts[0] = Text::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]);
}
$implode = implode($output);
$this->vars['content'] = $implode;
// Sanitize content.
//$this->vars['content'] = Sanitize::html($implode);
}
}
// Returns the post title.
public function title()
{
return $this->getField('title');
}
// Returns the content.
// This content is markdown parser.
// (boolean) $fullContent, TRUE returns all content, if FALSE returns the first part of the content.
// (boolean) $raw, TRUE returns the content without sanitized, FALSE otherwise.
public function content($fullContent=true, $raw=true)
{
// This content is not sanitized.
$content = $this->getField('content');
if(!$fullContent) {
$content = $this->getField('breakContent');
}
if($raw) {
return $content;
}
return Sanitize::html($content);
}
public function readMore()
{
return $this->getField('readMore');
}
// Returns the content. This content is not markdown parser.
// (boolean) $raw, TRUE returns the content without sanitized, FALSE otherwise.
public function contentRaw($raw=true)
{
// This content is not sanitized.
$content = $this->getField('contentRaw');
if($raw) {
return $content;
}
return Sanitize::html($content);
}
public function key()
{
return $this->getField('key');
}
// Returns TRUE if the post is published, FALSE otherwise.
public function published()
{
return ($this->getField('status')==='published');
}
// Returns TRUE if the post is scheduled, FALSE otherwise.
public function scheduled()
{
return ($this->getField('status')==='scheduled');
}
// Returns TRUE if the post is draft, FALSE otherwise.
public function draft()
{
return ($this->getField('status')=='draft');
}
public function coverImage($absolute=true)
{
$fileName = $this->getField('coverImage');
if(empty($fileName)) {
return false;
}
if($absolute) {
return HTML_PATH_UPLOADS.$fileName;
}
return $fileName;
}
public function profilePicture()
{
return HTML_PATH_UPLOADS_PROFILES.$this->username().'.jpg';
}
// Returns the user object if $field is false, otherwise returns the field's value.
public function user($field=false)
{
// Get the user object.
$User = $this->getField('user');
if($field) {
return $User->getField($field);
}
return $User;
}
public function username()
{
return $this->getField('username');
}
public function description()
{
return $this->getField('description');
}
// Returns the post date according to locale settings and format settings.
public function date()
{
return $this->getField('date');
}
// Returns the post date according to locale settings and format as database stored.
public function dateRaw($format=false)
{
$date = $this->getField('dateRaw');
if($format) {
return Date::format($date, DB_DATE_FORMAT, $format);
}
return $date;
}
public function tags($returnsArray=false)
{
global $Url;
$tags = $this->getField('tags');
if($returnsArray) {
if($tags==false) {
return array();
}
return $tags;
}
else {
if($tags==false) {
return false;
}
// Return string with tags separeted by comma.
return implode(', ', $tags);
}
}
public function permalink($absolute=false)
{
global $Url;
global $Site;
$filterType = $this->getField('filterType');
$url = trim(DOMAIN_BASE,'/');
$key = $this->key();
$filter = trim($Url->filters($filterType), '/');
$htmlPath = trim(HTML_PATH_ROOT,'/');
if(empty($filter)) {
$tmp = $key;
}
else {
$tmp = $filter.'/'.$key;
}
if($absolute) {
return $url.'/'.$tmp;
}
if(empty($htmlPath)) {
return '/'.$tmp;
}
return '/'.$htmlPath.'/'.$tmp;
}
}

View File

@ -1,90 +0,0 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
class fileContent
{
public $vars;
function __construct($path)
{
if($this->build($path)===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($path)
{
if( !Sanitize::pathFile($path, 'index.txt') ) {
return false;
}
$tmp = 0;
$lines = file($path.'index.txt');
foreach($lines as $lineNumber=>$line)
{
$parts = array_map('trim', explode(':', $line, 2));
// Lowercase variable
$parts[0] = Text::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]);
}
$implode = implode($output);
$this->vars['content'] = $implode;
// Sanitize content.
//$this->vars['content'] = Sanitize::html($implode);
}
}
}

View File

@ -68,6 +68,11 @@ class Plugin {
return PATH_PLUGINS.$this->directoryName.DS; return PATH_PLUGINS.$this->directoryName.DS;
} }
public function phpPathDB()
{
return PATH_PLUGINS_DATABASES.$this->directoryName.DS;
}
// Returns the item from plugin-data. // Returns the item from plugin-data.
public function getData($key) public function getData($key)
{ {
@ -181,7 +186,13 @@ class Plugin {
public function uninstall() public function uninstall()
{ {
unlink($this->filenameDb); // Delete all files.
$files = Filesystem::listFiles( $this->phpPathDB() );
foreach($files as $file) {
unlink($file);
}
// Delete the directory.
rmdir(PATH_PLUGINS_DATABASES.$this->directoryName); rmdir(PATH_PLUGINS_DATABASES.$this->directoryName);
} }

View File

@ -1,5 +1,9 @@
<?php defined('BLUDIT') or die('Bludit CMS.'); <?php defined('BLUDIT') or die('Bludit CMS.');
// ============================================================================
// Check role
// ============================================================================
// ============================================================================ // ============================================================================
// Functions // Functions
// ============================================================================ // ============================================================================
@ -13,11 +17,17 @@ function editPage($args)
$args['parent'] = NO_PARENT_CHAR; $args['parent'] = NO_PARENT_CHAR;
} }
// Edit the page. // Add the page, if the $key is FALSE the creation of the post failure.
if( $dbPages->edit($args) ) $key = $dbPages->edit($args);
if($key)
{ {
$dbPages->regenerateCli(); $dbPages->regenerateCli();
// Call the plugins after page created.
Theme::plugins('afterPageModify');
// Alert the user
Alert::set($Language->g('The changes have been saved')); Alert::set($Language->g('The changes have been saved'));
Redirect::page('admin', 'edit-page/'.$args['slug']); Redirect::page('admin', 'edit-page/'.$args['slug']);
} }
@ -34,6 +44,9 @@ function deletePage($key)
if( $dbPages->delete($key) ) if( $dbPages->delete($key) )
{ {
// Call the plugins after post created.
Theme::plugins('afterPageDelete');
Alert::set($Language->g('The page has been deleted successfully')); Alert::set($Language->g('The page has been deleted successfully'));
Redirect::page('admin', 'manage-pages'); Redirect::page('admin', 'manage-pages');
} }

View File

@ -13,12 +13,18 @@ function editPost($args)
global $dbPosts; global $dbPosts;
global $Language; global $Language;
// Edit the post. // Add the page, if the $key is FALSE the creation of the post failure.
if( $dbPosts->edit($args) ) $key = $dbPosts->edit($args);
if($key)
{ {
// Reindex tags, this function is in 70.posts.php // Reindex tags, this function is in 70.posts.php
reIndexTagsPosts(); reIndexTagsPosts();
// Call the plugins after post created.
Theme::plugins('afterPostModify');
// Alert the user
Alert::set($Language->g('The changes have been saved')); Alert::set($Language->g('The changes have been saved'));
Redirect::page('admin', 'edit-post/'.$args['slug']); Redirect::page('admin', 'edit-post/'.$args['slug']);
} }
@ -40,6 +46,9 @@ function deletePost($key)
// Reindex tags, this function is in 70.posts.php // Reindex tags, this function is in 70.posts.php
reIndexTagsPosts(); reIndexTagsPosts();
// Call the plugins after post created.
Theme::plugins('afterPostDelete');
Alert::set($Language->g('The post has been deleted successfully')); Alert::set($Language->g('The post has been deleted successfully'));
Redirect::page('admin', 'manage-posts'); Redirect::page('admin', 'manage-posts');
} }

View File

@ -13,9 +13,15 @@ function addPage($args)
global $dbPages; global $dbPages;
global $Language; global $Language;
// Add the page. // Add the page, if the $key is FALSE the creation of the post failure.
if( $dbPages->add($args) ) $key = $dbPages->add($args);
if($key)
{ {
// Call the plugins after page created.
Theme::plugins('afterPageCreate');
// Alert the user
Alert::set($Language->g('Page added successfully')); Alert::set($Language->g('Page added successfully'));
Redirect::page('admin', 'manage-pages'); Redirect::page('admin', 'manage-pages');
} }

View File

@ -13,12 +13,18 @@ function addPost($args)
global $dbPosts; global $dbPosts;
global $Language; global $Language;
// Add the page. // Add the page, if the $key is FALSE the creation of the post failure.
if( $dbPosts->add($args) ) $key = $dbPosts->add($args);
if($key)
{ {
// Reindex tags, this function is in 70.posts.php // Reindex tags, this function is in 70.posts.php
reIndexTagsPosts(); reIndexTagsPosts();
// Call the plugins after post created.
Theme::plugins('afterPostCreate');
// Alert for the user
Alert::set($Language->g('Post added successfully')); Alert::set($Language->g('Post added successfully'));
Redirect::page('admin', 'manage-posts'); Redirect::page('admin', 'manage-posts');
} }

View File

@ -0,0 +1,9 @@
.autocomplete-suggestions {
text-align: left; cursor: default; border: 1px solid #ccc; border-top: 0; background: #fff; box-shadow: -1px 1px 3px rgba(0,0,0,.1);
/* core styles should not be changed */
position: absolute; display: none; z-index: 9999; max-height: 254px; overflow: hidden; overflow-y: auto; box-sizing: border-box;
}
.autocomplete-suggestion { position: relative; padding: 0 .6em; line-height: 23px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-size: 1.02em; color: #333; }
.autocomplete-suggestion b { font-weight: normal; color: #1f8dd6; }
.autocomplete-suggestion.selected { background: #f0f0f0; }

View File

@ -20,12 +20,14 @@
<link rel="stylesheet" type="text/css" href="./css/default.css?version=<?php echo BLUDIT_VERSION ?>"> <link rel="stylesheet" type="text/css" href="./css/default.css?version=<?php echo BLUDIT_VERSION ?>">
<link rel="stylesheet" type="text/css" href="./css/jquery.datetimepicker.css?version=<?php echo BLUDIT_VERSION ?>"> <link rel="stylesheet" type="text/css" href="./css/jquery.datetimepicker.css?version=<?php echo BLUDIT_VERSION ?>">
<link rel="stylesheet" type="text/css" href="./css/jquery.auto-complete.css?version=<?php echo BLUDIT_VERSION ?>">
<!-- Javascript --> <!-- Javascript -->
<script charset="utf-8" src="./js/jquery.min.js?version=<?php echo BLUDIT_VERSION ?>"></script> <script charset="utf-8" src="./js/jquery.min.js?version=<?php echo BLUDIT_VERSION ?>"></script>
<script charset="utf-8" src="./js/uikit/uikit.min.js?version=<?php echo BLUDIT_VERSION ?>"></script> <script charset="utf-8" src="./js/uikit/uikit.min.js?version=<?php echo BLUDIT_VERSION ?>"></script>
<script charset="utf-8" src="./js/uikit/upload.min.js?version=<?php echo BLUDIT_VERSION ?>"></script> <script charset="utf-8" src="./js/uikit/upload.min.js?version=<?php echo BLUDIT_VERSION ?>"></script>
<script charset="utf-8" src="./js/jquery.datetimepicker.js?version=<?php echo BLUDIT_VERSION ?>"></script> <script charset="utf-8" src="./js/jquery.datetimepicker.js?version=<?php echo BLUDIT_VERSION ?>"></script>
<script charset="utf-8" src="./js/jquery.auto-complete.min.js?version=<?php echo BLUDIT_VERSION ?>"></script>
<!-- Plugins --> <!-- Plugins -->
<?php Theme::plugins('adminHead') ?> <?php Theme::plugins('adminHead') ?>

View File

@ -52,6 +52,28 @@ class HTML {
echo $html; echo $html;
} }
public static function formInputAutocomplete($args)
{
self::formInputText($args);
$script = '<script>
$("input[name=\"'.$args['name'].'\"]").autoComplete({
minChars: 1,
source: function(term, suggest){
term = term.toLowerCase();
var choices = ['.$args['words'].'];
var matches = [];
for (i=0; i<choices.length; i++)
if (~choices[i].toLowerCase().indexOf(term)) matches.push(choices[i]);
suggest(matches);
}
});
</script>';
echo $script;
}
public static function formInputPassword($args) public static function formInputPassword($args)
{ {
$args['type'] = 'password'; $args['type'] = 'password';
@ -130,6 +152,7 @@ class HTML {
public static function bluditQuickImages() public static function bluditQuickImages()
{ {
global $L;
$html = '<!-- BLUDIT QUICK IMAGES -->'; $html = '<!-- BLUDIT QUICK IMAGES -->';
$html .= ' $html .= '
@ -153,7 +176,7 @@ if(empty($thumbnailList)) {
} }
$html .= ' $html .= '
<a data-uk-modal href="#bludit-images-v8" class="moreImages uk-button">More images</a> <a data-uk-modal href="#bludit-images-v8" class="moreImages uk-button">'.$L->g('More images').'</a>
</div> </div>
'; ';
@ -327,7 +350,7 @@ if(empty($thumbnailList)) {
$html .= ' $html .= '
<div class="uk-modal-footer"> <div class="uk-modal-footer">
Double click on the image to add it or <a href="" class="uk-modal-close">click here to cancel</a> '.$L->g('Double click on the image to add it').' <a href="" class="uk-modal-close">'.$L->g('Click here to cancel').'</a>
</div> </div>
</div> </div>

View File

@ -0,0 +1,3 @@
// jQuery autoComplete v1.0.7
// https://github.com/Pixabay/jQuery-autoComplete
!function(e){e.fn.autoComplete=function(t){var o=e.extend({},e.fn.autoComplete.defaults,t);return"string"==typeof t?(this.each(function(){var o=e(this);"destroy"==t&&(e(window).off("resize.autocomplete",o.updateSC),o.off("blur.autocomplete focus.autocomplete keydown.autocomplete keyup.autocomplete"),o.data("autocomplete")?o.attr("autocomplete",o.data("autocomplete")):o.removeAttr("autocomplete"),e(o.data("sc")).remove(),o.removeData("sc").removeData("autocomplete"))}),this):this.each(function(){function t(e){var t=s.val();if(s.cache[t]=e,e.length&&t.length>=o.minChars){for(var a="",c=0;c<e.length;c++)a+=o.renderItem(e[c],t);s.sc.html(a),s.updateSC(0)}else s.sc.hide()}var s=e(this);s.sc=e('<div class="autocomplete-suggestions '+o.menuClass+'"></div>'),s.data("sc",s.sc).data("autocomplete",s.attr("autocomplete")),s.attr("autocomplete","off"),s.cache={},s.last_val="",s.updateSC=function(t,o){if(s.sc.css({top:s.offset().top+s.outerHeight(),left:s.offset().left,width:s.outerWidth()}),!t&&(s.sc.show(),s.sc.maxHeight||(s.sc.maxHeight=parseInt(s.sc.css("max-height"))),s.sc.suggestionHeight||(s.sc.suggestionHeight=e(".autocomplete-suggestion",s.sc).first().outerHeight()),s.sc.suggestionHeight))if(o){var a=s.sc.scrollTop(),c=o.offset().top-s.sc.offset().top;c+s.sc.suggestionHeight-s.sc.maxHeight>0?s.sc.scrollTop(c+s.sc.suggestionHeight+a-s.sc.maxHeight):0>c&&s.sc.scrollTop(c+a)}else s.sc.scrollTop(0)},e(window).on("resize.autocomplete",s.updateSC),s.sc.appendTo("body"),s.sc.on("mouseleave",".autocomplete-suggestion",function(){e(".autocomplete-suggestion.selected").removeClass("selected")}),s.sc.on("mouseenter",".autocomplete-suggestion",function(){e(".autocomplete-suggestion.selected").removeClass("selected"),e(this).addClass("selected")}),s.sc.on("mousedown",".autocomplete-suggestion",function(t){var a=e(this),c=a.data("val");return(c||a.hasClass("autocomplete-suggestion"))&&(s.val(c),o.onSelect(t,c,a),s.sc.hide()),!1}),s.on("blur.autocomplete",function(){try{over_sb=e(".autocomplete-suggestions:hover").length}catch(t){over_sb=0}over_sb?s.is(":focus")||setTimeout(function(){s.focus()},20):(s.last_val=s.val(),s.sc.hide(),setTimeout(function(){s.sc.hide()},350))}),o.minChars||s.on("focus.autocomplete",function(){s.last_val="\n",s.trigger("keyup.autocomplete")}),s.on("keydown.autocomplete",function(t){if((40==t.which||38==t.which)&&s.sc.html()){var a,c=e(".autocomplete-suggestion.selected",s.sc);return c.length?(a=40==t.which?c.next(".autocomplete-suggestion"):c.prev(".autocomplete-suggestion"),a.length?(c.removeClass("selected"),s.val(a.addClass("selected").data("val"))):(c.removeClass("selected"),s.val(s.last_val),a=0)):(a=40==t.which?e(".autocomplete-suggestion",s.sc).first():e(".autocomplete-suggestion",s.sc).last(),s.val(a.addClass("selected").data("val"))),s.updateSC(0,a),!1}if(27==t.which)s.val(s.last_val).sc.hide();else if(13==t.which||9==t.which){var c=e(".autocomplete-suggestion.selected",s.sc);c.length&&s.sc.is(":visible")&&(o.onSelect(t,c.data("val"),c),setTimeout(function(){s.sc.hide()},20))}}),s.on("keyup.autocomplete",function(a){if(!~e.inArray(a.which,[13,27,35,36,37,38,39,40])){var c=s.val();if(c.length>=o.minChars){if(c!=s.last_val){if(s.last_val=c,clearTimeout(s.timer),o.cache){if(c in s.cache)return void t(s.cache[c]);for(var l=1;l<c.length-o.minChars;l++){var i=c.slice(0,c.length-l);if(i in s.cache&&!s.cache[i].length)return void t([])}}s.timer=setTimeout(function(){o.source(c,t)},o.delay)}}else s.last_val=c,s.sc.hide()}})})},e.fn.autoComplete.defaults={source:0,minChars:3,delay:150,cache:1,menuClass:"",renderItem:function(e,t){t=t.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&");var o=new RegExp("("+t.split(" ").join("|")+")","gi");return'<div class="autocomplete-suggestion" data-val="'+e+'">'+e.replace(o,"<b>$1</b>")+"</div>"},onSelect:function(e,t,o){}}}(jQuery);

View File

@ -77,12 +77,13 @@ echo '<div class="sidebar uk-width-large-2-10">';
)); ));
// Tags input // Tags input
HTML::formInputText(array( HTML::formInputAutocomplete(array(
'name'=>'tags', 'name'=>'tags',
'value'=>$_Page->tags(), 'value'=>$_Page->tags(),
'class'=>'uk-width-1-1 uk-form-large', 'class'=>'uk-width-1-1 uk-form-large',
'tip'=>$L->g('Write the tags separated by commas'), 'tip'=>$L->g('Write the tags separated by commas'),
'label'=>$L->g('Tags') 'label'=>$L->g('Tags'),
'words'=>'"'.implode('", "', $dbTags->getAll()).'"'
)); ));
echo '</li>'; echo '</li>';

View File

@ -71,12 +71,13 @@ echo '<div class="sidebar uk-width-large-2-10">';
)); ));
// Tags input // Tags input
HTML::formInputText(array( HTML::formInputAutocomplete(array(
'name'=>'tags', 'name'=>'tags',
'value'=>$_Post->tags(), 'value'=>$_Post->tags(),
'class'=>'uk-width-1-1 uk-form-large', 'class'=>'uk-width-1-1 uk-form-large',
'tip'=>$L->g('Write the tags separated by commas'), 'tip'=>$L->g('Write the tags separated by commas'),
'label'=>$L->g('Tags') 'label'=>$L->g('Tags'),
'words'=>'"'.implode('", "', $dbTags->getAll()).'"'
)); ));
echo '</li>'; echo '</li>';

View File

@ -64,12 +64,13 @@ echo '<div class="sidebar uk-width-large-2-10">';
)); ));
// Tags input // Tags input
HTML::formInputText(array( HTML::formInputAutocomplete(array(
'name'=>'tags', 'name'=>'tags',
'value'=>'', 'value'=>'',
'class'=>'uk-width-1-1 uk-form-large', 'class'=>'uk-width-1-1 uk-form-large',
'tip'=>$L->g('Write the tags separated by commas'), 'tip'=>$L->g('Write the tags separated by commas'),
'label'=>$L->g('Tags') 'label'=>$L->g('Tags'),
'words'=>'"'.implode('", "', $dbTags->getAll()).'"'
)); ));
echo '</li>'; echo '</li>';

View File

@ -64,12 +64,13 @@ echo '<div class="sidebar uk-width-large-2-10">';
)); ));
// Tags input // Tags input
HTML::formInputText(array( HTML::formInputAutocomplete(array(
'name'=>'tags', 'name'=>'tags',
'value'=>'', 'value'=>'',
'class'=>'uk-width-1-1 uk-form-large', 'class'=>'uk-width-1-1 uk-form-large',
'tip'=>$L->g('Write the tags separated by commas'), 'tip'=>$L->g('Write the tags separated by commas'),
'label'=>$L->g('Tags') 'label'=>$L->g('Tags'),
'words'=>'"'.implode('", "', $dbTags->getAll()).'"'
)); ));
echo '</li>'; echo '</li>';

View File

@ -84,6 +84,14 @@ HTML::formOpen(array('class'=>'uk-form-horizontal'));
'tip'=>'' 'tip'=>''
)); ));
HTML::formInputText(array(
'name'=>'uriBlog',
'label'=>$L->g('Blog'),
'value'=>$Site->uriFilters('blog'),
'class'=>'uk-width-1-2 uk-form-medium',
'tip'=>''
));
echo '<div class="uk-form-row"> echo '<div class="uk-form-row">
<div class="uk-form-controls"> <div class="uk-form-controls">
<button type="submit" class="uk-button uk-button-primary">'.$L->g('Save').'</button> <button type="submit" class="uk-button uk-button-primary">'.$L->g('Save').'</button>

View File

@ -40,9 +40,9 @@ if( $layout['slug']==='ajax' )
else else
{ {
// Boot rules // Boot rules
include(PATH_RULES.'60.plugins.php');
include(PATH_RULES.'70.posts.php'); include(PATH_RULES.'70.posts.php');
include(PATH_RULES.'70.pages.php'); include(PATH_RULES.'71.pages.php');
include(PATH_RULES.'80.plugins.php');
include(PATH_RULES.'99.header.php'); include(PATH_RULES.'99.header.php');
include(PATH_RULES.'99.paginator.php'); include(PATH_RULES.'99.paginator.php');
include(PATH_RULES.'99.themes.php'); include(PATH_RULES.'99.themes.php');

View File

@ -61,7 +61,6 @@ define('ALERT_STATUS_FAIL', 1);
// Salt length // Salt length
define('THUMBNAILS_WIDTH', 400); define('THUMBNAILS_WIDTH', 400);
define('THUMBNAILS_HEIGHT', 400); define('THUMBNAILS_HEIGHT', 400);
define('THUMBNAILS_AMOUNT', 6); define('THUMBNAILS_AMOUNT', 6);
// Salt length // Salt length
@ -82,9 +81,12 @@ define('JSON', function_exists('json_encode'));
// TRUE if new posts hand-made set published, or FALSE for draft. // TRUE if new posts hand-made set published, or FALSE for draft.
define('CLI_STATUS', 'published'); define('CLI_STATUS', 'published');
// Database format date // Database date format
define('DB_DATE_FORMAT', 'Y-m-d H:i:s'); define('DB_DATE_FORMAT', 'Y-m-d H:i:s');
// Sitemap date format
define('SITEMAP_DATE_FORMAT', 'Y-m-d');
// Date format for Dashboard schedule posts // Date format for Dashboard schedule posts
define('SCHEDULED_DATE_FORMAT', 'd M - h:i a'); define('SCHEDULED_DATE_FORMAT', 'd M - h:i a');
@ -111,7 +113,7 @@ if(MB_STRING)
// Inclde Abstract Classes // Inclde Abstract Classes
include(PATH_ABSTRACT.'dbjson.class.php'); include(PATH_ABSTRACT.'dbjson.class.php');
include(PATH_ABSTRACT.'filecontent.class.php'); include(PATH_ABSTRACT.'content.class.php');
include(PATH_ABSTRACT.'plugin.class.php'); include(PATH_ABSTRACT.'plugin.class.php');
// Inclde Classes // Inclde Classes
@ -216,6 +218,16 @@ define('PATH_THEME_JS', PATH_THEME.'js'.DS);
define('PATH_THEME_IMG', PATH_THEME.'img'.DS); define('PATH_THEME_IMG', PATH_THEME.'img'.DS);
define('PATH_THEME_LANG', PATH_THEME.'languages'.DS); define('PATH_THEME_LANG', PATH_THEME.'languages'.DS);
// --- Absolute paths with domain ---
define('DOMAIN', $Site->domain());
define('DOMAIN_BASE', DOMAIN.HTML_PATH_ROOT);
define('DOMAIN_THEME_CSS', DOMAIN.HTML_PATH_THEME_CSS);
define('DOMAIN_THEME_JS', DOMAIN.HTML_PATH_THEME_JS);
define('DOMAIN_THEME_IMG', DOMAIN.HTML_PATH_THEME_IMG);
define('DOMAIN_UPLOADS', DOMAIN.HTML_PATH_UPLOADS);
define('DOMAIN_UPLOADS_PROFILES', DOMAIN.HTML_PATH_UPLOADS_PROFILES);
define('DOMAIN_UPLOADS_THUMBNAILS', DOMAIN.HTML_PATH_UPLOADS_THUMBNAILS);
// --- Objects with dependency --- // --- Objects with dependency ---
$Language = new dbLanguage( $Site->locale() ); $Language = new dbLanguage( $Site->locale() );
$Login = new Login( $dbUsers ); $Login = new Login( $dbUsers );

View File

@ -24,6 +24,15 @@ $plugins = array(
'beforeAdminLoad'=>array(), 'beforeAdminLoad'=>array(),
'afterAdminLoad'=>array(), 'afterAdminLoad'=>array(),
'beforeRulesLoad'=>array(),
'afterPostCreate'=>array(),
'afterPostModify'=>array(),
'afterPostDelete'=>array(),
'afterPageCreate'=>array(),
'afterPageModify'=>array(),
'afterPageDelete'=>array(),
'loginHead'=>array(), 'loginHead'=>array(),
'loginBodyBegin'=>array(), 'loginBodyBegin'=>array(),
'loginBodyEnd'=>array(), 'loginBodyEnd'=>array(),

View File

@ -4,6 +4,8 @@
// Variables // Variables
// ============================================================================ // ============================================================================
// Array with all posts specified by a filter.
// Filter by page number, by tag, etc.
$posts = array(); $posts = array();
// ============================================================================ // ============================================================================
@ -42,7 +44,7 @@ function buildPost($key)
} }
// Post database, content from DATABASE JSON. // Post database, content from DATABASE JSON.
$db = $dbPosts->getDb($key); $db = $dbPosts->getPostDB($key);
if( !$db ) { if( !$db ) {
Log::set(__METHOD__.LOG_SEP.'Error occurred when trying build the post from database with key: '.$key); Log::set(__METHOD__.LOG_SEP.'Error occurred when trying build the post from database with key: '.$key);
return false; return false;
@ -86,9 +88,10 @@ function buildPostsForPage($pageNumber=0, $amount=POSTS_PER_PAGE_ADMIN, $removeU
{ {
global $dbPosts; global $dbPosts;
global $dbTags; global $dbTags;
global $posts;
global $Url; global $Url;
$posts = array();
if($tagKey) { if($tagKey) {
// Get the keys list from tags database, this database is optimized for this case. // Get the keys list from tags database, this database is optimized for this case.
$list = $dbTags->getList($pageNumber, $amount, $tagKey); $list = $dbTags->getList($pageNumber, $amount, $tagKey);
@ -111,6 +114,8 @@ function buildPostsForPage($pageNumber=0, $amount=POSTS_PER_PAGE_ADMIN, $removeU
array_push($posts, $Post); array_push($posts, $Post);
} }
} }
return $posts;
} }
// ============================================================================ // ============================================================================
@ -135,11 +140,13 @@ if( ($Url->whereAmI()==='post') && ($Url->notFound()===false) )
{ {
$Post = buildPost( $Url->slug() ); $Post = buildPost( $Url->slug() );
// The post doesn't exist.
if($Post===false) if($Post===false)
{ {
$Url->setNotFound(true); $Url->setNotFound(true);
unset($Post); unset($Post);
} }
// The post is not published yet.
elseif( !$Post->published() ) elseif( !$Post->published() )
{ {
$Url->setNotFound(true); $Url->setNotFound(true);
@ -154,17 +161,17 @@ if( ($Url->whereAmI()==='post') && ($Url->notFound()===false) )
// Build posts by specific tag. // Build posts by specific tag.
elseif( ($Url->whereAmI()==='tag') && ($Url->notFound()===false) ) elseif( ($Url->whereAmI()==='tag') && ($Url->notFound()===false) )
{ {
buildPostsForPage($Url->pageNumber(), $Site->postsPerPage(), true, $Url->slug()); $posts = buildPostsForPage($Url->pageNumber(), $Site->postsPerPage(), true, $Url->slug());
} }
// Build posts for homepage or admin area. // Build posts for homepage or admin area.
else else
{ {
// Posts for admin area. // Posts for admin area.
if($Url->whereAmI()==='admin') { if($Url->whereAmI()==='admin') {
buildPostsForPage($Url->pageNumber(), POSTS_PER_PAGE_ADMIN, false); $posts = buildPostsForPage($Url->pageNumber(), POSTS_PER_PAGE_ADMIN, false);
} }
// Posts for homepage // Posts for home and blog filter.
else { elseif( ( ($Url->whereAmI()==='home') || ($Url->whereAmI()==='blog') ) && ($Url->notFound()===false) ) {
buildPostsForPage($Url->pageNumber(), $Site->postsPerPage(), true); $posts = buildPostsForPage($Url->pageNumber(), $Site->postsPerPage(), true);
} }
} }

View File

@ -23,7 +23,7 @@ function sortPages($a, $b)
return ($a->position() < $b->position()) ? -1 : 1; return ($a->position() < $b->position()) ? -1 : 1;
} }
function build_page($key) function buildPage($key)
{ {
global $dbPages; global $dbPages;
global $dbUsers; global $dbUsers;
@ -38,7 +38,7 @@ function build_page($key)
} }
// Page database, content from DATABASE JSON. // Page database, content from DATABASE JSON.
$db = $dbPages->getDb($key); $db = $dbPages->getPageDB($key);
if( !$db ) { if( !$db ) {
Log::set(__METHOD__.LOG_SEP.'Error occurred when trying build the page from database with key: '.$key); Log::set(__METHOD__.LOG_SEP.'Error occurred when trying build the page from database with key: '.$key);
return false; return false;
@ -59,6 +59,11 @@ function build_page($key)
$content = Text::imgRel2Abs($content, HTML_PATH_UPLOADS); // Parse img src relative to absolute. $content = Text::imgRel2Abs($content, HTML_PATH_UPLOADS); // Parse img src relative to absolute.
$Page->setField('content', $content, true); $Page->setField('content', $content, true);
// Pagebrake
$explode = explode(PAGE_BREAK, $content);
$Page->setField('breakContent', $explode[0], true);
$Page->setField('readMore', !empty($explode[1]), true);
// Date format // Date format
$pageDate = $Page->date(); $pageDate = $Page->date();
$Page->setField('dateRaw', $pageDate, true); $Page->setField('dateRaw', $pageDate, true);
@ -73,19 +78,21 @@ function build_page($key)
return $Page; return $Page;
} }
function build_all_pages() function buildAllPages()
{ {
global $pages;
global $pagesParents; global $pagesParents;
global $dbPages; global $dbPages;
$list = $dbPages->getAll(); $list = $dbPages->getDB();
// Clean pages array.
$pages = array();
unset($list['error']); unset($list['error']);
foreach($list as $key=>$db) foreach($list as $key=>$db)
{ {
$Page = build_page($key); $Page = buildPage($key);
if($Page!==false) if($Page!==false)
{ {
@ -130,6 +137,8 @@ function build_all_pages()
} }
$pagesParents = array(NO_PARENT_CHAR=>$parents) + $tmpPageWithParent; $pagesParents = array(NO_PARENT_CHAR=>$parents) + $tmpPageWithParent;
return $pages;
} }
// ============================================================================ // ============================================================================
@ -141,16 +150,18 @@ if( $Site->cliMode() ) {
$dbPages->regenerateCli(); $dbPages->regenerateCli();
} }
// Filter by page, then build it // Build specific page.
if( ($Url->whereAmI()==='page') && ($Url->notFound()===false) ) if( ($Url->whereAmI()==='page') && ($Url->notFound()===false) )
{ {
$Page = build_page( $Url->slug() ); $Page = buildPage( $Url->slug() );
// The page doesn't exist.
if($Page===false) if($Page===false)
{ {
$Url->setNotFound(true); $Url->setNotFound(true);
unset($Page); unset($Page);
} }
// The page is not published yet.
elseif( !$Page->published() ) elseif( !$Page->published() )
{ {
$Url->setNotFound(true); $Url->setNotFound(true);
@ -158,14 +169,15 @@ if( ($Url->whereAmI()==='page') && ($Url->notFound()===false) )
} }
} }
// Default homepage // Homepage
if($Url->notFound()===false) if( ($Url->whereAmI()==='home') && ($Url->notFound()===false) )
{ {
if( Text::isNotEmpty($Site->homepage()) && ($Url->whereAmI()==='home') ) // The user defined as homepage a particular page.
if( Text::isNotEmpty( $Site->homepage() ) )
{ {
$Url->setWhereAmI('page'); $Url->setWhereAmI('page');
$Page = build_page( $Site->homepage() ); $Page = buildPage( $Site->homepage() );
if($Page===false) { if($Page===false) {
$Url->setWhereAmI('home'); $Url->setWhereAmI('home');
@ -180,4 +192,4 @@ if($Url->notFound())
} }
// Build all pages // Build all pages
build_all_pages(); $pages = buildAllPages();

View File

@ -1,9 +1,14 @@
<?php defined('BLUDIT') or die('Bludit CMS.'); <?php defined('BLUDIT') or die('Bludit CMS.');
// Boot rules // Load plugins rules
include(PATH_RULES.'60.plugins.php');
// Plugins before rules loaded, except plugins rules
Theme::plugins('beforeRulesLoad');
// Load rules
include(PATH_RULES.'70.posts.php'); include(PATH_RULES.'70.posts.php');
include(PATH_RULES.'70.pages.php'); include(PATH_RULES.'71.pages.php');
include(PATH_RULES.'80.plugins.php');
include(PATH_RULES.'99.header.php'); include(PATH_RULES.'99.header.php');
include(PATH_RULES.'99.paginator.php'); include(PATH_RULES.'99.paginator.php');
include(PATH_RULES.'99.themes.php'); include(PATH_RULES.'99.themes.php');

View File

@ -14,6 +14,7 @@ class dbPages extends dbJSON
'date'=> array('inFile'=>false, 'value'=>''), 'date'=> array('inFile'=>false, 'value'=>''),
'position'=> array('inFile'=>false, 'value'=>0), 'position'=> array('inFile'=>false, 'value'=>0),
'coverImage'=> array('inFile'=>false, 'value'=>''), 'coverImage'=> array('inFile'=>false, 'value'=>''),
'hash'=> array('inFile'=>false, 'value'=>'')
); );
function __construct() function __construct()
@ -75,6 +76,10 @@ class dbPages extends dbJSON
} }
} }
// Create Hash
$serialize = serialize($dataForDb+$dataForFile);
$dataForDb['hash'] = sha1($serialize);
// Make the directory. Recursive. // Make the directory. Recursive.
if( Filesystem::mkdir(PATH_PAGES.$key, true) === false ) { if( Filesystem::mkdir(PATH_PAGES.$key, true) === false ) {
Log::set(__METHOD__.LOG_SEP.'Error occurred when trying to create the directory '.PATH_PAGES.$key); Log::set(__METHOD__.LOG_SEP.'Error occurred when trying to create the directory '.PATH_PAGES.$key);
@ -95,7 +100,7 @@ class dbPages extends dbJSON
return false; return false;
} }
return true; return $key;
} }
public function edit($args) public function edit($args)
@ -157,6 +162,10 @@ class dbPages extends dbJSON
} }
} }
// Create Hash
$serialize = serialize($dataForDb+$dataForFile);
$dataForDb['hash'] = sha1($serialize);
// Move the directory from old key to new key. // Move the directory from old key to new key.
if($newKey!==$args['key']) if($newKey!==$args['key'])
{ {
@ -183,7 +192,7 @@ class dbPages extends dbJSON
return false; return false;
} }
return true; return $newKey;
} }
public function delete($key) public function delete($key)
@ -215,7 +224,7 @@ class dbPages extends dbJSON
} }
// Return an array with the database for a page, FALSE otherwise. // Return an array with the database for a page, FALSE otherwise.
public function getDb($key) public function getPageDB($key)
{ {
if($this->pageExists($key)) { if($this->pageExists($key)) {
return $this->db[$key]; return $this->db[$key];
@ -288,8 +297,8 @@ class dbPages extends dbJSON
return $newKey; return $newKey;
} }
// Return an array with all databases. // Returns the database
public function getAll() public function getDB()
{ {
return $this->db; return $this->db;
} }

View File

@ -12,6 +12,7 @@ class dbPosts extends dbJSON
'allowComments'=> array('inFile'=>false, 'value'=>false), 'allowComments'=> array('inFile'=>false, 'value'=>false),
'date'=> array('inFile'=>false, 'value'=>''), 'date'=> array('inFile'=>false, 'value'=>''),
'coverImage'=> array('inFile'=>false, 'value'=>''), 'coverImage'=> array('inFile'=>false, 'value'=>''),
'hash'=> array('inFile'=>false, 'value'=>'')
); );
private $numberPosts = array( private $numberPosts = array(
@ -35,8 +36,14 @@ class dbPosts extends dbJSON
return $this->numberPosts['published']; return $this->numberPosts['published'];
} }
// Returns the database
public function getDB()
{
return $this->db;
}
// Return an array with the post's database, FALSE otherwise. // Return an array with the post's database, FALSE otherwise.
public function getDb($key) public function getPostDB($key)
{ {
if($this->postExists($key)) { if($this->postExists($key)) {
return $this->db[$key]; return $this->db[$key];
@ -45,7 +52,7 @@ class dbPosts extends dbJSON
return false; return false;
} }
public function setDb($key, $field, $value) public function setPostDb($key, $field, $value)
{ {
if($this->postExists($key)) { if($this->postExists($key)) {
$this->db[$key][$field] = $value; $this->db[$key][$field] = $value;
@ -152,6 +159,10 @@ class dbPosts extends dbJSON
} }
} }
// Create Hash
$serialize = serialize($dataForDb+$dataForFile);
$dataForDb['hash'] = sha1($serialize);
// Make the directory. // Make the directory.
if( Filesystem::mkdir(PATH_POSTS.$key) === false ) { if( Filesystem::mkdir(PATH_POSTS.$key) === false ) {
Log::set(__METHOD__.LOG_SEP.'Error occurred when trying to create the directory '.PATH_POSTS.$key); Log::set(__METHOD__.LOG_SEP.'Error occurred when trying to create the directory '.PATH_POSTS.$key);
@ -176,7 +187,7 @@ class dbPosts extends dbJSON
return false; return false;
} }
return true; return $key;
} }
public function edit($args) public function edit($args)

View File

@ -17,6 +17,7 @@ class dbSite extends dbJSON
'uriPage'=> array('inFile'=>false, 'value'=>'/'), 'uriPage'=> array('inFile'=>false, 'value'=>'/'),
'uriPost'=> array('inFile'=>false, 'value'=>'/post/'), 'uriPost'=> array('inFile'=>false, 'value'=>'/post/'),
'uriTag'=> array('inFile'=>false, 'value'=>'/tag/'), 'uriTag'=> array('inFile'=>false, 'value'=>'/tag/'),
'uriBlog'=> array('inFile'=>false, 'value'=>'/blog/'),
'url'=> array('inFile'=>false, 'value'=>''), 'url'=> array('inFile'=>false, 'value'=>''),
'cliMode'=> array('inFile'=>false, 'value'=>true), 'cliMode'=> array('inFile'=>false, 'value'=>true),
'emailFrom'=> array('inFile'=>false, 'value'=>''), 'emailFrom'=> array('inFile'=>false, 'value'=>''),
@ -67,6 +68,7 @@ class dbSite extends dbJSON
$filters['post'] = $this->getField('uriPost'); $filters['post'] = $this->getField('uriPost');
$filters['page'] = $this->getField('uriPage'); $filters['page'] = $this->getField('uriPage');
$filters['tag'] = $this->getField('uriTag'); $filters['tag'] = $this->getField('uriTag');
$filters['blog'] = $this->getField('uriBlog');
if(empty($filter)) { if(empty($filter)) {
return $filters; return $filters;
@ -93,6 +95,12 @@ class dbSite extends dbJSON
return $this->url().ltrim($filter, '/'); return $this->url().ltrim($filter, '/');
} }
public function urlBlog()
{
$filter = $this->getField('uriBlog');
return $this->url().ltrim($filter, '/');
}
// Returns the site title. // Returns the site title.
public function title() public function title()
{ {
@ -162,16 +170,17 @@ class dbSite extends dbJSON
$protocol = 'http://'; $protocol = 'http://';
} }
$domain = $_SERVER['HTTP_HOST']; $domain = trim($_SERVER['HTTP_HOST'], '/');
return $protocol.$domain.HTML_PATH_ROOT; return $protocol.$domain;
} }
// Parse the domain from the field URL. // Parse the domain from the field URL.
$parse = parse_url($this->url()); $parse = parse_url($this->url());
$domain = $parse['scheme']."://".$parse['host'];
return $domain; $domain = trim($parse['host'], '/');
return $parse['scheme'].'://'.$domain;
} }
// Returns TRUE if the cli mode is enabled, otherwise FALSE. // Returns TRUE if the cli mode is enabled, otherwise FALSE.

View File

@ -2,8 +2,6 @@
class Filesystem { class Filesystem {
// NEW
// Returns an array with the absolutes directories. // Returns an array with the absolutes directories.
public static function listDirectories($path, $regex='*') public static function listDirectories($path, $regex='*')
{ {
@ -52,50 +50,4 @@ class Filesystem {
return unlink($filename); return unlink($filename);
} }
// OLD
public static function get_images($regex)
{
return self::ls(PATH_UPLOAD, $regex, '*', false, false, false);
}
// Devuelve un arreglo con el listado de archivos
// $path con una barra al final, ej: /home/
// $file_expression : *.0.*.*.*.*.*.*.*.*
// $ext : xml
// $flag_dir : si quiero listar directorios
// $sort_asc_numeric : ordeno ascedente numerico
// $sort_desc_numeric : ordeno descendente numerico
public static function ls($path, $file_expression = NULL, $ext, $flag_dir = false, $sort_asc_numeric = false, $sort_desc_numeric = true)
{
if($flag_dir)
{
$files = glob($path . $file_expression, GLOB_ONLYDIR);
}
else
{
$files = glob($path . $file_expression . '.' . $ext);
}
if( ($files==false) || (empty($files)) )
{
$files = array();
}
foreach($files as $key=>$file)
{
$files[$key] = basename($file);
}
// Sort
if($sort_asc_numeric)
{
sort($files, SORT_NUMERIC);
}
elseif($sort_desc_numeric)
{
rsort($files, SORT_NUMERIC);
}
return $files;
}
} }

View File

@ -131,103 +131,6 @@ class Theme {
return $tmp; return $tmp;
} }
// OLD
public static function url($relative = true)
{
if($relative)
return HTML_PATH_ROOT;
else
return BLOG_URL;
}
public static function name()
{
global $settings;
return $settings['name'];
}
public static function slogan()
{
global $settings;
return $settings['slogan'];
}
public static function footer()
{
global $settings;
return $settings['footer'];
}
public static function language()
{
global $settings;
$lang = explode("_",$settings['locale']);
return $lang[0];
}
public static function locale()
{
global $settings;
return $settings['locale'];
}
public static function meta_tags()
{
global $layout;
global $seo;
// The validator W3C doesn't support???
//$meta = '<meta charset="UTF-8">'.PHP_EOL;
$meta = '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">'.PHP_EOL;
if(!empty($layout['title']))
$meta .= '<title>'.$layout['title'].'</title>'.PHP_EOL;
if(!empty($layout['description']))
$meta .= '<meta name="description" content="'.$layout['description'].'">'.PHP_EOL;
if(!empty($layout['generator']))
$meta .= '<meta name="generator" content="'.$layout['generator'].'">'.PHP_EOL;
if(!empty($layout['keywords']))
$meta .= '<meta name="keywords" content="'.$layout['keywords'].'">'.PHP_EOL;
if(!empty($layout['author']))
{
if(filter_var($layout['author'], FILTER_VALIDATE_URL))
$meta .= '<link rel="author" href="'.$layout['author'].'">'.PHP_EOL;
else
$meta .= '<meta name="author" content="'.$layout['author'].'">'.PHP_EOL;
}
if(!empty($layout['canonical']))
$meta .= '<link rel="canonical" href="'.$layout['canonical'].'">'.PHP_EOL;
if(!empty($layout['robots']))
$meta .= '<meta name="robots" content="'.$layout['robots'].'">'.PHP_EOL;
if(!empty($seo['google_code']))
$meta .= '<meta name="google-site-verification" content="'.$seo['google_code'].'">'.PHP_EOL;
if(!empty($seo['bing_code']))
$meta .= '<meta name="msvalidate.01" content="'.$seo['bing_code'].'">'.PHP_EOL;
$meta .= '<link rel="alternate" type="application/atom+xml" title="ATOM Feed" href="'.$layout['feed'].'">'.PHP_EOL;
return $meta;
}
} }
?> ?>

View File

@ -1,168 +1,37 @@
<?php defined('BLUDIT') or die('Bludit CMS.'); <?php defined('BLUDIT') or die('Bludit CMS.');
class Page extends fileContent class Page extends Content {
{
function __construct($key) function __construct($key)
{ {
// Database Key // Database Key
$this->setField('key', $key); $this->setField('key', $key);
// Set filterType
$this->setField('filterType', 'page');
parent::__construct(PATH_PAGES.$key.DS); parent::__construct(PATH_PAGES.$key.DS);
} }
// Returns the post title. // Returns the page position.
public function title()
{
return $this->getField('title');
}
// Returns the content. This content is markdown parser.
// (boolean) $html, TRUE returns the content without satinize, FALSE otherwise.
public function content($html=true)
{
// This content is not sanitized.
$content = $this->getField('content');
if($html) {
return $content;
}
return Sanitize::html($content);
}
// Returns the content. This content is not markdown parser.
// (boolean) $raw, TRUE returns the content without sanitized, FALSE otherwise.
public function contentRaw($raw=true)
{
// This content is not sanitized.
$content = $this->getField('contentRaw');
if($raw) {
return $content;
}
return Sanitize::html($content);
}
public function description()
{
return $this->getField('description');
}
public function tags($returnsArray=false)
{
global $Url;
$tags = $this->getField('tags');
if($returnsArray) {
if($tags==false) {
return array();
}
return $tags;
}
else {
if($tags==false) {
return false;
}
// Return string with tags separeted by comma.
return implode(', ', $tags);
}
}
public function position() public function position()
{ {
return $this->getField('position'); return $this->getField('position');
} }
// Returns the post date according to locale settings and format settings.
public function date()
{
return $this->getField('date');
}
// Returns the post date according to locale settings and format as database stored.
public function dateRaw($format=false)
{
$date = $this->getField('dateRaw');
if($format) {
return Date::format($date, DB_DATE_FORMAT, $format);
}
return $date;
}
// Returns the page slug. // Returns the page slug.
public function slug() public function slug()
{ {
$explode = explode('/', $this->getField('key')); $explode = explode('/', $this->getField('key'));
if(!empty($explode[1]))
// Check if the page have a parent.
if(!empty($explode[1])) {
return $explode[1]; return $explode[1];
}
return $explode[0]; return $explode[0];
} }
public function key()
{
return $this->getField('key');
}
public function coverImage($absolute=true)
{
$fileName = $this->getField('coverImage');
if($absolute) {
return HTML_PATH_UPLOADS.$fileName;
}
return $fileName;
}
// Returns TRUE if the page is published, FALSE otherwise.
public function published()
{
return ($this->getField('status')==='published');
}
// Returns TRUE if the post is draft, FALSE otherwise.
public function draft()
{
return ($this->getField('status')=='draft');
}
// Returns the page permalink.
public function permalink($absolute=false)
{
global $Url;
global $Site;
$url = trim($Site->url(),'/');
$key = $this->key();
$filter = trim($Url->filters('page'), '/');
$htmlPath = trim(HTML_PATH_ROOT,'/');
if(empty($filter)) {
$tmp = $key;
}
else {
$tmp = $filter.'/'.$key;
}
if($absolute) {
return $url.'/'.$tmp;
}
if(empty($htmlPath)) {
return '/'.$tmp;
}
return '/'.$htmlPath.'/'.$tmp;
}
// Returns the parent key, if the page doesn't have a parent returns FALSE. // Returns the parent key, if the page doesn't have a parent returns FALSE.
public function parentKey() public function parentKey()
{ {
@ -198,35 +67,4 @@ class Page extends fileContent
return $tmp; return $tmp;
} }
// Returns the user object if $field is false, otherwise returns the field's value.
public function user($field=false)
{
// Get the user object.
$User = $this->getField('user');
if($field) {
return $User->getField($field);
}
return $User;
}
// DEPRECATED
public function username()
{
return $this->getField('username');
}
// DEPRECATED
public function authorFirstName()
{
return $this->getField('authorFirstName');
}
// DEPRECATED
public function authorLastName()
{
return $this->getField('authorLastName');
}
} }

View File

@ -1,69 +1,26 @@
<?php defined('BLUDIT') or die('Bludit CMS.'); <?php defined('BLUDIT') or die('Bludit CMS.');
class Post extends fileContent class Post extends Content {
{
function __construct($key) function __construct($key)
{ {
// Database Key // Database Key
$this->setField('key', $key); $this->setField('key', $key);
// Set filterType
$this->setField('filterType', 'post');
parent::__construct(PATH_POSTS.$key.DS); parent::__construct(PATH_POSTS.$key.DS);
} }
// Returns the post title.
public function title()
{
return $this->getField('title');
}
// Returns the content.
// This content is markdown parser.
// (boolean) $fullContent, TRUE returns all content, if FALSE returns the first part of the content.
// (boolean) $raw, TRUE returns the content without sanitized, FALSE otherwise.
public function content($fullContent=true, $raw=true)
{
// This content is not sanitized.
$content = $this->getField('content');
if(!$fullContent) {
$content = $this->getField('breakContent');
}
if($raw) {
return $content;
}
return Sanitize::html($content);
}
public function readMore()
{
return $this->getField('readMore');
}
// Returns the content. This content is not markdown parser.
// (boolean) $raw, TRUE returns the content without sanitized, FALSE otherwise.
public function contentRaw($raw=true)
{
// This content is not sanitized.
$content = $this->getField('contentRaw');
if($raw) {
return $content;
}
return Sanitize::html($content);
}
public function key() public function key()
{ {
return $this->getField('key'); return $this->getField('key');
} }
// Returns TRUE if the post is published, FALSE otherwise. public function slug()
public function published()
{ {
return ($this->getField('status')==='published'); return $this->getField('key');
} }
// Returns TRUE if the post is scheduled, FALSE otherwise. // Returns TRUE if the post is scheduled, FALSE otherwise.
@ -71,138 +28,4 @@ class Post extends fileContent
{ {
return ($this->getField('status')==='scheduled'); return ($this->getField('status')==='scheduled');
} }
// Returns TRUE if the post is draft, FALSE otherwise.
public function draft()
{
return ($this->getField('status')=='draft');
}
public function coverImage($absolute=true)
{
$fileName = $this->getField('coverImage');
if($absolute) {
return HTML_PATH_UPLOADS.$fileName;
}
return $fileName;
}
public function profilePicture()
{
return HTML_PATH_UPLOADS_PROFILES.$this->username().'.jpg';
}
// Returns the user object if $field is false, otherwise returns the field's value.
public function user($field=false)
{
// Get the user object.
$User = $this->getField('user');
if($field) {
return $User->getField($field);
}
return $User;
}
// DEPRECATED
public function username()
{
return $this->getField('username');
}
// DEPRECATED
public function authorFirstName()
{
return $this->getField('authorFirstName');
}
// DEPRECATED
public function authorLastName()
{
return $this->getField('authorLastName');
}
public function description()
{
return $this->getField('description');
}
// Returns the post date according to locale settings and format settings.
public function date($format=false)
{
return $this->getField('date');
}
// Returns the post date according to locale settings and format as database stored.
public function dateRaw($format=false)
{
$date = $this->getField('dateRaw');
if($format) {
return Date::format($date, DB_DATE_FORMAT, $format);
}
return $date;
}
public function tags($returnsArray=false)
{
global $Url;
$tags = $this->getField('tags');
if($returnsArray) {
if($tags==false) {
return array();
}
return $tags;
}
else {
if($tags==false) {
return false;
}
// Return string with tags separeted by comma.
return implode(', ', $tags);
}
}
public function slug()
{
return $this->getField('key');
}
public function permalink($absolute=false)
{
global $Url;
global $Site;
$url = trim($Site->url(),'/');
$key = $this->key();
$filter = trim($Url->filters('post'), '/');
$htmlPath = trim(HTML_PATH_ROOT,'/');
if(empty($filter)) {
$tmp = $key;
}
else {
$tmp = $filter.'/'.$key;
}
if($absolute) {
return $url.'/'.$tmp;
}
if(empty($htmlPath)) {
return '/'.$tmp;
}
return '/'.$htmlPath.'/'.$tmp;
}
} }

View File

@ -67,6 +67,12 @@ class Url
break; break;
} }
if($filterURI===$filters['blog'])
{
$this->whereAmI = 'blog';
break;
}
if($filterURI===$adminFilter['admin']) if($filterURI===$adminFilter['admin'])
{ {
$this->whereAmI = 'admin'; $this->whereAmI = 'admin';

View File

@ -218,6 +218,8 @@
"site-information": "Информация за сайта", "site-information": "Информация за сайта",
"date-and-time-formats": "Формат дата и час", "date-and-time-formats": "Формат дата и час",
"activate": "Активиране", "activate": "Активиране",
"deactivate": "Деактивиране" "deactivate": "Деактивиране",
"cover-image": "Обложка"
} }

View File

@ -220,5 +220,9 @@
"activate": "Activate", "activate": "Activate",
"deactivate": "Deactivate", "deactivate": "Deactivate",
"cover-image": "Cover image" "cover-image": "Cover image",
"blog": "Blog",
"more-images": "More images",
"double-click-on-the-image-to-add-it": "Double click on the image to add it.",
"click-here-to-cancel": "Click here to cancel."
} }

View File

@ -42,7 +42,7 @@
"email": "Email", "email": "Email",
"settings": "Instellingen", "settings": "Instellingen",
"general": "Algemeen", "general": "Algemeen",
"Advanced": "Geadvanceerd", "advanced": "Geadvanceerd",
"regional": "Taal/Tijd/Locatie", "regional": "Taal/Tijd/Locatie",
"about": "Over", "about": "Over",
"login": "Aanmelden", "login": "Aanmelden",

View File

@ -220,5 +220,9 @@
"activate": "Aktifleştir", "activate": "Aktifleştir",
"deactivate": "Deaktive et", "deactivate": "Deaktive et",
"cover-image": "Kapak resmi" "cover-image": "Kapak resmi",
"blog": "Blog",
"more-images": "Daha çok resim",
"double-click-on-the-image-to-add-it": "Eklemek istediğiniz resime çift tıklayın.",
"click-here-to-cancel": "İptal etmek için tıklayın."
} }

View File

@ -0,0 +1,15 @@
{
"plugin-data":
{
"name": "Latest posts",
"description": "Shows the latest posts published.",
"author": "Bludit",
"email": "",
"website": "https://github.com/dignajar/bludit-plugins",
"version": "1.0",
"releaseDate": "2016-01-08"
},
"amount-of-posts": "Amount of posts",
"show-home-link": "Show home link"
}

View File

@ -0,0 +1,59 @@
<?php
class pluginLatestPosts extends Plugin {
public function init()
{
$this->dbFields = array(
'label'=>'Latest posts',
'amount'=>5
);
}
public function form()
{
global $Language;
$html = '<div>';
$html .= '<label>'.$Language->get('Plugin label').'</label>';
$html .= '<input name="label" id="jslabel" type="text" value="'.$this->getDbField('label').'">';
$html .= '</div>';
$html .= '<div>';
$html .= '<label>'.$Language->get('Amount of posts').'</label>';
$html .= '<input name="amount" id="jsamount" type="text" value="'.$this->getDbField('amount').'">';
$html .= '</div>';
return $html;
}
public function siteSidebar()
{
// This function is declared in 70.posts.php
$posts = buildPostsForPage(0, $this->getDbField('amount'), true, false);
$html = '<div class="plugin plugin-latest-posts">';
// Print the label if not empty.
$label = $this->getDbField('label');
if( !empty($label) ) {
$html .= '<h2 class="plugin-title">'.$label.'</h2>';
}
$html .= '<div class="plugin-content">';
$html .= '<ul>';
foreach($posts as $Post)
{
$html .= '<li>';
$html .= '<a href="'.$Post->permalink().'">'.$Post->title().'</a>';
$html .= '</li>';
}
$html .= '</ul>';
$html .= '</div>';
$html .= '</div>';
return $html;
}
}

View File

@ -2,17 +2,22 @@
class pluginOpenGraph extends Plugin { class pluginOpenGraph extends Plugin {
// Returns the first image that is in the content
private function getImage($content) private function getImage($content)
{ {
$dom = new DOMDocument(); $dom = new DOMDocument();
$dom->loadHTML('<meta http-equiv="content-type" content="text/html; charset=utf-8">'.$content); $dom->loadHTML('<meta http-equiv="content-type" content="text/html; charset=utf-8">'.$content);
$finder = new DomXPath($dom); $finder = new DomXPath($dom);
/* DEPRECATED
$images = $finder->query("//img[contains(@class, 'bludit-img-opengraph')]"); $images = $finder->query("//img[contains(@class, 'bludit-img-opengraph')]");
if($images->length==0) { if($images->length==0) {
$images = $finder->query("//img"); $images = $finder->query("//img");
} }
*/
$images = $finder->query("//img");
if($images->length>0) if($images->length>0)
{ {
@ -49,6 +54,7 @@ class pluginOpenGraph extends Plugin {
$og['title'] = $Post->title().' | '.$og['title']; $og['title'] = $Post->title().' | '.$og['title'];
$og['description'] = $Post->description(); $og['description'] = $Post->description();
$og['url'] = $Post->permalink(true); $og['url'] = $Post->permalink(true);
$og['image'] = $Post->coverImage(false);
$content = $Post->content(); $content = $Post->content();
break; break;
@ -58,12 +64,16 @@ class pluginOpenGraph extends Plugin {
$og['title'] = $Page->title().' | '.$og['title']; $og['title'] = $Page->title().' | '.$og['title'];
$og['description'] = $Page->description(); $og['description'] = $Page->description();
$og['url'] = $Page->permalink(true); $og['url'] = $Page->permalink(true);
$og['image'] = $Page->coverImage(false);
$content = $Page->content(); $content = $Page->content();
break; break;
default: default:
$content = isset($posts[0])?$posts[0]->content():''; if(isset($posts[0])) {
$og['image'] = $posts[0]->coverImage(false);
$content = $posts[0]->content();
}
break; break;
} }
@ -75,11 +85,21 @@ class pluginOpenGraph extends Plugin {
$html .= '<meta property="og:url" content="'.$og['url'].'">'.PHP_EOL; $html .= '<meta property="og:url" content="'.$og['url'].'">'.PHP_EOL;
$html .= '<meta property="og:siteName" content="'.$og['siteName'].'">'.PHP_EOL; $html .= '<meta property="og:siteName" content="'.$og['siteName'].'">'.PHP_EOL;
$domain = trim($Site->domain(),'/');
$urlImage = $domain.HTML_PATH_UPLOADS;
// If the post o page doesn't have a coverImage try to get it from the content
if($og['image']===false)
{
// Get the image from the content // Get the image from the content
$src = $this->getImage( $content ); $src = $this->getImage( $content );
if($src!==false) { if($src!==false) {
$og['image'] = $Site->domain().$src; $html .= '<meta property="og:image" content="'.$urlImage.$og['image'].'">'.PHP_EOL;
$html .= '<meta property="og:image" content="'.$og['image'].'">'.PHP_EOL; }
}
else
{
$html .= '<meta property="og:image" content="'.$urlImage.$og['image'].'">'.PHP_EOL;
} }
return $html; return $html;

View File

@ -0,0 +1,12 @@
{
"plugin-data":
{
"name": "RSS",
"description": "This plugin generate a file rss.xml.",
"author": "Bludit",
"email": "",
"website": "https://github.com/dignajar/bludit-plugins",
"version": "1.0",
"releaseDate": "2016-01-07"
}
}

View File

@ -0,0 +1,12 @@
{
"plugin-data":
{
"name": "RSS",
"description": "This plugin generate a file rss.xml.",
"author": "Bludit",
"email": "",
"website": "https://github.com/dignajar/bludit-plugins",
"version": "1.0",
"releaseDate": "2016-01-07"
}
}

102
plugins/rss/plugin.php Normal file
View File

@ -0,0 +1,102 @@
<?php
class pluginRSS extends Plugin {
private function createXML()
{
global $Site;
global $dbPages;
global $dbPosts;
global $Url;
$xml = '<?xml version="1.0" encoding="UTF-8" ?>';
$xml .= '<rss version="2.0">';
$xml .= '<channel>';
$xml .= '<title>'.$Site->title().'</title>';
$xml .= '<link>'.$Site->url().'</link>';
$xml .= '<description>'.$Site->description().'</description>';
$posts = buildPostsForPage(0, 10, true);
foreach($posts as $Post)
{
$xml .= '<item>';
$xml .= '<title>'.$Post->title().'</title>';
$xml .= '<link>'.$Post->permalink(true).'</link>';
$xml .= '<description>'.$Post->description().'</description>';
$xml .= '</item>';
}
$xml .= '</channel></rss>';
// New DOM document
$doc = new DOMDocument();
// Friendly XML code
$doc->formatOutput = true;
$doc->loadXML($xml);
$doc->save(PATH_PLUGINS_DATABASES.$this->directoryName.DS.'rss.xml');
}
public function install($position = 0)
{
parent::install($position);
$this->createXML();
}
public function afterPostCreate()
{
$this->createXML();
}
public function afterPageCreate()
{
$this->createXML();
}
public function afterPostModify()
{
$this->createXML();
}
public function afterPageModify()
{
$this->createXML();
}
public function afterPostDelete()
{
$this->createXML();
}
public function afterPageDelete()
{
$this->createXML();
}
public function beforeRulesLoad()
{
global $Url;
if( $Url->uri() === HTML_PATH_ROOT.'rss.xml' )
{
// Send XML header
header('Content-type: text/xml');
// New DOM document
$doc = new DOMDocument();
// Load XML
$doc->load(PATH_PLUGINS_DATABASES.$this->directoryName.DS.'rss.xml');
// Print the XML
echo $doc->saveXML();
// Stop Bludit running
exit;
}
}
}

View File

@ -0,0 +1,12 @@
{
"plugin-data":
{
"name": "Sitemap",
"description": "This plugin generate a file sitemap.xml where you can list the web pages of your site to tell to search engines about the organization of your site content.",
"author": "Bludit",
"email": "",
"website": "https://github.com/dignajar/bludit-plugins",
"version": "1.0",
"releaseDate": "2016-01-07"
}
}

144
plugins/sitemap/plugin.php Normal file
View File

@ -0,0 +1,144 @@
<?php
class pluginSitemap extends Plugin {
private function createXML()
{
global $Site;
global $dbPages;
global $dbPosts;
global $Url;
$doc = new DOMDocument('1.0', 'UTF-8');
// Friendly XML code
$doc->formatOutput = true;
// Create urlset element
$urlset = $doc->createElement('urlset');
$attribute = $doc->createAttribute('xmlns');
$attribute->value = 'http://www.sitemaps.org/schemas/sitemap/0.9';
$urlset->appendChild($attribute);
// --- Base URL ---
// Create url, loc and lastmod elements
$url = $doc->createElement('url');
$loc = $doc->createElement('loc', $Site->url());
$lastmod = $doc->createElement('lastmod', '');
// Append loc and lastmod -> url
$url->appendChild($loc);
$url->appendChild($lastmod);
// Append url -> urlset
$urlset->appendChild($url);
// --- Pages and Posts ---
$all = array();
$url = trim($Site->url(),'/');
// --- Pages ---
$filter = trim($Url->filters('page'),'/');
$pages = $dbPages->getDB();
unset($pages['error']);
foreach($pages as $key=>$db)
{
$permalink = empty($filter) ? $url.'/'.$key : $url.'/'.$filter.'/'.$key;
$date = Date::format($db['date'], DB_DATE_FORMAT, SITEMAP_DATE_FORMAT);
array_push($all, array('permalink'=>$permalink, 'date'=>$date));
}
// --- Posts ---
$filter = rtrim($Url->filters('post'),'/');
$posts = $dbPosts->getDB();
foreach($posts as $key=>$db)
{
$permalink = empty($filter) ? $url.'/'.$key : $url.'/'.$filter.'/'.$key;
$date = Date::format($db['date'], DB_DATE_FORMAT, SITEMAP_DATE_FORMAT);
array_push($all, array('permalink'=>$permalink, 'date'=>$date));
}
// Generate the XML for posts and pages
foreach($all as $db)
{
// Create url, loc and lastmod elements
$url = $doc->createElement('url');
$loc = $doc->createElement('loc', $db['permalink']);
$lastmod = $doc->createElement('lastmod', $db['date']);
// Append loc and lastmod -> url
$url->appendChild($loc);
$url->appendChild($lastmod);
// Append url -> urlset
$urlset->appendChild($url);
}
// Append urlset -> XML
$doc->appendChild($urlset);
$doc->save(PATH_PLUGINS_DATABASES.$this->directoryName.DS.'sitemap.xml');
}
public function install($position = 0)
{
parent::install($position);
$this->createXML();
}
public function afterPostCreate()
{
$this->createXML();
}
public function afterPageCreate()
{
$this->createXML();
}
public function afterPostModify()
{
$this->createXML();
}
public function afterPageModify()
{
$this->createXML();
}
public function afterPostDelete()
{
$this->createXML();
}
public function afterPageDelete()
{
$this->createXML();
}
public function beforeRulesLoad()
{
global $Url;
if( $Url->uri() === HTML_PATH_ROOT.'sitemap.xml' )
{
// Send XML header
header('Content-type: text/xml');
// New DOM document
$doc = new DOMDocument();
// Load XML
$doc->load(PATH_PLUGINS_DATABASES.$this->directoryName.DS.'sitemap.xml');
// Print the XML
echo $doc->saveXML();
// Stop Bludit running
exit;
}
}
}

View File

@ -24,7 +24,7 @@
<!-- Content --> <!-- Content -->
<?php <?php
if( ($Url->whereAmI()=='home') || ($Url->whereAmI()=='tag') ) if( ($Url->whereAmI()=='home') || ($Url->whereAmI()=='tag') || ($Url->whereAmI()=='blog') )
{ {
include(PATH_THEME_PHP.'home.php'); include(PATH_THEME_PHP.'home.php');
} }

View File

@ -1,4 +1,4 @@
<h1 class="subhead"><?php echo $Language->get('Recent posts') ?></h1> <div class="subhead"><?php echo $Language->get('Recent posts') ?></div>
<?php foreach ($posts as $Post): ?> <?php foreach ($posts as $Post): ?>
@ -11,9 +11,9 @@
<header class="post-header"> <header class="post-header">
<!-- Post title --> <!-- Post title -->
<h2 class="post-title"> <h1 class="post-title">
<a href="<?php echo $Post->permalink() ?>"><?php echo $Post->title() ?></a> <a href="<?php echo $Post->permalink() ?>"><?php echo $Post->title() ?></a>
</h2> </h1>
<!-- Post date and author --> <!-- Post date and author -->
<div class="post-meta"> <div class="post-meta">

View File

@ -1,4 +1,4 @@
<h1 class="subhead"><?php echo $Language->get('Page') ?></h1> <div class="subhead"><?php echo $Language->get('Page') ?></div>
<section class="page"> <section class="page">
@ -9,9 +9,9 @@
<header class="page-header"> <header class="page-header">
<!-- page title --> <!-- page title -->
<h2 class="page-title"> <h1 class="page-title">
<a href="<?php echo $Page->permalink() ?>"><?php echo $Page->title() ?></a> <a href="<?php echo $Page->permalink() ?>"><?php echo $Page->title() ?></a>
</h2> </h1>
</header> </header>

View File

@ -1,4 +1,4 @@
<h1 class="subhead"><?php echo $Language->get('Post') ?></h1> <div class="subhead"><?php echo $Language->get('Post') ?></div>
<section class="post"> <section class="post">
@ -9,9 +9,9 @@
<header class="post-header"> <header class="post-header">
<!-- Post title --> <!-- Post title -->
<h2 class="post-title"> <h1 class="post-title">
<a href="<?php echo $Post->permalink() ?>"><?php echo $Post->title() ?></a> <a href="<?php echo $Post->permalink() ?>"><?php echo $Post->title() ?></a>
</h2> </h1>
<!-- Post date and author --> <!-- Post date and author -->
<div class="post-meta"> <div class="post-meta">