mirror of
https://github.com/typemill/typemill.git
synced 2025-08-06 14:16:46 +02:00
version 1.3.3: Pages and Posts
This commit is contained in:
@@ -77,7 +77,8 @@ class Field
|
||||
/* defines additional data, that are allowed for fields */
|
||||
private $helpers = array(
|
||||
'help',
|
||||
'description'
|
||||
'description',
|
||||
'fieldsize'
|
||||
);
|
||||
|
||||
public function __construct($fieldName, array $fieldConfigs)
|
||||
|
@@ -91,11 +91,13 @@ class Folder
|
||||
return $folderContent;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Transforms array of folder item into an array of item-objects with additional information for each item
|
||||
* vars: multidimensional array with folder- and file-names
|
||||
* returns: array of objects. Each object contains information about an item (file or folder).
|
||||
*/
|
||||
*/
|
||||
|
||||
public static function getFolderContentDetails(array $folderContent, $extended, $baseUrl, $fullSlugWithFolder = NULL, $fullSlugWithoutFolder = NULL, $fullPath = NULL, $keyPath = NULL, $chapter = NULL)
|
||||
{
|
||||
$contentDetails = [];
|
||||
@@ -129,13 +131,14 @@ class Folder
|
||||
|
||||
$item->originalName = $key;
|
||||
$item->elementType = 'folder';
|
||||
$item->contains = self::getFolderContentType($name, $fullPath . DIRECTORY_SEPARATOR . $key . DIRECTORY_SEPARATOR . 'index.yaml');
|
||||
$item->status = $status;
|
||||
$item->fileType = $fileType;
|
||||
$item->order = count($nameParts) > 1 ? array_shift($nameParts) : NULL;
|
||||
$item->name = implode(" ",$nameParts);
|
||||
$item->name = iconv(mb_detect_encoding($item->name, mb_detect_order(), true), "UTF-8", $item->name);
|
||||
$item->slug = implode("-",$nameParts);
|
||||
$item->slug = URLify::filter(iconv(mb_detect_encoding($item->slug, mb_detect_order(), true), "UTF-8", $item->slug));
|
||||
$item->slug = URLify::filter(iconv(mb_detect_encoding($item->slug, mb_detect_order(), true), "UTF-8", $item->slug));
|
||||
$item->path = $fullPath . DIRECTORY_SEPARATOR . $key;
|
||||
$item->pathWithoutType = $fullPath . DIRECTORY_SEPARATOR . $key . DIRECTORY_SEPARATOR . 'index';
|
||||
$item->urlRelWoF = $fullSlugWithoutFolder . '/' . $item->slug;
|
||||
@@ -156,6 +159,12 @@ class Folder
|
||||
$item->hide = ($extended[$item->urlRelWoF]['hide'] === true) ? true : false;
|
||||
}
|
||||
|
||||
# sort posts in descending order
|
||||
if($item->contains == "posts")
|
||||
{
|
||||
rsort($name);
|
||||
}
|
||||
|
||||
$item->folderContent = self::getFolderContentDetails($name, $extended, $baseUrl, $item->urlRel, $item->urlRelWoF, $item->path, $item->keyPath, $item->chapter);
|
||||
}
|
||||
else
|
||||
@@ -192,7 +201,7 @@ class Folder
|
||||
$item->name = implode(" ",$nameParts);
|
||||
$item->name = iconv(mb_detect_encoding($item->name, mb_detect_order(), true), "UTF-8", $item->name);
|
||||
$item->slug = implode("-",$nameParts);
|
||||
$item->slug = URLify::filter(iconv(mb_detect_encoding($item->slug, mb_detect_order(), true), "UTF-8", $item->slug));
|
||||
$item->slug = URLify::filter(iconv(mb_detect_encoding($item->slug, mb_detect_order(), true), "UTF-8", $item->slug));
|
||||
$item->path = $fullPath . DIRECTORY_SEPARATOR . $name;
|
||||
$item->pathWithoutType = $fullPath . DIRECTORY_SEPARATOR . $nameWithoutType;
|
||||
$item->key = $iteration;
|
||||
@@ -221,6 +230,44 @@ class Folder
|
||||
return $contentDetails;
|
||||
}
|
||||
|
||||
public static function getFolderContentType($folder, $yamlpath)
|
||||
{
|
||||
# check if folder is empty or has only index.yaml-file. This is a rare case so make it quick and dirty
|
||||
if(count($folder) == 1)
|
||||
{
|
||||
# check if in folder yaml file contains "posts", then return posts
|
||||
$folderyamlpath = getcwd() . DIRECTORY_SEPARATOR . 'content' . DIRECTORY_SEPARATOR . $yamlpath;
|
||||
|
||||
$fileContent = false;
|
||||
if(file_exists($folderyamlpath))
|
||||
{
|
||||
$fileContent = file_get_contents($folderyamlpath);
|
||||
}
|
||||
|
||||
if($fileContent && strpos($fileContent, 'contains: posts') !== false)
|
||||
{
|
||||
return 'posts';
|
||||
}
|
||||
return 'pages';
|
||||
}
|
||||
else
|
||||
{
|
||||
$file = $folder[0];
|
||||
$nameParts = self::getStringParts($file);
|
||||
$order = count($nameParts) > 1 ? array_shift($nameParts) : NULL;
|
||||
$order = substr($order, 0, 7);
|
||||
|
||||
if(\DateTime::createFromFormat('Ymd', $order) !== FALSE)
|
||||
{
|
||||
return "posts";
|
||||
}
|
||||
else
|
||||
{
|
||||
return "pages";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function getItemForUrl($folderContentDetails, $url, $baseUrl, $result = NULL)
|
||||
{
|
||||
|
||||
|
@@ -48,6 +48,16 @@ class Validation
|
||||
return false;
|
||||
}, 'wrong password');
|
||||
|
||||
Validator::addRule('navigation', function($field, $value, array $params, array $fields)
|
||||
{
|
||||
$format = '/[@#^*()=\[\]{};:"\\|,.<>\/]/';
|
||||
if ( preg_match($format, $value))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}, 'contains special characters');
|
||||
|
||||
Validator::addRule('noSpecialChars', function($field, $value, array $params, array $fields)
|
||||
{
|
||||
$format = '/[!@#$%^&*()_+=\[\]{};\':"\\|,.<>\/?]/';
|
||||
@@ -283,11 +293,12 @@ class Validation
|
||||
public function navigationItem(array $params)
|
||||
{
|
||||
$v = new Validator($params);
|
||||
|
||||
|
||||
$v->rule('required', ['folder_id', 'item_name', 'type', 'url']);
|
||||
$v->rule('regex', 'folder_id', '/^[0-9.]+$/i');
|
||||
$v->rule('noSpecialChars', 'item_name');
|
||||
$v->rule('lengthBetween', 'item_name', 1, 40);
|
||||
# $v->rule('noSpecialChars', 'item_name');
|
||||
$v->rule('navigation', 'item_name');
|
||||
$v->rule('lengthBetween', 'item_name', 1, 60);
|
||||
$v->rule('in', 'type', ['file', 'folder']);
|
||||
|
||||
if($v->validate())
|
||||
@@ -305,7 +316,8 @@ class Validation
|
||||
$v = new Validator($params);
|
||||
|
||||
$v->rule('required', ['item_name', 'type', 'url']);
|
||||
$v->rule('noSpecialChars', 'item_name');
|
||||
# $v->rule('noSpecialChars', 'item_name');
|
||||
$v->rule('navigation', 'item_name');
|
||||
$v->rule('lengthBetween', 'item_name', 1, 40);
|
||||
$v->rule('in', 'type', ['file', 'folder']);
|
||||
|
||||
@@ -397,7 +409,7 @@ class Validation
|
||||
case "text":
|
||||
$v->rule('noHTML', $fieldName);
|
||||
$v->rule('lengthMax', $fieldName, 500);
|
||||
$v->rule('regex', $fieldName, '/^[\pL0-9_ \-\.\?\!\/\:]*$/u');
|
||||
# $v->rule('regex', $fieldName, '/^[\pL0-9_ \-\.\?\!\/\:]*$/u');
|
||||
break;
|
||||
case "textarea":
|
||||
$v->rule('noHTML', $fieldName);
|
||||
|
@@ -2,6 +2,8 @@
|
||||
|
||||
namespace Typemill\Models;
|
||||
|
||||
# this check is not in use anymore (was in use to check and store latest version in user settings on page refresh)
|
||||
|
||||
class VersionCheck
|
||||
{
|
||||
function checkVersion($url)
|
||||
@@ -15,11 +17,13 @@ class VersionCheck
|
||||
|
||||
$context = stream_context_create($opts);
|
||||
|
||||
if(false === ($version = @file_get_contents('http://typemill.net/api/v1/checkversion', false, $context)))
|
||||
if(false === ($version = @file_get_contents('https://typemill.net/api/v1/checkversion', false, $context)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
$version = json_decode($version);
|
||||
die();
|
||||
|
||||
return $version->system->typemill;
|
||||
}
|
||||
}
|
@@ -110,7 +110,7 @@ class Write
|
||||
return false;
|
||||
}
|
||||
|
||||
public function moveElement($item, $folderPath, $index)
|
||||
public function moveElement($item, $folderPath, $index, $date = null)
|
||||
{
|
||||
$filetypes = array('md', 'txt', 'yaml');
|
||||
|
||||
@@ -159,4 +159,35 @@ class Write
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function renamePost($oldPathWithoutType, $newPathWithoutType)
|
||||
{
|
||||
$filetypes = array('md', 'txt', 'yaml');
|
||||
|
||||
$oldPath = $this->basePath . 'content' . $oldPathWithoutType;
|
||||
$newPath = $this->basePath . 'content' . $newPathWithoutType;
|
||||
|
||||
$result = true;
|
||||
|
||||
foreach($filetypes as $filetype)
|
||||
{
|
||||
$oldFilePath = $oldPath . '.' . $filetype;
|
||||
$newFilePath = $newPath . '.' . $filetype;
|
||||
|
||||
#check if file with filetype exists and rename
|
||||
if($oldFilePath != $newFilePath && file_exists($oldFilePath))
|
||||
{
|
||||
if(@rename($oldFilePath, $newFilePath))
|
||||
{
|
||||
$result = $result;
|
||||
}
|
||||
else
|
||||
{
|
||||
$result = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
@@ -115,6 +115,7 @@ class WriteYaml extends Write
|
||||
'description' => $description,
|
||||
'author' => $author,
|
||||
'created' => date("Y-m-d"),
|
||||
'time' => date("H-i-s"),
|
||||
]
|
||||
];
|
||||
|
||||
@@ -162,4 +163,109 @@ class WriteYaml extends Write
|
||||
|
||||
return $meta;
|
||||
}
|
||||
|
||||
|
||||
public function transformPagesToPosts($folder){
|
||||
|
||||
$filetypes = array('md', 'txt', 'yaml');
|
||||
|
||||
foreach($folder->folderContent as $page)
|
||||
{
|
||||
# create old filename without filetype
|
||||
$oldFile = $this->basePath . 'content' . $page->pathWithoutType;
|
||||
|
||||
# set default date
|
||||
$date = date('Y-m-d', time());
|
||||
$time = date('H-i', time());
|
||||
|
||||
$meta = $this->getYaml('content', $page->pathWithoutType . '.yaml');
|
||||
|
||||
if($meta)
|
||||
{
|
||||
# get dates from meta
|
||||
if(isset($meta['meta']['manualdate'])){ $date = $meta['meta']['manualdate']; }
|
||||
elseif(isset($meta['meta']['created'])){ $date = $meta['meta']['created']; }
|
||||
elseif(isset($meta['meta']['modified'])){ $date = $meta['meta']['modified']; }
|
||||
|
||||
# set time
|
||||
if(isset($meta['meta']['time']))
|
||||
{
|
||||
$time = $meta['meta']['time'];
|
||||
}
|
||||
}
|
||||
|
||||
$datetime = $date . '-' . $time;
|
||||
$datetime = implode(explode('-', $datetime));
|
||||
$datetime = substr($datetime,0,12);
|
||||
|
||||
# create new file-name without filetype
|
||||
$newFile = $this->basePath . 'content' . $folder->path . DIRECTORY_SEPARATOR . $datetime . '-' . $page->slug;
|
||||
|
||||
$result = true;
|
||||
|
||||
foreach($filetypes as $filetype)
|
||||
{
|
||||
$oldFilePath = $oldFile . '.' . $filetype;
|
||||
$newFilePath = $newFile . '.' . $filetype;
|
||||
|
||||
#check if file with filetype exists and rename
|
||||
if($oldFilePath != $newFilePath && file_exists($oldFilePath))
|
||||
{
|
||||
if(@rename($oldFilePath, $newFilePath))
|
||||
{
|
||||
$result = $result;
|
||||
}
|
||||
else
|
||||
{
|
||||
$result = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function transformPostsToPages($folder){
|
||||
|
||||
$filetypes = array('md', 'txt', 'yaml');
|
||||
$index = 0;
|
||||
|
||||
foreach($folder->folderContent as $page)
|
||||
{
|
||||
# create old filename without filetype
|
||||
$oldFile = $this->basePath . 'content' . $page->pathWithoutType;
|
||||
|
||||
$order = $index;
|
||||
|
||||
if($index < 10)
|
||||
{
|
||||
$order = '0' . $index;
|
||||
}
|
||||
|
||||
# create new file-name without filetype
|
||||
$newFile = $this->basePath . 'content' . $folder->path . DIRECTORY_SEPARATOR . $order . '-' . $page->slug;
|
||||
|
||||
$result = true;
|
||||
|
||||
foreach($filetypes as $filetype)
|
||||
{
|
||||
$oldFilePath = $oldFile . '.' . $filetype;
|
||||
$newFilePath = $newFile . '.' . $filetype;
|
||||
|
||||
#check if file with filetype exists and rename
|
||||
if($oldFilePath != $newFilePath && file_exists($oldFilePath))
|
||||
{
|
||||
if(@rename($oldFilePath, $newFilePath))
|
||||
{
|
||||
$result = $result;
|
||||
}
|
||||
else
|
||||
{
|
||||
$result = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$index++;
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user