mirror of
https://github.com/typemill/typemill.git
synced 2025-01-17 05:18:19 +01:00
Version 1.4.9-1.5.0: Refactor controller logic
This commit is contained in:
parent
f279afe888
commit
5c4a7c9f6a
5
cache/securitylog.txt
vendored
5
cache/securitylog.txt
vendored
@ -1,5 +0,0 @@
|
||||
127.0.0.1;2021-09-26 12:01:24;wrong captcha http://localhost/typemill/tm/recoverpw
|
||||
127.0.0.1;2021-09-26 12:06:16;wrong captcha http://localhost/typemill/tm/recoverpw
|
||||
127.0.0.1;2021-09-27 23:44:57;wrong captcha http://localhost/typemill/tm/recoverpw
|
||||
127.0.0.1;2021-09-27 23:51:19;wrong captcha http://localhost/typemill/tm/recoverpw
|
||||
127.0.0.1;2021-09-27 23:51:30;wrong captcha http://localhost/typemill/tm/recoverpw
|
BIN
media/live/multilanguage.png
Normal file
BIN
media/live/multilanguage.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 32 KiB |
BIN
media/original/multilanguage.png
Normal file
BIN
media/original/multilanguage.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 32 KiB |
BIN
media/thumbs/multilanguage.png
Normal file
BIN
media/thumbs/multilanguage.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 21 KiB |
@ -1,59 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Typemill\Controllers;
|
||||
|
||||
/* Use the slim-container */
|
||||
use Slim\Http\Request;
|
||||
use Slim\Http\Response;
|
||||
use Slim\Views\Twig;
|
||||
use Psr\Container\ContainerInterface;
|
||||
use Typemill\Events\OnPageReady;
|
||||
|
||||
abstract class Controller
|
||||
{
|
||||
protected $c;
|
||||
|
||||
protected $settings;
|
||||
|
||||
public function __construct(ContainerInterface $c)
|
||||
{
|
||||
$this->c = $c;
|
||||
$this->settings = $this->c->get('settings');
|
||||
|
||||
$this->c->dispatcher->dispatch('onTwigLoaded');
|
||||
}
|
||||
|
||||
# frontend rendering
|
||||
protected function render($response, $route, $data)
|
||||
{
|
||||
# why commented this out??
|
||||
$data = $this->c->dispatcher->dispatch('onPageReady', new OnPageReady($data))->getData();
|
||||
|
||||
if(isset($_SESSION['old']))
|
||||
{
|
||||
unset($_SESSION['old']);
|
||||
}
|
||||
|
||||
$response = $response->withoutHeader('Server');
|
||||
$response = $response->withAddedHeader('X-Powered-By', 'Typemill');
|
||||
|
||||
if(!isset($this->settings['headersoff']) or !$this->settings['headersoff'])
|
||||
{
|
||||
$response = $response->withAddedHeader('X-Content-Type-Options', 'nosniff');
|
||||
$response = $response->withAddedHeader('X-Frame-Options', 'SAMEORIGIN');
|
||||
$response = $response->withAddedHeader('X-XSS-Protection', '1;mode=block');
|
||||
$response = $response->withAddedHeader('Referrer-Policy', 'no-referrer-when-downgrade');
|
||||
if($this->c->request->getUri()->getScheme() == 'https')
|
||||
{
|
||||
$response = $response->withAddedHeader('Strict-Transport-Security', 'max-age=63072000');
|
||||
}
|
||||
}
|
||||
|
||||
return $this->c->view->render($response, $route, $data);
|
||||
}
|
||||
|
||||
protected function render404($response, $data = NULL)
|
||||
{
|
||||
return $this->c->view->render($response->withStatus(404), '/404.twig', $data);
|
||||
}
|
||||
}
|
@ -2,42 +2,22 @@
|
||||
|
||||
namespace Typemill\Controllers;
|
||||
|
||||
use Slim\Http\Request;
|
||||
use Slim\Http\Response;
|
||||
use Psr\Container\ContainerInterface;
|
||||
use Typemill\Models\Validation;
|
||||
use Typemill\Models\Folder;
|
||||
use Typemill\Models\Write;
|
||||
use Typemill\Models\WriteCache;
|
||||
use Typemill\Models\WriteYaml;
|
||||
use Typemill\Models\WriteMeta;
|
||||
use Typemill\Models\WriteYaml;
|
||||
use Typemill\Models\Validation;
|
||||
|
||||
abstract class ContentController
|
||||
{
|
||||
# holds the pimple container
|
||||
protected $c;
|
||||
|
||||
class ControllerAuthor extends ControllerShared
|
||||
{
|
||||
# holds the params from request
|
||||
protected $params;
|
||||
|
||||
# holds the slim-uri-object
|
||||
# holds the slim-uri-object from request
|
||||
protected $uri;
|
||||
|
||||
# holds the errors to output in frontend
|
||||
protected $errors = false;
|
||||
|
||||
# holds a write object to write files
|
||||
protected $write;
|
||||
|
||||
# holds the structure of content folder as a serialized array of objects
|
||||
protected $structure;
|
||||
|
||||
# holds the name of the structure-file with drafts for author environment
|
||||
protected $structureDraftName;
|
||||
|
||||
# holds the name of the structure-file without drafts for live site
|
||||
protected $structureLiveName;
|
||||
|
||||
# holds informations about the homepage
|
||||
protected $homepage;
|
||||
|
||||
@ -56,72 +36,33 @@ abstract class ContentController
|
||||
# holds the ownership (my content or not my content)
|
||||
protected $mycontent = false;
|
||||
|
||||
public function __construct(ContainerInterface $c)
|
||||
{
|
||||
$this->c = $c;
|
||||
$this->settings = $this->c->get('settings');
|
||||
$this->structureLiveName = 'structure.txt';
|
||||
$this->structureDraftName = 'structure-draft.txt';
|
||||
|
||||
$this->c->dispatcher->dispatch('onTwigLoaded');
|
||||
}
|
||||
|
||||
# admin ui rendering
|
||||
protected function render($response, $route, $data)
|
||||
{
|
||||
if(isset($_SESSION['old']))
|
||||
{
|
||||
unset($_SESSION['old']);
|
||||
}
|
||||
|
||||
$response = $response->withoutHeader('Server');
|
||||
$response = $response->withAddedHeader('X-Powered-By', 'Typemill');
|
||||
|
||||
if(!isset($this->settings['headersoff']) or !$this->settings['headersoff'])
|
||||
{
|
||||
$response = $response->withAddedHeader('X-Content-Type-Options', 'nosniff');
|
||||
$response = $response->withAddedHeader('X-Frame-Options', 'SAMEORIGIN');
|
||||
$response = $response->withAddedHeader('X-XSS-Protection', '1;mode=block');
|
||||
$response = $response->withAddedHeader('Referrer-Policy', 'no-referrer-when-downgrade');
|
||||
if($this->c->request->getUri()->getScheme() == 'https')
|
||||
{
|
||||
$response = $response->withAddedHeader('Strict-Transport-Security', 'max-age=63072000');
|
||||
}
|
||||
}
|
||||
|
||||
return $this->c->view->render($response, $route, $data);
|
||||
}
|
||||
|
||||
protected function render404($response, $data = NULL)
|
||||
{
|
||||
return $this->c->view->render($response->withStatus(404), '/404.twig', $data);
|
||||
}
|
||||
|
||||
protected function renderIntern404($response, $data = NULL)
|
||||
{
|
||||
return $this->c->view->render($response->withStatus(404), '/intern404.twig', $data);
|
||||
}
|
||||
|
||||
# author
|
||||
protected function getValidator()
|
||||
{
|
||||
return new Validation();
|
||||
}
|
||||
|
||||
# author
|
||||
protected function validateEditorInput()
|
||||
{
|
||||
$validate = new Validation();
|
||||
$vResult = $validate->editorInput($this->params);
|
||||
$validate = new Validation();
|
||||
$vResult = $validate->editorInput($this->params);
|
||||
|
||||
if(is_array($vResult))
|
||||
{
|
||||
$message = reset($vResult);
|
||||
$this->errors = ['errors' => $vResult];
|
||||
if(isset($message[0])){ $this->errors['errors']['message'] = $message[0]; }
|
||||
$message = reset($vResult);
|
||||
$this->errors = ['errors' => $vResult];
|
||||
|
||||
if(isset($message[0])){
|
||||
$this->errors['errors']['message'] = $message[0];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
# author
|
||||
protected function validateBlockInput()
|
||||
{
|
||||
$validate = new Validation();
|
||||
@ -131,12 +72,18 @@ abstract class ContentController
|
||||
{
|
||||
$message = reset($vResult);
|
||||
$this->errors = ['errors' => $vResult];
|
||||
if(isset($message[0])){ $this->errors['errors']['message'] = $message[0]; }
|
||||
|
||||
if(isset($message[0]))
|
||||
{
|
||||
$this->errors['errors']['message'] = $message[0];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
# author
|
||||
protected function validateNavigationSort()
|
||||
{
|
||||
$validate = new Validation();
|
||||
@ -146,12 +93,17 @@ abstract class ContentController
|
||||
{
|
||||
$message = reset($vResult);
|
||||
$this->errors = ['errors' => $vResult];
|
||||
if(isset($message[0])){ $this->errors['errors']['message'] = $message[0]; }
|
||||
|
||||
if(isset($message[0])){
|
||||
$this->errors['errors']['message'] = $message[0];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
# author
|
||||
protected function validateNaviItem()
|
||||
{
|
||||
$validate = new Validation();
|
||||
@ -161,12 +113,18 @@ abstract class ContentController
|
||||
{
|
||||
$message = reset($vResult);
|
||||
$this->errors = ['errors' => $vResult];
|
||||
if(isset($message[0])){ $this->errors['errors']['message'] = $message[0]; }
|
||||
|
||||
if(isset($message[0]))
|
||||
{
|
||||
$this->errors['errors']['message'] = $message[0];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
# author
|
||||
protected function validateBaseNaviItem()
|
||||
{
|
||||
$validate = new Validation();
|
||||
@ -176,110 +134,18 @@ abstract class ContentController
|
||||
{
|
||||
$message = reset($vResult);
|
||||
$this->errors = ['errors' => $vResult];
|
||||
if(isset($message[0])){ $this->errors['errors']['message'] = $message[0]; }
|
||||
|
||||
if(isset($message[0]))
|
||||
{
|
||||
$this->errors['errors']['message'] = $message[0];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function setStructure($draft = false, $cache = true)
|
||||
{
|
||||
# set initial structure to false
|
||||
$structure = false;
|
||||
|
||||
# name of structure-file for draft or live
|
||||
$filename = $draft ? $this->structureDraftName : $this->structureLiveName;
|
||||
|
||||
# set variables and objects
|
||||
$this->write = new writeCache();
|
||||
|
||||
# check, if cached structure is still valid
|
||||
if($cache && $this->write->validate('cache', 'lastCache.txt', 600))
|
||||
{
|
||||
# get the cached structure
|
||||
$structure = $this->write->getCache('cache', $filename);
|
||||
}
|
||||
|
||||
# if no structure was found or cache is deactivated
|
||||
if(!$structure)
|
||||
{
|
||||
# scan the content of the folder
|
||||
$structure = Folder::scanFolder($this->settings['rootPath'] . $this->settings['contentFolder'], $draft);
|
||||
|
||||
# if there is content, then get the content details
|
||||
if(count($structure) > 0)
|
||||
{
|
||||
# get the extended structure files with changes like navigation title or hidden pages
|
||||
$yaml = new writeYaml();
|
||||
$extended = $yaml->getYaml('cache', 'structure-extended.yaml');
|
||||
|
||||
# create an array of object with the whole content of the folder and changes from extended file
|
||||
$structure = Folder::getFolderContentDetails($structure, $extended, $this->uri->getBaseUrl(), $this->uri->getBasePath());
|
||||
}
|
||||
|
||||
# cache navigation
|
||||
$this->write->updateCache('cache', $filename, 'lastCache.txt', $structure);
|
||||
}
|
||||
|
||||
$this->structure = $structure;
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function renameExtended($item, $newFolder)
|
||||
{
|
||||
# get the extended structure files with changes like navigation title or hidden pages
|
||||
$yaml = new writeYaml();
|
||||
$extended = $yaml->getYaml('cache', 'structure-extended.yaml');
|
||||
|
||||
if(isset($extended[$item->urlRelWoF]))
|
||||
{
|
||||
$newUrl = $newFolder->urlRelWoF . '/' . $item->slug;
|
||||
|
||||
$entry = $extended[$item->urlRelWoF];
|
||||
|
||||
unset($extended[$item->urlRelWoF]);
|
||||
|
||||
$extended[$newUrl] = $entry;
|
||||
$yaml->updateYaml('cache', 'structure-extended.yaml', $extended);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function deleteFromExtended()
|
||||
{
|
||||
# get the extended structure files with changes like navigation title or hidden pages
|
||||
$yaml = new writeYaml();
|
||||
$extended = $yaml->getYaml('cache', 'structure-extended.yaml');
|
||||
|
||||
if($this->item->elementType == "file" && isset($extended[$this->item->urlRelWoF]))
|
||||
{
|
||||
unset($extended[$this->item->urlRelWoF]);
|
||||
$yaml->updateYaml('cache', 'structure-extended.yaml', $extended);
|
||||
}
|
||||
|
||||
if($this->item->elementType == "folder")
|
||||
{
|
||||
$changed = false;
|
||||
|
||||
# delete all entries with that folder url
|
||||
foreach($extended as $url => $entries)
|
||||
{
|
||||
if( strpos($url, $this->item->urlRelWoF) !== false )
|
||||
{
|
||||
$changed = true;
|
||||
unset($extended[$url]);
|
||||
}
|
||||
}
|
||||
|
||||
if($changed)
|
||||
{
|
||||
$yaml->updateYaml('cache', 'structure-extended.yaml', $extended);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# this is only set by content backend controller
|
||||
# only backoffice
|
||||
protected function setHomepage($args)
|
||||
{
|
||||
$contentFolder = Folder::scanFolderFlat($this->settings['rootPath'] . $this->settings['contentFolder']);
|
||||
@ -308,13 +174,14 @@ abstract class ContentController
|
||||
$this->homepage = ['status' => $status, 'active' => $active];
|
||||
}
|
||||
|
||||
# only backoffice
|
||||
protected function setItem()
|
||||
{
|
||||
# home is only set by backend controller, not by api calls
|
||||
$home = isset($this->homepage['active']) ? $this->homepage['active'] : false;
|
||||
|
||||
# search for the url in the structure
|
||||
$item = Folder::getItemForUrl($this->structure, $this->params['url'], $this->uri->getBaseUrl(), NULL, $home);
|
||||
$item = Folder::getItemForUrl($this->structureDraft, $this->params['url'], $this->uri->getBaseUrl(), NULL, $home);
|
||||
|
||||
if($item)
|
||||
{
|
||||
@ -327,12 +194,14 @@ abstract class ContentController
|
||||
return false;
|
||||
}
|
||||
|
||||
# only backoffice
|
||||
# determine if you want to write to published file (md) or to draft (txt)
|
||||
protected function setItemPath($fileType)
|
||||
{
|
||||
$this->path = $this->item->pathWithoutType . '.' . $fileType;
|
||||
}
|
||||
|
||||
|
||||
# only backoffice
|
||||
protected function setPublishStatus()
|
||||
{
|
||||
$this->item->published = false;
|
||||
@ -360,7 +229,56 @@ abstract class ContentController
|
||||
$this->item->fileType = "txt";
|
||||
}
|
||||
}
|
||||
|
||||
# only backoffice
|
||||
protected function setContent()
|
||||
{
|
||||
# if the file exists
|
||||
if($this->item->published OR $this->item->drafted)
|
||||
{
|
||||
$content = $this->writeCache->getFile($this->settings['contentFolder'], $this->path);
|
||||
if($this->item->fileType == 'txt')
|
||||
{
|
||||
# decode the json-draft to an array
|
||||
$content = json_decode($content);
|
||||
}
|
||||
}
|
||||
elseif($this->item->elementType == "folder")
|
||||
{
|
||||
$content = '';
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->errors = ['errors' => ['message' => 'requested file not found']];
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->content = $content;
|
||||
return true;
|
||||
}
|
||||
|
||||
# only backoffice
|
||||
protected function checkContentOwnership()
|
||||
{
|
||||
# get page meta
|
||||
$writeMeta = new writeMeta();
|
||||
$pagemeta = $writeMeta->getPageMeta($this->settings, $this->item);
|
||||
|
||||
# check ownership
|
||||
if(isset($pagemeta['meta']['owner']) && $pagemeta['meta']['owner'] && $pagemeta['meta']['owner'] !== '' )
|
||||
{
|
||||
$allowedusers = array_map('trim', explode(",", $pagemeta['meta']['owner']));
|
||||
if(isset($_SESSION['user']) && in_array($_SESSION['user'], $allowedusers))
|
||||
{
|
||||
$this->mycontent = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
# only backoffice
|
||||
protected function deleteContentFiles($fileTypes, $folder = false)
|
||||
{
|
||||
$basePath = $this->settings['rootPath'] . $this->settings['contentFolder'];
|
||||
@ -381,6 +299,7 @@ abstract class ContentController
|
||||
return true;
|
||||
}
|
||||
|
||||
# only backoffice
|
||||
protected function deleteContentFolder()
|
||||
{
|
||||
$basePath = $this->settings['rootPath'] . $this->settings['contentFolder'];
|
||||
@ -418,50 +337,4 @@ abstract class ContentController
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function setContent()
|
||||
{
|
||||
# if the file exists
|
||||
if($this->item->published OR $this->item->drafted)
|
||||
{
|
||||
$content = $this->write->getFile($this->settings['contentFolder'], $this->path);
|
||||
if($this->item->fileType == 'txt')
|
||||
{
|
||||
# decode the json-draft to an array
|
||||
$content = json_decode($content);
|
||||
}
|
||||
}
|
||||
elseif($this->item->elementType == "folder")
|
||||
{
|
||||
$content = '';
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->errors = ['errors' => ['message' => 'requested file not found']];
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->content = $content;
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function checkContentOwnership()
|
||||
{
|
||||
# get page meta
|
||||
$writeMeta = new writeMeta();
|
||||
$pagemeta = $writeMeta->getPageMeta($this->settings, $this->item);
|
||||
|
||||
# check ownership
|
||||
if(isset($pagemeta['meta']['owner']) && $pagemeta['meta']['owner'] && $pagemeta['meta']['owner'] !== '' )
|
||||
{
|
||||
$allowedusers = array_map('trim', explode(",", $pagemeta['meta']['owner']));
|
||||
if(isset($_SESSION['user']) && in_array($_SESSION['user'], $allowedusers))
|
||||
{
|
||||
$this->mycontent = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
@ -5,19 +5,15 @@ namespace Typemill\Controllers;
|
||||
use Slim\Http\Request;
|
||||
use Slim\Http\Response;
|
||||
use Typemill\Models\Folder;
|
||||
use Typemill\Models\Write;
|
||||
use Typemill\Models\WriteYaml;
|
||||
use Typemill\Models\WriteMeta;
|
||||
use Typemill\Models\WriteCache;
|
||||
use Typemill\Extensions\ParsedownExtension;
|
||||
use Typemill\Events\OnPagePublished;
|
||||
use Typemill\Events\OnPageUnpublished;
|
||||
use Typemill\Events\OnPageDeleted;
|
||||
use Typemill\Events\OnPageSorted;
|
||||
use \URLify;
|
||||
|
||||
|
||||
class ArticleApiController extends ContentController
|
||||
class ControllerAuthorArticleApi extends ControllerAuthor
|
||||
{
|
||||
public function publishArticle(Request $request, Response $response, $args)
|
||||
{
|
||||
@ -38,7 +34,7 @@ class ArticleApiController extends ContentController
|
||||
}
|
||||
|
||||
# set structure
|
||||
if(!$this->setStructure($draft = true)){ return $response->withJson($this->errors, 404); }
|
||||
if(!$this->setStructureDraft()){ return $response->withJson($this->errors, 404); }
|
||||
|
||||
# set information for homepage
|
||||
$this->setHomepage($args = false);
|
||||
@ -87,16 +83,22 @@ class ArticleApiController extends ContentController
|
||||
$this->setItemPath('md');
|
||||
|
||||
# update the file
|
||||
if($this->write->writeFile($this->settings['contentFolder'], $this->path, $this->content))
|
||||
if($this->writeCache->writeFile($this->settings['contentFolder'], $this->path, $this->content))
|
||||
{
|
||||
# update the file
|
||||
$delete = $this->deleteContentFiles(['txt']);
|
||||
|
||||
# update the internal structure
|
||||
$this->setStructure($draft = true, $cache = false);
|
||||
$this->setFreshStructureDraft();
|
||||
|
||||
# update the public structure
|
||||
$this->setStructure($draft = false, $cache = false);
|
||||
$this->setFreshStructureLive();
|
||||
|
||||
# update the navigation
|
||||
$this->setFreshNavigation();
|
||||
|
||||
# update the sitemap
|
||||
$this->updateSitemap();
|
||||
|
||||
# complete the page meta if title or description not set
|
||||
$writeMeta = new WriteMeta();
|
||||
@ -127,7 +129,7 @@ class ArticleApiController extends ContentController
|
||||
}
|
||||
|
||||
# set structure
|
||||
if(!$this->setStructure($draft = true)){ return $response->withJson($this->errors, 404); }
|
||||
if(!$this->setStructureDraft()){ return $response->withJson($this->errors, 404); }
|
||||
|
||||
# set information for homepage
|
||||
$this->setHomepage($args = false);
|
||||
@ -151,7 +153,7 @@ class ArticleApiController extends ContentController
|
||||
# check if draft exists, if not, create one.
|
||||
if(!$this->item->drafted)
|
||||
{
|
||||
# set path for the file (or folder)
|
||||
# set path for the live file (or folder)
|
||||
$this->setItemPath('md');
|
||||
|
||||
# set content of markdown-file
|
||||
@ -166,11 +168,11 @@ class ArticleApiController extends ContentController
|
||||
# encode the content into json
|
||||
$contentJson = json_encode($contentArray);
|
||||
|
||||
# set path for the file (or folder)
|
||||
# set path for the draft file (or folder)
|
||||
$this->setItemPath('txt');
|
||||
|
||||
/* update the file */
|
||||
if(!$this->write->writeFile($this->settings['contentFolder'], $this->path, $contentJson))
|
||||
# update the file
|
||||
if(!$this->writeCache->writeFile($this->settings['contentFolder'], $this->path, $contentJson))
|
||||
{
|
||||
return $response->withJson(['errors' => ['message' => 'Could not create a draft of the page. Please check if the folder is writable']], 404);
|
||||
}
|
||||
@ -189,16 +191,22 @@ class ArticleApiController extends ContentController
|
||||
}
|
||||
}
|
||||
|
||||
# update the file
|
||||
# delete the live file
|
||||
$delete = $this->deleteContentFiles(['md']);
|
||||
|
||||
if($delete)
|
||||
{
|
||||
# update the internal structure
|
||||
$this->setStructure($draft = true, $cache = false);
|
||||
$this->setFreshStructureDraft();
|
||||
|
||||
# update the live structure
|
||||
$this->setStructure($draft = false, $cache = false);
|
||||
$this->setFreshStructureLive();
|
||||
|
||||
# update the navigation
|
||||
$this->setFreshNavigation();
|
||||
|
||||
# update the sitemap
|
||||
$this->updateSitemap();
|
||||
|
||||
# dispatch event
|
||||
$this->c->dispatcher->dispatch('onPageUnpublished', new OnPageUnpublished($this->item));
|
||||
@ -224,7 +232,7 @@ class ArticleApiController extends ContentController
|
||||
}
|
||||
|
||||
# set structure
|
||||
if(!$this->setStructure($draft = true)){ return $response->withJson($this->errors, 404); }
|
||||
if(!$this->setStructureDraft()){ return $response->withJson($this->errors, 404); }
|
||||
|
||||
# set information for homepage
|
||||
$this->setHomepage($args = false);
|
||||
@ -242,9 +250,6 @@ class ArticleApiController extends ContentController
|
||||
}
|
||||
}
|
||||
|
||||
# remove the unpublished changes
|
||||
$delete = $this->deleteContentFiles(['txt']);
|
||||
|
||||
# set redirect url to edit page
|
||||
$url = $this->uri->getBaseUrl() . '/tm/content/' . $this->settings['editor'];
|
||||
if(isset($this->item->urlRelWoF) && $this->item->urlRelWoF != '/' )
|
||||
@ -258,13 +263,13 @@ class ArticleApiController extends ContentController
|
||||
if($delete)
|
||||
{
|
||||
# update the backend structure
|
||||
$this->setStructure($draft = true, $cache = false);
|
||||
$this->setFreshStructureDraft();
|
||||
|
||||
return $response->withJson(['data' => $this->structure, 'errors' => false, 'url' => $url], 200);
|
||||
return $response->withJson(['data' => $this->structureDraft, 'errors' => false, 'url' => $url], 200);
|
||||
}
|
||||
else
|
||||
{
|
||||
return $response->withJson(['data' => $this->structure, 'errors' => $this->errors], 404);
|
||||
return $response->withJson(['data' => $this->structureDraft, 'errors' => $this->errors], 404);
|
||||
}
|
||||
}
|
||||
|
||||
@ -284,7 +289,7 @@ class ArticleApiController extends ContentController
|
||||
$url = $this->uri->getBaseUrl() . '/tm/content/' . $this->settings['editor'];
|
||||
|
||||
# set structure
|
||||
if(!$this->setStructure($draft = true)){ return $response->withJson($this->errors, 404); }
|
||||
if(!$this->setStructureDraft()){ return $response->withJson($this->errors, 404); }
|
||||
|
||||
# set information for homepage
|
||||
$this->setHomepage($args = false);
|
||||
@ -317,7 +322,7 @@ class ArticleApiController extends ContentController
|
||||
if(count($this->item->keyPathArray) > 1)
|
||||
{
|
||||
# get the parent item
|
||||
$parentItem = Folder::getParentItem($this->structure, $this->item->keyPathArray);
|
||||
$parentItem = Folder::getParentItem($this->structureDraft, $this->item->keyPathArray);
|
||||
|
||||
if($parentItem)
|
||||
{
|
||||
@ -327,18 +332,24 @@ class ArticleApiController extends ContentController
|
||||
}
|
||||
|
||||
# update the live structure
|
||||
$this->setStructure($draft = false, $cache = false);
|
||||
$this->setFreshStructureDraft();
|
||||
|
||||
# update the backend structure
|
||||
$this->setStructure($draft = true, $cache = false);
|
||||
$this->setFreshStructureLive();
|
||||
|
||||
# check if page is in extended structure and delete it
|
||||
$this->deleteFromExtended();
|
||||
|
||||
# update the navigation
|
||||
$this->setFreshNavigation();
|
||||
|
||||
# update the sitemap
|
||||
$this->updateSitemap();
|
||||
|
||||
# dispatch event
|
||||
$this->c->dispatcher->dispatch('onPageDeleted', new OnPageDeleted($this->item));
|
||||
|
||||
return $response->withJson(array('data' => $this->structure, 'errors' => false, 'url' => $url), 200);
|
||||
return $response->withJson(array('data' => $this->structureDraft, 'errors' => false, 'url' => $url), 200);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -362,7 +373,7 @@ class ArticleApiController extends ContentController
|
||||
if(!$this->validateEditorInput()){ return $response->withJson($this->errors,422); }
|
||||
|
||||
# set structure
|
||||
if(!$this->setStructure($draft = true)){ return $response->withJson($this->errors, 404); }
|
||||
if(!$this->setStructureDraft()){ return $response->withJson($this->errors, 404); }
|
||||
|
||||
# set information for homepage
|
||||
$this->setHomepage($args = false);
|
||||
@ -380,7 +391,7 @@ class ArticleApiController extends ContentController
|
||||
}
|
||||
}
|
||||
|
||||
# set path for the file (or folder)
|
||||
# set draft path for the file (or folder)
|
||||
$this->setItemPath('txt');
|
||||
|
||||
# merge title with content for complete markdown document
|
||||
@ -395,11 +406,11 @@ class ArticleApiController extends ContentController
|
||||
# encode the content into json
|
||||
$contentJson = json_encode($contentArray);
|
||||
|
||||
/* update the file */
|
||||
if($this->write->writeFile($this->settings['contentFolder'], $this->path, $contentJson))
|
||||
# update the file
|
||||
if($this->writeCache->writeFile($this->settings['contentFolder'], $this->path, $contentJson))
|
||||
{
|
||||
# update the internal structure
|
||||
$this->setStructure($draft = true, $cache = false);
|
||||
# update the internal structure to show that this page has drafted changes now
|
||||
$this->setFreshStructureDraft();
|
||||
|
||||
return $response->withJson(['success'], 200);
|
||||
}
|
||||
@ -423,14 +434,14 @@ class ArticleApiController extends ContentController
|
||||
return $response->withJson(array('data' => false, 'errors' => 'You are not allowed to update content.'), 403);
|
||||
}
|
||||
|
||||
# validate input
|
||||
# validate input 1: check if valid characters
|
||||
if(!preg_match("/^[a-z0-9\-]*$/", $this->params['slug']))
|
||||
{
|
||||
return $response->withJson(['errors' => ['message' => 'the slug contains invalid characters.' ]],422);
|
||||
}
|
||||
|
||||
# set structure
|
||||
if(!$this->setStructure($draft = true)){ return $response->withJson($this->errors, 404); }
|
||||
if(!$this->setStructureDraft()){ return $response->withJson($this->errors, 404); }
|
||||
|
||||
# set information for homepage
|
||||
$this->setHomepage($args = false);
|
||||
@ -438,7 +449,7 @@ class ArticleApiController extends ContentController
|
||||
# set item
|
||||
if(!$this->setItem()){ return $response->withJson($this->errors, 404); }
|
||||
|
||||
# validate input part 2
|
||||
# validate input part 2: check if slug has changed or is empty
|
||||
if($this->params['slug'] == $this->item->slug OR $this->params['slug'] == '')
|
||||
{
|
||||
return $response->withJson(['errors' => ['message' => 'the slug is empty or the same as the old one.' ]],422);
|
||||
@ -460,19 +471,54 @@ class ArticleApiController extends ContentController
|
||||
# create the new file name with the updated slug
|
||||
$newPathWithoutType = $pathWithoutFile . $this->item->order . '-' . $this->params['slug'];
|
||||
|
||||
# rename the file
|
||||
$write = new WriteCache();
|
||||
$write->renamePost($this->item->pathWithoutType, $newPathWithoutType);
|
||||
|
||||
# delete the cache
|
||||
$error = $write->deleteCacheFiles($dir);
|
||||
if($error)
|
||||
# validate input part 3: check if name is taken already
|
||||
$parentKey = $this->item->keyPathArray;
|
||||
array_pop($parentKey);
|
||||
if(!empty($parentKey))
|
||||
{
|
||||
return $response->withJson(['errors' => $error], 500);
|
||||
$parentFolder = Folder::getItemWithKeyPath($this->structureDraft, $parentKey);
|
||||
|
||||
foreach($parentFolder->folderContent as $item)
|
||||
{
|
||||
if($item->slug == $this->params['slug'])
|
||||
{
|
||||
return $response->withJson(['errors' => ['message' => 'There is already a page with that slug' ]],422);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach($this->structureDraft as $baseItem)
|
||||
{
|
||||
if($baseItem->slug == $this->params['slug'])
|
||||
{
|
||||
return $response->withJson(['errors' => ['message' => 'There is already a page with that slug' ]],422);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# recreates the cache for structure, structure-extended and navigation
|
||||
$write->getFreshStructure($pathToContent, $this->uri);
|
||||
# rename the file
|
||||
if($this->item->elementType == 'file')
|
||||
{
|
||||
$this->writeCache->renamePost($this->item->pathWithoutType, $newPathWithoutType);
|
||||
}
|
||||
elseif($this->item->elementType == 'folder')
|
||||
{
|
||||
$this->writeCache->renameFile('content', $this->item->path, $newPathWithoutType);
|
||||
}
|
||||
|
||||
# delete the cache
|
||||
$error = $this->writeCache->deleteCacheFiles($dir);
|
||||
if($error)
|
||||
{
|
||||
return $response->withJson(['errors' => $errors], 500);
|
||||
}
|
||||
|
||||
# recreates the cache for structure, structure-extended, navigation, sitemap
|
||||
$this->setFreshStructureDraft();
|
||||
$this->setFreshStructureLive();
|
||||
$this->setFreshNavigation();
|
||||
$this->updateSitemap();
|
||||
|
||||
$newUrlRel = str_replace($this->item->slug, $this->params['slug'], $this->item->urlRelWoF);
|
||||
|
||||
@ -497,10 +543,10 @@ class ArticleApiController extends ContentController
|
||||
$url = false;
|
||||
|
||||
# set structure
|
||||
if(!$this->setStructure($draft = true)){ return $response->withJson(array('data' => false, 'errors' => $this->errors, 'url' => $url), 404); }
|
||||
if(!$this->setStructureDraft()){ return $response->withJson(array('data' => false, 'errors' => $this->errors, 'url' => $url), 404); }
|
||||
|
||||
# validate input
|
||||
if(!$this->validateNavigationSort()){ return $response->withJson(array('data' => $this->structure, 'errors' => 'Data not valid. Please refresh the page and try again.', 'url' => $url), 422); }
|
||||
if(!$this->validateNavigationSort()){ return $response->withJson(array('data' => $this->structureDraft, 'errors' => 'Data not valid. Please refresh the page and try again.', 'url' => $url), 422); }
|
||||
|
||||
# get the ids (key path) for item, old folder and new folder
|
||||
$itemKeyPath = explode('.', $this->params['item_id']);
|
||||
@ -508,9 +554,9 @@ class ArticleApiController extends ContentController
|
||||
$parentKeyTo = explode('.', $this->params['parent_id_to']);
|
||||
|
||||
# get the item from structure
|
||||
$item = Folder::getItemWithKeyPath($this->structure, $itemKeyPath);
|
||||
$item = Folder::getItemWithKeyPath($this->structureDraft, $itemKeyPath);
|
||||
|
||||
if(!$item){ return $response->withJson(array('data' => $this->structure, 'errors' => 'We could not find this page. Please refresh and try again.', 'url' => $url), 404); }
|
||||
if(!$item){ return $response->withJson(array('data' => $this->structureDraft, 'errors' => 'We could not find this page. Please refresh and try again.', 'url' => $url), 404); }
|
||||
|
||||
# needed for acl check
|
||||
$this->item = $item;
|
||||
@ -521,7 +567,7 @@ class ArticleApiController extends ContentController
|
||||
# check ownership. This code should nearly never run, because there is no button/interface to trigger it.
|
||||
if(!$this->checkContentOwnership())
|
||||
{
|
||||
return $response->withJson(array('data' => $this->structure, 'errors' => 'You are not allowed to move that content.'), 403);
|
||||
return $response->withJson(array('data' => $this->structureDraft, 'errors' => 'You are not allowed to move that content.'), 403);
|
||||
}
|
||||
}
|
||||
|
||||
@ -531,12 +577,12 @@ class ArticleApiController extends ContentController
|
||||
# create empty and default values so that the logic below still works
|
||||
$newFolder = new \stdClass();
|
||||
$newFolder->path = '';
|
||||
$folderContent = $this->structure;
|
||||
$folderContent = $this->structureDraft;
|
||||
}
|
||||
else
|
||||
{
|
||||
# get the target folder from structure
|
||||
$newFolder = Folder::getItemWithKeyPath($this->structure, $parentKeyTo);
|
||||
$newFolder = Folder::getItemWithKeyPath($this->structureDraft, $parentKeyTo);
|
||||
|
||||
# get the content of the target folder
|
||||
$folderContent = $newFolder->folderContent;
|
||||
@ -570,43 +616,42 @@ class ArticleApiController extends ContentController
|
||||
# initialize index
|
||||
$index = 0;
|
||||
|
||||
# initialise write object
|
||||
$write = new Write();
|
||||
|
||||
# iterate through the whole content of the new folder to rename the files
|
||||
$writeError = false;
|
||||
foreach($folderContent as $folderItem)
|
||||
{
|
||||
if(!$write->moveElement($folderItem, $newFolder->path, $index))
|
||||
if(!$this->writeCache->moveElement($folderItem, $newFolder->path, $index))
|
||||
{
|
||||
$writeError = true;
|
||||
}
|
||||
$index++;
|
||||
}
|
||||
if($writeError){ return $response->withJson(array('data' => $this->structure, 'errors' => ['message' => 'Something went wrong. Please refresh the page and check, if all folders and files are writable.'], 'url' => $url), 404); }
|
||||
if($writeError){ return $response->withJson(array('data' => $this->structureDraft, 'errors' => ['message' => 'Something went wrong. Please refresh the page and check, if all folders and files are writable.'], 'url' => $url), 404); }
|
||||
|
||||
# update the structure for editor
|
||||
$this->setStructure($draft = true, $cache = false);
|
||||
$this->setFreshStructureDraft();
|
||||
|
||||
# get item for url and set it active again
|
||||
if(isset($this->params['url']))
|
||||
{
|
||||
$activeItem = Folder::getItemForUrl($this->structure, $this->params['url'], $this->uri->getBaseUrl());
|
||||
$activeItem = Folder::getItemForUrl($this->structureDraft, $this->params['url'], $this->uri->getBaseUrl());
|
||||
}
|
||||
|
||||
# keep the internal structure for response
|
||||
$internalStructure = $this->structure;
|
||||
|
||||
|
||||
# update the structure for website
|
||||
$this->setStructure($draft = false, $cache = false);
|
||||
$this->setFreshStructureLive();
|
||||
|
||||
# update the navigation
|
||||
$this->setFreshNavigation();
|
||||
|
||||
# update the sitemap
|
||||
$this->updateSitemap();
|
||||
|
||||
# dispatch event
|
||||
$this->c->dispatcher->dispatch('onPageSorted', new OnPageSorted($this->params));
|
||||
|
||||
return $response->withJson(array('data' => $internalStructure, 'errors' => false, 'url' => $url));
|
||||
return $response->withJson(array('data' => $this->structureDraft, 'errors' => false, 'url' => $url));
|
||||
}
|
||||
|
||||
|
||||
public function createPost(Request $request, Response $response, $args)
|
||||
{
|
||||
# get params from call
|
||||
@ -623,41 +668,41 @@ class ArticleApiController extends ContentController
|
||||
$url = false;
|
||||
|
||||
# set structure
|
||||
if(!$this->setStructure($draft = true)){ return $response->withJson(array('data' => false, 'errors' => $this->errors, 'url' => $url), 404); }
|
||||
|
||||
if(!$this->setStructureDraft()){ return $response->withJson(array('data' => false, 'errors' => $this->errors, 'url' => $url), 404); }
|
||||
|
||||
# validate input
|
||||
if(!$this->validateNaviItem()){ return $response->withJson(array('data' => $this->structure, 'errors' => ['message' => 'Special Characters not allowed. Length between 1 and 60 chars.'], 'url' => $url), 422); }
|
||||
if(!$this->validateNaviItem()){ return $response->withJson(array('data' => $this->structureDraft, 'errors' => ['message' => 'Special Characters not allowed. Length between 1 and 60 chars.'], 'url' => $url), 422); }
|
||||
|
||||
# get the ids (key path) for item, old folder and new folder
|
||||
$folderKeyPath = explode('.', $this->params['folder_id']);
|
||||
|
||||
# get the item from structure
|
||||
$folder = Folder::getItemWithKeyPath($this->structure, $folderKeyPath);
|
||||
$folder = Folder::getItemWithKeyPath($this->structureDraft, $folderKeyPath);
|
||||
|
||||
if(!$folder){ return $response->withJson(array('data' => $this->structure, 'errors' => ['message' => 'We could not find this page. Please refresh and try again.'], 'url' => $url), 404); }
|
||||
|
||||
if(!$folder){ return $response->withJson(array('data' => $this->structureDraft, 'errors' => ['message' => 'We could not find this page. Please refresh and try again.'], 'url' => $url), 404); }
|
||||
|
||||
$name = $this->params['item_name'];
|
||||
$slug = URLify::filter(iconv(mb_detect_encoding($this->params['item_name'], mb_detect_order(), true), "UTF-8", $this->params['item_name']));
|
||||
$slug = Folder::createSlug($this->params['item_name'], $this->settings);
|
||||
$namePath = date("YmdHi") . '-' . $slug;
|
||||
$folderPath = 'content' . $folder->path;
|
||||
$content = json_encode(['# ' . $name, 'Content']);
|
||||
|
||||
# initialise write object
|
||||
$write = new WriteYaml();
|
||||
$writeYaml = new WriteYaml();
|
||||
|
||||
# check, if name exists
|
||||
if($write->checkFile($folderPath, $namePath . '.txt') OR $write->checkFile($folderPath, $namePath . '.md'))
|
||||
if($writeYaml->checkFile($folderPath, $namePath . '.txt') OR $writeYaml->checkFile($folderPath, $namePath . '.md'))
|
||||
{
|
||||
return $response->withJson(array('data' => $this->structure, 'errors' => 'There is already a page with this name. Please choose another name.', 'url' => $url), 404);
|
||||
return $response->withJson(array('data' => $this->structureDraft, 'errors' => 'There is already a page with this name. Please choose another name.', 'url' => $url), 404);
|
||||
}
|
||||
|
||||
if(!$write->writeFile($folderPath, $namePath . '.txt', $content))
|
||||
if(!$writeYaml->writeFile($folderPath, $namePath . '.txt', $content))
|
||||
{
|
||||
return $response->withJson(array('data' => $this->structure, 'errors' => 'We could not create the file. Please refresh the page and check, if all folders and files are writable.', 'url' => $url), 404);
|
||||
return $response->withJson(array('data' => $this->structureDraft, 'errors' => 'We could not create the file. Please refresh the page and check, if all folders and files are writable.', 'url' => $url), 404);
|
||||
}
|
||||
|
||||
# get extended structure
|
||||
$extended = $write->getYaml('cache', 'structure-extended.yaml');
|
||||
$extended = $writeYaml->getYaml('cache', 'structure-extended.yaml');
|
||||
|
||||
# create the url for the item
|
||||
$urlWoF = $folder->urlRelWoF . '/' . $slug;
|
||||
@ -666,17 +711,17 @@ class ArticleApiController extends ContentController
|
||||
$extended[$urlWoF] = ['hide' => false, 'navtitle' => $name];
|
||||
|
||||
# store the extended structure
|
||||
$write->updateYaml('cache', 'structure-extended.yaml', $extended);
|
||||
$writeYaml->updateYaml('cache', 'structure-extended.yaml', $extended);
|
||||
|
||||
# update the structure for editor
|
||||
$this->setStructure($draft = true, $cache = false);
|
||||
$this->setFreshStructureDraft();
|
||||
|
||||
$folder = Folder::getItemWithKeyPath($this->structure, $folderKeyPath);
|
||||
$folder = Folder::getItemWithKeyPath($this->structureYaml, $folderKeyPath);
|
||||
|
||||
# activate this if you want to redirect after creating the page...
|
||||
# $url = $this->uri->getBaseUrl() . '/tm/content/' . $this->settings['editor'] . $folder->urlRelWoF . '/' . $slug;
|
||||
|
||||
return $response->withJson(array('posts' => $folder, $this->structure, 'errors' => false, 'url' => $url));
|
||||
return $response->withJson(array('posts' => $folder, $this->structureDraft, 'errors' => false, 'url' => $url));
|
||||
}
|
||||
|
||||
public function createArticle(Request $request, Response $response, $args)
|
||||
@ -695,36 +740,31 @@ class ArticleApiController extends ContentController
|
||||
$url = false;
|
||||
|
||||
# set structure
|
||||
if(!$this->setStructure($draft = true)){ return $response->withJson(array('data' => false, 'errors' => $this->errors, 'url' => $url), 404); }
|
||||
if(!$this->setStructureDraft()){ return $response->withJson(array('data' => false, 'errors' => $this->errors, 'url' => $url), 404); }
|
||||
|
||||
# validate input
|
||||
if(!$this->validateNaviItem()){ return $response->withJson(array('data' => $this->structure, 'errors' => 'Special Characters not allowed. Length between 1 and 60 chars.', 'url' => $url), 422); }
|
||||
if(!$this->validateNaviItem()){ return $response->withJson(array('data' => $this->structureDraft, 'errors' => 'Special Characters not allowed. Length between 1 and 60 chars.', 'url' => $url), 422); }
|
||||
|
||||
# get the ids (key path) for item, old folder and new folder
|
||||
$folderKeyPath = explode('.', $this->params['folder_id']);
|
||||
|
||||
# get the item from structure
|
||||
$folder = Folder::getItemWithKeyPath($this->structure, $folderKeyPath);
|
||||
$folder = Folder::getItemWithKeyPath($this->structureDraft, $folderKeyPath);
|
||||
|
||||
if(!$folder){ return $response->withJson(array('data' => $this->structure, 'errors' => 'We could not find this page. Please refresh and try again.', 'url' => $url), 404); }
|
||||
if(!$folder){ return $response->withJson(array('data' => $this->structureDraft, 'errors' => 'We could not find this page. Please refresh and try again.', 'url' => $url), 404); }
|
||||
|
||||
# Rename all files within the folder to make sure, that namings and orders are correct
|
||||
# get the content of the target folder
|
||||
$folderContent = $folder->folderContent;
|
||||
|
||||
$name = $this->params['item_name'];
|
||||
$slug = URLify::filter(iconv(mb_detect_encoding($this->params['item_name'], mb_detect_order(), true), "UTF-8", $this->params['item_name']));
|
||||
|
||||
# create the name for the new item
|
||||
# $nameParts = Folder::getStringParts($this->params['item_name']);
|
||||
# $name = implode("-", $nameParts);
|
||||
# $slug = $name;
|
||||
$slug = Folder::createSlug($this->params['item_name'], $this->settings);
|
||||
|
||||
# initialize index
|
||||
$index = 0;
|
||||
|
||||
# initialise write object
|
||||
$write = new WriteYaml();
|
||||
$writeYaml = new WriteYaml();
|
||||
|
||||
# iterate through the whole content of the new folder
|
||||
$writeError = false;
|
||||
@ -734,17 +774,17 @@ class ArticleApiController extends ContentController
|
||||
# check, if the same name as new item, then return an error
|
||||
if($folderItem->slug == $slug)
|
||||
{
|
||||
return $response->withJson(array('data' => $this->structure, 'errors' => 'There is already a page with this name. Please choose another name.', 'url' => $url), 404);
|
||||
return $response->withJson(array('data' => $this->structureDraft, 'errors' => 'There is already a page with this name. Please choose another name.', 'url' => $url), 404);
|
||||
}
|
||||
|
||||
if(!$write->moveElement($folderItem, $folder->path, $index))
|
||||
if(!$writeYaml->moveElement($folderItem, $folder->path, $index))
|
||||
{
|
||||
$writeError = true;
|
||||
}
|
||||
$index++;
|
||||
}
|
||||
|
||||
if($writeError){ return $response->withJson(array('data' => $this->structure, 'errors' => 'Something went wrong. Please refresh the page and check, if all folders and files are writable.', 'url' => $url), 404); }
|
||||
if($writeError){ return $response->withJson(array('data' => $this->structureDraft, 'errors' => 'Something went wrong. Please refresh the page and check, if all folders and files are writable.', 'url' => $url), 404); }
|
||||
|
||||
# add prefix number to the name
|
||||
$namePath = $index > 9 ? $index . '-' . $slug : '0' . $index . '-' . $slug;
|
||||
@ -755,18 +795,18 @@ class ArticleApiController extends ContentController
|
||||
|
||||
if($this->params['type'] == 'file')
|
||||
{
|
||||
if(!$write->writeFile($folderPath, $namePath . '.txt', $content))
|
||||
if(!$writeYaml->writeFile($folderPath, $namePath . '.txt', $content))
|
||||
{
|
||||
return $response->withJson(array('data' => $this->structure, 'errors' => 'We could not create the file. Please refresh the page and check, if all folders and files are writable.', 'url' => $url), 404);
|
||||
return $response->withJson(array('data' => $this->structureDraft, 'errors' => 'We could not create the file. Please refresh the page and check, if all folders and files are writable.', 'url' => $url), 404);
|
||||
}
|
||||
}
|
||||
elseif($this->params['type'] == 'folder')
|
||||
{
|
||||
if(!$write->checkPath($folderPath . DIRECTORY_SEPARATOR . $namePath))
|
||||
if(!$writeYaml->checkPath($folderPath . DIRECTORY_SEPARATOR . $namePath))
|
||||
{
|
||||
return $response->withJson(array('data' => $this->structure, 'errors' => 'We could not create the folder. Please refresh the page and check, if all folders and files are writable.', 'url' => $url), 404);
|
||||
return $response->withJson(array('data' => $this->structureDraft, 'errors' => 'We could not create the folder. Please refresh the page and check, if all folders and files are writable.', 'url' => $url), 404);
|
||||
}
|
||||
$write->writeFile($folderPath . DIRECTORY_SEPARATOR . $namePath, 'index.txt', $content);
|
||||
$this->writeCache->writeFile($folderPath . DIRECTORY_SEPARATOR . $namePath, 'index.txt', $content);
|
||||
|
||||
# always redirect to a folder
|
||||
$url = $this->uri->getBaseUrl() . '/tm/content/' . $this->settings['editor'] . $folder->urlRelWoF . '/' . $slug;
|
||||
@ -774,7 +814,7 @@ class ArticleApiController extends ContentController
|
||||
}
|
||||
|
||||
# get extended structure
|
||||
$extended = $write->getYaml('cache', 'structure-extended.yaml');
|
||||
$extended = $writeYaml->getYaml('cache', 'structure-extended.yaml');
|
||||
|
||||
# create the url for the item
|
||||
$urlWoF = $folder->urlRelWoF . '/' . $slug;
|
||||
@ -783,21 +823,21 @@ class ArticleApiController extends ContentController
|
||||
$extended[$urlWoF] = ['hide' => false, 'navtitle' => $name];
|
||||
|
||||
# store the extended structure
|
||||
$write->updateYaml('cache', 'structure-extended.yaml', $extended);
|
||||
$writeYaml->updateYaml('cache', 'structure-extended.yaml', $extended);
|
||||
|
||||
# update the structure for editor
|
||||
$this->setStructure($draft = true, $cache = false);
|
||||
$this->setFreshStructureDraft();
|
||||
|
||||
# get item for url and set it active again
|
||||
if(isset($this->params['url']))
|
||||
{
|
||||
$activeItem = Folder::getItemForUrl($this->structure, $this->params['url'], $this->uri->getBaseUrl());
|
||||
$activeItem = Folder::getItemForUrl($this->structureDraft, $this->params['url'], $this->uri->getBaseUrl());
|
||||
}
|
||||
|
||||
# activate this if you want to redirect after creating the page...
|
||||
# $url = $this->uri->getBaseUrl() . '/tm/content/' . $this->settings['editor'] . $folder->urlRelWoF . '/' . $slug;
|
||||
|
||||
return $response->withJson(array('data' => $this->structure, 'errors' => false, 'url' => $url));
|
||||
return $response->withJson(array('data' => $this->structureDraft, 'errors' => false, 'url' => $url));
|
||||
}
|
||||
|
||||
public function createBaseItem(Request $request, Response $response, $args)
|
||||
@ -816,67 +856,61 @@ class ArticleApiController extends ContentController
|
||||
$url = false;
|
||||
|
||||
# set structure
|
||||
if(!$this->setStructure($draft = true)){ return $response->withJson(array('data' => false, 'errors' => $this->errors, 'url' => $url), 404); }
|
||||
if(!$this->setStructureDraft()){ return $response->withJson(array('data' => false, 'errors' => $this->errors, 'url' => $url), 404); }
|
||||
|
||||
# validate input
|
||||
if(!$this->validateBaseNaviItem()){ return $response->withJson(array('data' => $this->structure, 'errors' => 'Special Characters not allowed. Length between 1 and 20 chars.', 'url' => $url), 422); }
|
||||
|
||||
# create the name for the new item
|
||||
# $nameParts = Folder::getStringParts($this->params['item_name']);
|
||||
# $name = implode("-", $nameParts);
|
||||
# $slug = $name;
|
||||
if(!$this->validateBaseNaviItem()){ return $response->withJson(array('data' => $this->structureDraft, 'errors' => 'Special Characters not allowed. Length between 1 and 20 chars.', 'url' => $url), 422); }
|
||||
|
||||
$name = $this->params['item_name'];
|
||||
$slug = URLify::filter(iconv(mb_detect_encoding($this->params['item_name'], mb_detect_order(), true), "UTF-8", $this->params['item_name']));
|
||||
$slug = Folder::createSlug($this->params['item_name'], $this->settings);
|
||||
|
||||
# initialize index
|
||||
$index = 0;
|
||||
$index = 0;
|
||||
|
||||
# initialise write object
|
||||
$write = new WriteYaml();
|
||||
$writeYaml = new WriteYaml();
|
||||
|
||||
# iterate through the whole content of the new folder
|
||||
$writeError = false;
|
||||
|
||||
foreach($this->structure as $item)
|
||||
foreach($this->structureDraft as $item)
|
||||
{
|
||||
# check, if the same name as new item, then return an error
|
||||
if($item->slug == $slug)
|
||||
{
|
||||
return $response->withJson(array('data' => $this->structure, 'errors' => 'There is already a page with this name. Please choose another name.', 'url' => $url), 422);
|
||||
return $response->withJson(array('data' => $this->structureDraft, 'errors' => 'There is already a page with this name. Please choose another name.', 'url' => $url), 422);
|
||||
}
|
||||
|
||||
if(!$write->moveElement($item, '', $index))
|
||||
if(!$writeYaml->moveElement($item, '', $index))
|
||||
{
|
||||
$writeError = true;
|
||||
}
|
||||
$index++;
|
||||
}
|
||||
|
||||
if($writeError){ return $response->withJson(array('data' => $this->structure, 'errors' => 'Something went wrong. Please refresh the page and check, if all folders and files are writable.', 'url' => $url), 422); }
|
||||
if($writeError){ return $response->withJson(array('data' => $this->structureDraft, 'errors' => 'Something went wrong. Please refresh the page and check, if all folders and files are writable.', 'url' => $url), 422); }
|
||||
|
||||
# add prefix number to the name
|
||||
$namePath = $index > 9 ? $index . '-' . $slug : '0' . $index . '-' . $slug;
|
||||
$folderPath = 'content';
|
||||
|
||||
# create default content
|
||||
# $content = json_encode(['# Add Title', 'Add Content']);
|
||||
$content = json_encode(['# ' . $name, 'Content']);
|
||||
|
||||
if($this->params['type'] == 'file')
|
||||
{
|
||||
if(!$write->writeFile($folderPath, $namePath . '.txt', $content))
|
||||
if(!$writeYaml->writeFile($folderPath, $namePath . '.txt', $content))
|
||||
{
|
||||
return $response->withJson(array('data' => $this->structure, 'errors' => 'We could not create the file. Please refresh the page and check, if all folders and files are writable.', 'url' => $url), 422);
|
||||
return $response->withJson(array('data' => $this->structureDraft, 'errors' => 'We could not create the file. Please refresh the page and check, if all folders and files are writable.', 'url' => $url), 422);
|
||||
}
|
||||
}
|
||||
elseif($this->params['type'] == 'folder')
|
||||
{
|
||||
if(!$write->checkPath($folderPath . DIRECTORY_SEPARATOR . $namePath))
|
||||
if(!$this->writeCache->checkPath($folderPath . DIRECTORY_SEPARATOR . $namePath))
|
||||
{
|
||||
return $response->withJson(array('data' => $this->structure, 'errors' => 'We could not create the folder. Please refresh the page and check, if all folders and files are writable.', 'url' => $url), 422);
|
||||
return $response->withJson(array('data' => $this->structureDraft, 'errors' => 'We could not create the folder. Please refresh the page and check, if all folders and files are writable.', 'url' => $url), 422);
|
||||
}
|
||||
$write->writeFile($folderPath . DIRECTORY_SEPARATOR . $namePath, 'index.txt', $content);
|
||||
$writeYaml->writeFile($folderPath . DIRECTORY_SEPARATOR . $namePath, 'index.txt', $content);
|
||||
|
||||
# activate this if you want to redirect after creating the page...
|
||||
$url = $this->uri->getBaseUrl() . '/tm/content/' . $this->settings['editor'] . '/' . $slug;
|
||||
@ -884,7 +918,7 @@ class ArticleApiController extends ContentController
|
||||
|
||||
|
||||
# get extended structure
|
||||
$extended = $write->getYaml('cache', 'structure-extended.yaml');
|
||||
$extended = $writeYaml->getYaml('cache', 'structure-extended.yaml');
|
||||
|
||||
# create the url for the item
|
||||
$urlWoF = '/' . $slug;
|
||||
@ -893,20 +927,21 @@ class ArticleApiController extends ContentController
|
||||
$extended[$urlWoF] = ['hide' => false, 'navtitle' => $name];
|
||||
|
||||
# store the extended structure
|
||||
$write->updateYaml('cache', 'structure-extended.yaml', $extended);
|
||||
$writeYaml->updateYaml('cache', 'structure-extended.yaml', $extended);
|
||||
|
||||
# update the structure for editor
|
||||
$this->setStructure($draft = true, $cache = false);
|
||||
$this->setFreshStructureDraft();
|
||||
|
||||
# get item for url and set it active again
|
||||
if(isset($this->params['url']))
|
||||
{
|
||||
$activeItem = Folder::getItemForUrl($this->structure, $this->params['url'], $this->uri->getBaseUrl());
|
||||
$activeItem = Folder::getItemForUrl($this->structureDraft, $this->params['url'], $this->uri->getBaseUrl());
|
||||
}
|
||||
|
||||
return $response->withJson(array('data' => $this->structure, 'errors' => false, 'url' => $url));
|
||||
return $response->withJson(array('data' => $this->structureDraft, 'errors' => false, 'url' => $url));
|
||||
}
|
||||
|
||||
# get the backend navigation
|
||||
public function getNavigation(Request $request, Response $response, $args)
|
||||
{
|
||||
# get params from call
|
||||
@ -914,7 +949,7 @@ class ArticleApiController extends ContentController
|
||||
$this->uri = $request->getUri()->withUserInfo('');
|
||||
|
||||
# set structure
|
||||
if(!$this->setStructure($draft = true, $cache = false)){ return $response->withJson(array('data' => false, 'errors' => $this->errors, 'url' => $url), 404); }
|
||||
if(!$this->setStructureDraft()){ return $response->withJson(array('data' => false, 'errors' => $this->errors, 'url' => $url), 404); }
|
||||
|
||||
# set information for homepage
|
||||
$this->setHomepage($args = false);
|
||||
@ -922,10 +957,10 @@ class ArticleApiController extends ContentController
|
||||
# get item for url and set it active again
|
||||
if(isset($this->params['url']))
|
||||
{
|
||||
$activeItem = Folder::getItemForUrl($this->structure, $this->params['url'], $this->uri->getBaseUrl());
|
||||
$activeItem = Folder::getItemForUrl($this->structureDraft, $this->params['url'], $this->uri->getBaseUrl());
|
||||
}
|
||||
|
||||
return $response->withJson(array('data' => $this->structure, 'homepage' => $this->homepage, 'errors' => false));
|
||||
return $response->withJson(array('data' => $this->structureDraft, 'homepage' => $this->homepage, 'errors' => false));
|
||||
}
|
||||
|
||||
public function getArticleMarkdown(Request $request, Response $response, $args)
|
||||
@ -941,7 +976,7 @@ class ArticleApiController extends ContentController
|
||||
}
|
||||
|
||||
# set structure
|
||||
if(!$this->setStructure($draft = true)){ return $response->withJson(array('data' => false, 'errors' => $this->errors), 404); }
|
||||
if(!$this->setStructureDraft()){ return $response->withJson(array('data' => false, 'errors' => $this->errors), 404); }
|
||||
|
||||
# set information for homepage
|
||||
$this->setHomepage($args = false);
|
||||
@ -1006,7 +1041,7 @@ class ArticleApiController extends ContentController
|
||||
}
|
||||
|
||||
# set structure
|
||||
if(!$this->setStructure($draft = true)){ return $response->withJson(array('data' => false, 'errors' => $this->errors), 404); }
|
||||
if(!$this->setStructureDraft()){ return $response->withJson(array('data' => false, 'errors' => $this->errors), 404); }
|
||||
|
||||
# set information for homepage
|
||||
$this->setHomepage($args = false);
|
@ -4,17 +4,10 @@ namespace Typemill\Controllers;
|
||||
|
||||
use Slim\Http\Request;
|
||||
use Slim\Http\Response;
|
||||
use Typemill\Models\Folder;
|
||||
use Typemill\Models\Write;
|
||||
use Typemill\Models\WriteYaml;
|
||||
use Typemill\Models\ProcessImage;
|
||||
use Typemill\Models\ProcessFile;
|
||||
use Typemill\Extensions\ParsedownExtension;
|
||||
use \URLify;
|
||||
|
||||
class BlockApiController extends ContentController
|
||||
class ControllerAuthorBlockApi extends ControllerAuthor
|
||||
{
|
||||
|
||||
public function addBlock(Request $request, Response $response, $args)
|
||||
{
|
||||
/* get params from call */
|
||||
@ -31,7 +24,7 @@ class BlockApiController extends ContentController
|
||||
if(!$this->validateBlockInput()){ return $response->withJson($this->errors,422); }
|
||||
|
||||
# set structure
|
||||
if(!$this->setStructure($draft = true)){ return $response->withJson(array('data' => false, 'errors' => $this->errors), 404); }
|
||||
if(!$this->setStructureDraft()){ return $response->withJson(array('data' => false, 'errors' => $this->errors), 404); }
|
||||
|
||||
$this->setHomepage($args = false);
|
||||
|
||||
@ -111,10 +104,10 @@ class BlockApiController extends ContentController
|
||||
$this->setItemPath('txt');
|
||||
|
||||
/* update the file */
|
||||
if($this->write->writeFile($this->settings['contentFolder'], $this->path, $pageJson))
|
||||
if($this->writeCache->writeFile($this->settings['contentFolder'], $this->path, $pageJson))
|
||||
{
|
||||
# update the internal structure
|
||||
$this->setStructure($draft = true, $cache = false);
|
||||
$this->setFreshStructureDraft();
|
||||
$this->content = $pageMarkdown;
|
||||
}
|
||||
else
|
||||
@ -229,7 +222,7 @@ class BlockApiController extends ContentController
|
||||
if(!$this->validateBlockInput()){ return $response->withJson($this->errors,422); }
|
||||
|
||||
# set structure
|
||||
if(!$this->setStructure($draft = true)){ return $response->withJson(array('data' => false, 'errors' => $this->errors), 404); }
|
||||
if(!$this->setStructureDraft()){ return $response->withJson(array('data' => false, 'errors' => $this->errors), 404); }
|
||||
|
||||
$this->setHomepage($args = false);
|
||||
|
||||
@ -312,11 +305,11 @@ class BlockApiController extends ContentController
|
||||
# set path for the file (or folder)
|
||||
$this->setItemPath('txt');
|
||||
|
||||
/* update the file */
|
||||
if($this->write->writeFile($this->settings['contentFolder'], $this->path, $pageJson))
|
||||
# update the file
|
||||
if($this->writeCache->writeFile($this->settings['contentFolder'], $this->path, $pageJson))
|
||||
{
|
||||
# update the internal structure
|
||||
$this->setStructure($draft = true, $cache = false);
|
||||
$this->setFreshStructureDraft();
|
||||
|
||||
# updated the content variable
|
||||
$this->content = $pageMarkdown;
|
||||
@ -326,7 +319,7 @@ class BlockApiController extends ContentController
|
||||
return $response->withJson(['errors' => ['message' => 'Could not write to file. Please check if the file is writable']], 404);
|
||||
}
|
||||
|
||||
/* parse markdown-file to content-array, if title parse title. */
|
||||
# parse markdown-file to content-array, if title parse title.
|
||||
if($this->params['block_id'] == 0)
|
||||
{
|
||||
$blockArray = $parsedown->text($blockMarkdownTitle);
|
||||
@ -380,12 +373,9 @@ class BlockApiController extends ContentController
|
||||
{
|
||||
return $response->withJson(array('data' => false, 'errors' => ['message' => 'You are not allowed to publish content.']), 403);
|
||||
}
|
||||
|
||||
# validate input
|
||||
# if(!$this->validateBlockInput()){ return $response->withJson($this->errors,422); }
|
||||
|
||||
# set structure
|
||||
if(!$this->setStructure($draft = true)){ return $response->withJson(array('data' => false, 'errors' => $this->errors), 404); }
|
||||
if(!$this->setStructureDraft()){ return $response->withJson(array('data' => false, 'errors' => $this->errors), 404); }
|
||||
|
||||
$this->setHomepage($args = false);
|
||||
|
||||
@ -448,10 +438,10 @@ class BlockApiController extends ContentController
|
||||
$this->setItemPath('txt');
|
||||
|
||||
/* update the file */
|
||||
if($this->write->writeFile($this->settings['contentFolder'], $this->path, $pageJson))
|
||||
if($this->writeCache->writeFile($this->settings['contentFolder'], $this->path, $pageJson))
|
||||
{
|
||||
# update the internal structure
|
||||
$this->setStructure($draft = true, $cache = false);
|
||||
$this->setFreshStructureDraft();
|
||||
|
||||
# update this content
|
||||
$this->content = $pageMarkdown;
|
||||
@ -493,7 +483,7 @@ class BlockApiController extends ContentController
|
||||
}
|
||||
|
||||
# set structure
|
||||
if(!$this->setStructure($draft = true)){ return $response->withJson(array('data' => false, 'errors' => $this->errors), 404); }
|
||||
if(!$this->setStructureDraft()){ return $response->withJson(array('data' => false, 'errors' => $this->errors), 404); }
|
||||
|
||||
$this->setHomepage($args = false);
|
||||
|
||||
@ -561,10 +551,10 @@ class BlockApiController extends ContentController
|
||||
$this->setItemPath('txt');
|
||||
|
||||
/* update the file */
|
||||
if($this->write->writeFile($this->settings['contentFolder'], $this->path, $pageJson))
|
||||
if($this->writeCache->writeFile($this->settings['contentFolder'], $this->path, $pageJson))
|
||||
{
|
||||
# update the internal structure
|
||||
$this->setStructure($draft = true, $cache = false);
|
||||
$this->setFreshStructureDraft();
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -580,335 +570,4 @@ class BlockApiController extends ContentController
|
||||
|
||||
return $response->withJson(array('markdown' => $pageMarkdown, 'toc' => $toc, 'errors' => $errors));
|
||||
}
|
||||
|
||||
public function getMediaLibImages(Request $request, Response $response, $args)
|
||||
{
|
||||
# get params from call
|
||||
$this->params = $request->getParams();
|
||||
$this->uri = $request->getUri()->withUserInfo('');
|
||||
|
||||
$imageProcessor = new ProcessImage($this->settings['images']);
|
||||
if(!$imageProcessor->checkFolders('images'))
|
||||
{
|
||||
return $response->withJson(['errors' => ['message' => 'Please check if your media-folder exists and all folders inside are writable.']], 500);
|
||||
}
|
||||
|
||||
$imagelist = $imageProcessor->scanMediaFlat();
|
||||
|
||||
return $response->withJson(array('images' => $imagelist));
|
||||
}
|
||||
|
||||
public function getMediaLibFiles(Request $request, Response $response, $args)
|
||||
{
|
||||
# get params from call
|
||||
$this->params = $request->getParams();
|
||||
$this->uri = $request->getUri()->withUserInfo('');
|
||||
|
||||
$fileProcessor = new ProcessFile();
|
||||
if(!$fileProcessor->checkFolders())
|
||||
{
|
||||
return $response->withJson(['errors' => ['message' => 'Please check if your media-folder exists and all folders inside are writable.']], 500);
|
||||
}
|
||||
|
||||
$filelist = $fileProcessor->scanFilesFlat();
|
||||
|
||||
return $response->withJson(array('files' => $filelist));
|
||||
}
|
||||
|
||||
public function getImage(Request $request, Response $response, $args)
|
||||
{
|
||||
# get params from call
|
||||
$this->params = $request->getParams();
|
||||
$this->uri = $request->getUri()->withUserInfo('');
|
||||
|
||||
$this->setStructure($draft = true, $cache = false);
|
||||
|
||||
$imageProcessor = new ProcessImage($this->settings['images']);
|
||||
if(!$imageProcessor->checkFolders('images'))
|
||||
{
|
||||
return $response->withJson(['errors' => ['message' => 'Please check if your media-folder exists and all folders inside are writable.']], 500);
|
||||
}
|
||||
|
||||
$imageDetails = $imageProcessor->getImageDetails($this->params['name'], $this->structure);
|
||||
|
||||
if($imageDetails)
|
||||
{
|
||||
return $response->withJson(array('image' => $imageDetails));
|
||||
}
|
||||
|
||||
# return $response->withJson(array('image' => false, 'errors' => 'image name invalid or not found'));
|
||||
return $response->withJson(['errors' => ['message' => 'Image name invalid or not found.']], 404);
|
||||
}
|
||||
|
||||
public function getFile(Request $request, Response $response, $args)
|
||||
{
|
||||
# get params from call
|
||||
$this->params = $request->getParams();
|
||||
$this->uri = $request->getUri()->withUserInfo('');
|
||||
|
||||
$this->setStructure($draft = true, $cache = false);
|
||||
|
||||
$fileProcessor = new ProcessFile();
|
||||
if(!$fileProcessor->checkFolders())
|
||||
{
|
||||
return $response->withJson(['errors' => ['message' => 'Please check if your media-folder exists and all folders inside are writable.']], 500);
|
||||
}
|
||||
|
||||
$fileDetails = $fileProcessor->getFileDetails($this->params['name'], $this->structure);
|
||||
|
||||
if($fileDetails)
|
||||
{
|
||||
return $response->withJson(['file' => $fileDetails]);
|
||||
}
|
||||
|
||||
return $response->withJson(['errors' => ['message' => 'file name invalid or not found']],404);
|
||||
}
|
||||
|
||||
public function createImage(Request $request, Response $response, $args)
|
||||
{
|
||||
# get params from call
|
||||
$this->params = $request->getParams();
|
||||
$this->uri = $request->getUri()->withUserInfo('');
|
||||
|
||||
# do this shit in the model ...
|
||||
$imagename = explode('.', $this->params['name']);
|
||||
array_pop($imagename);
|
||||
$imagename = implode('-', $imagename);
|
||||
$name = URLify::filter(iconv(mb_detect_encoding($imagename, mb_detect_order(), true), "UTF-8", $imagename));
|
||||
|
||||
$imageProcessor = new ProcessImage($this->settings['images']);
|
||||
if(!$imageProcessor->checkFolders('images'))
|
||||
{
|
||||
return $response->withJson(['errors' => ['message' => 'Please check if your media-folder exists and all folders inside are writable.']], 500);
|
||||
}
|
||||
|
||||
if($imageProcessor->createImage($this->params['image'], $name, $this->settings['images']))
|
||||
{
|
||||
return $response->withJson(array('errors' => false));
|
||||
}
|
||||
|
||||
return $response->withJson(array('errors' => ['message' => 'could not store image to temporary folder']));
|
||||
}
|
||||
|
||||
public function createFile(Request $request, Response $response, $args)
|
||||
{
|
||||
# get params from call
|
||||
$this->params = $request->getParams();
|
||||
$this->uri = $request->getUri()->withUserInfo('');
|
||||
|
||||
$finfo = finfo_open( FILEINFO_MIME_TYPE );
|
||||
$mtype = finfo_file( $finfo, $this->params['file'] );
|
||||
finfo_close( $finfo );
|
||||
|
||||
$allowedMimes = $this->getAllowedMtypes();
|
||||
if(!in_array($mtype, $allowedMimes))
|
||||
{
|
||||
return $response->withJson(array('errors' => ['message' => 'File-type is not allowed']));
|
||||
}
|
||||
|
||||
# sanitize file name
|
||||
$filename = basename($this->params['name']);
|
||||
$filename = explode('.', $this->params['name']);
|
||||
array_pop($filename);
|
||||
$filename = implode('-', $filename);
|
||||
$name = URLify::filter(iconv(mb_detect_encoding($filename, mb_detect_order(), true), "UTF-8", $filename));
|
||||
|
||||
$fileProcessor = new ProcessFile();
|
||||
if(!$fileProcessor->checkFolders())
|
||||
{
|
||||
return $response->withJson(['errors' => ['message' => 'Please check if your media-folder exists and all folders inside are writable.']], 500);
|
||||
}
|
||||
|
||||
if($fileProcessor->createFile($this->params['file'], $name))
|
||||
{
|
||||
return $response->withJson(array('errors' => false, 'name' => $name));
|
||||
}
|
||||
|
||||
return $response->withJson(array('errors' => ['message' => 'could not store file to temporary folder']));
|
||||
}
|
||||
|
||||
public function publishImage(Request $request, Response $response, $args)
|
||||
{
|
||||
$params = $request->getParsedBody();
|
||||
|
||||
$imageProcessor = new ProcessImage($this->settings['images']);
|
||||
if(!$imageProcessor->checkFolders())
|
||||
{
|
||||
return $response->withJson(['errors' => ['message' => 'Please check if your media-folder exists and all folders inside are writable.']], 500);
|
||||
}
|
||||
|
||||
$imageUrl = $imageProcessor->publishImage();
|
||||
if($imageUrl)
|
||||
{
|
||||
# replace the image placeholder in markdown with the image url
|
||||
$params['markdown'] = str_replace('imgplchldr', $imageUrl, $params['markdown']);
|
||||
|
||||
$request = $request->withParsedBody($params);
|
||||
|
||||
if($params['new'])
|
||||
{
|
||||
return $this->addBlock($request, $response, $args);
|
||||
}
|
||||
return $this->updateBlock($request, $response, $args);
|
||||
}
|
||||
|
||||
return $response->withJson(array('errors' => ['message' => 'could not store image to media folder']));
|
||||
}
|
||||
|
||||
public function deleteImage(Request $request, Response $response, $args)
|
||||
{
|
||||
# get params from call
|
||||
$this->params = $request->getParams();
|
||||
$this->uri = $request->getUri()->withUserInfo('');
|
||||
|
||||
if(!isset($this->params['name']))
|
||||
{
|
||||
return $response->withJson(array('errors' => ['message' => 'image name is missing']));
|
||||
}
|
||||
|
||||
$imageProcessor = new ProcessImage($this->settings['images']);
|
||||
if(!$imageProcessor->checkFolders())
|
||||
{
|
||||
return $response->withJson(['errors' => ['message' => 'Please check if your media-folder exists and all folders inside are writable.']], 500);
|
||||
}
|
||||
|
||||
$errors = $imageProcessor->deleteImage($this->params['name']);
|
||||
|
||||
return $response->withJson(array('errors' => $errors));
|
||||
}
|
||||
|
||||
public function deleteFile(Request $request, Response $response, $args)
|
||||
{
|
||||
# get params from call
|
||||
$this->params = $request->getParams();
|
||||
$this->uri = $request->getUri()->withUserInfo('');
|
||||
|
||||
if(!isset($this->params['name']))
|
||||
{
|
||||
return $response->withJson(array('errors' => ['message' => 'file name is missing']));
|
||||
}
|
||||
|
||||
$fileProcessor = new ProcessFile();
|
||||
|
||||
$errors = false;
|
||||
if($fileProcessor->deleteFile($this->params['name']))
|
||||
{
|
||||
return $response->withJson(array('errors' => false));
|
||||
}
|
||||
|
||||
return $response->withJson(array('errors' => ['message' => 'could not delete the file']));
|
||||
}
|
||||
|
||||
public function saveVideoImage(Request $request, Response $response, $args)
|
||||
{
|
||||
/* get params from call */
|
||||
$this->params = $request->getParams();
|
||||
$this->uri = $request->getUri()->withUserInfo('');
|
||||
$class = false;
|
||||
|
||||
$imageUrl = $this->params['markdown'];
|
||||
|
||||
if(strpos($imageUrl, 'https://www.youtube.com/watch?v=') !== false)
|
||||
{
|
||||
$videoID = str_replace('https://www.youtube.com/watch?v=', '', $imageUrl);
|
||||
$videoID = strpos($videoID, '&') ? substr($videoID, 0, strpos($videoID, '&')) : $videoID;
|
||||
$class = 'youtube';
|
||||
}
|
||||
if(strpos($imageUrl, 'https://youtu.be/') !== false)
|
||||
{
|
||||
$videoID = str_replace('https://youtu.be/', '', $imageUrl);
|
||||
$videoID = strpos($videoID, '?') ? substr($videoID, 0, strpos($videoID, '?')) : $videoID;
|
||||
$class = 'youtube';
|
||||
}
|
||||
|
||||
if($class == 'youtube')
|
||||
{
|
||||
$videoURLmaxres = 'https://i1.ytimg.com/vi/' . $videoID . '/maxresdefault.jpg';
|
||||
$videoURL0 = 'https://i1.ytimg.com/vi/' . $videoID . '/0.jpg';
|
||||
}
|
||||
|
||||
$ctx = stream_context_create(array(
|
||||
'https' => array(
|
||||
'timeout' => 1
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
$imageData = @file_get_contents($videoURLmaxres, 0, $ctx);
|
||||
if($imageData === false)
|
||||
{
|
||||
$imageData = @file_get_contents($videoURL0, 0, $ctx);
|
||||
if($imageData === false)
|
||||
{
|
||||
return $response->withJson(['errors' => ['message' => 'We did not find that video or could not get a preview image.']], 500);
|
||||
}
|
||||
}
|
||||
|
||||
$imageData64 = 'data:image/jpeg;base64,' . base64_encode($imageData);
|
||||
$desiredSizes = $this->settings['images'];
|
||||
$desiredSizes['live'] = ['width' => 560, 'height' => 315];
|
||||
$imageProcessor = new ProcessImage($desiredSizes);
|
||||
|
||||
if(!$imageProcessor->checkFolders('images'))
|
||||
{
|
||||
return $response->withJson(['errors' => ['message' => 'Please check if your media-folder exists and all folders inside are writable.']], 500);
|
||||
}
|
||||
|
||||
if(!$imageProcessor->createImage($imageData64, 'youtube-' . $videoID, $desiredSizes, $overwrite = true))
|
||||
{
|
||||
return $response->withJson(['errors' => ['message' => 'We could not create the image.']], 500);
|
||||
}
|
||||
|
||||
$imageUrl = $imageProcessor->publishImage();
|
||||
if($imageUrl)
|
||||
{
|
||||
|
||||
$this->params['markdown'] = '![' . $class . '-video](' . $imageUrl . ' "click to load video"){#' . $videoID. ' .' . $class . '}';
|
||||
|
||||
$request = $request->withParsedBody($this->params);
|
||||
|
||||
if($this->params['new'])
|
||||
{
|
||||
return $this->addBlock($request, $response, $args);
|
||||
}
|
||||
return $this->updateBlock($request, $response, $args);
|
||||
}
|
||||
|
||||
return $response->withJson(array('errors' => ['message' => 'could not store the preview image']));
|
||||
}
|
||||
|
||||
private function getAllowedMtypes()
|
||||
{
|
||||
return array(
|
||||
'application/zip',
|
||||
'application/gzip',
|
||||
'application/vnd.rar',
|
||||
'application/vnd.visio',
|
||||
'application/vnd.ms-excel',
|
||||
'application/vnd.ms-powerpoint',
|
||||
'application/vnd.ms-word.document.macroEnabled.12',
|
||||
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
||||
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||
'application/vnd.openxmlformats-officedocument.presentationml.presentation',
|
||||
'application/vnd.apple.keynote',
|
||||
'application/vnd.apple.mpegurl',
|
||||
'application/vnd.apple.numbers',
|
||||
'application/vnd.apple.pages',
|
||||
'application/vnd.amazon.mobi8-ebook',
|
||||
'application/epub+zip',
|
||||
'application/pdf',
|
||||
'image/png',
|
||||
'image/jpeg',
|
||||
'image/jpg',
|
||||
'image/gif',
|
||||
'image/svg+xml',
|
||||
'font/*',
|
||||
'audio/mpeg',
|
||||
'audio/mp4',
|
||||
'audio/ogg',
|
||||
'video/mpeg',
|
||||
'video/mp4',
|
||||
'video/ogg',
|
||||
);
|
||||
}
|
||||
}
|
@ -4,11 +4,10 @@ namespace Typemill\Controllers;
|
||||
|
||||
use Slim\Http\Request;
|
||||
use Slim\Http\Response;
|
||||
use Slim\Views\Twig;
|
||||
use Typemill\Models\Folder;
|
||||
use Typemill\Extensions\ParsedownExtension;
|
||||
|
||||
class ContentBackendController extends ContentController
|
||||
class ControllerAuthorEditor extends ControllerAuthor
|
||||
{
|
||||
/**
|
||||
* Show Content for raw editor
|
||||
@ -25,7 +24,7 @@ class ContentBackendController extends ContentController
|
||||
$this->params = isset($args['params']) ? ['url' => $this->uri->getBasePath() . '/' . $args['params']] : ['url' => $this->uri->getBasePath()];
|
||||
|
||||
# set structure
|
||||
if(!$this->setStructure($draft = true)){ return $this->renderIntern404($response, array( 'navigation' => true, 'content' => $this->errors )); }
|
||||
if(!$this->setStructureDraft()){ return $this->renderIntern404($response, array( 'navigation' => true, 'content' => $this->errors )); }
|
||||
|
||||
# set information for homepage
|
||||
$this->setHomepage($args);
|
||||
@ -37,7 +36,7 @@ class ContentBackendController extends ContentController
|
||||
$this->checkContentOwnership();
|
||||
|
||||
# get the breadcrumb (here we need it only to mark the actual item active in navigation)
|
||||
$breadcrumb = isset($this->item->keyPathArray) ? Folder::getBreadcrumb($this->structure, $this->item->keyPathArray) : false;
|
||||
$breadcrumb = isset($this->item->keyPathArray) ? Folder::getBreadcrumb($this->structureDraft, $this->item->keyPathArray) : false;
|
||||
|
||||
# set the status for published and drafted
|
||||
$this->setPublishStatus();
|
||||
@ -78,10 +77,10 @@ class ContentBackendController extends ContentController
|
||||
}
|
||||
}
|
||||
|
||||
return $this->render($response, 'editor/editor-raw.twig', array(
|
||||
return $this->renderIntern($response, 'editor/editor-raw.twig', array(
|
||||
'acl' => $this->c->acl,
|
||||
'mycontent' => $this->mycontent,
|
||||
'navigation' => $this->structure,
|
||||
'navigation' => $this->structureDraft,
|
||||
'homepage' => $this->homepage,
|
||||
'title' => $title,
|
||||
'content' => $content,
|
||||
@ -105,13 +104,13 @@ class ContentBackendController extends ContentController
|
||||
$this->params = isset($args['params']) ? ['url' => $this->uri->getBasePath() . '/' . $args['params']] : ['url' => $this->uri->getBasePath()];
|
||||
|
||||
# set structure
|
||||
if(!$this->setStructure($draft = true)){ return $this->renderIntern404($response, array( 'navigation' => true, 'content' => $this->errors )); }
|
||||
if(!$this->setStructureDraft()){ return $this->renderIntern404($response, array( 'navigation' => true, 'content' => $this->errors )); }
|
||||
|
||||
# set information for homepage
|
||||
$this->setHomepage($args);
|
||||
|
||||
# set item
|
||||
if(!$this->setItem()){ return $this->renderIntern404($response, array( 'navigation' => $this->structure, 'settings' => $this->settings, 'content' => $this->errors )); }
|
||||
if(!$this->setItem()){ return $this->renderIntern404($response, array( 'navigation' => $this->structureDraft, 'settings' => $this->settings, 'content' => $this->errors )); }
|
||||
|
||||
# we have to check ownership here to use it for permission-check in tempates
|
||||
$this->checkContentOwnership();
|
||||
@ -168,20 +167,15 @@ class ContentBackendController extends ContentController
|
||||
unset($content[0]);
|
||||
}
|
||||
|
||||
return $this->render($response, 'editor/editor-blox.twig', array(
|
||||
return $this->renderIntern($response, 'editor/editor-blox.twig', array(
|
||||
'acl' => $this->c->acl,
|
||||
'mycontent' => $this->mycontent,
|
||||
'navigation' => $this->structure,
|
||||
'homepage' => $this->homepage,
|
||||
'navigation' => $this->structureDraft,
|
||||
'homepage' => $this->homepage,
|
||||
'title' => $title,
|
||||
'content' => $content,
|
||||
'item' => $this->item,
|
||||
'item' => $this->item,
|
||||
'settings' => $this->settings
|
||||
));
|
||||
}
|
||||
|
||||
public function showEmpty(Request $request, Response $response, $args)
|
||||
{
|
||||
return $this->renderIntern404($response, array( 'settings' => $this->settings ));
|
||||
}
|
||||
}
|
@ -7,9 +7,8 @@ use Slim\Http\Response;
|
||||
use Typemill\Models\ProcessImage;
|
||||
use Typemill\Models\ProcessFile;
|
||||
use Typemill\Controllers\BlockApiController;
|
||||
use \URLify;
|
||||
|
||||
class MediaApiController extends ContentController
|
||||
class ControllerAuthorMediaApi extends ControllerAuthor
|
||||
{
|
||||
public function getMediaLibImages(Request $request, Response $response, $args)
|
||||
{
|
||||
@ -51,7 +50,7 @@ class MediaApiController extends ContentController
|
||||
$this->params = $request->getParams();
|
||||
$this->uri = $request->getUri()->withUserInfo('');
|
||||
|
||||
$this->setStructure($draft = true, $cache = false);
|
||||
$this->setStructureDraft();
|
||||
|
||||
$imageProcessor = new ProcessImage($this->settings['images']);
|
||||
if(!$imageProcessor->checkFolders('images'))
|
||||
@ -59,7 +58,7 @@ class MediaApiController extends ContentController
|
||||
return $response->withJson(['errors' => 'Please check if your media-folder exists and all folders inside are writable.'], 500);
|
||||
}
|
||||
|
||||
$imageDetails = $imageProcessor->getImageDetails($this->params['name'], $this->structure);
|
||||
$imageDetails = $imageProcessor->getImageDetails($this->params['name'], $this->structureDraft);
|
||||
|
||||
if($imageDetails)
|
||||
{
|
||||
@ -75,7 +74,7 @@ class MediaApiController extends ContentController
|
||||
$this->params = $request->getParams();
|
||||
$this->uri = $request->getUri()->withUserInfo('');
|
||||
|
||||
$this->setStructure($draft = true, $cache = false);
|
||||
$this->setStructureDraft();
|
||||
|
||||
$fileProcessor = new ProcessFile();
|
||||
if(!$fileProcessor->checkFolders())
|
||||
@ -83,7 +82,7 @@ class MediaApiController extends ContentController
|
||||
return $response->withJson(['errors' => 'Please check if your media-folder exists and all folders inside are writable.'], 500);
|
||||
}
|
||||
|
||||
$fileDetails = $fileProcessor->getFileDetails($this->params['name'], $this->structure);
|
||||
$fileDetails = $fileProcessor->getFileDetails($this->params['name'], $this->structureDraft);
|
||||
|
||||
if($fileDetails)
|
||||
{
|
@ -9,7 +9,7 @@ use Typemill\Models\WriteMeta;
|
||||
use Typemill\Models\Folder;
|
||||
use Typemill\Events\OnMetaDefinitionsLoaded;
|
||||
|
||||
class MetaApiController extends ContentController
|
||||
class ControllerAuthorMetaApi extends ControllerAuthor
|
||||
{
|
||||
# get the standard meta-definitions and the meta-definitions from plugins (same for all sites)
|
||||
public function getMetaDefinitions(Request $request, Response $response, $args)
|
||||
@ -75,7 +75,7 @@ class MetaApiController extends ContentController
|
||||
$this->uri = $request->getUri()->withUserInfo('');
|
||||
|
||||
# set structure
|
||||
if(!$this->setStructure($draft = true)){ return $response->withJson($this->errors, 404); }
|
||||
if(!$this->setStructureDraft()){ return $response->withJson($this->errors, 404); }
|
||||
|
||||
# set information for homepage
|
||||
$this->setHomepage($args = false);
|
||||
@ -148,16 +148,6 @@ class MetaApiController extends ContentController
|
||||
$metadefinitions[$tabname]['fields'][$fieldname]['options'] = $userroles;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
# special treatment for customfields
|
||||
if(isset($fielddefinitions['type']) && ($fielddefinitions['type'] == 'customfields' ) && $metadata[$tabname][$fieldname] )
|
||||
{
|
||||
|
||||
$metadata[$tabname][$fieldname] = $this->customfieldsPrepareForEdit($metadata[$tabname][$fieldname]);
|
||||
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
@ -190,7 +180,7 @@ class MetaApiController extends ContentController
|
||||
}
|
||||
|
||||
# set structure
|
||||
if(!$this->setStructure($draft = true)){ return $response->withJson($this->errors, 404); }
|
||||
if(!$this->setStructureDraft()){ return $response->withJson($this->errors, 404); }
|
||||
|
||||
# set information for homepage
|
||||
$this->setHomepage($args = false);
|
||||
@ -256,20 +246,6 @@ class MetaApiController extends ContentController
|
||||
{
|
||||
$errors[$tab][$fieldName] = $result[$fieldName][0];
|
||||
}
|
||||
|
||||
/*
|
||||
# special treatment for customfields
|
||||
if($fieldDefinition && isset($fieldDefinition['type']) && ($fieldDefinition['type'] == 'customfields' ) )
|
||||
{
|
||||
$arrayFeatureOn = false;
|
||||
if(isset($fieldDefinition['data']) && ($fieldDefinition['data'] == 'array'))
|
||||
{
|
||||
$arrayFeatureOn = true;
|
||||
}
|
||||
|
||||
$metaInput[$fieldName] = $this->customfieldsPrepareForSave($metaInput[$fieldName], $arrayFeatureOn);
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
@ -312,7 +288,7 @@ class MetaApiController extends ContentController
|
||||
$writeMeta->renamePost($this->item->pathWithoutType, $newPathWithoutType);
|
||||
|
||||
# recreate the draft structure
|
||||
$this->setStructure($draft = true, $cache = false);
|
||||
$this->setFreshStructureDraft();
|
||||
|
||||
# update item
|
||||
$this->setItem();
|
||||
@ -372,16 +348,25 @@ class MetaApiController extends ContentController
|
||||
$writeMeta->updateYaml('cache', 'structure-extended.yaml', $extended);
|
||||
|
||||
# recreate the draft structure
|
||||
$this->setStructure($draft = true, $cache = false);
|
||||
$this->setFreshStructureDraft();
|
||||
|
||||
# recreate the live structure
|
||||
$this->setFreshStructureLive();
|
||||
|
||||
# recreate the navigation
|
||||
$this->setFreshNavigation();
|
||||
|
||||
# update the sitemap
|
||||
$this->updateSitemap();
|
||||
|
||||
# update item
|
||||
$this->setItem();
|
||||
|
||||
# set item in navigation active again
|
||||
$activeItem = Folder::getItemForUrl($this->structure, $this->item->urlRel, $this->uri->getBaseUrl());
|
||||
$activeItem = Folder::getItemForUrl($this->structureDraft, $this->item->urlRel, $this->uri->getBaseUrl());
|
||||
|
||||
# send new structure to frontend
|
||||
$structure = $this->structure;
|
||||
$structure = $this->structureDraft;
|
||||
}
|
||||
|
||||
# return with the new metadata
|
||||
@ -410,75 +395,6 @@ class MetaApiController extends ContentController
|
||||
return $flattab;
|
||||
}
|
||||
|
||||
|
||||
# can be deleted ??
|
||||
private function customfieldsPrepareForEdit($customfields)
|
||||
{
|
||||
# to edit fields in vue we have to transform the arrays in yaml into an array of objects like [{key: abc, value: xyz}{...}]
|
||||
|
||||
$customfieldsForEdit = [];
|
||||
|
||||
foreach($customfields as $key => $value)
|
||||
{
|
||||
$valuestring = $value;
|
||||
|
||||
# and make sure that arrays are transformed back into strings
|
||||
if(isset($value) && is_array($value))
|
||||
{
|
||||
$valuestring = '- ' . implode(PHP_EOL . '- ', $value);
|
||||
}
|
||||
|
||||
$customfieldsForEdit[] = ['key' => $key, 'value' => $valuestring];
|
||||
}
|
||||
|
||||
return $customfieldsForEdit;
|
||||
}
|
||||
|
||||
# can be deleted?
|
||||
private function customfieldsPrepareForSave($customfields, $arrayFeatureOn)
|
||||
{
|
||||
# we have to convert the incoming array of objects from vue [{key: abc, value: xyz}{...}] into key-value arrays for yaml.
|
||||
|
||||
$customfieldsForSave = [];
|
||||
|
||||
foreach($customfields as $valuePair)
|
||||
{
|
||||
# doupbe check, not really needed because it is validated already
|
||||
if(!isset($valuePair['key']) OR ($valuePair['key'] == ''))
|
||||
{
|
||||
# do not use data without valid keys
|
||||
continue;
|
||||
}
|
||||
|
||||
$key = $valuePair['key'];
|
||||
$value = '';
|
||||
|
||||
if(isset($valuePair['value']))
|
||||
{
|
||||
$value = $valuePair['value'];
|
||||
|
||||
# check if value is formatted as a list, then transform it into an array
|
||||
if($arrayFeatureOn)
|
||||
{
|
||||
# normalize line breaks, php-eol does not work here
|
||||
$cleanvalue = str_replace(array("\r\n", "\r"), "\n", $valuePair['value']);
|
||||
$cleanvalue = trim($cleanvalue, "\n");
|
||||
|
||||
$arrayValues = explode("\n- ",$cleanvalue);
|
||||
|
||||
if(count($arrayValues) > 1)
|
||||
{
|
||||
$value = array_map(function($item) { return trim($item, '- '); }, $arrayValues);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$customfieldsForSave[$key] = $value;
|
||||
}
|
||||
|
||||
return $customfieldsForSave;
|
||||
}
|
||||
|
||||
protected function hasChanged($input, $page, $field)
|
||||
{
|
||||
if(isset($input[$field]) && isset($page[$field]) && $input[$field] == $page[$field])
|
@ -10,7 +10,7 @@ use Typemill\Models\User;
|
||||
use Typemill\Models\WriteYaml;
|
||||
use Typemill\Extensions\ParsedownExtension;
|
||||
|
||||
class AuthController extends Controller
|
||||
class ControllerFrontendAuth extends ControllerShared
|
||||
{
|
||||
# redirect if visit /setup route
|
||||
public function redirect(Request $request, Response $response)
|
@ -5,11 +5,8 @@ namespace Typemill\Controllers;
|
||||
use Typemill\Models\Validation;
|
||||
use Typemill\Models\WriteYaml;
|
||||
|
||||
class FormController extends Controller
|
||||
class ControllerFrontendForms extends ControllerShared
|
||||
{
|
||||
/*************************************
|
||||
** SAVE THEME- AND PLUGIN-SETTINGS **
|
||||
*************************************/
|
||||
|
||||
public function savePublicForm($request, $response, $args)
|
||||
{
|
@ -7,7 +7,7 @@ use Typemill\Models\Validation;
|
||||
use Typemill\Models\User;
|
||||
use Typemill\Models\Write;
|
||||
|
||||
class SetupController extends Controller
|
||||
class ControllerFrontendSetup extends ControllerShared
|
||||
{
|
||||
|
||||
# redirect if visit /setup route
|
@ -3,14 +3,8 @@
|
||||
namespace Typemill\Controllers;
|
||||
|
||||
use Typemill\Models\Folder;
|
||||
use Typemill\Models\WriteCache;
|
||||
use Typemill\Models\WriteSitemap;
|
||||
use Typemill\Models\WriteYaml;
|
||||
use Typemill\Models\WriteMeta;
|
||||
use \Symfony\Component\Yaml\Yaml;
|
||||
use Typemill\Models\VersionCheck;
|
||||
use Typemill\Models\Markdown;
|
||||
use Typemill\Events\OnCacheUpdated;
|
||||
use Typemill\Extensions\ParsedownExtension;
|
||||
use Typemill\Events\OnPagetreeLoaded;
|
||||
use Typemill\Events\OnBreadcrumbLoaded;
|
||||
use Typemill\Events\OnItemLoaded;
|
||||
@ -20,78 +14,59 @@ use Typemill\Events\OnMarkdownLoaded;
|
||||
use Typemill\Events\OnContentArrayLoaded;
|
||||
use Typemill\Events\OnHtmlLoaded;
|
||||
use Typemill\Events\OnRestrictionsLoaded;
|
||||
use Typemill\Extensions\ParsedownExtension;
|
||||
|
||||
class PageController extends Controller
|
||||
class ControllerFrontendWebsite extends ControllerShared
|
||||
{
|
||||
public function index($request, $response, $args)
|
||||
{
|
||||
{
|
||||
# Initiate Variables
|
||||
$contentHTML = false;
|
||||
$item = false;
|
||||
$home = false;
|
||||
$breadcrumb = false;
|
||||
$currentpage = false;
|
||||
$this->pathToContent = $this->settings['rootPath'] . $this->settings['contentFolder'];
|
||||
$this->uri = $request->getUri()->withUserInfo('');
|
||||
$this->base_url = $this->uri->getBaseUrl();
|
||||
|
||||
/* Initiate Variables */
|
||||
$structure = false;
|
||||
$contentHTML = false;
|
||||
$item = false;
|
||||
$home = false;
|
||||
$breadcrumb = false;
|
||||
$currentpage = false;
|
||||
$pathToContent = $this->settings['rootPath'] . $this->settings['contentFolder'];
|
||||
$cache = new WriteCache();
|
||||
$uri = $request->getUri()->withUserInfo('');
|
||||
$base_url = $uri->getBaseUrl();
|
||||
|
||||
$this->pathToContent = $pathToContent;
|
||||
|
||||
try
|
||||
# if there is no structure at all, the content folder is probably empty
|
||||
if(!$this->setStructureLive())
|
||||
{
|
||||
# if the cached structure is still valid, use it
|
||||
if($cache->validate('cache', 'lastCache.txt', 600))
|
||||
{
|
||||
$structure = $cache->getCachedStructure();
|
||||
}
|
||||
else
|
||||
{
|
||||
# dispatch message that the cache has been refreshed
|
||||
$this->c->dispatcher->dispatch('onCacheUpdated', new OnCacheUpdated(false));
|
||||
}
|
||||
return $this->render($response, '/index.twig', array( 'content' => '<h1>No Content</h1><p>Your content folder is empty.</p>' ));
|
||||
}
|
||||
|
||||
if(!isset($structure) OR !$structure)
|
||||
{
|
||||
# if not, get a fresh structure of the content folder
|
||||
$structure = $cache->getFreshStructure($pathToContent, $uri);
|
||||
# we can create an initial sitemap here, but makes no sense for every pagecall. Sitemap will be created on first author interaction (publish/delete/channge page).
|
||||
# $this->checkSitemap();
|
||||
|
||||
# if there is no structure at all, the content folder is probably empty
|
||||
if(!$structure)
|
||||
{
|
||||
$content = '<h1>No Content</h1><p>Your content folder is empty.</p>';
|
||||
# if the admin activated to refresh the cache automatically each 10 minutes (e.g. use without admin area)
|
||||
if(isset($this->settings['refreshcache']) && $this->settings['refreshcache'] && !$this->writeCache->validate('cache', 'lastCache.txt', 600))
|
||||
{
|
||||
# delete the cache
|
||||
$dir = $this->settings['basePath'] . 'cache';
|
||||
$this->writeCache->deleteCacheFiles($dir);
|
||||
|
||||
return $this->render($response, '/index.twig', array( 'content' => $content ));
|
||||
}
|
||||
elseif(!$cache->validate('cache', 'lastSitemap.txt', 86400))
|
||||
{
|
||||
# update sitemap
|
||||
$sitemap = new WriteSitemap();
|
||||
$sitemap->updateSitemap('cache', 'sitemap.xml', 'lastSitemap.txt', $structure, $uri->getBaseUrl());
|
||||
}
|
||||
}
|
||||
# update the internal structure
|
||||
$this->setFreshStructureDraft();
|
||||
|
||||
# dispatch event and let others manipulate the structure
|
||||
$structure = $this->c->dispatcher->dispatch('onPagetreeLoaded', new OnPagetreeLoaded($structure))->getData();
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
echo $e->getMessage();
|
||||
exit(1);
|
||||
# update the public structure
|
||||
$this->setFreshStructureLive();
|
||||
|
||||
# update the navigation
|
||||
$this->setFreshNavigation();
|
||||
|
||||
# update the sitemap
|
||||
$this->updateSitemap();
|
||||
}
|
||||
|
||||
# get meta-Information
|
||||
$writeMeta = new WriteMeta();
|
||||
$theme = $this->settings['theme'];
|
||||
# dispatch event and let others manipulate the structure
|
||||
$this->structureLive = $this->c->dispatcher->dispatch('onPagetreeLoaded', new OnPagetreeLoaded($this->structureLive))->getData();
|
||||
|
||||
# check if there is a custom theme css
|
||||
$customcss = $writeMeta->checkFile('cache', $theme . '-custom.css');
|
||||
$theme = $this->settings['theme'];
|
||||
$customcss = $this->writeCache->checkFile('cache', $theme . '-custom.css');
|
||||
if($customcss)
|
||||
{
|
||||
$this->c->assets->addCSS($base_url . '/cache/' . $theme . '-custom.css');
|
||||
$this->c->assets->addCSS($this->base_url . '/cache/' . $theme . '-custom.css');
|
||||
}
|
||||
|
||||
$logo = false;
|
||||
@ -106,13 +81,13 @@ class PageController extends Controller
|
||||
$favicon = true;
|
||||
}
|
||||
|
||||
|
||||
# the navigation is a copy of the structure without the hidden pages
|
||||
$navigation = $cache->getCache('cache', 'navigation.txt');
|
||||
# hint: if the navigation has been deleted from the cache, then we do not recreate it here to save performace. Instead you have to recreate cache in admin or change a page (publish/unpublish/delete/move)
|
||||
$navigation = $this->writeCache->getCache('cache', 'navigation.txt');
|
||||
if(!$navigation)
|
||||
{
|
||||
# use the structure if there is no cached navigation
|
||||
$navigation = $structure;
|
||||
$navigation = $this->structureLive;
|
||||
}
|
||||
|
||||
# start pagination
|
||||
@ -149,23 +124,23 @@ class PageController extends Controller
|
||||
if(empty($args))
|
||||
{
|
||||
$home = true;
|
||||
$item = Folder::getItemForUrl($navigation, $uri->getBasePath(), $uri->getBaseUrl(), NULL, $home);
|
||||
$urlRel = $uri->getBasePath();
|
||||
$item = Folder::getItemForUrl($navigation, $this->uri->getBasePath(), $this->uri->getBaseUrl(), NULL, $home);
|
||||
$urlRel = $this->uri->getBasePath();
|
||||
}
|
||||
else
|
||||
{
|
||||
# get the request url, trim args so physical folders have no trailing slash
|
||||
$urlRel = $uri->getBasePath() . '/' . trim($args['params'], "/");
|
||||
$urlRel = $this->uri->getBasePath() . '/' . trim($args['params'], "/");
|
||||
|
||||
# find the url in the content-item-tree and return the item-object for the file
|
||||
# important to use the structure here so it is found, even if the item is hidden.
|
||||
$item = Folder::getItemForUrl($structure, $urlRel, $uri->getBasePath());
|
||||
$item = Folder::getItemForUrl($this->structureLive, $urlRel, $this->uri->getBasePath());
|
||||
|
||||
# if the item is a folder and if that folder is not hidden
|
||||
if($item && $item->elementType == 'folder' && isset($item->hide) && !$item->hide)
|
||||
{
|
||||
# use the navigation instead of the structure so that hidden elements are erased
|
||||
$item = Folder::getItemForUrl($navigation, $urlRel, $uri->getBaseUrl(), NULL, $home);
|
||||
$item = Folder::getItemForUrl($navigation, $urlRel, $this->uri->getBaseUrl(), NULL, $home);
|
||||
}
|
||||
|
||||
# if there is still no item, return a 404-page
|
||||
@ -174,7 +149,7 @@ class PageController extends Controller
|
||||
return $this->render404($response, array(
|
||||
'navigation' => $navigation,
|
||||
'settings' => $this->settings,
|
||||
'base_url' => $base_url,
|
||||
'base_url' => $this->base_url,
|
||||
'title' => false,
|
||||
'content' => false,
|
||||
'item' => false,
|
||||
@ -187,7 +162,6 @@ class PageController extends Controller
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(isset($item->hide))
|
||||
{
|
||||
# if it is a hidden page
|
||||
@ -195,11 +169,11 @@ class PageController extends Controller
|
||||
{
|
||||
# get breadcrumb for page and set pages active
|
||||
# use structure here because the hidden item is not part of the navigation
|
||||
$breadcrumb = Folder::getBreadcrumb($structure, $item->keyPathArray);
|
||||
$breadcrumb = Folder::getBreadcrumb($this->structureLive, $item->keyPathArray);
|
||||
$breadcrumb = $this->c->dispatcher->dispatch('onBreadcrumbLoaded', new OnBreadcrumbLoaded($breadcrumb))->getData();
|
||||
|
||||
# add the paging to the item
|
||||
$item = Folder::getPagingForItem($structure, $item);
|
||||
$item = Folder::getPagingForItem($this->structureLive, $item);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -217,7 +191,7 @@ class PageController extends Controller
|
||||
$item = $this->c->dispatcher->dispatch('onItemLoaded', new OnItemLoaded($item))->getData();
|
||||
|
||||
# set the filepath
|
||||
$filePath = $pathToContent . $item->path;
|
||||
$filePath = $this->pathToContent . $item->path;
|
||||
|
||||
# check if url is a folder and add index.md
|
||||
if($item->elementType == 'folder')
|
||||
@ -230,6 +204,9 @@ class PageController extends Controller
|
||||
|
||||
# dispatch the original content without plugin-manipulations for case anyone wants to use it
|
||||
$this->c->dispatcher->dispatch('onOriginalLoaded', new OnOriginalLoaded($contentMD));
|
||||
|
||||
# initiate object for metadata
|
||||
$writeMeta = new WriteMeta();
|
||||
|
||||
# makes sure that you always have the full meta with title, description and all the rest.
|
||||
$metatabs = $writeMeta->completePageMeta($contentMD, $this->settings, $item);
|
||||
@ -243,7 +220,7 @@ class PageController extends Controller
|
||||
$itemUrl = isset($item->urlRel) ? $item->urlRel : false;
|
||||
|
||||
/* initialize parsedown */
|
||||
$parsedown = new ParsedownExtension($base_url, $this->settings);
|
||||
$parsedown = new ParsedownExtension($this->base_url, $this->settings);
|
||||
|
||||
/* set safe mode to escape javascript and html in markdown */
|
||||
$parsedown->setSafeMode(true);
|
||||
@ -334,21 +311,21 @@ class PageController extends Controller
|
||||
$firstImage = false;
|
||||
if($img_url)
|
||||
{
|
||||
$firstImage = array('img_url' => $base_url . '/' . $img_url, 'img_alt' => $img_alt);
|
||||
$firstImage = array('img_url' => $this->base_url . '/' . $img_url, 'img_alt' => $img_alt);
|
||||
}
|
||||
|
||||
$route = empty($args) && isset($this->settings['themes'][$theme]['cover']) ? '/cover.twig' : '/index.twig';
|
||||
|
||||
return $this->render($response, $route, [
|
||||
'home' => $home,
|
||||
'navigation' => $navigation,
|
||||
'navigation' => $navigation,
|
||||
'title' => $title,
|
||||
'content' => $contentHTML,
|
||||
'item' => $item,
|
||||
'breadcrumb' => $breadcrumb,
|
||||
'settings' => $this->settings,
|
||||
'base_url' => $this->base_url,
|
||||
'metatabs' => $metatabs,
|
||||
'base_url' => $base_url,
|
||||
'image' => $firstImage,
|
||||
'logo' => $logo,
|
||||
'favicon' => $favicon,
|
@ -14,7 +14,7 @@ use Typemill\Events\OnUserfieldsLoaded;
|
||||
use Typemill\Events\OnSystemnaviLoaded;
|
||||
use Typemill\Events\OnUserDeleted;
|
||||
|
||||
class SettingsController extends Controller
|
||||
class ControllerSettings extends ControllerShared
|
||||
{
|
||||
|
||||
public function showBlank($request, $response, $args)
|
||||
@ -22,7 +22,7 @@ class SettingsController extends Controller
|
||||
$user = new User();
|
||||
$settings = $this->c->get('settings');
|
||||
$route = $request->getAttribute('route');
|
||||
$navigation = $this->getNavigation();
|
||||
$navigation = $this->getMainNavigation();
|
||||
|
||||
$content = '<h1>Hello</h1><p>I am the showBlank method from the settings controller</p><p>In most cases I have been called from a plugin. But if you see this content, then the plugin does not work or has forgotten to inject its own content.</p>';
|
||||
|
||||
@ -48,7 +48,7 @@ class SettingsController extends Controller
|
||||
$languages = $this->getLanguages();
|
||||
$locale = isset($_SERVER['HTTP_ACCEPT_LANGUAGE']) ? substr($_SERVER["HTTP_ACCEPT_LANGUAGE"],0,2) : 'en';
|
||||
$route = $request->getAttribute('route');
|
||||
$navigation = $this->getNavigation();
|
||||
$navigation = $this->getMainNavigation();
|
||||
|
||||
# set navigation active
|
||||
$navigation['System']['active'] = true;
|
||||
@ -118,6 +118,8 @@ class SettingsController extends Controller
|
||||
'recoversubject' => $newSettings['recoversubject'],
|
||||
'recovermessage' => $newSettings['recovermessage'],
|
||||
'securitylog' => isset($newSettings['securitylog']) ? true : null,
|
||||
'oldslug' => isset($newSettings['oldslug']) ? true : null,
|
||||
'refreshcache' => isset($newSettings['refreshcache']) ? true : null,
|
||||
);
|
||||
|
||||
# https://www.slimframework.com/docs/v3/cookbook/uploading-files.html;
|
||||
@ -294,7 +296,7 @@ class SettingsController extends Controller
|
||||
|
||||
/* add the users for navigation */
|
||||
$route = $request->getAttribute('route');
|
||||
$navigation = $this->getNavigation();
|
||||
$navigation = $this->getMainNavigation();
|
||||
|
||||
# set navigation active
|
||||
$navigation['Themes']['active'] = true;
|
||||
@ -363,7 +365,7 @@ class SettingsController extends Controller
|
||||
}
|
||||
|
||||
$route = $request->getAttribute('route');
|
||||
$navigation = $this->getNavigation();
|
||||
$navigation = $this->getMainNavigation();
|
||||
|
||||
# set navigation active
|
||||
$navigation['Plugins']['active'] = true;
|
||||
@ -591,7 +593,7 @@ class SettingsController extends Controller
|
||||
$userform = $fieldsModel->getFields($userSettings, 'users', 'user', $fieldDefinitions);
|
||||
|
||||
$route = $request->getAttribute('route');
|
||||
$navigation = $this->getNavigation();
|
||||
$navigation = $this->getMainNavigation();
|
||||
|
||||
# set navigation active
|
||||
$navigation['Account']['active'] = true;
|
||||
@ -647,7 +649,7 @@ class SettingsController extends Controller
|
||||
$userform = $fieldsModel->getFields($userSettings, 'users', 'user', $fieldDefinitions);
|
||||
|
||||
$route = $request->getAttribute('route');
|
||||
$navigation = $this->getNavigation();
|
||||
$navigation = $this->getMainNavigation();
|
||||
|
||||
# set navigation active
|
||||
$navigation['Users']['active'] = true;
|
||||
@ -675,7 +677,7 @@ class SettingsController extends Controller
|
||||
$userdata = array();
|
||||
$route = $request->getAttribute('route');
|
||||
$settings = $this->c->get('settings');
|
||||
$navigation = $this->getNavigation();
|
||||
$navigation = $this->getMainNavigation();
|
||||
|
||||
# set navigation active
|
||||
$navigation['Users']['active'] = true;
|
||||
@ -764,7 +766,7 @@ class SettingsController extends Controller
|
||||
$userroles = $this->c->acl->getRoles();
|
||||
$route = $request->getAttribute('route');
|
||||
$settings = $this->c->get('settings');
|
||||
$navigation = $this->getNavigation();
|
||||
$navigation = $this->getMainNavigation();
|
||||
|
||||
# set navigation active
|
||||
$navigation['Users']['active'] = true;
|
||||
@ -969,22 +971,26 @@ class SettingsController extends Controller
|
||||
|
||||
public function clearCache($request, $response, $args)
|
||||
{
|
||||
$settings = $this->c->get('settings');
|
||||
$dir = $settings['basePath'] . 'cache';
|
||||
$uri = $request->getUri()->withUserInfo('');
|
||||
$pathToContent = $settings['rootPath'] . $settings['contentFolder'];
|
||||
|
||||
$writeCache = new writeCache();
|
||||
|
||||
$error = $writeCache->deleteCacheFiles($dir);
|
||||
$this->uri = $request->getUri()->withUserInfo('');
|
||||
$dir = $this->settings['basePath'] . 'cache';
|
||||
|
||||
$error = $this->writeCache->deleteCacheFiles($dir);
|
||||
if($error)
|
||||
{
|
||||
return $response->withJson(['errors' => $error], 500);
|
||||
}
|
||||
|
||||
# this recreates the cache for structure, structure-extended and navigation
|
||||
$writeCache->getFreshStructure($pathToContent, $uri);
|
||||
# create a new draft structure
|
||||
$this->setFreshStructureDraft();
|
||||
|
||||
# create a new draft structure
|
||||
$this->setFreshStructureLive();
|
||||
|
||||
# create a new draft structure
|
||||
$this->setFreshNavigation();
|
||||
|
||||
# update the sitemap
|
||||
$this->updateSitemap();
|
||||
|
||||
return $response->withJson(array('errors' => false));
|
||||
}
|
||||
@ -1083,7 +1089,7 @@ class SettingsController extends Controller
|
||||
);
|
||||
}
|
||||
|
||||
private function getNavigation()
|
||||
private function getMainNavigation()
|
||||
{
|
||||
$navigation = [
|
||||
'System' => ['routename' => 'settings.show', 'icon' => 'icon-wrench', 'aclresource' => 'system', 'aclprivilege' => 'view'],
|
446
system/Controllers/ControllerShared.php
Normal file
446
system/Controllers/ControllerShared.php
Normal file
@ -0,0 +1,446 @@
|
||||
<?php
|
||||
|
||||
namespace Typemill\Controllers;
|
||||
|
||||
use Psr\Container\ContainerInterface;
|
||||
use Typemill\Models\Folder;
|
||||
use Typemill\Models\WriteCache;
|
||||
use Typemill\Models\WriteYaml;
|
||||
use Typemill\Events\OnPageReady;
|
||||
|
||||
abstract class ControllerShared
|
||||
{
|
||||
# holds the pimple container
|
||||
protected $c;
|
||||
|
||||
# holds the settings
|
||||
protected $settings;
|
||||
|
||||
# holds the write cache object
|
||||
protected $writeCache;
|
||||
|
||||
# holds the structure of content folder as a serialized array of objects
|
||||
protected $structureDraft = false;
|
||||
|
||||
# holds the structure of content folder as a serialized array of objects
|
||||
protected $structureLive = false;
|
||||
|
||||
# holds the name of the structure-file with drafts for author environment
|
||||
protected $structureDraftName = 'structure-draft.txt';
|
||||
|
||||
# holds the name of the structure-file without drafts for live site
|
||||
protected $structureLiveName = 'structure.txt';
|
||||
|
||||
# holds the frontend navigation without hidden pages
|
||||
protected $navigation = false;
|
||||
|
||||
# holds the list of pages with navigation titles and hidden pages. It extends the structures and navigations
|
||||
protected $extended = false;
|
||||
|
||||
public function __construct(ContainerInterface $c)
|
||||
{
|
||||
$this->c = $c;
|
||||
$this->settings = $this->c->get('settings');
|
||||
|
||||
# used everywhere so instantiate it
|
||||
$this->writeCache = new writeCache();
|
||||
|
||||
$this->c->dispatcher->dispatch('onTwigLoaded');
|
||||
}
|
||||
|
||||
# render page for frontend
|
||||
protected function render($response, $route, $data)
|
||||
{
|
||||
# why commented this out??
|
||||
$data = $this->c->dispatcher->dispatch('onPageReady', new OnPageReady($data))->getData();
|
||||
|
||||
if(isset($_SESSION['old']))
|
||||
{
|
||||
unset($_SESSION['old']);
|
||||
}
|
||||
|
||||
$response = $response->withoutHeader('Server');
|
||||
$response = $response->withAddedHeader('X-Powered-By', 'Typemill');
|
||||
|
||||
if(!isset($this->settings['headersoff']) or !$this->settings['headersoff'])
|
||||
{
|
||||
$response = $response->withAddedHeader('X-Content-Type-Options', 'nosniff');
|
||||
$response = $response->withAddedHeader('X-Frame-Options', 'SAMEORIGIN');
|
||||
$response = $response->withAddedHeader('X-XSS-Protection', '1;mode=block');
|
||||
$response = $response->withAddedHeader('Referrer-Policy', 'no-referrer-when-downgrade');
|
||||
if($this->c->request->getUri()->getScheme() == 'https')
|
||||
{
|
||||
$response = $response->withAddedHeader('Strict-Transport-Security', 'max-age=63072000');
|
||||
}
|
||||
}
|
||||
|
||||
return $this->c->view->render($response, $route, $data);
|
||||
}
|
||||
|
||||
# render 404 for frontend
|
||||
protected function render404($response, $data = NULL)
|
||||
{
|
||||
return $this->c->view->render($response->withStatus(404), '/404.twig', $data);
|
||||
}
|
||||
|
||||
# render page for authors (admin-area)
|
||||
protected function renderIntern($response, $route, $data)
|
||||
{
|
||||
if(isset($_SESSION['old']))
|
||||
{
|
||||
unset($_SESSION['old']);
|
||||
}
|
||||
|
||||
$response = $response->withoutHeader('Server');
|
||||
$response = $response->withAddedHeader('X-Powered-By', 'Typemill');
|
||||
|
||||
if(!isset($this->settings['headersoff']) or !$this->settings['headersoff'])
|
||||
{
|
||||
$response = $response->withAddedHeader('X-Content-Type-Options', 'nosniff');
|
||||
$response = $response->withAddedHeader('X-Frame-Options', 'SAMEORIGIN');
|
||||
$response = $response->withAddedHeader('X-XSS-Protection', '1;mode=block');
|
||||
$response = $response->withAddedHeader('Referrer-Policy', 'no-referrer-when-downgrade');
|
||||
if($this->c->request->getUri()->getScheme() == 'https')
|
||||
{
|
||||
$response = $response->withAddedHeader('Strict-Transport-Security', 'max-age=63072000');
|
||||
}
|
||||
}
|
||||
|
||||
return $this->c->view->render($response, $route, $data);
|
||||
}
|
||||
|
||||
# render 404 for authors
|
||||
protected function renderIntern404($response, $data = NULL)
|
||||
{
|
||||
return $this->c->view->render($response->withStatus(404), '/intern404.twig', $data);
|
||||
}
|
||||
|
||||
# reads the cached structure with published and non-published pages for the author
|
||||
protected function setStructureDraft()
|
||||
{
|
||||
# get the cached structure
|
||||
$this->structureDraft = $this->writeCache->getCache('cache', $this->structureDraftName);
|
||||
|
||||
# if there is no cached structure
|
||||
if(!$this->structureDraft)
|
||||
{
|
||||
return $this->setFreshStructureDraft();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
# creates a fresh structure with published and non-published pages for the author
|
||||
protected function setFreshStructureDraft()
|
||||
{
|
||||
# scan the content of the folder
|
||||
$pagetreeDraft = Folder::scanFolder($this->settings['rootPath'] . $this->settings['contentFolder'], $draft = true );
|
||||
|
||||
# if there is content, then get the content details
|
||||
if(count($pagetreeDraft) > 0)
|
||||
{
|
||||
# get the extended structure files with changes like navigation title or hidden pages
|
||||
$yaml = new writeYaml();
|
||||
$extended = $this->getExtended();
|
||||
|
||||
# create an array of object with the whole content of the folder and changes from extended file
|
||||
$this->structureDraft = Folder::getFolderContentDetails($pagetreeDraft, $extended, $this->settings, $this->uri->getBaseUrl(), $this->uri->getBasePath());
|
||||
|
||||
# cache structure draft
|
||||
$this->writeCache->updateCache('cache', $this->structureDraftName, 'lastCache.txt', $this->structureDraft);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
# reads the cached structure of published pages
|
||||
protected function setStructureLive()
|
||||
{
|
||||
# get the cached structure
|
||||
$this->structureLive = $this->writeCache->getCache('cache', $this->structureLiveName);
|
||||
|
||||
# if there is no cached structure
|
||||
if(!$this->structureLive)
|
||||
{
|
||||
return $this->setFreshStructureLive();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
# creates a fresh structure with published pages
|
||||
protected function setFreshStructureLive()
|
||||
{
|
||||
# scan the content of the folder
|
||||
$pagetreeLive = Folder::scanFolder($this->settings['rootPath'] . $this->settings['contentFolder'], $draft = false );
|
||||
|
||||
# if there is content, then get the content details
|
||||
if(count($pagetreeLive) > 0)
|
||||
{
|
||||
# get the extended structure files with changes like navigation title or hidden pages
|
||||
$yaml = new writeYaml();
|
||||
$extended = $this->getExtended();
|
||||
|
||||
# create an array of object with the whole content of the folder and changes from extended file
|
||||
$this->structureLive = Folder::getFolderContentDetails($pagetreeLive, $extended, $this->settings, $this->uri->getBaseUrl(), $this->uri->getBasePath());
|
||||
|
||||
# cache structure live
|
||||
$this->writeCache->updateCache('cache', $this->structureLiveName, 'lastCache.txt', $this->structureLive);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
# reads the live navigation from cache (live structure without hidden pages)
|
||||
protected function setNavigation()
|
||||
{
|
||||
# get the cached structure
|
||||
$this->navigation = $this->writeCache->getCache('cache', 'navigation.txt');
|
||||
|
||||
# if there is no cached structure
|
||||
if(!$this->navigation)
|
||||
{
|
||||
return $this->setFreshNavigation();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
# creates a fresh live navigation (live structure without hidden pages)
|
||||
protected function setFreshNavigation()
|
||||
{
|
||||
|
||||
if(!$this->extended)
|
||||
{
|
||||
$extended = $this->getExtended();
|
||||
}
|
||||
|
||||
if($this->containsHiddenPages($this->extended))
|
||||
{
|
||||
if(!$this->structureLive)
|
||||
{
|
||||
$this->setStructureLive();
|
||||
}
|
||||
|
||||
$structureLive = $this->structureLive;
|
||||
$this->navigation = $this->createNavigation($structureLive);
|
||||
|
||||
# cache navigation
|
||||
$this->writeCache->updateCache('cache', 'navigation.txt', false, $this->navigation);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
# make sure no old navigation file is left
|
||||
$this->writeCache->deleteFileWithPath('cache' . DIRECTORY_SEPARATOR . 'navigation.txt');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
# create navigation from structure
|
||||
protected function createNavigation($structureLive)
|
||||
{
|
||||
foreach ($structureLive as $key => $element)
|
||||
{
|
||||
if($element->hide === true)
|
||||
{
|
||||
unset($structureLive[$key]);
|
||||
}
|
||||
elseif(isset($element->folderContent))
|
||||
{
|
||||
$structureLive[$key]->folderContent = $this->createNavigation($element->folderContent);
|
||||
}
|
||||
}
|
||||
|
||||
return $structureLive;
|
||||
}
|
||||
|
||||
# controllerFrontendWebsite, but not in use, makes no sense to check on each page load
|
||||
public function checkSitemap()
|
||||
{
|
||||
if(!$this->writeCache->getCache('cache', 'sitemap.xml'))
|
||||
{
|
||||
if(!$this->structureLive)
|
||||
{
|
||||
$this->setStructureLive();
|
||||
}
|
||||
|
||||
$this->updateSitemap();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function updateSitemap()
|
||||
{
|
||||
$sitemap = '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
|
||||
$sitemap .= '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">' . "\n";
|
||||
$sitemap = $this->addUrlSet($sitemap, $this->uri->getBaseUrl());
|
||||
$sitemap .= $this->generateUrlSets($this->structureLive);
|
||||
$sitemap .= '</urlset>';
|
||||
|
||||
$this->writeCache->writeFile('cache', 'sitemap.xml', $sitemap);
|
||||
}
|
||||
|
||||
public function generateUrlSets($structureLive)
|
||||
{
|
||||
$urlset = '';
|
||||
|
||||
foreach($structureLive as $item)
|
||||
{
|
||||
if($item->elementType == 'folder')
|
||||
{
|
||||
$urlset = $this->addUrlSet($urlset, $item->urlAbs);
|
||||
$urlset .= $this->generateUrlSets($item->folderContent, $urlset);
|
||||
}
|
||||
else
|
||||
{
|
||||
$urlset = $this->addUrlSet($urlset, $item->urlAbs);
|
||||
}
|
||||
}
|
||||
return $urlset;
|
||||
}
|
||||
|
||||
public function addUrlSet($urlset, $url)
|
||||
{
|
||||
$urlset .= ' <url>' . "\n";
|
||||
$urlset .= ' <loc>' . $url . '</loc>' . "\n";
|
||||
$urlset .= ' </url>' . "\n";
|
||||
return $urlset;
|
||||
}
|
||||
|
||||
protected function getExtended()
|
||||
{
|
||||
$yaml = new writeYaml();
|
||||
|
||||
if(!$this->extended)
|
||||
{
|
||||
$this->extended = $yaml->getYaml('cache', 'structure-extended.yaml');
|
||||
}
|
||||
|
||||
if(!$this->extended)
|
||||
{
|
||||
# scan the content of the folder
|
||||
$pagetreeDraft = Folder::scanFolder($this->settings['rootPath'] . $this->settings['contentFolder'], $draft = true );
|
||||
|
||||
# if there is content, then get the content details
|
||||
if(count($pagetreeDraft) == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
# create an array of object with the whole content of the folder and changes from extended file
|
||||
$structureDraft = Folder::getFolderContentDetails($pagetreeDraft, $extended = false, $this->settings, $this->uri->getBaseUrl(), $this->uri->getBasePath());
|
||||
|
||||
$this->extended = $this->createExtended($this->settings['rootPath'] . $this->settings['contentFolder'], $yaml, $structureDraft);
|
||||
|
||||
$yaml->updateYaml('cache', 'structure-extended.yaml', $this->extended);
|
||||
}
|
||||
|
||||
return $this->extended;
|
||||
}
|
||||
|
||||
# creates a file that holds all hide flags and navigation titles
|
||||
# reads all meta-files and creates an array with url => ['hide' => bool, 'navtitle' => 'bla']
|
||||
public function createExtended($contentPath, $yaml, $structureLive, $extended = NULL)
|
||||
{
|
||||
if(!$extended)
|
||||
{
|
||||
$extended = [];
|
||||
}
|
||||
|
||||
foreach ($structureLive as $key => $item)
|
||||
{
|
||||
# $filename = ($item->elementType == 'folder') ? DIRECTORY_SEPARATOR . 'index.yaml' : $item->pathWithoutType . '.yaml';
|
||||
$filename = $item->pathWithoutType . '.yaml';
|
||||
|
||||
if(file_exists($contentPath . $filename))
|
||||
{
|
||||
# read file
|
||||
$meta = $yaml->getYaml('content', $filename);
|
||||
|
||||
$extended[$item->urlRelWoF]['hide'] = isset($meta['meta']['hide']) ? $meta['meta']['hide'] : false;
|
||||
$extended[$item->urlRelWoF]['navtitle'] = isset($meta['meta']['navtitle']) ? $meta['meta']['navtitle'] : '';
|
||||
}
|
||||
|
||||
if ($item->elementType == 'folder')
|
||||
{
|
||||
$extended = $this->createExtended($contentPath, $yaml, $item->folderContent, $extended);
|
||||
}
|
||||
}
|
||||
return $extended;
|
||||
}
|
||||
|
||||
# only backoffice
|
||||
protected function renameExtended($item, $newFolder)
|
||||
{
|
||||
# get the extended structure files with changes like navigation title or hidden pages
|
||||
$yaml = new writeYaml();
|
||||
$extended = $yaml->getYaml('cache', 'structure-extended.yaml');
|
||||
|
||||
if(isset($extended[$item->urlRelWoF]))
|
||||
{
|
||||
$newUrl = $newFolder->urlRelWoF . '/' . $item->slug;
|
||||
|
||||
$entry = $extended[$item->urlRelWoF];
|
||||
|
||||
unset($extended[$item->urlRelWoF]);
|
||||
|
||||
$extended[$newUrl] = $entry;
|
||||
$yaml->updateYaml('cache', 'structure-extended.yaml', $extended);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
# only backoffice
|
||||
protected function deleteFromExtended()
|
||||
{
|
||||
# get the extended structure files with changes like navigation title or hidden pages
|
||||
$yaml = new writeYaml();
|
||||
$extended = $yaml->getYaml('cache', 'structure-extended.yaml');
|
||||
|
||||
if($this->item->elementType == "file" && isset($extended[$this->item->urlRelWoF]))
|
||||
{
|
||||
unset($extended[$this->item->urlRelWoF]);
|
||||
$yaml->updateYaml('cache', 'structure-extended.yaml', $extended);
|
||||
}
|
||||
|
||||
if($this->item->elementType == "folder")
|
||||
{
|
||||
$changed = false;
|
||||
|
||||
# delete all entries with that folder url
|
||||
foreach($extended as $url => $entries)
|
||||
{
|
||||
if( strpos($url, $this->item->urlRelWoF) !== false )
|
||||
{
|
||||
$changed = true;
|
||||
unset($extended[$url]);
|
||||
}
|
||||
}
|
||||
|
||||
if($changed)
|
||||
{
|
||||
$yaml->updateYaml('cache', 'structure-extended.yaml', $extended);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# checks if there is a hidden page, returns true on first find
|
||||
protected function containsHiddenPages($extended)
|
||||
{
|
||||
foreach($extended as $element)
|
||||
{
|
||||
if(isset($element['hide']) && $element['hide'] === true)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
@ -2,7 +2,7 @@
|
||||
|
||||
namespace Typemill\Extensions;
|
||||
|
||||
use \URLify;
|
||||
use Typemill\Models\Folder;
|
||||
|
||||
class ParsedownExtension extends \ParsedownExtra
|
||||
{
|
||||
@ -10,6 +10,8 @@ class ParsedownExtension extends \ParsedownExtra
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->settings = $settings;
|
||||
|
||||
# show anchor next to headline?
|
||||
$this->showAnchor = isset($settings['headlineanchors']) ? $settings['headlineanchors'] : false;
|
||||
|
||||
@ -329,7 +331,7 @@ class ParsedownExtension extends \ParsedownExtra
|
||||
}
|
||||
|
||||
$text = trim($Line['text'], '#');
|
||||
$headline = URLify::filter($Line['text']);
|
||||
$headline = Folder::createSlug($Line['text'], $this->settings);
|
||||
|
||||
if ($this->strictMode and isset($text[0]) and $text[0] !== ' ')
|
||||
{
|
||||
|
@ -69,7 +69,7 @@ class Folder
|
||||
|
||||
if($fileType == 'md')
|
||||
{
|
||||
$folderContent[] = $item;
|
||||
$folderContent[] = $item;
|
||||
}
|
||||
|
||||
if($draft === true && $fileType == 'txt')
|
||||
@ -97,7 +97,7 @@ class Folder
|
||||
* 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)
|
||||
public static function getFolderContentDetails(array $folderContent, $extended, $settings, $baseUrl, $fullSlugWithFolder = NULL, $fullSlugWithoutFolder = NULL, $fullPath = NULL, $keyPath = NULL, $chapter = NULL)
|
||||
{
|
||||
$contentDetails = [];
|
||||
$iteration = 0;
|
||||
@ -130,14 +130,14 @@ class Folder
|
||||
|
||||
$item->originalName = $key;
|
||||
$item->elementType = 'folder';
|
||||
$item->contains = self::getFolderContentType($name, $fullPath . DIRECTORY_SEPARATOR . $key . DIRECTORY_SEPARATOR . 'index.yaml');
|
||||
$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 = self::createSlug($item->slug, $settings);
|
||||
$item->path = $fullPath . DIRECTORY_SEPARATOR . $key;
|
||||
$item->pathWithoutType = $fullPath . DIRECTORY_SEPARATOR . $key . DIRECTORY_SEPARATOR . 'index';
|
||||
$item->urlRelWoF = $fullSlugWithoutFolder . '/' . $item->slug;
|
||||
@ -164,7 +164,7 @@ class Folder
|
||||
rsort($name);
|
||||
}
|
||||
|
||||
$item->folderContent = self::getFolderContentDetails($name, $extended, $baseUrl, $item->urlRel, $item->urlRelWoF, $item->path, $item->keyPath, $item->chapter);
|
||||
$item->folderContent = self::getFolderContentDetails($name, $extended, $settings, $baseUrl, $item->urlRel, $item->urlRelWoF, $item->path, $item->keyPath, $item->chapter);
|
||||
}
|
||||
elseif($name)
|
||||
{
|
||||
@ -200,7 +200,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 = self::createSlug($item->slug, $settings);
|
||||
$item->path = $fullPath . DIRECTORY_SEPARATOR . $name;
|
||||
$item->pathWithoutType = $fullPath . DIRECTORY_SEPARATOR . $nameWithoutType;
|
||||
$item->key = $iteration;
|
||||
@ -637,4 +637,31 @@ class Folder
|
||||
$parts = preg_split('/\./',$fileName);
|
||||
return $parts[0];
|
||||
}
|
||||
|
||||
public static function createSlug($name, $settings = NULL)
|
||||
{
|
||||
$name = iconv(mb_detect_encoding($name, mb_detect_order(), true), "UTF-8", $name);
|
||||
|
||||
# prior version 1.5.0 settings was no language and remove stop words from slug
|
||||
$language = "";
|
||||
$use_remove_list = true;
|
||||
|
||||
# if user has not activated the old slug logig < version 1.5.0 style
|
||||
if($settings && ( !isset($settings['oldslug']) OR !$settings['oldslug'] ) )
|
||||
{
|
||||
# then use the language attr and do not remove stop words as default behavior
|
||||
$language = isset($settings['langattr']) ? $settings['langattr'] : "";
|
||||
$use_remove_list = false;
|
||||
}
|
||||
|
||||
return URLify::filter(
|
||||
$name,
|
||||
$length = 60,
|
||||
$language,
|
||||
$file_name = false,
|
||||
$use_remove_list,
|
||||
$lower_case = true,
|
||||
$treat_underscore_as_space = true
|
||||
);
|
||||
}
|
||||
}
|
@ -28,6 +28,7 @@ class Helpers{
|
||||
return $ip;
|
||||
}
|
||||
|
||||
|
||||
public static function addLogEntry($action)
|
||||
{
|
||||
$line = self::getUserIP();
|
||||
|
@ -1,7 +1,7 @@
|
||||
<?php
|
||||
namespace Typemill\Models;
|
||||
|
||||
use \URLify;
|
||||
use Typemill\Models\Folder;
|
||||
|
||||
class ProcessAssets
|
||||
{
|
||||
@ -107,7 +107,7 @@ class ProcessAssets
|
||||
$pathinfo = pathinfo($originalname);
|
||||
|
||||
$this->extension = strtolower($pathinfo['extension']);
|
||||
$this->filename = URLify::filter(iconv(mb_detect_encoding($pathinfo['filename'], mb_detect_order(), true), "UTF-8", $pathinfo['filename']));
|
||||
$this->filename = Folder::createSlug($pathinfo['filename']);
|
||||
|
||||
$filename = $this->filename;
|
||||
|
||||
|
@ -3,7 +3,6 @@ namespace Typemill\Models;
|
||||
|
||||
use Slim\Http\UploadedFile;
|
||||
use Typemill\Models\Helpers;
|
||||
use \URLify;
|
||||
|
||||
class ProcessFile extends ProcessAssets
|
||||
{
|
||||
|
@ -1,29 +0,0 @@
|
||||
<?php
|
||||
|
||||
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)
|
||||
{
|
||||
$opts = array(
|
||||
'http'=>array(
|
||||
'method' => "GET",
|
||||
'header' => "Referer: $url\r\n"
|
||||
)
|
||||
);
|
||||
|
||||
$context = stream_context_create($opts);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
@ -127,8 +127,39 @@ class Write
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
public function moveElement($item, $folderPath, $index, $date = null)
|
||||
{
|
||||
$filetypes = array('md', 'txt', 'yaml');
|
||||
@ -178,35 +209,4 @@ 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;
|
||||
}
|
||||
}
|
@ -110,124 +110,4 @@ class WriteCache extends Write
|
||||
|
||||
return $error;
|
||||
}
|
||||
|
||||
public function getFreshStructure($contentPath, $uri)
|
||||
{
|
||||
# scan the content of the folder
|
||||
$pagetree = Folder::scanFolder('content');
|
||||
|
||||
# if there is no content, render an empty page
|
||||
if(count($pagetree) == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
# get the extended structure files with changes like navigation title or hidden pages
|
||||
$yaml = new writeYaml();
|
||||
$extended = $yaml->getYaml('cache', 'structure-extended.yaml');
|
||||
|
||||
# create an array of object with the whole content of the folder
|
||||
$structure = Folder::getFolderContentDetails($pagetree, $extended, $uri->getBaseUrl(), $uri->getBasePath());
|
||||
|
||||
# now update the extended structure
|
||||
if(!$extended)
|
||||
{
|
||||
$extended = $this->createExtended($contentPath, $yaml, $structure);
|
||||
|
||||
if(!empty($extended))
|
||||
{
|
||||
$yaml->updateYaml('cache', 'structure-extended.yaml', $extended);
|
||||
|
||||
# we have to update the structure with extended again
|
||||
$structure = Folder::getFolderContentDetails($pagetree, $extended, $uri->getBaseUrl(), $uri->getBasePath());
|
||||
}
|
||||
else
|
||||
{
|
||||
$extended = false;
|
||||
}
|
||||
}
|
||||
|
||||
# cache structure
|
||||
$this->updateCache('cache', 'structure.txt', 'lastCache.txt', $structure);
|
||||
|
||||
if($extended && $this->containsHiddenPages($extended))
|
||||
{
|
||||
# generate the navigation (delete empty pages)
|
||||
$navigation = $this->createNavigationFromStructure($structure);
|
||||
|
||||
# cache navigation
|
||||
$this->updateCache('cache', 'navigation.txt', false, $navigation);
|
||||
}
|
||||
else
|
||||
{
|
||||
# make sure no separate navigation file is set
|
||||
$this->deleteFileWithPath('cache' . DIRECTORY_SEPARATOR . 'navigation.txt');
|
||||
}
|
||||
|
||||
# load and return the cached structure, because might be manipulated with navigation....
|
||||
$structure = $this->getCachedStructure();
|
||||
|
||||
return $structure;
|
||||
}
|
||||
|
||||
# creates a file that holds all hide flags and navigation titles
|
||||
# reads all meta-files and creates an array with url => ['hide' => bool, 'navtitle' => 'bla']
|
||||
public function createExtended($contentPath, $yaml, $structure, $extended = NULL)
|
||||
{
|
||||
if(!$extended)
|
||||
{
|
||||
$extended = [];
|
||||
}
|
||||
|
||||
foreach ($structure as $key => $item)
|
||||
{
|
||||
# $filename = ($item->elementType == 'folder') ? DIRECTORY_SEPARATOR . 'index.yaml' : $item->pathWithoutType . '.yaml';
|
||||
$filename = $item->pathWithoutType . '.yaml';
|
||||
|
||||
if(file_exists($contentPath . $filename))
|
||||
{
|
||||
# read file
|
||||
$meta = $yaml->getYaml('content', $filename);
|
||||
|
||||
$extended[$item->urlRelWoF]['hide'] = isset($meta['meta']['hide']) ? $meta['meta']['hide'] : false;
|
||||
$extended[$item->urlRelWoF]['navtitle'] = isset($meta['meta']['navtitle']) ? $meta['meta']['navtitle'] : '';
|
||||
}
|
||||
|
||||
if ($item->elementType == 'folder')
|
||||
{
|
||||
$extended = $this->createExtended($contentPath, $yaml, $item->folderContent, $extended);
|
||||
}
|
||||
}
|
||||
return $extended;
|
||||
}
|
||||
|
||||
public function createNavigationFromStructure($navigation)
|
||||
{
|
||||
foreach ($navigation as $key => $element)
|
||||
{
|
||||
if($element->hide === true)
|
||||
{
|
||||
unset($navigation[$key]);
|
||||
}
|
||||
elseif(isset($element->folderContent))
|
||||
{
|
||||
$navigation[$key]->folderContent = $this->createNavigationFromStructure($element->folderContent);
|
||||
}
|
||||
}
|
||||
|
||||
return $navigation;
|
||||
}
|
||||
|
||||
# checks if there is a hidden page, returns true on first find
|
||||
protected function containsHiddenPages($extended)
|
||||
{
|
||||
foreach($extended as $element)
|
||||
{
|
||||
if(isset($element['hide']) && $element['hide'] === true)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Typemill\Models;
|
||||
|
||||
class WriteSitemap extends Write
|
||||
{
|
||||
public function updateSitemap($folderName, $sitemapFileName, $requestFileName, $data, $baseUrl)
|
||||
{
|
||||
$sitemap = '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
|
||||
$sitemap .= '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">' . "\n";
|
||||
$sitemap = $this->addUrlSet($sitemap, $baseUrl);
|
||||
$sitemap .= $this->generateUrlSets($data);
|
||||
$sitemap .= '</urlset>';
|
||||
|
||||
$this->writeFile($folderName, $sitemapFileName, $sitemap);
|
||||
$this->writeFile($folderName, $requestFileName, time());
|
||||
}
|
||||
|
||||
public function generateUrlSets($data)
|
||||
{
|
||||
$urlset = '';
|
||||
|
||||
foreach($data as $item)
|
||||
{
|
||||
if($item->elementType == 'folder')
|
||||
{
|
||||
$urlset = $this->addUrlSet($urlset, $item->urlAbs);
|
||||
$urlset .= $this->generateUrlSets($item->folderContent, $urlset);
|
||||
}
|
||||
else
|
||||
{
|
||||
$urlset = $this->addUrlSet($urlset, $item->urlAbs);
|
||||
}
|
||||
}
|
||||
return $urlset;
|
||||
}
|
||||
|
||||
public function addUrlSet($urlset, $url)
|
||||
{
|
||||
$urlset .= ' <url>' . "\n";
|
||||
$urlset .= ' <loc>' . $url . '</loc>' . "\n";
|
||||
$urlset .= ' </url>' . "\n";
|
||||
return $urlset;
|
||||
}
|
||||
}
|
@ -1,52 +1,50 @@
|
||||
<?php
|
||||
|
||||
use Typemill\Controllers\SettingsController;
|
||||
use Typemill\Controllers\ContentController;
|
||||
use Typemill\Controllers\ContentApiController;
|
||||
use Typemill\Controllers\ArticleApiController;
|
||||
use Typemill\Controllers\BlockApiController;
|
||||
use Typemill\Controllers\MediaApiController;
|
||||
use Typemill\Controllers\MetaApiController;
|
||||
use Typemill\Controllers\ControllerAuthorArticleApi;
|
||||
use Typemill\Controllers\ControllerAuthorBlockApi;
|
||||
use Typemill\Controllers\ControllerAuthorMetaApi;
|
||||
use Typemill\Controllers\ControllerAuthorMediaApi;
|
||||
use Typemill\Controllers\ControllerSettings;
|
||||
use Typemill\Middleware\RestrictApiAccess;
|
||||
|
||||
$app->get('/api/v1/themes', SettingsController::class . ':getThemeSettings')->setName('api.themes')->add(new RestrictApiAccess($container['router']));
|
||||
$app->delete('/api/v1/clearcache', SettingsController::class . ':clearCache')->setName('api.clearcache')->add(new RestrictApiAccess($container['router']));
|
||||
$app->get('/api/v1/users/getbynames', SettingsController::class . ':getUsersByNames')->setName('api.usersbynames')->add(new RestrictApiAccess($container['router']));
|
||||
$app->get('/api/v1/users/getbyemail', SettingsController::class . ':getUsersByEmail')->setName('api.usersbyemail')->add(new RestrictApiAccess($container['router']));
|
||||
$app->get('/api/v1/users/getbyrole', SettingsController::class . ':getUsersByRole')->setName('api.usersbyrole')->add(new RestrictApiAccess($container['router']));
|
||||
$app->get('/api/v1/themes', ControllerSettings::class . ':getThemeSettings')->setName('api.themes')->add(new RestrictApiAccess($container['router']));
|
||||
$app->delete('/api/v1/clearcache', ControllerSettings::class . ':clearCache')->setName('api.clearcache')->add(new RestrictApiAccess($container['router']));
|
||||
$app->get('/api/v1/users/getbynames', ControllerSettings::class . ':getUsersByNames')->setName('api.usersbynames')->add(new RestrictApiAccess($container['router']));
|
||||
$app->get('/api/v1/users/getbyemail', ControllerSettings::class . ':getUsersByEmail')->setName('api.usersbyemail')->add(new RestrictApiAccess($container['router']));
|
||||
$app->get('/api/v1/users/getbyrole', ControllerSettings::class . ':getUsersByRole')->setName('api.usersbyrole')->add(new RestrictApiAccess($container['router']));
|
||||
|
||||
$app->post('/api/v1/article/markdown', ArticleApiController::class . ':getArticleMarkdown')->setName('api.article.markdown')->add(new RestrictApiAccess($container['router']));
|
||||
$app->post('/api/v1/article/html', ArticleApiController::class . ':getArticleHtml')->setName('api.article.html')->add(new RestrictApiAccess($container['router']));
|
||||
$app->post('/api/v1/article/publish', ArticleApiController::class . ':publishArticle')->setName('api.article.publish')->add(new RestrictApiAccess($container['router']));
|
||||
$app->delete('/api/v1/article/unpublish', ArticleApiController::class . ':unpublishArticle')->setName('api.article.unpublish')->add(new RestrictApiAccess($container['router']));
|
||||
$app->delete('/api/v1/article/discard', ArticleApiController::class . ':discardArticleChanges')->setName('api.article.discard')->add(new RestrictApiAccess($container['router']));
|
||||
$app->post('/api/v1/article/rename', ArticleApiController::class . ':renameArticle')->setName('api.article.rename')->add(new RestrictApiAccess($container['router']));
|
||||
$app->post('/api/v1/article/sort', ArticleApiController::class . ':sortArticle')->setName('api.article.sort')->add(new RestrictApiAccess($container['router']));
|
||||
$app->post('/api/v1/article', ArticleApiController::class . ':createArticle')->setName('api.article.create')->add(new RestrictApiAccess($container['router']));
|
||||
$app->put('/api/v1/article', ArticleApiController::class . ':updateArticle')->setName('api.article.update')->add(new RestrictApiAccess($container['router']));
|
||||
$app->delete('/api/v1/article', ArticleApiController::class . ':deleteArticle')->setName('api.article.delete')->add(new RestrictApiAccess($container['router']));
|
||||
$app->post('/api/v1/baseitem', ArticleApiController::class . ':createBaseItem')->setName('api.baseitem.create')->add(new RestrictApiAccess($container['router']));
|
||||
$app->get('/api/v1/navigation', ArticleApiController::class . ':getNavigation')->setName('api.navigation.get')->add(new RestrictApiAccess($container['router']));
|
||||
$app->post('/api/v1/post', ArticleApiController::class . ':createPost')->setName('api.post.create')->add(new RestrictApiAccess($container['router']));
|
||||
$app->post('/api/v1/article/markdown', ControllerAuthorArticleApi::class . ':getArticleMarkdown')->setName('api.article.markdown')->add(new RestrictApiAccess($container['router']));
|
||||
$app->post('/api/v1/article/html', ControllerAuthorArticleApi::class . ':getArticleHtml')->setName('api.article.html')->add(new RestrictApiAccess($container['router']));
|
||||
$app->post('/api/v1/article/publish', ControllerAuthorArticleApi::class . ':publishArticle')->setName('api.article.publish')->add(new RestrictApiAccess($container['router']));
|
||||
$app->delete('/api/v1/article/unpublish', ControllerAuthorArticleApi::class . ':unpublishArticle')->setName('api.article.unpublish')->add(new RestrictApiAccess($container['router']));
|
||||
$app->delete('/api/v1/article/discard', ControllerAuthorArticleApi::class . ':discardArticleChanges')->setName('api.article.discard')->add(new RestrictApiAccess($container['router']));
|
||||
$app->post('/api/v1/article/rename', ControllerAuthorArticleApi::class . ':renameArticle')->setName('api.article.rename')->add(new RestrictApiAccess($container['router']));
|
||||
$app->post('/api/v1/article/sort', ControllerAuthorArticleApi::class . ':sortArticle')->setName('api.article.sort')->add(new RestrictApiAccess($container['router']));
|
||||
$app->post('/api/v1/article', ControllerAuthorArticleApi::class . ':createArticle')->setName('api.article.create')->add(new RestrictApiAccess($container['router']));
|
||||
$app->put('/api/v1/article', ControllerAuthorArticleApi::class . ':updateArticle')->setName('api.article.update')->add(new RestrictApiAccess($container['router']));
|
||||
$app->delete('/api/v1/article', ControllerAuthorArticleApi::class . ':deleteArticle')->setName('api.article.delete')->add(new RestrictApiAccess($container['router']));
|
||||
$app->post('/api/v1/baseitem', ControllerAuthorArticleApi::class . ':createBaseItem')->setName('api.baseitem.create')->add(new RestrictApiAccess($container['router']));
|
||||
$app->get('/api/v1/navigation', ControllerAuthorArticleApi::class . ':getNavigation')->setName('api.navigation.get')->add(new RestrictApiAccess($container['router']));
|
||||
$app->post('/api/v1/post', ControllerAuthorArticleApi::class . ':createPost')->setName('api.post.create')->add(new RestrictApiAccess($container['router']));
|
||||
|
||||
$app->get('/api/v1/metadefinitions', MetaApiController::class . ':getMetaDefinitions')->setName('api.metadefinitions.get')->add(new RestrictApiAccess($container['router']));
|
||||
$app->get('/api/v1/article/metaobject', MetaApiController::class . ':getArticleMetaobject')->setName('api.articlemetaobject.get')->add(new RestrictApiAccess($container['router']));
|
||||
$app->get('/api/v1/article/metadata', MetaApiController::class . ':getArticleMeta')->setName('api.articlemeta.get')->add(new RestrictApiAccess($container['router']));
|
||||
$app->post('/api/v1/article/metadata', MetaApiController::class . ':updateArticleMeta')->setName('api.articlemeta.update')->add(new RestrictApiAccess($container['router']));
|
||||
$app->get('/api/v1/metadefinitions', ControllerAuthorMetaApi::class . ':getMetaDefinitions')->setName('api.metadefinitions.get')->add(new RestrictApiAccess($container['router']));
|
||||
$app->get('/api/v1/article/metaobject', ControllerAuthorMetaApi::class . ':getArticleMetaobject')->setName('api.articlemetaobject.get')->add(new RestrictApiAccess($container['router']));
|
||||
$app->get('/api/v1/article/metadata', ControllerAuthorMetaApi::class . ':getArticleMeta')->setName('api.articlemeta.get')->add(new RestrictApiAccess($container['router']));
|
||||
$app->post('/api/v1/article/metadata', ControllerAuthorMetaApi::class . ':updateArticleMeta')->setName('api.articlemeta.update')->add(new RestrictApiAccess($container['router']));
|
||||
|
||||
$app->post('/api/v1/block', BlockApiController::class . ':addBlock')->setName('api.block.add')->add(new RestrictApiAccess($container['router']));
|
||||
$app->put('/api/v1/block', BlockApiController::class . ':updateBlock')->setName('api.block.update')->add(new RestrictApiAccess($container['router']));
|
||||
$app->delete('/api/v1/block', BlockApiController::class . ':deleteBlock')->setName('api.block.delete')->add(new RestrictApiAccess($container['router']));
|
||||
$app->put('/api/v1/moveblock', BlockApiController::class . ':moveBlock')->setName('api.block.move')->add(new RestrictApiAccess($container['router']));
|
||||
$app->post('/api/v1/video', BlockApiController::class . ':saveVideoImage')->setName('api.video.save')->add(new RestrictApiAccess($container['router']));
|
||||
$app->post('/api/v1/block', ControllerAuthorBlockApi::class . ':addBlock')->setName('api.block.add')->add(new RestrictApiAccess($container['router']));
|
||||
$app->put('/api/v1/block', ControllerAuthorBlockApi::class . ':updateBlock')->setName('api.block.update')->add(new RestrictApiAccess($container['router']));
|
||||
$app->delete('/api/v1/block', ControllerAuthorBlockApi::class . ':deleteBlock')->setName('api.block.delete')->add(new RestrictApiAccess($container['router']));
|
||||
$app->put('/api/v1/moveblock', ControllerAuthorBlockApi::class . ':moveBlock')->setName('api.block.move')->add(new RestrictApiAccess($container['router']));
|
||||
$app->post('/api/v1/video', ControllerAuthorBlockApi::class . ':saveVideoImage')->setName('api.video.save')->add(new RestrictApiAccess($container['router']));
|
||||
|
||||
$app->get('/api/v1/medialib/images', MediaApiController::class . ':getMediaLibImages')->setName('api.medialibimg.get')->add(new RestrictApiAccess($container['router']));
|
||||
$app->get('/api/v1/medialib/files', MediaApiController::class . ':getMediaLibFiles')->setName('api.medialibfiles.get')->add(new RestrictApiAccess($container['router']));
|
||||
$app->get('/api/v1/image', MediaApiController::class . ':getImage')->setName('api.image.get')->add(new RestrictApiAccess($container['router']));
|
||||
$app->post('/api/v1/image', MediaApiController::class . ':createImage')->setName('api.image.create')->add(new RestrictApiAccess($container['router']));
|
||||
$app->put('/api/v1/image', MediaApiController::class . ':publishImage')->setName('api.image.publish')->add(new RestrictApiAccess($container['router']));
|
||||
$app->delete('/api/v1/image', MediaApiController::class . ':deleteImage')->setName('api.image.delete')->add(new RestrictApiAccess($container['router']));
|
||||
$app->get('/api/v1/file', MediaApiController::class . ':getFile')->setName('api.file.get')->add(new RestrictApiAccess($container['router']));
|
||||
$app->post('/api/v1/file', MediaApiController::class . ':uploadFile')->setName('api.file.upload')->add(new RestrictApiAccess($container['router']));
|
||||
$app->put('/api/v1/file', MediaApiController::class . ':publishFile')->setName('api.file.publish')->add(new RestrictApiAccess($container['router']));
|
||||
$app->delete('/api/v1/file', MediaApiController::class . ':deleteFile')->setName('api.file.delete')->add(new RestrictApiAccess($container['router']));
|
||||
$app->get('/api/v1/medialib/images', ControllerAuthorMediaApi::class . ':getMediaLibImages')->setName('api.medialibimg.get')->add(new RestrictApiAccess($container['router']));
|
||||
$app->get('/api/v1/medialib/files', ControllerAuthorMediaApi::class . ':getMediaLibFiles')->setName('api.medialibfiles.get')->add(new RestrictApiAccess($container['router']));
|
||||
$app->get('/api/v1/image', ControllerAuthorMediaApi::class . ':getImage')->setName('api.image.get')->add(new RestrictApiAccess($container['router']));
|
||||
$app->post('/api/v1/image', ControllerAuthorMediaApi::class . ':createImage')->setName('api.image.create')->add(new RestrictApiAccess($container['router']));
|
||||
$app->put('/api/v1/image', ControllerAuthorMediaApi::class . ':publishImage')->setName('api.image.publish')->add(new RestrictApiAccess($container['router']));
|
||||
$app->delete('/api/v1/image', ControllerAuthorMediaApi::class . ':deleteImage')->setName('api.image.delete')->add(new RestrictApiAccess($container['router']));
|
||||
$app->get('/api/v1/file', ControllerAuthorMediaApi::class . ':getFile')->setName('api.file.get')->add(new RestrictApiAccess($container['router']));
|
||||
$app->post('/api/v1/file', ControllerAuthorMediaApi::class . ':uploadFile')->setName('api.file.upload')->add(new RestrictApiAccess($container['router']));
|
||||
$app->put('/api/v1/file', ControllerAuthorMediaApi::class . ':publishFile')->setName('api.file.publish')->add(new RestrictApiAccess($container['router']));
|
||||
$app->delete('/api/v1/file', ControllerAuthorMediaApi::class . ':deleteFile')->setName('api.file.delete')->add(new RestrictApiAccess($container['router']));
|
@ -1,11 +1,10 @@
|
||||
<?php
|
||||
|
||||
use Typemill\Controllers\PageController;
|
||||
use Typemill\Controllers\FormController;
|
||||
use Typemill\Controllers\SetupController;
|
||||
use Typemill\Controllers\AuthController;
|
||||
use Typemill\Controllers\SettingsController;
|
||||
use Typemill\Controllers\ContentBackendController;
|
||||
use Typemill\Controllers\ControllerAuthorEditor;
|
||||
use Typemill\Controllers\ControllerSettings;
|
||||
use Typemill\Controllers\ControllerFrontendWebsite;
|
||||
use Typemill\Controllers\ControllerFrontendForms;
|
||||
use Typemill\Controllers\ControllerFrontendAuth;
|
||||
use Typemill\Controllers\ControllerFrontendSetup;
|
||||
use Typemill\Middleware\RedirectIfUnauthenticated;
|
||||
use Typemill\Middleware\RedirectIfAuthenticated;
|
||||
use Typemill\Middleware\RedirectIfNoAdmin;
|
||||
@ -13,57 +12,57 @@ use Typemill\Middleware\accessMiddleware;
|
||||
|
||||
if($settings['settings']['setup'])
|
||||
{
|
||||
$app->get('/setup', SetupController::class . ':show')->setName('setup.show');
|
||||
$app->post('/setup', SetupController::class . ':create')->setName('setup.create');
|
||||
$app->get('/setup', ControllerFrontendSetup::class . ':show')->setName('setup.show');
|
||||
$app->post('/setup', ControllerFrontendSetup::class . ':create')->setName('setup.create');
|
||||
}
|
||||
else
|
||||
{
|
||||
$app->get('/setup', AuthController::class . ':redirect');
|
||||
$app->get('/setup', ControllerFrontendAuth::class . ':redirect');
|
||||
}
|
||||
if($settings['settings']['welcome'])
|
||||
{
|
||||
$app->get('/setup/welcome', SetupController::class . ':welcome')->setName('setup.welcome')->add(new RedirectIfUnauthenticated($container['router'], $container['flash']));
|
||||
$app->get('/setup/welcome', ControllerFrontendSetup::class . ':welcome')->setName('setup.welcome')->add(new RedirectIfUnauthenticated($container['router'], $container['flash']));
|
||||
}
|
||||
else
|
||||
{
|
||||
$app->get('/setup/welcome', AuthController::class . ':redirect')->setName('setup.welcome');
|
||||
$app->get('/setup/welcome', ControllerFrontendAuth::class . ':redirect')->setName('setup.welcome');
|
||||
}
|
||||
|
||||
$app->post('/tm/formpost', FormController::class . ':savePublicForm')->setName('form.save');
|
||||
$app->post('/tm/formpost', ControllerFrontendForms::class . ':savePublicForm')->setName('form.save');
|
||||
|
||||
$app->get('/tm', AuthController::class . ':redirect');
|
||||
$app->get('/tm/login', AuthController::class . ':show')->setName('auth.show')->add(new RedirectIfAuthenticated($container['router'], $container['settings']));
|
||||
$app->post('/tm/login', AuthController::class . ':login')->setName('auth.login')->add(new RedirectIfAuthenticated($container['router'], $container['settings']));
|
||||
$app->get('/tm/logout', AuthController::class . ':logout')->setName('auth.logout')->add(new RedirectIfUnauthenticated($container['router'], $container['flash']));
|
||||
$app->get('/tm', ControllerFrontendAuth::class . ':redirect');
|
||||
$app->get('/tm/login', ControllerFrontendAuth::class . ':show')->setName('auth.show')->add(new RedirectIfAuthenticated($container['router'], $container['settings']));
|
||||
$app->post('/tm/login', ControllerFrontendAuth::class . ':login')->setName('auth.login')->add(new RedirectIfAuthenticated($container['router'], $container['settings']));
|
||||
$app->get('/tm/logout', ControllerFrontendAuth::class . ':logout')->setName('auth.logout')->add(new RedirectIfUnauthenticated($container['router'], $container['flash']));
|
||||
|
||||
if(isset($settings['settings']['recoverpw']) && $settings['settings']['recoverpw'])
|
||||
{
|
||||
$app->get('/tm/recoverpw', AuthController::class . ':showrecoverpassword')->setName('auth.recoverpwshow')->add(new RedirectIfAuthenticated($container['router'], $container['settings']));
|
||||
$app->post('/tm/recoverpw', AuthController::class . ':recoverpassword')->setName('auth.recoverpw')->add(new RedirectIfAuthenticated($container['router'], $container['settings']));
|
||||
$app->get('/tm/recoverpwnew', AuthController::class . ':showrecoverpasswordnew')->setName('auth.recoverpwshownew')->add(new RedirectIfAuthenticated($container['router'], $container['settings']));
|
||||
$app->post('/tm/recoverpwnew', AuthController::class . ':createrecoverpasswordnew')->setName('auth.recoverpwnew')->add(new RedirectIfAuthenticated($container['router'], $container['settings']));
|
||||
$app->get('/tm/recoverpw', ControllerFrontendAuth::class . ':showrecoverpassword')->setName('auth.recoverpwshow')->add(new RedirectIfAuthenticated($container['router'], $container['settings']));
|
||||
$app->post('/tm/recoverpw', ControllerFrontendAuth::class . ':recoverpassword')->setName('auth.recoverpw')->add(new RedirectIfAuthenticated($container['router'], $container['settings']));
|
||||
$app->get('/tm/recoverpwnew', ControllerFrontendAuth::class . ':showrecoverpasswordnew')->setName('auth.recoverpwshownew')->add(new RedirectIfAuthenticated($container['router'], $container['settings']));
|
||||
$app->post('/tm/recoverpwnew', ControllerFrontendAuth::class . ':createrecoverpasswordnew')->setName('auth.recoverpwnew')->add(new RedirectIfAuthenticated($container['router'], $container['settings']));
|
||||
}
|
||||
|
||||
$app->get('/tm/settings', SettingsController::class . ':showSettings')->setName('settings.show')->add(new accessMiddleware($container['router'], $container['acl'], 'system', 'view'));
|
||||
$app->post('/tm/settings', SettingsController::class . ':saveSettings')->setName('settings.save')->add(new accessMiddleware($container['router'], $container['acl'], 'system', 'update'));
|
||||
$app->get('/tm/settings', ControllerSettings::class . ':showSettings')->setName('settings.show')->add(new accessMiddleware($container['router'], $container['acl'], 'system', 'view'));
|
||||
$app->post('/tm/settings', ControllerSettings::class . ':saveSettings')->setName('settings.save')->add(new accessMiddleware($container['router'], $container['acl'], 'system', 'update'));
|
||||
|
||||
$app->get('/tm/themes', SettingsController::class . ':showThemes')->setName('themes.show')->add(new accessMiddleware($container['router'], $container['acl'], 'system', 'view'));
|
||||
$app->post('/tm/themes', SettingsController::class . ':saveThemes')->setName('themes.save')->add(new accessMiddleware($container['router'], $container['acl'], 'system', 'update'));
|
||||
$app->get('/tm/themes', ControllerSettings::class . ':showThemes')->setName('themes.show')->add(new accessMiddleware($container['router'], $container['acl'], 'system', 'view'));
|
||||
$app->post('/tm/themes', ControllerSettings::class . ':saveThemes')->setName('themes.save')->add(new accessMiddleware($container['router'], $container['acl'], 'system', 'update'));
|
||||
|
||||
$app->get('/tm/plugins', SettingsController::class . ':showPlugins')->setName('plugins.show')->add(new accessMiddleware($container['router'], $container['acl'], 'system', 'view'));
|
||||
$app->post('/tm/plugins', SettingsController::class . ':savePlugins')->setName('plugins.save')->add(new accessMiddleware($container['router'], $container['acl'], 'system', 'update'));
|
||||
$app->get('/tm/plugins', ControllerSettings::class . ':showPlugins')->setName('plugins.show')->add(new accessMiddleware($container['router'], $container['acl'], 'system', 'view'));
|
||||
$app->post('/tm/plugins', ControllerSettings::class . ':savePlugins')->setName('plugins.save')->add(new accessMiddleware($container['router'], $container['acl'], 'system', 'update'));
|
||||
|
||||
$app->get('/tm/account', SettingsController::class . ':showAccount')->setName('user.account')->add(new accessMiddleware($container['router'], $container['acl'], 'user', 'view'));
|
||||
$app->get('/tm/user/new', SettingsController::class . ':newUser')->setName('user.new')->add(new accessMiddleware($container['router'], $container['acl'], 'user', 'create'));
|
||||
$app->post('/tm/user/create', SettingsController::class . ':createUser')->setName('user.create')->add(new accessMiddleware($container['router'], $container['acl'], 'user', 'create'));
|
||||
$app->post('/tm/user/update', SettingsController::class . ':updateUser')->setName('user.update')->add(new accessMiddleware($container['router'], $container['acl'], 'user', 'update'));
|
||||
$app->post('/tm/user/delete', SettingsController::class . ':deleteUser')->setName('user.delete')->add(new accessMiddleware($container['router'], $container['acl'], 'user', 'delete'));
|
||||
$app->get('/tm/user/{username}', SettingsController::class . ':showUser')->setName('user.show')->add(new accessMiddleware($container['router'], $container['acl'], 'user', 'view'));
|
||||
$app->get('/tm/users', SettingsController::class . ':listUser')->setName('user.list')->add(new accessMiddleware($container['router'], $container['acl'], 'userlist', 'view'));
|
||||
$app->get('/tm/account', ControllerSettings::class . ':showAccount')->setName('user.account')->add(new accessMiddleware($container['router'], $container['acl'], 'user', 'view'));
|
||||
$app->get('/tm/user/new', ControllerSettings::class . ':newUser')->setName('user.new')->add(new accessMiddleware($container['router'], $container['acl'], 'user', 'create'));
|
||||
$app->post('/tm/user/create', ControllerSettings::class . ':createUser')->setName('user.create')->add(new accessMiddleware($container['router'], $container['acl'], 'user', 'create'));
|
||||
$app->post('/tm/user/update', ControllerSettings::class . ':updateUser')->setName('user.update')->add(new accessMiddleware($container['router'], $container['acl'], 'user', 'update'));
|
||||
$app->post('/tm/user/delete', ControllerSettings::class . ':deleteUser')->setName('user.delete')->add(new accessMiddleware($container['router'], $container['acl'], 'user', 'delete'));
|
||||
$app->get('/tm/user/{username}', ControllerSettings::class . ':showUser')->setName('user.show')->add(new accessMiddleware($container['router'], $container['acl'], 'user', 'view'));
|
||||
$app->get('/tm/users', ControllerSettings::class . ':listUser')->setName('user.list')->add(new accessMiddleware($container['router'], $container['acl'], 'userlist', 'view'));
|
||||
|
||||
$app->get('/tm/content/raw[/{params:.*}]', ContentBackendController::class . ':showContent')->setName('content.raw')->add(new accessMiddleware($container['router'], $container['acl'], 'content', 'view'));
|
||||
$app->get('/tm/content/visual[/{params:.*}]', ContentBackendController::class . ':showBlox')->setName('content.visual')->add(new accessMiddleware($container['router'], $container['acl'], 'content', 'view'));
|
||||
$app->get('/tm/content[/{params:.*}]', ContentBackendController::class . ':showEmpty')->setName('content.empty')->add(new accessMiddleware($container['router'], $container['acl'], 'content', 'view'));
|
||||
$app->get('/tm/content/raw[/{params:.*}]', ControllerAuthorEditor::class . ':showContent')->setName('content.raw')->add(new accessMiddleware($container['router'], $container['acl'], 'content', 'view'));
|
||||
$app->get('/tm/content/visual[/{params:.*}]', ControllerAuthorEditor::class . ':showBlox')->setName('content.visual')->add(new accessMiddleware($container['router'], $container['acl'], 'content', 'view'));
|
||||
$app->get('/tm/content[/{params:.*}]', ControllerAuthorEditor::class . ':showEmpty')->setName('content.empty')->add(new accessMiddleware($container['router'], $container['acl'], 'content', 'view'));
|
||||
|
||||
foreach($routes as $pluginRoute)
|
||||
{
|
||||
@ -85,13 +84,13 @@ foreach($routes as $pluginRoute)
|
||||
|
||||
if($settings['settings']['setup'])
|
||||
{
|
||||
$app->get('/[{params:.*}]', SetupController::class . ':redirect');
|
||||
$app->get('/[{params:.*}]', ControllerFrontendSetup::class . ':redirect');
|
||||
}
|
||||
elseif(isset($settings['settings']['access']) && $settings['settings']['access'] != '')
|
||||
{
|
||||
$app->get('/[{params:.*}]', PageController::class . ':index')->setName('home')->add(new accessMiddleware($container['router'], $container['acl'], 'user', 'view'));
|
||||
$app->get('/[{params:.*}]', ControllerFrontendWebsite::class . ':index')->setName('home')->add(new accessMiddleware($container['router'], $container['acl'], 'user', 'view'));
|
||||
}
|
||||
else
|
||||
{
|
||||
$app->get('/[{params:.*}]', PageController::class . ':index')->setName('home');
|
||||
$app->get('/[{params:.*}]', ControllerFrontendWebsite::class . ':index')->setName('home');
|
||||
}
|
@ -191,6 +191,8 @@ class Settings
|
||||
'recovermessage' => true,
|
||||
'recoverfrom' => true,
|
||||
'securitylog' => true,
|
||||
'oldslug' => true,
|
||||
'refreshcache' => true,
|
||||
];
|
||||
|
||||
# cleanup the existing usersettings
|
||||
|
@ -1,5 +1,19 @@
|
||||
meta:
|
||||
fields:
|
||||
fieldsetnavi:
|
||||
type: fieldset
|
||||
legend: Navigation
|
||||
fields:
|
||||
navtitle:
|
||||
type: text
|
||||
label: Navigation Title
|
||||
class: medium
|
||||
maxlength: 60
|
||||
hide:
|
||||
type: checkbox
|
||||
label: Hide
|
||||
checkboxlabel: Hide page from navigation
|
||||
class: medium
|
||||
fieldsetcontent:
|
||||
type: fieldset
|
||||
legend: Meta-Content
|
||||
@ -76,20 +90,6 @@ meta:
|
||||
hidden: true
|
||||
class: hidden
|
||||
pattern: '[0-9][0-9]-[0-9][0-9]-[0-9][0-9]'
|
||||
fieldsetnavi:
|
||||
type: fieldset
|
||||
legend: Navigation
|
||||
fields:
|
||||
navtitle:
|
||||
type: text
|
||||
label: Navigation Title
|
||||
class: medium
|
||||
maxlength: 60
|
||||
hide:
|
||||
type: checkbox
|
||||
label: Hide
|
||||
checkboxlabel: Hide page from navigation
|
||||
class: medium
|
||||
contains:
|
||||
type: radio
|
||||
label: This folder contains
|
||||
|
@ -261,6 +261,13 @@
|
||||
<span class="checkmark"></span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="large{{ errors.settings.oldslug ? ' error' : '' }}">
|
||||
<label for="settings[oldslug]">{{ __('Old Slug Logic') }}</label>
|
||||
<label class="control-group">{{ __('Use the old logic from versions < 1.5.0 to create the slug') }}
|
||||
<input name="settings[oldslug]" type="checkbox" {% if (settings.oldslug or old.settings.oldslug) %} checked {% endif %}>
|
||||
<span class="checkmark"></span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="medium{{ errors.settings.twigcache ? ' error' : '' }}">
|
||||
<label for="settings[twigcache]">{{ __('Twig Cache') }}</label>
|
||||
<label class="control-group">{{ __('Activate Cache for Twig Templates') }}
|
||||
@ -272,6 +279,13 @@
|
||||
<div class="label">{{ __('Recreate cached files') }}</div>
|
||||
<button id="clearcache" class="link bg-tm-green white dim bn br1 ph3 pv2 f6">{{ __('Recreate Cache') }}</button><div id="cacheresult" class="dib ph3 pv2"></div>
|
||||
</div>
|
||||
<div class="large{{ errors.settings.refreshcache ? ' error' : '' }}">
|
||||
<label for="settings[refreshcache]">{{ __('Refresh Cache') }}</label>
|
||||
<label class="control-group">{{ __('Refresh the cache after 10 minutes. Use this if you change content files manually e.g. with FTP.') }}
|
||||
<input name="settings[refreshcache]" type="checkbox" {% if (settings.refreshcache or old.settings.refreshcache) %} checked {% endif %}>
|
||||
<span class="checkmark"></span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="medium{{ errors.settings.proxy ? ' error' : '' }}">
|
||||
<label for="settings[proxy]">{{ __('Proxy') }}</label>
|
||||
<label class="control-group">{{ __('Use X-Forwarded Headers') }}
|
||||
|
Loading…
x
Reference in New Issue
Block a user