mirror of
https://github.com/typemill/typemill.git
synced 2025-08-02 12:21:03 +02:00
Version 1.4.9-1.5.0: Refactor controller logic
This commit is contained in:
@@ -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'] = '{#' . $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;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user