diff --git a/kernel/abstract/dbjson.class.php b/kernel/abstract/dbjson.class.php
index a792164d..ccd3fa80 100644
--- a/kernel/abstract/dbjson.class.php
+++ b/kernel/abstract/dbjson.class.php
@@ -58,6 +58,15 @@ class dbJSON
return count($this->db);
}
+ public function getField($field)
+ {
+ if(isset($this->db[$field])) {
+ return $this->db[$field];
+ }
+
+ return $this->dbFields[$field]['value'];
+ }
+
// Save the JSON file.
public function save()
{
diff --git a/kernel/boot/init.php b/kernel/boot/init.php
index ccef230e..291acba0 100644
--- a/kernel/boot/init.php
+++ b/kernel/boot/init.php
@@ -75,7 +75,7 @@ define('CLI_STATUS', 'published');
// Database format date
define('DB_DATE_FORMAT', 'Y-m-d H:i');
-// Database format date
+// Date format for Dashboard schedule posts
define('SCHEDULED_DATE_FORMAT', 'd M - h:i a');
// Token time to live for login via email. The offset is defined by http://php.net/manual/en/datetime.modify.php
@@ -128,6 +128,7 @@ include(PATH_HELPERS.'email.class.php');
include(PATH_HELPERS.'filesystem.class.php');
include(PATH_HELPERS.'alert.class.php');
include(PATH_HELPERS.'paginator.class.php');
+include(PATH_HELPERS.'image.class.php');
// Session
Session::start();
diff --git a/kernel/boot/rules/70.posts.php b/kernel/boot/rules/70.posts.php
index 62f6ff9e..2294d624 100644
--- a/kernel/boot/rules/70.posts.php
+++ b/kernel/boot/rules/70.posts.php
@@ -68,6 +68,13 @@ function buildPost($key)
$Post->setField('breakContent', $explode[0], true);
$Post->setField('readMore', !empty($explode[1]), true);
+ // Date format
+ $postDate = $Post->date();
+ $Post->setField('dateRaw', $postDate, true);
+
+ $postDateFormated = $Post->dateRaw( $Site->dateFormat() );
+ $Post->setField('date', $postDateFormated, true);
+
// Parse username for the post.
if( $dbUsers->userExists( $Post->username() ) )
{
diff --git a/kernel/dbsite.class.php b/kernel/dbsite.class.php
index b1058d9a..7a000448 100644
--- a/kernel/dbsite.class.php
+++ b/kernel/dbsite.class.php
@@ -2,7 +2,7 @@
class dbSite extends dbJSON
{
- private $dbFields = array(
+ public $dbFields = array(
'title'=> array('inFile'=>false, 'value'=>'I am Guybrush Threepwood, mighty developer'),
'slogan'=> array('inFile'=>false, 'value'=>''),
'description'=> array('inFile'=>false, 'value'=>''),
@@ -19,7 +19,9 @@ class dbSite extends dbJSON
'uriTag'=> array('inFile'=>false, 'value'=>'/tag/'),
'url'=> array('inFile'=>false, 'value'=>''),
'cliMode'=> array('inFile'=>false, 'value'=>true),
- 'emailFrom'=> array('inFile'=>false, 'value'=>'')
+ 'emailFrom'=> array('inFile'=>false, 'value'=>''),
+ 'dateFormat'=> array('inFile'=>false, 'value'=>'F j, Y'),
+ 'timeFormat'=> array('inFile'=>false, 'value'=>'g:i a')
);
function __construct()
@@ -61,9 +63,9 @@ class dbSite extends dbJSON
public function uriFilters($filter='')
{
$filters['admin'] = '/admin/';
- $filters['post'] = $this->db['uriPost'];
- $filters['page'] = $this->db['uriPage'];
- $filters['tag'] = $this->db['uriTag'];
+ $filters['post'] = $this->getField('uriPost');
+ $filters['page'] = $this->getField('uriPage');
+ $filters['tag'] = $this->getField('uriTag');
if(empty($filter)) {
return $filters;
@@ -74,70 +76,83 @@ class dbSite extends dbJSON
public function urlPost()
{
- return $this->url().ltrim($this->db['uriPost'], '/');
+ $filter = $this->getField('uriPost');
+ return $this->url().ltrim($filter, '/');
}
public function urlPage()
{
- return $this->url().ltrim($this->db['uriPage'], '/');
+ $filter = $this->getField('uriPage');
+ return $this->url().ltrim($filter, '/');
}
public function urlTag()
{
- return $this->url().ltrim($this->db['uriTag'], '/');
+ $filter = $this->getField('uriTag');
+ return $this->url().ltrim($filter, '/');
}
// Returns the site title.
public function title()
{
- return $this->db['title'];
+ return $this->getField('title');
}
public function emailFrom()
{
- return $this->db['emailFrom'];
+ return $this->getField('emailFrom');
+ }
+
+ public function dateFormat()
+ {
+ return $this->getField('dateFormat');
+ }
+
+ public function timeFormat()
+ {
+ return $this->getField('timeFormat');
}
// Returns the site slogan.
public function slogan()
{
- return $this->db['slogan'];
+ return $this->getField('slogan');
}
// Returns the site description.
public function description()
{
- return $this->db['description'];
+ return $this->getField('description');
}
// Returns the site theme name.
public function theme()
{
- return $this->db['theme'];
+ return $this->getField('theme');
}
// Returns the admin theme name.
public function adminTheme()
{
- return $this->db['adminTheme'];
+ return $this->getField('adminTheme');
}
// Returns the footer text.
public function footer()
{
- return $this->db['footer'];
+ return $this->getField('footer');
}
// Returns the url site.
public function url()
{
- return $this->db['url'];
+ return $this->getField('url');
}
// Returns TRUE if the cli mode is enabled, otherwise FALSE.
public function cliMode()
{
- return $this->db['cliMode'];
+ return $this->getField('cliMode');
}
// Returns the relative home link
@@ -149,25 +164,25 @@ class dbSite extends dbJSON
// Returns the timezone.
public function timezone()
{
- return $this->db['timezone'];
+ return $this->getField('timezone');
}
// Returns posts per page.
public function postsPerPage()
{
- return $this->db['postsperpage'];
+ return $this->getField('postsperpage');
}
// Returns the current language.
public function language()
{
- return $this->db['language'];
+ return $this->getField('language');
}
// Returns the current locale.
public function locale()
{
- return $this->db['locale'];
+ return $this->getField('locale');
}
// Returns the current language in short format.
@@ -183,7 +198,7 @@ class dbSite extends dbJSON
// Returns the current homepage.
public function homepage()
{
- return $this->db['homepage'];
+ return $this->getField('homepage');
}
// Set the locale.
diff --git a/kernel/helpers/image.class.php b/kernel/helpers/image.class.php
new file mode 100644
index 00000000..1ee2453e
--- /dev/null
+++ b/kernel/helpers/image.class.php
@@ -0,0 +1,232 @@
+image = $this->openImage($fileName);
+
+ // *** Get width and height
+ $this->width = imagesx($this->image);
+ $this->height = imagesy($this->image);
+
+ $this->resizeImage($newWidth, $newHeight, $option);
+ }
+
+ public function saveImage($savePath, $imageQuality="100", $force_jpg=false)
+ {
+ $extension = strtolower(pathinfo($savePath, PATHINFO_EXTENSION));
+
+ // Remove the extension
+ $filename = substr($savePath, 0,strrpos($savePath,'.'));
+
+ $path_complete = $filename.'.'.$extension;
+
+ if($force_jpg)
+ {
+ imagejpeg($this->imageResized, $filename.'.jpg', $imageQuality);
+ }
+ else
+ {
+ switch($extension)
+ {
+ case 'jpg':
+ case 'jpeg':
+ if (imagetypes() & IMG_JPG) {
+ imagejpeg($this->imageResized, $path_complete, $imageQuality);
+ }
+ break;
+
+ case 'gif':
+ if (imagetypes() & IMG_GIF) {
+ imagegif($this->imageResized, $path_complete);
+ }
+ break;
+
+ case 'png':
+ // *** Scale quality from 0-100 to 0-9
+ $scaleQuality = round(($imageQuality/100) * 9);
+
+ // *** Invert quality setting as 0 is best, not 9
+ $invertScaleQuality = 9 - $scaleQuality;
+
+ if (imagetypes() & IMG_PNG) {
+ imagepng($this->imageResized, $path_complete, $invertScaleQuality);
+ }
+ break;
+
+ default:
+ // *** No extension - No save.
+ break;
+ }
+ }
+
+ imagedestroy($this->imageResized);
+ }
+
+ private function openImage($file)
+ {
+ // *** Get extension
+ $extension = strtolower(strrchr($file, '.'));
+
+ switch($extension)
+ {
+ case '.jpg':
+ case '.jpeg':
+ $img = imagecreatefromjpeg($file);
+ break;
+ case '.gif':
+ $img = imagecreatefromgif($file);
+ break;
+ case '.png':
+ $img = imagecreatefrompng($file);
+ break;
+ default:
+ $img = false;
+ break;
+ }
+ return $img;
+ }
+
+ private function resizeImage($newWidth, $newHeight, $option)
+ {
+ // *** Get optimal width and height - based on $option
+ $optionArray = $this->getDimensions($newWidth, $newHeight, $option);
+
+ $optimalWidth = $optionArray['optimalWidth'];
+ $optimalHeight = $optionArray['optimalHeight'];
+
+
+ // *** Resample - create image canvas of x, y size
+ $this->imageResized = imagecreatetruecolor($optimalWidth, $optimalHeight);
+ imagecopyresampled($this->imageResized, $this->image, 0, 0, 0, 0, $optimalWidth, $optimalHeight, $this->width, $this->height);
+
+
+ // *** if option is 'crop', then crop too
+ if ($option == 'crop') {
+ $this->crop($optimalWidth, $optimalHeight, $newWidth, $newHeight);
+ }
+ }
+
+ private function getDimensions($newWidth, $newHeight, $option)
+ {
+
+ if( ($this->width < $newWidth) and ($this->height < $newHeight) )
+ {
+ return array('optimalWidth' => $this->width, 'optimalHeight' => $this->height);
+ }
+
+ switch ($option)
+ {
+ case 'exact':
+ $optimalWidth = $newWidth;
+ $optimalHeight= $newHeight;
+ break;
+ case 'portrait':
+ $optimalWidth = $this->getSizeByFixedHeight($newHeight);
+ $optimalHeight= $newHeight;
+ break;
+ case 'landscape':
+ $optimalWidth = $newWidth;
+ $optimalHeight= $this->getSizeByFixedWidth($newWidth);
+ break;
+ case 'auto':
+ $optionArray = $this->getSizeByAuto($newWidth, $newHeight);
+ $optimalWidth = $optionArray['optimalWidth'];
+ $optimalHeight = $optionArray['optimalHeight'];
+ break;
+ case 'crop':
+ $optionArray = $this->getOptimalCrop($newWidth, $newHeight);
+ $optimalWidth = $optionArray['optimalWidth'];
+ $optimalHeight = $optionArray['optimalHeight'];
+ break;
+ }
+
+ return array('optimalWidth' => $optimalWidth, 'optimalHeight' => $optimalHeight);
+ }
+
+ private function getSizeByFixedHeight($newHeight)
+ {
+ $ratio = $this->width / $this->height;
+ $newWidth = $newHeight * $ratio;
+ return $newWidth;
+ }
+
+ private function getSizeByFixedWidth($newWidth)
+ {
+ $ratio = $this->height / $this->width;
+ $newHeight = $newWidth * $ratio;
+ return $newHeight;
+ }
+
+ private function getSizeByAuto($newWidth, $newHeight)
+ {
+ if ($this->height < $this->width)
+ // *** Image to be resized is wider (landscape)
+ {
+ $optimalWidth = $newWidth;
+ $optimalHeight= $this->getSizeByFixedWidth($newWidth);
+ }
+ elseif ($this->height > $this->width)
+ // *** Image to be resized is taller (portrait)
+ {
+ $optimalWidth = $this->getSizeByFixedHeight($newHeight);
+ $optimalHeight= $newHeight;
+ }
+ else
+ // *** Image to be resizerd is a square
+ {
+ if ($newHeight < $newWidth) {
+ $optimalWidth = $newWidth;
+ $optimalHeight= $this->getSizeByFixedWidth($newWidth);
+ } else if ($newHeight > $newWidth) {
+ $optimalWidth = $this->getSizeByFixedHeight($newHeight);
+ $optimalHeight= $newHeight;
+ } else {
+ // *** Sqaure being resized to a square
+ $optimalWidth = $newWidth;
+ $optimalHeight= $newHeight;
+ }
+ }
+
+ return array('optimalWidth' => $optimalWidth, 'optimalHeight' => $optimalHeight);
+ }
+
+ private function getOptimalCrop($newWidth, $newHeight)
+ {
+
+ $heightRatio = $this->height / $newHeight;
+ $widthRatio = $this->width / $newWidth;
+
+ if ($heightRatio < $widthRatio) {
+ $optimalRatio = $heightRatio;
+ } else {
+ $optimalRatio = $widthRatio;
+ }
+
+ $optimalHeight = $this->height / $optimalRatio;
+ $optimalWidth = $this->width / $optimalRatio;
+
+ return array('optimalWidth' => $optimalWidth, 'optimalHeight' => $optimalHeight);
+ }
+
+ private function crop($optimalWidth, $optimalHeight, $newWidth, $newHeight)
+ {
+ // *** Find center - this will be used for the crop
+ $cropStartX = ( $optimalWidth / 2) - ( $newWidth /2 );
+ $cropStartY = ( $optimalHeight/ 2) - ( $newHeight/2 );
+
+ $crop = $this->imageResized;
+ //imagedestroy($this->imageResized);
+
+ // *** Now crop from center to exact requested size
+ $this->imageResized = imagecreatetruecolor($newWidth , $newHeight);
+ imagecopyresampled($this->imageResized, $crop , 0, 0, $cropStartX, $cropStartY, $newWidth, $newHeight , $newWidth, $newHeight);
+ }
+}
diff --git a/kernel/post.class.php b/kernel/post.class.php
index f2eb18eb..3abed452 100644
--- a/kernel/post.class.php
+++ b/kernel/post.class.php
@@ -101,7 +101,13 @@ class Post extends fileContent
// Returns the post date according to locale settings and format settings.
public function date($format=false)
{
- $date = $this->getField('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);
diff --git a/languages/en_US.json b/languages/en_US.json
index e308c6f4..4334f55c 100644
--- a/languages/en_US.json
+++ b/languages/en_US.json
@@ -204,5 +204,7 @@
"upload-image": "Upload image",
"drag-and-drop-or-click-here": "Drag and drop or click here",
"insert-image": "Insert image",
- "supported-image-file-types": "Supported image file types"
+ "supported-image-file-types": "Supported image file types",
+ "date-format": "Date format",
+ "time-format": "Time format"
}
\ No newline at end of file
diff --git a/plugins/pages/plugin.php b/plugins/pages/plugin.php
index c75636f8..324d5bda 100644
--- a/plugins/pages/plugin.php
+++ b/plugins/pages/plugin.php
@@ -54,24 +54,32 @@ class pluginPages extends Plugin {
$parents = $pagesParents[NO_PARENT_CHAR];
foreach($parents as $parent)
{
- // Print the parent
- $html .= '
';
- $html .= ''.$parent->title().'';
-
- // Check if the parent has children
- if(isset($pagesParents[$parent->key()]))
+ // Check if the parent is published
+ if( $parent->published() )
{
- $children = $pagesParents[$parent->key()];
+ // Print the parent
+ $html .= '