mirror of
https://github.com/typemill/typemill.git
synced 2025-08-04 21:27:41 +02:00
Version 1.3.4: Media Library
This commit is contained in:
@@ -7,7 +7,6 @@ use Slim\Http\Response;
|
||||
use Typemill\Models\Folder;
|
||||
use Typemill\Models\Write;
|
||||
use Typemill\Models\WriteYaml;
|
||||
use Typemill\Models\ProcessImage;
|
||||
use Typemill\Extensions\ParsedownExtension;
|
||||
use Typemill\Events\OnPagePublished;
|
||||
use Typemill\Events\OnPageUnpublished;
|
||||
@@ -16,7 +15,7 @@ use Typemill\Events\OnPageSorted;
|
||||
use \URLify;
|
||||
|
||||
|
||||
class ContentApiController extends ContentController
|
||||
class ArticleApiController extends ContentController
|
||||
{
|
||||
public function publishArticle(Request $request, Response $response, $args)
|
||||
{
|
||||
@@ -847,619 +846,4 @@ class ContentApiController extends ContentController
|
||||
|
||||
return $response->withJson(array('data' => $content, 'errors' => false));
|
||||
}
|
||||
|
||||
public function addBlock(Request $request, Response $response, $args)
|
||||
{
|
||||
/* get params from call */
|
||||
$this->params = $request->getParams();
|
||||
$this->uri = $request->getUri();
|
||||
|
||||
/* 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); }
|
||||
|
||||
/* set item */
|
||||
if(!$this->setItem()){ return $response->withJson($this->errors, 404); }
|
||||
|
||||
# set the status for published and drafted
|
||||
$this->setPublishStatus();
|
||||
|
||||
# set path
|
||||
$this->setItemPath($this->item->fileType);
|
||||
|
||||
# read content from file
|
||||
if(!$this->setContent()){ return $response->withJson(array('data' => false, 'errors' => $this->errors), 404); }
|
||||
|
||||
# make it more clear which content we have
|
||||
$pageMarkdown = $this->content;
|
||||
|
||||
$blockMarkdown = $this->params['markdown'];
|
||||
|
||||
# standardize line breaks
|
||||
$blockMarkdown = str_replace(array("\r\n", "\r"), "\n", $blockMarkdown);
|
||||
|
||||
# remove surrounding line breaks
|
||||
$blockMarkdown = trim($blockMarkdown, "\n");
|
||||
|
||||
if($pageMarkdown == '')
|
||||
{
|
||||
$pageMarkdown = [];
|
||||
}
|
||||
|
||||
# initialize parsedown extension
|
||||
$parsedown = new ParsedownExtension();
|
||||
|
||||
# if content is not an array, then transform it
|
||||
if(!is_array($pageMarkdown))
|
||||
{
|
||||
# turn markdown into an array of markdown-blocks
|
||||
$pageMarkdown = $parsedown->markdownToArrayBlocks($pageMarkdown);
|
||||
}
|
||||
|
||||
# if it is a new content-block
|
||||
if($this->params['block_id'] == 99999)
|
||||
{
|
||||
# set the id of the markdown-block (it will be one more than the actual array, so count is perfect)
|
||||
$id = count($pageMarkdown);
|
||||
|
||||
# add the new markdown block to the page content
|
||||
$pageMarkdown[] = $blockMarkdown;
|
||||
}
|
||||
elseif(($this->params['block_id'] == 0) OR !isset($pageMarkdown[$this->params['block_id']]))
|
||||
{
|
||||
# if the block does not exists, return an error
|
||||
return $response->withJson(array('data' => false, 'errors' => 'The ID of the content-block is wrong.'), 404);
|
||||
}
|
||||
else
|
||||
{
|
||||
# insert new markdown block
|
||||
array_splice( $pageMarkdown, $this->params['block_id'], 0, $blockMarkdown );
|
||||
$id = $this->params['block_id'];
|
||||
}
|
||||
|
||||
# encode the content into json
|
||||
$pageJson = json_encode($pageMarkdown);
|
||||
|
||||
# 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 internal structure
|
||||
$this->setStructure($draft = true, $cache = false);
|
||||
$this->content = $pageMarkdown;
|
||||
}
|
||||
else
|
||||
{
|
||||
return $response->withJson(['errors' => ['message' => 'Could not write to file. Please check if the file is writable']], 404);
|
||||
}
|
||||
|
||||
/* set safe mode to escape javascript and html in markdown */
|
||||
$parsedown->setSafeMode(true);
|
||||
|
||||
/* parse markdown-file to content-array */
|
||||
$blockArray = $parsedown->text($blockMarkdown);
|
||||
|
||||
# we assume that toc is not relevant
|
||||
$toc = false;
|
||||
|
||||
# needed for ToC links
|
||||
$relurl = '/tm/content/' . $this->settings['editor'] . '/' . $this->item->urlRel;
|
||||
|
||||
if($blockMarkdown == '[TOC]')
|
||||
{
|
||||
# if block is table of content itself, then generate the table of content
|
||||
$tableofcontent = $this->generateToc();
|
||||
|
||||
# and only use the html-markup
|
||||
$blockHTML = $tableofcontent['html'];
|
||||
}
|
||||
else
|
||||
{
|
||||
# parse markdown-content-array to content-string
|
||||
$blockHTML = $parsedown->markup($blockArray, $relurl);
|
||||
|
||||
# if it is a headline
|
||||
if($blockMarkdown[0] == '#')
|
||||
{
|
||||
# then the TOC holds either false (if no toc used in the page) or it holds an object with the id and toc-markup
|
||||
$toc = $this->generateToc();
|
||||
}
|
||||
}
|
||||
|
||||
return $response->withJson(array('content' => [ 'id' => $id, 'html' => $blockHTML ] , 'markdown' => $blockMarkdown, 'id' => $id, 'toc' => $toc, 'errors' => false));
|
||||
}
|
||||
|
||||
protected function generateToc()
|
||||
{
|
||||
# we assume that page has no table of content
|
||||
$toc = false;
|
||||
|
||||
# make sure $this->content is updated
|
||||
$content = $this->content;
|
||||
|
||||
if($content == '')
|
||||
{
|
||||
$content = [];
|
||||
}
|
||||
|
||||
# initialize parsedown extension
|
||||
$parsedown = new ParsedownExtension();
|
||||
|
||||
# if content is not an array, then transform it
|
||||
if(!is_array($content))
|
||||
{
|
||||
# turn markdown into an array of markdown-blocks
|
||||
$content = $parsedown->markdownToArrayBlocks($content);
|
||||
}
|
||||
|
||||
# needed for ToC links
|
||||
$relurl = '/tm/content/' . $this->settings['editor'] . '/' . $this->item->urlRel;
|
||||
|
||||
# loop through mardkown-array and create html-blocks
|
||||
foreach($content as $key => $block)
|
||||
{
|
||||
# parse markdown-file to content-array
|
||||
$contentArray = $parsedown->text($block);
|
||||
|
||||
if($block == '[TOC]')
|
||||
{
|
||||
# toc is true and holds the key of the table of content now
|
||||
$toc = $key;
|
||||
}
|
||||
|
||||
# parse markdown-content-array to content-string
|
||||
$content[$key] = ['id' => $key, 'html' => $parsedown->markup($contentArray, $relurl)];
|
||||
}
|
||||
|
||||
# if page has a table of content
|
||||
if($toc)
|
||||
{
|
||||
# generate the toc markup
|
||||
$tocMarkup = $parsedown->buildTOC($parsedown->headlines);
|
||||
|
||||
# toc holds the id of the table of content and the html-markup now
|
||||
$toc = ['id' => $toc, 'html' => $tocMarkup];
|
||||
}
|
||||
|
||||
return $toc;
|
||||
}
|
||||
|
||||
public function updateBlock(Request $request, Response $response, $args)
|
||||
{
|
||||
/* get params from call */
|
||||
$this->params = $request->getParams();
|
||||
$this->uri = $request->getUri();
|
||||
|
||||
/* 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); }
|
||||
|
||||
/* set item */
|
||||
if(!$this->setItem()){ return $response->withJson($this->errors, 404); }
|
||||
|
||||
# set the status for published and drafted
|
||||
$this->setPublishStatus();
|
||||
|
||||
# set path
|
||||
$this->setItemPath($this->item->fileType);
|
||||
|
||||
# read content from file
|
||||
if(!$this->setContent()){ return $response->withJson(array('data' => false, 'errors' => $this->errors), 404); }
|
||||
|
||||
# make it more clear which content we have
|
||||
$pageMarkdown = $this->content;
|
||||
|
||||
$blockMarkdown = $this->params['markdown'];
|
||||
|
||||
# standardize line breaks
|
||||
$blockMarkdown = str_replace(array("\r\n", "\r"), "\n", $blockMarkdown);
|
||||
|
||||
# remove surrounding line breaks
|
||||
$blockMarkdown = trim($blockMarkdown, "\n");
|
||||
|
||||
if($pageMarkdown == '')
|
||||
{
|
||||
$pageMarkdown = [];
|
||||
}
|
||||
|
||||
# initialize parsedown extension
|
||||
$parsedown = new ParsedownExtension();
|
||||
$parsedown->setVisualMode();
|
||||
|
||||
# if content is not an array, then transform it
|
||||
if(!is_array($pageMarkdown))
|
||||
{
|
||||
# turn markdown into an array of markdown-blocks
|
||||
$pageMarkdown = $parsedown->markdownToArrayBlocks($pageMarkdown);
|
||||
}
|
||||
|
||||
if(!isset($pageMarkdown[$this->params['block_id']]))
|
||||
{
|
||||
# if the block does not exists, return an error
|
||||
return $response->withJson(array('data' => false, 'errors' => 'The ID of the content-block is wrong.'), 404);
|
||||
}
|
||||
elseif($this->params['block_id'] == 0)
|
||||
{
|
||||
# if it is the title, then delete the "# " if it exists
|
||||
$blockMarkdown = trim($blockMarkdown, "# ");
|
||||
|
||||
# store the markdown-headline in a separate variable
|
||||
$blockMarkdownTitle = '# ' . $blockMarkdown;
|
||||
|
||||
# add the markdown-headline to the page-markdown
|
||||
$pageMarkdown[0] = $blockMarkdownTitle;
|
||||
$id = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
# update the markdown block in the page content
|
||||
$pageMarkdown[$this->params['block_id']] = $blockMarkdown;
|
||||
$id = $this->params['block_id'];
|
||||
}
|
||||
|
||||
# encode the content into json
|
||||
$pageJson = json_encode($pageMarkdown);
|
||||
|
||||
# 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 internal structure
|
||||
$this->setStructure($draft = true, $cache = false);
|
||||
|
||||
# updated the content variable
|
||||
$this->content = $pageMarkdown;
|
||||
}
|
||||
else
|
||||
{
|
||||
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. */
|
||||
if($this->params['block_id'] == 0)
|
||||
{
|
||||
$blockArray = $parsedown->text($blockMarkdownTitle);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* set safe mode to escape javascript and html in markdown */
|
||||
$parsedown->setSafeMode(true);
|
||||
|
||||
$blockArray = $parsedown->text($blockMarkdown);
|
||||
}
|
||||
|
||||
# we assume that toc is not relevant
|
||||
$toc = false;
|
||||
|
||||
# needed for ToC links
|
||||
$relurl = '/tm/content/' . $this->settings['editor'] . '/' . $this->item->urlRel;
|
||||
|
||||
if($blockMarkdown == '[TOC]')
|
||||
{
|
||||
# if block is table of content itself, then generate the table of content
|
||||
$tableofcontent = $this->generateToc();
|
||||
|
||||
# and only use the html-markup
|
||||
$blockHTML = $tableofcontent['html'];
|
||||
}
|
||||
else
|
||||
{
|
||||
# parse markdown-content-array to content-string
|
||||
$blockHTML = $parsedown->markup($blockArray, $relurl);
|
||||
|
||||
# if it is a headline
|
||||
if($blockMarkdown[0] == '#')
|
||||
{
|
||||
# then the TOC holds either false (if no toc used in the page) or it holds an object with the id and toc-markup
|
||||
$toc = $this->generateToc();
|
||||
}
|
||||
}
|
||||
|
||||
return $response->withJson(array('content' => [ 'id' => $id, 'html' => $blockHTML ] , 'markdown' => $blockMarkdown, 'id' => $id, 'toc' => $toc, 'errors' => false));
|
||||
}
|
||||
|
||||
public function moveBlock(Request $request, Response $response, $args)
|
||||
{
|
||||
# get params from call
|
||||
$this->params = $request->getParams();
|
||||
$this->uri = $request->getUri();
|
||||
|
||||
# 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); }
|
||||
|
||||
# set item
|
||||
if(!$this->setItem()){ return $response->withJson($this->errors, 404); }
|
||||
|
||||
# set the status for published and drafted
|
||||
$this->setPublishStatus();
|
||||
|
||||
# set path
|
||||
$this->setItemPath($this->item->fileType);
|
||||
|
||||
# read content from file
|
||||
if(!$this->setContent()){ return $response->withJson(array('data' => false, 'errors' => $this->errors), 404); }
|
||||
|
||||
# make it more clear which content we have
|
||||
$pageMarkdown = $this->content;
|
||||
|
||||
if($pageMarkdown == '')
|
||||
{
|
||||
$pageMarkdown = [];
|
||||
}
|
||||
|
||||
# initialize parsedown extension
|
||||
$parsedown = new ParsedownExtension();
|
||||
|
||||
# if content is not an array, then transform it
|
||||
if(!is_array($pageMarkdown))
|
||||
{
|
||||
# turn markdown into an array of markdown-blocks
|
||||
$pageMarkdown = $parsedown->markdownToArrayBlocks($pageMarkdown);
|
||||
}
|
||||
|
||||
$oldIndex = ($this->params['old_index'] + 1);
|
||||
$newIndex = ($this->params['new_index'] + 1);
|
||||
|
||||
if(!isset($pageMarkdown[$oldIndex]))
|
||||
{
|
||||
# if the block does not exists, return an error
|
||||
return $response->withJson(array('data' => false, 'errors' => 'The ID of the content-block is wrong.'), 404);
|
||||
}
|
||||
|
||||
$extract = array_splice($pageMarkdown, $oldIndex, 1);
|
||||
array_splice($pageMarkdown, $newIndex, 0, $extract);
|
||||
|
||||
# encode the content into json
|
||||
$pageJson = json_encode($pageMarkdown);
|
||||
|
||||
# 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 internal structure
|
||||
$this->setStructure($draft = true, $cache = false);
|
||||
|
||||
# update this content
|
||||
$this->content = $pageMarkdown;
|
||||
}
|
||||
else
|
||||
{
|
||||
return $response->withJson(['errors' => ['message' => 'Could not write to file. Please check if the file is writable']], 404);
|
||||
}
|
||||
|
||||
# we assume that toc is not relevant
|
||||
$toc = false;
|
||||
|
||||
# needed for ToC links
|
||||
$relurl = '/tm/content/' . $this->settings['editor'] . '/' . $this->item->urlRel;
|
||||
|
||||
# if the moved item is a headline
|
||||
if($extract[0][0] == '#')
|
||||
{
|
||||
$toc = $this->generateToc();
|
||||
}
|
||||
|
||||
# if it is the title, then delete the "# " if it exists
|
||||
$pageMarkdown[0] = trim($pageMarkdown[0], "# ");
|
||||
|
||||
return $response->withJson(array('markdown' => $pageMarkdown, 'toc' => $toc, 'errors' => false));
|
||||
}
|
||||
|
||||
public function deleteBlock(Request $request, Response $response, $args)
|
||||
{
|
||||
/* get params from call */
|
||||
$this->params = $request->getParams();
|
||||
$this->uri = $request->getUri();
|
||||
$errors = false;
|
||||
|
||||
# set structure
|
||||
if(!$this->setStructure($draft = true)){ return $response->withJson(array('data' => false, 'errors' => $this->errors), 404); }
|
||||
|
||||
# set item
|
||||
if(!$this->setItem()){ return $response->withJson($this->errors, 404); }
|
||||
|
||||
# set the status for published and drafted
|
||||
$this->setPublishStatus();
|
||||
|
||||
# set path
|
||||
$this->setItemPath($this->item->fileType);
|
||||
|
||||
# read content from file
|
||||
if(!$this->setContent()){ return $response->withJson(array('data' => false, 'errors' => $this->errors), 404); }
|
||||
|
||||
# get content
|
||||
$this->content;
|
||||
|
||||
if($this->content == '')
|
||||
{
|
||||
$this->content = [];
|
||||
}
|
||||
|
||||
# initialize parsedown extension
|
||||
$parsedown = new ParsedownExtension();
|
||||
|
||||
# if content is not an array, then transform it
|
||||
if(!is_array($this->content))
|
||||
{
|
||||
# turn markdown into an array of markdown-blocks
|
||||
$this->content = $parsedown->markdownToArrayBlocks($this->content);
|
||||
}
|
||||
|
||||
# check if id exists
|
||||
if(!isset($this->content[$this->params['block_id']])){ return $response->withJson(array('data' => false, 'errors' => 'The ID of the content-block is wrong.'), 404); }
|
||||
|
||||
# check if block is image
|
||||
$contentBlock = $this->content[$this->params['block_id']];
|
||||
$contentBlockStart = substr($contentBlock, 0, 2);
|
||||
if($contentBlockStart == '[!' OR $contentBlockStart == '![')
|
||||
{
|
||||
# extract image path
|
||||
preg_match("/\((.*?)\)/",$contentBlock,$matches);
|
||||
if(isset($matches[1]))
|
||||
{
|
||||
$imageBaseName = explode('-', $matches[1]);
|
||||
$imageBaseName = str_replace('media/live/', '', $imageBaseName[0]);
|
||||
$processImage = new ProcessImage();
|
||||
if(!$processImage->deleteImage($imageBaseName))
|
||||
{
|
||||
$errors = 'Could not delete some of the images, please check manually';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# delete the block
|
||||
unset($this->content[$this->params['block_id']]);
|
||||
$this->content = array_values($this->content);
|
||||
|
||||
$pageMarkdown = $this->content;
|
||||
|
||||
# delete markdown from title
|
||||
if(isset($pageMarkdown[0]))
|
||||
{
|
||||
$pageMarkdown[0] = trim($pageMarkdown[0], "# ");
|
||||
}
|
||||
|
||||
# encode the content into json
|
||||
$pageJson = json_encode($this->content);
|
||||
|
||||
# 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 internal structure
|
||||
$this->setStructure($draft = true, $cache = false);
|
||||
}
|
||||
else
|
||||
{
|
||||
return $response->withJson(['errors' => ['message' => 'Could not write to file. Please check if the file is writable']], 404);
|
||||
}
|
||||
|
||||
$toc = false;
|
||||
|
||||
if($contentBlock[0] == '#')
|
||||
{
|
||||
$toc = $this->generateToc();
|
||||
}
|
||||
|
||||
return $response->withJson(array('markdown' => $pageMarkdown, 'toc' => $toc, 'errors' => $errors));
|
||||
}
|
||||
|
||||
public function createImage(Request $request, Response $response, $args)
|
||||
{
|
||||
/* get params from call */
|
||||
$this->params = $request->getParams();
|
||||
$this->uri = $request->getUri();
|
||||
|
||||
$imageProcessor = new ProcessImage();
|
||||
|
||||
if($imageProcessor->createImage($this->params['image'], $this->settings['images']))
|
||||
{
|
||||
return $response->withJson(array('errors' => false));
|
||||
}
|
||||
|
||||
return $response->withJson(array('errors' => 'could not store image to temporary folder'));
|
||||
}
|
||||
|
||||
public function publishImage(Request $request, Response $response, $args)
|
||||
{
|
||||
$params = $request->getParsedBody();
|
||||
|
||||
$imageProcessor = new ProcessImage();
|
||||
|
||||
$imageUrl = $imageProcessor->publishImage($this->settings['images'], $name = false);
|
||||
if($imageUrl)
|
||||
{
|
||||
$params['markdown'] = str_replace('imgplchldr', $imageUrl, $params['markdown']);
|
||||
|
||||
$request = $request->withParsedBody($params);
|
||||
|
||||
return $this->addBlock($request, $response, $args);
|
||||
}
|
||||
|
||||
return $response->withJson(array('errors' => 'could not store image to media folder'));
|
||||
}
|
||||
|
||||
public function saveVideoImage(Request $request, Response $response, $args)
|
||||
{
|
||||
/* get params from call */
|
||||
$this->params = $request->getParams();
|
||||
$this->uri = $request->getUri();
|
||||
$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(array('errors' => 'could not get the video image'));
|
||||
}
|
||||
}
|
||||
|
||||
$imageData64 = 'data:image/jpeg;base64,' . base64_encode($imageData);
|
||||
$desiredSizes = ['live' => ['width' => 560, 'height' => 315]];
|
||||
$imageProcessor = new ProcessImage();
|
||||
$tmpImage = $imageProcessor->createImage($imageData64, $desiredSizes);
|
||||
|
||||
if(!$tmpImage)
|
||||
{
|
||||
return $response->withJson(array('errors' => 'could not create temporary image'));
|
||||
}
|
||||
|
||||
$imageUrl = $imageProcessor->publishImage($desiredSizes, $videoID);
|
||||
if($imageUrl)
|
||||
{
|
||||
$this->params['markdown'] = '{#' . $videoID. ' .' . $class . '}';
|
||||
|
||||
$request = $request->withParsedBody($this->params);
|
||||
|
||||
return $this->addBlock($request, $response, $args);
|
||||
}
|
||||
|
||||
return $response->withJson(array('errors' => 'could not store the preview image'));
|
||||
}
|
||||
}
|
841
system/Controllers/BlockApiController.php
Normal file
841
system/Controllers/BlockApiController.php
Normal file
@@ -0,0 +1,841 @@
|
||||
<?php
|
||||
|
||||
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
|
||||
{
|
||||
|
||||
public function addBlock(Request $request, Response $response, $args)
|
||||
{
|
||||
/* get params from call */
|
||||
$this->params = $request->getParams();
|
||||
$this->uri = $request->getUri();
|
||||
|
||||
/* 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); }
|
||||
|
||||
/* set item */
|
||||
if(!$this->setItem()){ return $response->withJson($this->errors, 404); }
|
||||
|
||||
# set the status for published and drafted
|
||||
$this->setPublishStatus();
|
||||
|
||||
# set path
|
||||
$this->setItemPath($this->item->fileType);
|
||||
|
||||
# read content from file
|
||||
if(!$this->setContent()){ return $response->withJson(array('data' => false, 'errors' => $this->errors), 404); }
|
||||
|
||||
# make it more clear which content we have
|
||||
$pageMarkdown = $this->content;
|
||||
|
||||
$blockMarkdown = $this->params['markdown'];
|
||||
|
||||
# standardize line breaks
|
||||
$blockMarkdown = str_replace(array("\r\n", "\r"), "\n", $blockMarkdown);
|
||||
|
||||
# remove surrounding line breaks
|
||||
$blockMarkdown = trim($blockMarkdown, "\n");
|
||||
|
||||
if($pageMarkdown == '')
|
||||
{
|
||||
$pageMarkdown = [];
|
||||
}
|
||||
|
||||
# initialize parsedown extension
|
||||
$parsedown = new ParsedownExtension();
|
||||
|
||||
# if content is not an array, then transform it
|
||||
if(!is_array($pageMarkdown))
|
||||
{
|
||||
# turn markdown into an array of markdown-blocks
|
||||
$pageMarkdown = $parsedown->markdownToArrayBlocks($pageMarkdown);
|
||||
}
|
||||
|
||||
# if it is a new content-block
|
||||
if($this->params['block_id'] == 99999)
|
||||
{
|
||||
# set the id of the markdown-block (it will be one more than the actual array, so count is perfect)
|
||||
$id = count($pageMarkdown);
|
||||
|
||||
# add the new markdown block to the page content
|
||||
$pageMarkdown[] = $blockMarkdown;
|
||||
}
|
||||
elseif(($this->params['block_id'] == 0) OR !isset($pageMarkdown[$this->params['block_id']]))
|
||||
{
|
||||
# if the block does not exists, return an error
|
||||
return $response->withJson(array('data' => false, 'errors' => 'The ID of the content-block is wrong.'), 404);
|
||||
}
|
||||
else
|
||||
{
|
||||
# insert new markdown block
|
||||
array_splice( $pageMarkdown, $this->params['block_id'], 0, $blockMarkdown );
|
||||
$id = $this->params['block_id'];
|
||||
}
|
||||
|
||||
# encode the content into json
|
||||
$pageJson = json_encode($pageMarkdown);
|
||||
|
||||
# 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 internal structure
|
||||
$this->setStructure($draft = true, $cache = false);
|
||||
$this->content = $pageMarkdown;
|
||||
}
|
||||
else
|
||||
{
|
||||
return $response->withJson(['errors' => ['message' => 'Could not write to file. Please check if the file is writable']], 404);
|
||||
}
|
||||
|
||||
/* set safe mode to escape javascript and html in markdown */
|
||||
$parsedown->setSafeMode(true);
|
||||
|
||||
/* parse markdown-file to content-array */
|
||||
$blockArray = $parsedown->text($blockMarkdown);
|
||||
|
||||
# we assume that toc is not relevant
|
||||
$toc = false;
|
||||
|
||||
# needed for ToC links
|
||||
$relurl = '/tm/content/' . $this->settings['editor'] . '/' . $this->item->urlRel;
|
||||
|
||||
if($blockMarkdown == '[TOC]')
|
||||
{
|
||||
# if block is table of content itself, then generate the table of content
|
||||
$tableofcontent = $this->generateToc();
|
||||
|
||||
# and only use the html-markup
|
||||
$blockHTML = $tableofcontent['html'];
|
||||
}
|
||||
else
|
||||
{
|
||||
# parse markdown-content-array to content-string
|
||||
$blockHTML = $parsedown->markup($blockArray, $relurl);
|
||||
|
||||
# if it is a headline
|
||||
if($blockMarkdown[0] == '#')
|
||||
{
|
||||
# then the TOC holds either false (if no toc used in the page) or it holds an object with the id and toc-markup
|
||||
$toc = $this->generateToc();
|
||||
}
|
||||
}
|
||||
|
||||
return $response->withJson(array('content' => [ 'id' => $id, 'html' => $blockHTML ] , 'markdown' => $blockMarkdown, 'id' => $id, 'toc' => $toc, 'errors' => false));
|
||||
}
|
||||
|
||||
protected function generateToc()
|
||||
{
|
||||
# we assume that page has no table of content
|
||||
$toc = false;
|
||||
|
||||
# make sure $this->content is updated
|
||||
$content = $this->content;
|
||||
|
||||
if($content == '')
|
||||
{
|
||||
$content = [];
|
||||
}
|
||||
|
||||
# initialize parsedown extension
|
||||
$parsedown = new ParsedownExtension();
|
||||
|
||||
# if content is not an array, then transform it
|
||||
if(!is_array($content))
|
||||
{
|
||||
# turn markdown into an array of markdown-blocks
|
||||
$content = $parsedown->markdownToArrayBlocks($content);
|
||||
}
|
||||
|
||||
# needed for ToC links
|
||||
$relurl = '/tm/content/' . $this->settings['editor'] . '/' . $this->item->urlRel;
|
||||
|
||||
# loop through mardkown-array and create html-blocks
|
||||
foreach($content as $key => $block)
|
||||
{
|
||||
# parse markdown-file to content-array
|
||||
$contentArray = $parsedown->text($block);
|
||||
|
||||
if($block == '[TOC]')
|
||||
{
|
||||
# toc is true and holds the key of the table of content now
|
||||
$toc = $key;
|
||||
}
|
||||
|
||||
# parse markdown-content-array to content-string
|
||||
$content[$key] = ['id' => $key, 'html' => $parsedown->markup($contentArray, $relurl)];
|
||||
}
|
||||
|
||||
# if page has a table of content
|
||||
if($toc)
|
||||
{
|
||||
# generate the toc markup
|
||||
$tocMarkup = $parsedown->buildTOC($parsedown->headlines);
|
||||
|
||||
# toc holds the id of the table of content and the html-markup now
|
||||
$toc = ['id' => $toc, 'html' => $tocMarkup];
|
||||
}
|
||||
|
||||
return $toc;
|
||||
}
|
||||
|
||||
public function updateBlock(Request $request, Response $response, $args)
|
||||
{
|
||||
/* get params from call */
|
||||
$this->params = $request->getParams();
|
||||
$this->uri = $request->getUri();
|
||||
|
||||
/* 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); }
|
||||
|
||||
/* set item */
|
||||
if(!$this->setItem()){ return $response->withJson($this->errors, 404); }
|
||||
|
||||
# set the status for published and drafted
|
||||
$this->setPublishStatus();
|
||||
|
||||
# set path
|
||||
$this->setItemPath($this->item->fileType);
|
||||
|
||||
# read content from file
|
||||
if(!$this->setContent()){ return $response->withJson(array('data' => false, 'errors' => $this->errors), 404); }
|
||||
|
||||
# make it more clear which content we have
|
||||
$pageMarkdown = $this->content;
|
||||
|
||||
$blockMarkdown = $this->params['markdown'];
|
||||
|
||||
# standardize line breaks
|
||||
$blockMarkdown = str_replace(array("\r\n", "\r"), "\n", $blockMarkdown);
|
||||
|
||||
# remove surrounding line breaks
|
||||
$blockMarkdown = trim($blockMarkdown, "\n");
|
||||
|
||||
if($pageMarkdown == '')
|
||||
{
|
||||
$pageMarkdown = [];
|
||||
}
|
||||
|
||||
# initialize parsedown extension
|
||||
$parsedown = new ParsedownExtension();
|
||||
$parsedown->setVisualMode();
|
||||
|
||||
# if content is not an array, then transform it
|
||||
if(!is_array($pageMarkdown))
|
||||
{
|
||||
# turn markdown into an array of markdown-blocks
|
||||
$pageMarkdown = $parsedown->markdownToArrayBlocks($pageMarkdown);
|
||||
}
|
||||
|
||||
if(!isset($pageMarkdown[$this->params['block_id']]))
|
||||
{
|
||||
# if the block does not exists, return an error
|
||||
return $response->withJson(array('data' => false, 'errors' => 'The ID of the content-block is wrong.'), 404);
|
||||
}
|
||||
elseif($this->params['block_id'] == 0)
|
||||
{
|
||||
# if it is the title, then delete the "# " if it exists
|
||||
$blockMarkdown = trim($blockMarkdown, "# ");
|
||||
|
||||
# store the markdown-headline in a separate variable
|
||||
$blockMarkdownTitle = '# ' . $blockMarkdown;
|
||||
|
||||
# add the markdown-headline to the page-markdown
|
||||
$pageMarkdown[0] = $blockMarkdownTitle;
|
||||
$id = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
# update the markdown block in the page content
|
||||
$pageMarkdown[$this->params['block_id']] = $blockMarkdown;
|
||||
$id = $this->params['block_id'];
|
||||
}
|
||||
|
||||
# encode the content into json
|
||||
$pageJson = json_encode($pageMarkdown);
|
||||
|
||||
# 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 internal structure
|
||||
$this->setStructure($draft = true, $cache = false);
|
||||
|
||||
# updated the content variable
|
||||
$this->content = $pageMarkdown;
|
||||
}
|
||||
else
|
||||
{
|
||||
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. */
|
||||
if($this->params['block_id'] == 0)
|
||||
{
|
||||
$blockArray = $parsedown->text($blockMarkdownTitle);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* set safe mode to escape javascript and html in markdown */
|
||||
$parsedown->setSafeMode(true);
|
||||
|
||||
$blockArray = $parsedown->text($blockMarkdown);
|
||||
}
|
||||
|
||||
# we assume that toc is not relevant
|
||||
$toc = false;
|
||||
|
||||
# needed for ToC links
|
||||
$relurl = '/tm/content/' . $this->settings['editor'] . '/' . $this->item->urlRel;
|
||||
|
||||
if($blockMarkdown == '[TOC]')
|
||||
{
|
||||
# if block is table of content itself, then generate the table of content
|
||||
$tableofcontent = $this->generateToc();
|
||||
|
||||
# and only use the html-markup
|
||||
$blockHTML = $tableofcontent['html'];
|
||||
}
|
||||
else
|
||||
{
|
||||
# parse markdown-content-array to content-string
|
||||
$blockHTML = $parsedown->markup($blockArray, $relurl);
|
||||
|
||||
# if it is a headline
|
||||
if($blockMarkdown[0] == '#')
|
||||
{
|
||||
# then the TOC holds either false (if no toc used in the page) or it holds an object with the id and toc-markup
|
||||
$toc = $this->generateToc();
|
||||
}
|
||||
}
|
||||
|
||||
return $response->withJson(array('content' => [ 'id' => $id, 'html' => $blockHTML ] , 'markdown' => $blockMarkdown, 'id' => $id, 'toc' => $toc, 'errors' => false));
|
||||
}
|
||||
|
||||
public function moveBlock(Request $request, Response $response, $args)
|
||||
{
|
||||
# get params from call
|
||||
$this->params = $request->getParams();
|
||||
$this->uri = $request->getUri();
|
||||
|
||||
# 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); }
|
||||
|
||||
# set item
|
||||
if(!$this->setItem()){ return $response->withJson($this->errors, 404); }
|
||||
|
||||
# set the status for published and drafted
|
||||
$this->setPublishStatus();
|
||||
|
||||
# set path
|
||||
$this->setItemPath($this->item->fileType);
|
||||
|
||||
# read content from file
|
||||
if(!$this->setContent()){ return $response->withJson(array('data' => false, 'errors' => $this->errors), 404); }
|
||||
|
||||
# make it more clear which content we have
|
||||
$pageMarkdown = $this->content;
|
||||
|
||||
if($pageMarkdown == '')
|
||||
{
|
||||
$pageMarkdown = [];
|
||||
}
|
||||
|
||||
# initialize parsedown extension
|
||||
$parsedown = new ParsedownExtension();
|
||||
|
||||
# if content is not an array, then transform it
|
||||
if(!is_array($pageMarkdown))
|
||||
{
|
||||
# turn markdown into an array of markdown-blocks
|
||||
$pageMarkdown = $parsedown->markdownToArrayBlocks($pageMarkdown);
|
||||
}
|
||||
|
||||
$oldIndex = ($this->params['old_index'] + 1);
|
||||
$newIndex = ($this->params['new_index'] + 1);
|
||||
|
||||
if(!isset($pageMarkdown[$oldIndex]))
|
||||
{
|
||||
# if the block does not exists, return an error
|
||||
return $response->withJson(array('data' => false, 'errors' => 'The ID of the content-block is wrong.'), 404);
|
||||
}
|
||||
|
||||
$extract = array_splice($pageMarkdown, $oldIndex, 1);
|
||||
array_splice($pageMarkdown, $newIndex, 0, $extract);
|
||||
|
||||
# encode the content into json
|
||||
$pageJson = json_encode($pageMarkdown);
|
||||
|
||||
# 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 internal structure
|
||||
$this->setStructure($draft = true, $cache = false);
|
||||
|
||||
# update this content
|
||||
$this->content = $pageMarkdown;
|
||||
}
|
||||
else
|
||||
{
|
||||
return $response->withJson(['errors' => ['message' => 'Could not write to file. Please check if the file is writable']], 404);
|
||||
}
|
||||
|
||||
# we assume that toc is not relevant
|
||||
$toc = false;
|
||||
|
||||
# needed for ToC links
|
||||
$relurl = '/tm/content/' . $this->settings['editor'] . '/' . $this->item->urlRel;
|
||||
|
||||
# if the moved item is a headline
|
||||
if($extract[0][0] == '#')
|
||||
{
|
||||
$toc = $this->generateToc();
|
||||
}
|
||||
|
||||
# if it is the title, then delete the "# " if it exists
|
||||
$pageMarkdown[0] = trim($pageMarkdown[0], "# ");
|
||||
|
||||
return $response->withJson(array('markdown' => $pageMarkdown, 'toc' => $toc, 'errors' => false));
|
||||
}
|
||||
|
||||
public function deleteBlock(Request $request, Response $response, $args)
|
||||
{
|
||||
/* get params from call */
|
||||
$this->params = $request->getParams();
|
||||
$this->uri = $request->getUri();
|
||||
$errors = false;
|
||||
|
||||
# set structure
|
||||
if(!$this->setStructure($draft = true)){ return $response->withJson(array('data' => false, 'errors' => $this->errors), 404); }
|
||||
|
||||
# set item
|
||||
if(!$this->setItem()){ return $response->withJson($this->errors, 404); }
|
||||
|
||||
# set the status for published and drafted
|
||||
$this->setPublishStatus();
|
||||
|
||||
# set path
|
||||
$this->setItemPath($this->item->fileType);
|
||||
|
||||
# read content from file
|
||||
if(!$this->setContent()){ return $response->withJson(array('data' => false, 'errors' => $this->errors), 404); }
|
||||
|
||||
# get content
|
||||
$this->content;
|
||||
|
||||
if($this->content == '')
|
||||
{
|
||||
$this->content = [];
|
||||
}
|
||||
|
||||
# initialize parsedown extension
|
||||
$parsedown = new ParsedownExtension();
|
||||
|
||||
# if content is not an array, then transform it
|
||||
if(!is_array($this->content))
|
||||
{
|
||||
# turn markdown into an array of markdown-blocks
|
||||
$this->content = $parsedown->markdownToArrayBlocks($this->content);
|
||||
}
|
||||
|
||||
# check if id exists
|
||||
if(!isset($this->content[$this->params['block_id']])){ return $response->withJson(array('data' => false, 'errors' => 'The ID of the content-block is wrong.'), 404); }
|
||||
|
||||
$contentBlock = $this->content[$this->params['block_id']];
|
||||
|
||||
# delete the block
|
||||
unset($this->content[$this->params['block_id']]);
|
||||
$this->content = array_values($this->content);
|
||||
|
||||
$pageMarkdown = $this->content;
|
||||
|
||||
# delete markdown from title
|
||||
if(isset($pageMarkdown[0]))
|
||||
{
|
||||
$pageMarkdown[0] = trim($pageMarkdown[0], "# ");
|
||||
}
|
||||
|
||||
# encode the content into json
|
||||
$pageJson = json_encode($this->content);
|
||||
|
||||
# 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 internal structure
|
||||
$this->setStructure($draft = true, $cache = false);
|
||||
}
|
||||
else
|
||||
{
|
||||
return $response->withJson(['errors' => ['message' => 'Could not write to file. Please check if the file is writable']], 404);
|
||||
}
|
||||
|
||||
$toc = false;
|
||||
|
||||
if($contentBlock[0] == '#')
|
||||
{
|
||||
$toc = $this->generateToc();
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
$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();
|
||||
|
||||
$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();
|
||||
|
||||
$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();
|
||||
|
||||
$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();
|
||||
|
||||
# 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' => '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();
|
||||
|
||||
$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' => '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' => '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' => '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();
|
||||
|
||||
if(!isset($this->params['name']))
|
||||
{
|
||||
return $response->withJson(array('errors' => '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();
|
||||
|
||||
if(!isset($this->params['name']))
|
||||
{
|
||||
return $response->withJson(array('errors' => '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' => '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();
|
||||
$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(array('errors' => 'could not get the video image'));
|
||||
}
|
||||
}
|
||||
|
||||
$imageData64 = 'data:image/jpeg;base64,' . base64_encode($imageData);
|
||||
$desiredSizes = ['live' => ['width' => 560, 'height' => 315]];
|
||||
$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);
|
||||
}
|
||||
|
||||
$tmpImage = $imageProcessor->createImage($imageData64, $desiredSizes);
|
||||
|
||||
if(!$tmpImage)
|
||||
{
|
||||
return $response->withJson(array('errors' => 'could not create temporary image'));
|
||||
}
|
||||
|
||||
$imageUrl = $imageProcessor->publishImage($desiredSizes, $videoID);
|
||||
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' => '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/gif',
|
||||
'image/svg+xml',
|
||||
'font/*',
|
||||
'audio/mpeg',
|
||||
'audio/mp4',
|
||||
'audio/ogg',
|
||||
'video/mpeg',
|
||||
'video/mp4',
|
||||
'video/ogg',
|
||||
);
|
||||
}
|
||||
}
|
356
system/Controllers/MediaApiController.php
Normal file
356
system/Controllers/MediaApiController.php
Normal file
@@ -0,0 +1,356 @@
|
||||
<?php
|
||||
|
||||
namespace Typemill\Controllers;
|
||||
|
||||
use Slim\Http\Request;
|
||||
use Slim\Http\Response;
|
||||
use Typemill\Models\ProcessImage;
|
||||
use Typemill\Models\ProcessFile;
|
||||
use Typemill\Controllers\BlockApiController;
|
||||
use \URLify;
|
||||
|
||||
class MediaApiController extends ContentController
|
||||
{
|
||||
public function getMediaLibImages(Request $request, Response $response, $args)
|
||||
{
|
||||
# get params from call
|
||||
$this->params = $request->getParams();
|
||||
$this->uri = $request->getUri();
|
||||
|
||||
$imageProcessor = new ProcessImage($this->settings['images']);
|
||||
if(!$imageProcessor->checkFolders('images'))
|
||||
{
|
||||
return $response->withJson(['errors' => 'Please check if your media-folder exists and all folders inside are writable.'], 500);
|
||||
}
|
||||
|
||||
$imagelist = $imageProcessor->scanMediaFlat();
|
||||
|
||||
return $response->withJson(['images' => $imagelist]);
|
||||
}
|
||||
|
||||
public function getMediaLibFiles(Request $request, Response $response, $args)
|
||||
{
|
||||
# get params from call
|
||||
$this->params = $request->getParams();
|
||||
$this->uri = $request->getUri();
|
||||
|
||||
$fileProcessor = new ProcessFile();
|
||||
if(!$fileProcessor->checkFolders())
|
||||
{
|
||||
return $response->withJson(['errors' => 'Please check if your media-folder exists and all folders inside are writable.'], 500);
|
||||
}
|
||||
|
||||
$filelist = $fileProcessor->scanFilesFlat();
|
||||
|
||||
return $response->withJson(['files' => $filelist]);
|
||||
}
|
||||
|
||||
public function getImage(Request $request, Response $response, $args)
|
||||
{
|
||||
# get params from call
|
||||
$this->params = $request->getParams();
|
||||
$this->uri = $request->getUri();
|
||||
|
||||
$this->setStructure($draft = true, $cache = false);
|
||||
|
||||
$imageProcessor = new ProcessImage($this->settings['images']);
|
||||
if(!$imageProcessor->checkFolders('images'))
|
||||
{
|
||||
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);
|
||||
|
||||
if($imageDetails)
|
||||
{
|
||||
return $response->withJson(['image' => $imageDetails]);
|
||||
}
|
||||
|
||||
return $response->withJson(['errors' => 'Image not found or image name not valid.'], 404);
|
||||
}
|
||||
|
||||
public function getFile(Request $request, Response $response, $args)
|
||||
{
|
||||
# get params from call
|
||||
$this->params = $request->getParams();
|
||||
$this->uri = $request->getUri();
|
||||
|
||||
$this->setStructure($draft = true, $cache = false);
|
||||
|
||||
$fileProcessor = new ProcessFile();
|
||||
if(!$fileProcessor->checkFolders())
|
||||
{
|
||||
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);
|
||||
|
||||
if($fileDetails)
|
||||
{
|
||||
return $response->withJson(['file' => $fileDetails]);
|
||||
}
|
||||
|
||||
return $response->withJson(['errors' => 'file not found or file name invalid'],404);
|
||||
}
|
||||
|
||||
public function createImage(Request $request, Response $response, $args)
|
||||
{
|
||||
# get params from call
|
||||
$this->params = $request->getParams();
|
||||
$this->uri = $request->getUri();
|
||||
|
||||
$imageProcessor = new ProcessImage($this->settings['images']);
|
||||
|
||||
if(!$imageProcessor->checkFolders('images'))
|
||||
{
|
||||
return $response->withJson(['errors' => 'Please check if your media-folder exists and all folders inside are writable.'], 500);
|
||||
}
|
||||
|
||||
if($imageProcessor->createImage($this->params['image'], $this->params['name'], $this->settings['images']))
|
||||
{
|
||||
return $response->withJson(['name' => 'media/live/' . $imageProcessor->getFullName(),'errors' => false]);
|
||||
}
|
||||
|
||||
return $response->withJson(['errors' => 'could not store image to temporary folder']);
|
||||
}
|
||||
|
||||
public function uploadFile(Request $request, Response $response, $args)
|
||||
{
|
||||
# get params from call
|
||||
$this->params = $request->getParams();
|
||||
$this->uri = $request->getUri();
|
||||
|
||||
# make sure only allowed filetypes are uploaded
|
||||
$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' => 'File-type is not allowed'));
|
||||
}
|
||||
|
||||
$fileProcessor = new ProcessFile();
|
||||
|
||||
if(!$fileProcessor->checkFolders())
|
||||
{
|
||||
return $response->withJson(['errors' => 'Please check if your media-folder exists and all folders inside are writable.'], 500);
|
||||
}
|
||||
|
||||
$fileinfo = $fileProcessor->storeFile($this->params['file'], $this->params['name']);
|
||||
if($fileinfo)
|
||||
{
|
||||
return $response->withJson(['errors' => false, 'info' => $fileinfo]);
|
||||
}
|
||||
|
||||
return $response->withJson(['errors' => 'could not store file to temporary folder'],500);
|
||||
}
|
||||
|
||||
public function publishImage(Request $request, Response $response, $args)
|
||||
{
|
||||
$params = $request->getParsedBody();
|
||||
|
||||
$imageProcessor = new ProcessImage($this->settings['images']);
|
||||
if(!$imageProcessor->checkFolders())
|
||||
{
|
||||
return $response->withJson(['errors' => 'Please check if your media-folder exists and all folders inside are writable.'], 500);
|
||||
}
|
||||
|
||||
if($imageProcessor->publishImage())
|
||||
{
|
||||
$request = $request->withParsedBody($params);
|
||||
|
||||
$block = new BlockApiController($this->c);
|
||||
if($params['new'])
|
||||
{
|
||||
return $block->addBlock($request, $response, $args);
|
||||
}
|
||||
return $block->updateBlock($request, $response, $args);
|
||||
}
|
||||
|
||||
return $response->withJson(['errors' => 'could not store image to media folder'],500);
|
||||
}
|
||||
|
||||
public function publishFile(Request $request, Response $response, $args)
|
||||
{
|
||||
$params = $request->getParsedBody();
|
||||
|
||||
$fileProcessor = new ProcessFile();
|
||||
if(!$fileProcessor->checkFolders())
|
||||
{
|
||||
return $response->withJson(['errors' => 'Please check if your media-folder exists and all folders inside are writable.'], 500);
|
||||
}
|
||||
|
||||
if($fileProcessor->publishFile())
|
||||
{
|
||||
$request = $request->withParsedBody($params);
|
||||
|
||||
$block = new BlockApiController($this->c);
|
||||
if($params['new'])
|
||||
{
|
||||
return $block->addBlock($request, $response, $args);
|
||||
}
|
||||
return $block->updateBlock($request, $response, $args);
|
||||
}
|
||||
|
||||
return $response->withJson(['errors' => 'could not store file to media folder'],500);
|
||||
}
|
||||
|
||||
public function deleteImage(Request $request, Response $response, $args)
|
||||
{
|
||||
# get params from call
|
||||
$this->params = $request->getParams();
|
||||
$this->uri = $request->getUri();
|
||||
|
||||
if(!isset($this->params['name']))
|
||||
{
|
||||
return $response->withJson(['errors' => 'image name is missing'],500);
|
||||
}
|
||||
|
||||
$imageProcessor = new ProcessImage($this->settings['images']);
|
||||
if(!$imageProcessor->checkFolders())
|
||||
{
|
||||
return $response->withJson(['errors' => 'Please check if your media-folder exists and all folders inside are writable.'], 500);
|
||||
}
|
||||
|
||||
if($imageProcessor->deleteImage($this->params['name']))
|
||||
{
|
||||
return $response->withJson(['errors' => false]);
|
||||
}
|
||||
|
||||
return $response->withJson(['errors' => 'Oops, looks like we could not delete all sizes of that image.'], 500);
|
||||
}
|
||||
|
||||
public function deleteFile(Request $request, Response $response, $args)
|
||||
{
|
||||
# get params from call
|
||||
$this->params = $request->getParams();
|
||||
$this->uri = $request->getUri();
|
||||
|
||||
if(!isset($this->params['name']))
|
||||
{
|
||||
return $response->withJson(['errors' => 'file name is missing'],500);
|
||||
}
|
||||
|
||||
$fileProcessor = new ProcessFile();
|
||||
|
||||
if($fileProcessor->deleteFile($this->params['name']))
|
||||
{
|
||||
return $response->withJson(['errors' => false]);
|
||||
}
|
||||
|
||||
return $response->withJson(['errors' => 'could not delete the file'],500);
|
||||
}
|
||||
|
||||
public function saveVideoImage(Request $request, Response $response, $args)
|
||||
{
|
||||
/* get params from call */
|
||||
$this->params = $request->getParams();
|
||||
$this->uri = $request->getUri();
|
||||
$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(array('errors' => 'could not get the video image'));
|
||||
}
|
||||
}
|
||||
|
||||
$imageData64 = 'data:image/jpeg;base64,' . base64_encode($imageData);
|
||||
$desiredSizes = ['live' => ['width' => 560, 'height' => 315]];
|
||||
$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);
|
||||
}
|
||||
|
||||
$tmpImage = $imageProcessor->createImage($imageData64, $desiredSizes);
|
||||
|
||||
if(!$tmpImage)
|
||||
{
|
||||
return $response->withJson(array('errors' => 'could not create temporary image'));
|
||||
}
|
||||
|
||||
$imageUrl = $imageProcessor->publishImage($desiredSizes, $videoID);
|
||||
if($imageUrl)
|
||||
{
|
||||
$this->params['markdown'] = '{#' . $videoID. ' .' . $class . '}';
|
||||
|
||||
$request = $request->withParsedBody($this->params);
|
||||
|
||||
$block = new BlockApiController($this->c);
|
||||
if($params['new'])
|
||||
{
|
||||
return $block->addBlock($request, $response, $args);
|
||||
}
|
||||
return $block->updateBlock($request, $response, $args);
|
||||
}
|
||||
|
||||
return $response->withJson(array('errors' => '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/gif',
|
||||
'image/svg+xml',
|
||||
'font/*',
|
||||
'audio/mpeg',
|
||||
'audio/mp4',
|
||||
'audio/ogg',
|
||||
'video/mpeg',
|
||||
'video/mp4',
|
||||
'video/ogg',
|
||||
);
|
||||
}
|
||||
}
|
@@ -200,9 +200,8 @@ class MetaApiController extends ContentController
|
||||
|
||||
if($tab == 'meta')
|
||||
{
|
||||
|
||||
# if manual date has been modified
|
||||
if(isset($metaInput['manualdate']) && !isset($metaPage['meta']['manualdate']) OR ($metaInput['manualdate'] != $metaPage['meta']['manualdate']))
|
||||
if( $this->hasChanged($metaInput, $metaPage['meta'], 'manualdate'))
|
||||
{
|
||||
# update the time
|
||||
$metaInput['time'] = date('H-i-s', time());
|
||||
@@ -230,7 +229,7 @@ class MetaApiController extends ContentController
|
||||
}
|
||||
|
||||
# if folder has changed and contains pages instead of posts or posts instead of pages
|
||||
if($this->item->elementType == "folder" && ($metaPage['meta']['contains'] !== $metaInput['contains']))
|
||||
if($this->item->elementType == "folder" && isset($metaInput['contains']) && $this->hasChanged($metaInput, $metaPage['meta'], 'contains'))
|
||||
{
|
||||
$structure = true;
|
||||
|
||||
@@ -258,9 +257,9 @@ class MetaApiController extends ContentController
|
||||
}
|
||||
elseif(
|
||||
# check if navtitle or hide-value has been changed
|
||||
($metaPage['meta']['navtitle'] != $metaInput['navtitle'])
|
||||
($this->hasChanged($metaInput, $metaPage['meta'], 'navtitle'))
|
||||
OR
|
||||
($metaPage['meta']['hide'] != $metaInput['hide'])
|
||||
($this->hasChanged($metaInput, $metaPage['meta'], 'hide'))
|
||||
)
|
||||
{
|
||||
# add new file data. Also makes sure that the value is set.
|
||||
@@ -297,6 +296,19 @@ class MetaApiController extends ContentController
|
||||
# return with the new metadata
|
||||
return $response->withJson(array('metadata' => $metaInput, 'structure' => $structure, 'item' => $this->item, 'errors' => false));
|
||||
}
|
||||
|
||||
protected function hasChanged($input, $page, $field)
|
||||
{
|
||||
if(isset($input[$field]) && isset($page[$field]) && $input[$field] == $page[$field])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if(!isset($input[$field]) && !isset($input[$field]))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
# check models -> writeYaml for getPageMeta and getPageMetaDefaults.
|
@@ -108,13 +108,16 @@ class PageController extends Controller
|
||||
/* get breadcrumb for page */
|
||||
$breadcrumb = Folder::getBreadcrumb($structure, $item->keyPathArray);
|
||||
$breadcrumb = $this->c->dispatcher->dispatch('onBreadcrumbLoaded', new OnBreadcrumbLoaded($breadcrumb))->getData();
|
||||
|
||||
# set pages active for navigation again
|
||||
Folder::getBreadcrumb($navigation, $item->keyPathArray);
|
||||
|
||||
/* add the paging to the item */
|
||||
$item = Folder::getPagingForItem($structure, $item);
|
||||
}
|
||||
|
||||
# dispatch the item
|
||||
$item = $this->c->dispatcher->dispatch('onItemLoaded', new OnItemLoaded($item))->getData();
|
||||
$item = $this->c->dispatcher->dispatch('onItemLoaded', new OnItemLoaded($item))->getData();
|
||||
|
||||
# set the filepath
|
||||
$filePath = $pathToContent . $item->path;
|
||||
@@ -211,6 +214,18 @@ class PageController extends Controller
|
||||
$this->c->assets->addCSS($base_url . '/cache/' . $theme . '-custom.css');
|
||||
}
|
||||
|
||||
$logo = false;
|
||||
if(isset($settings['logo']) && $settings['logo'] != '')
|
||||
{
|
||||
$logo = 'media/files/' . $settings['logo'];
|
||||
}
|
||||
|
||||
$favicon = false;
|
||||
if(isset($settings['favicon']) && $settings['favicon'] != '')
|
||||
{
|
||||
$favicon = true;
|
||||
}
|
||||
|
||||
return $this->render($response, $route, [
|
||||
'home' => $home,
|
||||
'navigation' => $navigation,
|
||||
@@ -221,7 +236,10 @@ class PageController extends Controller
|
||||
'settings' => $settings,
|
||||
'metatabs' => $metatabs,
|
||||
'base_url' => $base_url,
|
||||
'image' => $firstImage ]);
|
||||
'image' => $firstImage,
|
||||
'logo' => $logo,
|
||||
'favicon' => $favicon
|
||||
]);
|
||||
}
|
||||
|
||||
protected function getCachedStructure($cache)
|
||||
|
@@ -7,6 +7,8 @@ use Typemill\Models\Write;
|
||||
use Typemill\Models\Fields;
|
||||
use Typemill\Models\Validation;
|
||||
use Typemill\Models\User;
|
||||
use Typemill\Models\ProcessFile;
|
||||
use Typemill\Models\ProcessImage;
|
||||
|
||||
class SettingsController extends Controller
|
||||
{
|
||||
@@ -15,7 +17,7 @@ class SettingsController extends Controller
|
||||
*********************/
|
||||
|
||||
public function showSettings($request, $response, $args)
|
||||
{
|
||||
{
|
||||
$user = new User();
|
||||
$settings = $this->c->get('settings');
|
||||
$defaultSettings = \Typemill\Settings::getDefaultSettings();
|
||||
@@ -46,8 +48,10 @@ class SettingsController extends Controller
|
||||
$settings = \Typemill\Settings::getUserSettings();
|
||||
$defaultSettings = \Typemill\Settings::getDefaultSettings();
|
||||
$params = $request->getParams();
|
||||
$files = $request->getUploadedFiles();
|
||||
$newSettings = isset($params['settings']) ? $params['settings'] : false;
|
||||
$validate = new Validation();
|
||||
$processFiles = new ProcessFile();
|
||||
|
||||
if($newSettings)
|
||||
{
|
||||
@@ -62,6 +66,8 @@ class SettingsController extends Controller
|
||||
'formats' => $newSettings['formats'],
|
||||
);
|
||||
|
||||
# https://www.slimframework.com/docs/v3/cookbook/uploading-files.html;
|
||||
|
||||
$copyright = $this->getCopyright();
|
||||
|
||||
$validate->settings($newSettings, $copyright, $defaultSettings['formats'], 'settings');
|
||||
@@ -77,8 +83,80 @@ class SettingsController extends Controller
|
||||
$this->c->flash->addMessage('error', 'Please correct the errors');
|
||||
return $response->withRedirect($this->c->router->pathFor('settings.show'));
|
||||
}
|
||||
|
||||
/* store updated settings */
|
||||
|
||||
if(!$processFiles->checkFolders())
|
||||
{
|
||||
$this->c->flash->addMessage('error', 'Please make sure that your media folder exists and is writable.');
|
||||
return $response->withRedirect($this->c->router->pathFor('settings.show'));
|
||||
}
|
||||
|
||||
# handle single input with single file upload
|
||||
$logo = $files['settings']['logo'];
|
||||
if($logo->getError() === UPLOAD_ERR_OK)
|
||||
{
|
||||
$allowed = ['jpg', 'jpeg', 'png', 'svg'];
|
||||
$extension = pathinfo($logo->getClientFilename(), PATHINFO_EXTENSION);
|
||||
if(!in_array(strtolower($extension), $allowed))
|
||||
{
|
||||
$_SESSION['errors']['settings']['logo'] = array('Only jpg, jpeg, png and svg allowed');
|
||||
$this->c->flash->addMessage('error', 'Please correct the errors');
|
||||
return $response->withRedirect($this->c->router->pathFor('settings.show'));
|
||||
}
|
||||
|
||||
$processFiles->deleteFileWithName('logo');
|
||||
$newSettings['logo'] = $processFiles->moveUploadedFile($logo, $overwrite = true, $name = 'logo');
|
||||
}
|
||||
elseif(isset($params['settings']['deletelogo']) && $params['settings']['deletelogo'] == 'delete')
|
||||
{
|
||||
$processFiles->deleteFileWithName('logo');
|
||||
$newSettings['logo'] = '';
|
||||
}
|
||||
else
|
||||
{
|
||||
$newSettings['logo'] = isset($settings['logo']) ? $settings['logo'] : '';
|
||||
}
|
||||
|
||||
# handle single input with single file upload
|
||||
$favicon = $files['settings']['favicon'];
|
||||
if ($favicon->getError() === UPLOAD_ERR_OK)
|
||||
{
|
||||
$extension = pathinfo($favicon->getClientFilename(), PATHINFO_EXTENSION);
|
||||
if(strtolower($extension) != 'png')
|
||||
{
|
||||
$_SESSION['errors']['settings']['favicon'] = array('Only .png-files allowed');
|
||||
$this->c->flash->addMessage('error', 'Please correct the errors');
|
||||
return $response->withRedirect($this->c->router->pathFor('settings.show'));
|
||||
}
|
||||
|
||||
$processImage = new ProcessImage([
|
||||
'16' => ['width' => 16, 'height' => 16],
|
||||
'32' => ['width' => 32, 'height' => 32],
|
||||
'72' => ['width' => 72, 'height' => 72],
|
||||
'114' => ['width' => 114, 'height' => 114],
|
||||
'144' => ['width' => 144, 'height' => 144],
|
||||
'180' => ['width' => 180, 'height' => 180],
|
||||
]);
|
||||
$favicons = $processImage->generateSizesFromImageFile('favicon.png', $favicon->file);
|
||||
|
||||
foreach($favicons as $key => $favicon)
|
||||
{
|
||||
imagepng( $favicon, $processFiles->fileFolder . 'favicon-' . $key . '.png' );
|
||||
# $processFiles->moveUploadedFile($favicon, $overwrite = true, $name = 'favicon-' . $key);
|
||||
}
|
||||
|
||||
$newSettings['favicon'] = 'favicon';
|
||||
}
|
||||
elseif(isset($params['settings']['deletefav']) && $params['settings']['deletefav'] == 'delete')
|
||||
{
|
||||
$processFiles->deleteFileWithName('favicon');
|
||||
$newSettings['favicon'] = '';
|
||||
}
|
||||
else
|
||||
{
|
||||
$newSettings['favicon'] = isset($settings['favicon']) ? $settings['favicon'] : '';
|
||||
}
|
||||
|
||||
# store updated settings
|
||||
\Typemill\Settings::updateSettings(array_merge($settings, $newSettings));
|
||||
|
||||
$this->c->flash->addMessage('info', 'Settings are stored');
|
||||
|
@@ -9,6 +9,13 @@ use Typemill\Models\Write;
|
||||
|
||||
class SetupController extends Controller
|
||||
{
|
||||
|
||||
# redirect if visit /setup route
|
||||
public function redirect($request, $response)
|
||||
{
|
||||
return $response->withRedirect($this->c->router->pathFor('setup.show'));
|
||||
}
|
||||
|
||||
public function show($request, $response, $args)
|
||||
{
|
||||
/* make some checks befor you install */
|
||||
|
Reference in New Issue
Block a user