1
0
mirror of https://github.com/typemill/typemill.git synced 2025-07-31 11:20:15 +02:00

Add update checker and proxy detection

This commit is contained in:
trendschau
2023-08-20 14:39:44 +02:00
parent 6c01a3a96e
commit 52758def3c
33 changed files with 686 additions and 419 deletions

View File

@@ -127,6 +127,7 @@ abstract class Controller
return $formDefinitions;
}
# used to protect api access, can we do it with middleware?
protected function validateRights($userrole, $resource, $action)
{
$acl = $this->c->get('acl');
@@ -136,7 +137,9 @@ abstract class Controller
return true;
}
# check ownership.
die("PLEASE UPDATE THE METHOD validateRights in controller.php");
# check ownership. THIS WILL FAIL ANYWAY!!!
# MAYBE WE SHOUD ADD THIS CHECK INTO MIDDLEWARE, TOO ?
$writeMeta = new writeMeta();
$pagemeta = $writeMeta->getPageMeta($this->settings, $this->item);
@@ -159,74 +162,4 @@ abstract class Controller
return false;
}
# move to another place??
protected function recursiveValidation($validator, array $formdefinitions, $input, $output = [])
{
# loop through form-definitions, ignores everything that is not defined in yaml
foreach($formdefinitions as $fieldname => $fielddefinitions)
{
if(is_array($fielddefinitions) && $fielddefinitions['type'] == 'fieldset')
{
$output = $this->recursiveValidation($validator, $fielddefinitions['fields'], $input, $output);
}
# do not store values for disabled fields
if(isset($fielddefinitions['disabled']) && $fielddefinitions['type'])
{
continue;
}
if(isset($input[$fieldname]))
{
$fieldvalue = $input[$fieldname];
# fix false or null values for selectboxes
if($fielddefinitions['type'] == "select" && ($fieldvalue === 'NULL' OR $fieldvalue === false))
{
$fieldvalue = NULL;
}
$validationresult = $validator->field($fieldname, $fieldvalue, $fielddefinitions);
if($validationresult === true)
{
# MOVE THIS TO A SEPARATE FUNCTION SO YOU CAN STORE IMAGES ONLY IF ALL FIELDS SUCCESSFULLY VALIDATED
# images have special treatment, check ProcessImage-Model and ImageApiController
if($fielddefinitions['type'] == 'image')
{
# then check if file is there already: check for name and maybe correct image extension (if quality has been changed)
$storage = new StorageWrapper('\Typemill\Models\Storage');
$existingImagePath = $storage->checkImage($fieldvalue);
if($existingImagePath)
{
$fieldvalue = $existingImagePath;
}
else
{
# there is no published image with that name, so check if there is an unpublished image in tmp folder and publish it
$newImagePath = $storage->publishImage($fieldvalue);
if($newImagePath)
{
$fieldvalue = $newImagePath;
}
else
{
$fieldvalue = '';
}
}
}
$output[$fieldname] = $fieldvalue;
}
else
{
$this->errors[$fieldname] = $validationresult[$fieldname][0];
}
}
}
return $output;
}
}

View File

@@ -9,7 +9,14 @@ use Typemill\Models\StorageWrapper;
use Typemill\Models\Validation;
use Typemill\Models\Navigation;
use Typemill\Models\Content;
use Typemill\Models\Meta;
use Typemill\Models\Sitemap;
use Typemill\Static\Slug;
use Typemill\Events\OnPagePublished;
use Typemill\Events\OnPageUnpublished;
use Typemill\Events\OnPageDeleted;
use Typemill\Events\OnPageSorted;
use Typemill\Events\OnPageRenamed;
class ControllerApiAuthorArticle extends Controller
{
@@ -70,25 +77,29 @@ class ControllerApiAuthorArticle extends Controller
$draftNavigation = $navigation->setActiveNaviItems($draftNavigation, $item->keyPathArray);
$item = $navigation->getItemWithKeyPath($draftNavigation, $item->keyPathArray);
$sitemap = new Sitemap();
$sitemap->updateSitemap($draftNavigation, $urlinfo);
# META is important e.g. for newsletter, so send it, too
$meta = new Meta();
$metadata = $meta->getMetaData($item);
$metadata = $meta->addMetaDefaults($metadata, $item, $this->settings['author']);
# $metadata = $meta->addMetaTitleDescription($metadata, $item, $markdownArray);
# dispatch event, e.g. send newsletter and more
$data = [
'markdown' => $draftMarkdown,
'item' => $item,
'meta' => $metadata
];
$this->c->get('dispatcher')->dispatch(new OnPagePublished($data), 'onPagePublished');
$response->getBody()->write(json_encode([
'navigation' => $draftNavigation,
'item' => $item
]));
return $response->withHeader('Content-Type', 'application/json');
/*
# update the sitemap
$this->updateSitemap($ping = true);
# complete the page meta if title or description not set
$writeMeta = new WriteMeta();
$meta = $writeMeta->completePageMeta($this->content, $this->settings, $this->item);
# dispatch event
$page = ['content' => $this->content, 'meta' => $meta, 'item' => $this->item];
$page = $this->c->dispatcher->dispatch('onPagePublished', new OnPagePublished($page))->getData();
*/
}
public function unpublishArticle(Request $request, Response $response, $args)
@@ -140,6 +151,9 @@ class ControllerApiAuthorArticle extends Controller
$draftNavigation = $navigation->setActiveNaviItems($draftNavigation, $item->keyPathArray);
$item = $navigation->getItemWithKeyPath($draftNavigation, $item->keyPathArray);
$sitemap = new Sitemap();
$sitemap->updateSitemap($draftNavigation, $urlinfo);
# check if it is a folder and if the folder has published pages.
$message = false;
if($item->elementType == 'folder' && isset($item->folderContent))
@@ -153,6 +167,9 @@ class ControllerApiAuthorArticle extends Controller
}
}
# dispatch event
$this->c->get('dispatcher')->dispatch(new OnPageUnpublished($item), 'onPageUnpublished');
$response->getBody()->write(json_encode([
'message' => $message,
'navigation' => $draftNavigation,
@@ -274,11 +291,28 @@ class ControllerApiAuthorArticle extends Controller
$draftNavigation = $navigation->getDraftNavigation($urlinfo, $this->settings['langattr']);
$draftNavigation = $navigation->setActiveNaviItems($draftNavigation, $item->keyPathArray);
$item = $navigation->getItemWithKeyPath($draftNavigation, $item->keyPathArray);
$sitemap = new Sitemap();
$sitemap->updateSitemap($draftNavigation, $urlinfo);
# refresh content
$draftMarkdown = $content->getDraftMarkdown($item);
$draftMarkdownHtml = $content->addDraftHtml($draftMarkdown);
# META is important e.g. for newsletter, so send it, too
$meta = new Meta();
$metadata = $meta->getMetaData($item);
$metadata = $meta->addMetaDefaults($metadata, $item, $this->settings['author']);
# $metadata = $meta->addMetaTitleDescription($metadata, $item, $markdownArray);
# dispatch event, e.g. send newsletter and more
$data = [
'markdown' => $draftMarkdown,
'item' => $item,
'meta' => $metadata
];
$this->c->get('dispatcher')->dispatch(new OnPagePublished($data), 'onPagePublished');
$response->getBody()->write(json_encode([
'item' => $item,
'navigation' => $draftNavigation,
@@ -670,16 +704,24 @@ class ControllerApiAuthorArticle extends Controller
}
$navigation->renameItem($item, $params['slug']);
$navigation->clearNavigation();
# $this->updateSitemap($ping = true);
$draftNavigation = $navigation->getDraftNavigation($urlinfo, $this->settings['langattr']);
$sitemap = new Sitemap();
$sitemap->updateSitemap($draftNavigation, $urlinfo);
# create the new url for redirects
$newUrlRel = str_replace($item->slug, $params['slug'], $item->urlRelWoF);
$url = $urlinfo['baseurl'] . '/tm/content/' . $this->settings['editor'] . $newUrlRel;
$data = [
'item' => $item,
'newUrl' => $newUrlRel
];
$this->c->get('dispatcher')->dispatch(new OnPageRenamed($data), 'onPageRenamed');
$response->getBody()->write(json_encode([
'navigation' => $navigation->getDraftNavigation($urlinfo, $this->settings['langattr']),
'navigation' => $draftNavigation,
'message' => '',
'url' => $url
]));
@@ -687,7 +729,6 @@ class ControllerApiAuthorArticle extends Controller
return $response->withHeader('Content-Type', 'application/json');
}
public function sortArticle(Request $request, Response $response, $args)
{
$validRights = $this->validateRights($request->getAttribute('c_userrole'), 'content', 'update');
@@ -757,9 +798,6 @@ class ControllerApiAuthorArticle extends Controller
# if the item has been moved within the same folder
if($params['parent_id_from'] == $params['parent_id_to'])
{
# no need to ping search engines
$ping = false;
# get key of item
$itemKey = end($itemKeyPath);
reset($itemKeyPath);
@@ -769,9 +807,6 @@ class ControllerApiAuthorArticle extends Controller
}
else
{
# let us ping search engines
$ping = true;
# an active file has been moved to another folder, so send new url with response
if($params['active'] == 'active')
{
@@ -807,9 +842,15 @@ class ControllerApiAuthorArticle extends Controller
# refresh navigation and item
$navigation->clearNavigation();
$draftNavigation = $navigation->getDraftNavigation($urlinfo, $langattr);
$sitemap = new Sitemap();
$sitemap->updateSitemap($draftNavigation, $urlinfo);
$this->c->get('dispatcher')->dispatch(new OnPageSorted($params), 'onPageSorted');
$response->getBody()->write(json_encode([
'navigation' => $navigation->getDraftNavigation($urlinfo, $langattr),
'navigation' => $draftNavigation,
'message' => '',
'url' => false
]));
@@ -880,6 +921,9 @@ class ControllerApiAuthorArticle extends Controller
$navigation->clearNavigation();
$draftNavigation = $navigation->getDraftNavigation($urlinfo, $this->settings['langattr']);
$sitemap = new Sitemap();
$sitemap->updateSitemap($draftNavigation, $urlinfo);
# check if it is a subfile or subfolder and set the redirect-url to the parent item
$url = $urlinfo['baseurl'] . '/tm/content/' . $this->settings['editor'];
if(count($item->keyPathArray) > 1)
@@ -895,6 +939,9 @@ class ControllerApiAuthorArticle extends Controller
}
}
# dispatch event
$this->c->get('dispatcher')->dispatch(new OnPageDeleted($item), 'onPageDeleted');
$response->getBody()->write(json_encode([
'url' => $url
]));

View File

@@ -8,11 +8,15 @@ use Slim\Routing\RouteContext;
use Typemill\Models\Validation;
use Typemill\Models\Navigation;
use Typemill\Models\Meta;
use Typemill\Events\OnMetaLoaded;
class ControllerApiAuthorMeta extends Controller
{
public function getMeta(Request $request, Response $response, $args)
{
# is it really needed? Check middleware if rights are validated there already
$validRights = $this->validateRights($request->getAttribute('c_userrole'), 'content', 'update');
if(!$validRights)
{
@@ -87,6 +91,9 @@ class ControllerApiAuthorMeta extends Controller
# store the metascheme in cache for frontend
# $writeMeta->updateYaml('cache', 'metatabs.yaml', $metascheme);
$metacleared = $this->c->get('dispatcher')->dispatch(new OnMetaLoaded($metacleared),'onMetaLoaded')->getData();
$response->getBody()->write(json_encode([
'metadata' => $metacleared,
'metadefinitions' => $metadefinitions,
@@ -162,7 +169,7 @@ class ControllerApiAuthorMeta extends Controller
$tabdefinitions = $this->flattenTabFields($tabdefinitions['fields'], []);
# create validation object
$errors = false;
$errors = [];
# take the user input data and iterate over all fields and values
foreach($params['data'] as $fieldname => $fieldvalue)
@@ -187,7 +194,7 @@ class ControllerApiAuthorMeta extends Controller
}
# return validation errors
if($errors)
if(!empty($errors))
{
$response->getBody()->write(json_encode([
'message' => 'Please correct the errors.',

View File

@@ -23,12 +23,12 @@ class ControllerApiSystemPlugins extends Controller
# validate input
$validator = new Validation();
$validatedOutput = $this->recursiveValidation($validator, $formdefinitions, $plugininput);
if(!empty($this->errors))
$validatedOutput = $validator->recursiveValidation($formdefinitions, $plugininput);
if(!empty($validator->errors))
{
$response->getBody()->write(json_encode([
'message' => 'Please correct tbe errors in form.',
'errors' => $this->errors
'errors' => $validator->errors
]));
return $response->withHeader('Content-Type', 'application/json')->withStatus(400);

View File

@@ -34,13 +34,13 @@ class ControllerApiSystemSettings extends Controller
# validate input
$validator = new Validation();
$validatedOutput = $this->recursiveValidation($validator, $formdefinitions, $settingsinput);
$validatedOutput = $validator->recursiveValidation($formdefinitions, $settingsinput);
if(!empty($this->errors))
if(!empty($valiator->errors))
{
$response->getBody()->write(json_encode([
'message' => 'Please correct errors in form.',
'errors' => $this->errors
'errors' => $validator->errors
]));
return $response->withHeader('Content-Type', 'application/json')->withStatus(400);

View File

@@ -23,12 +23,12 @@ class ControllerApiSystemThemes extends Controller
# validate input
$validator = new Validation();
$validatedOutput = $this->recursiveValidation($validator, $formdefinitions, $themeinput);
if(!empty($this->errors))
$validatedOutput = $validator->recursiveValidation($formdefinitions, $themeinput);
if(!empty($validator->errors))
{
$response->getBody()->write(json_encode([
'message' => 'Please correct tbe errors in form.',
'errors' => $this->errors
'errors' => $validator->errors
]));
return $response->withHeader('Content-Type', 'application/json')->withStatus(400);

View File

@@ -158,12 +158,12 @@ class ControllerApiSystemUsers extends Controller
$formdefinitions = $user->getUserFields($this->c->get('acl'), $request->getAttribute('c_userrole'));
$validatedOutput = $this->recursiveValidation($validate, $formdefinitions, $userdata);
if(!empty($this->errors))
$validatedOutput = $validate->recursiveValidation($formdefinitions, $userdata);
if(!empty($validate->errors))
{
$response->getBody()->write(json_encode([
'message' => 'Please correct tbe errors in form.',
'errors' => $this->errors
'errors' => $validate->errors
]));
return $response->withHeader('Content-Type', 'application/json')->withStatus(400);
@@ -254,12 +254,12 @@ class ControllerApiSystemUsers extends Controller
$user = new User();
$formdefinitions = $user->getUserFields($this->c->get('acl'), $userdata['userrole'],$inspectorrole = $request->getAttribute('c_userrole'));
unset($formdefinitions['username']['readonly']);
$validatedOutput = $this->recursiveValidation($validate, $formdefinitions, $userdata);
if(!empty($this->errors))
$validatedOutput = $validate->recursiveValidation($formdefinitions, $userdata);
if(!empty($validate->errors))
{
$response->getBody()->write(json_encode([
'message' => 'Please correct tbe errors in form.',
'errors' => $this->errors
'errors' => $validate->errors
]));
return $response->withHeader('Content-Type', 'application/json')->withStatus(400);

View File

@@ -0,0 +1,94 @@
<?php
namespace Typemill\Controllers;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Message\ResponseInterface as Response;
use Typemill\Models\Validation;
class ControllerApiSystemVersions extends Controller
{
public function checkVersions(Request $request, Response $response)
{
$params = $request->getParsedBody();
# validate input
$validate = new Validation();
$vresult = $validate->checkVersions($params);
if($vresult !== true)
{
$response->getBody()->write(json_encode([
'message' => 'The version check failed because of invalid parameters.'
]));
return $response->withHeader('Content-Type', 'application/json')->withStatus(400);
}
$type = $params['type'];
$data = $params['data'];
$url = 'https://typemill.net/api/v1/checkversion';
if($type == 'plugins')
{
$pluginList = '';
foreach($data as $name => $plugin)
{
$pluginList .= $name . ',';
}
$url = 'https://plugins.typemill.net/api/v1/getplugins?plugins=' . urlencode($pluginList);
}
if($type == 'themes')
{
$themeList = '';
foreach($data as $name => $theme)
{
$themeList .= $name . ',';
}
$url = 'https://themes.typemill.net/api/v1/getthemes?themes=' . urlencode($themeList);
}
$opts = array(
'http'=>array(
'method'=>"GET",
'ignore_errors' => true,
'timeout' => 5,
'header'=>"Referer: http://typemill-version2.net"
)
);
$context = stream_context_create($opts);
$versions = file_get_contents($url, false, $context);
$versions = json_decode($versions, true);
$updateVersions = [];
if($type == 'system')
{
$latestVersion = $versions['system']['typemill'] ?? false;
$installedVersion = $data ?? false;
if($latestVersion && $installedVersion && version_compare($latestVersion, $installedVersion) <= 0)
{
$updateVersions['system'] = $latestVersion;
}
}
elseif(isset($versions[$type]))
{
foreach($versions[$type] as $name => $details)
{
$latestVersion = $details['version'] ?? false;
$installedVersion = $data[$name] ?? false;
if($latestVersion && $installedVersion && version_compare($latestVersion, $installedVersion) <= 0)
{
$updateVersions[$name] = $details;
}
}
}
$response->getBody()->write(json_encode([
$type => $updateVersions
]));
return $response->withHeader('Content-Type', 'application/json')->withStatus(200);
}
}

View File

@@ -7,6 +7,11 @@ use Psr\Http\Message\ResponseInterface as Response;
use Slim\Routing\RouteContext;
use Typemill\Models\Navigation;
use Typemill\Models\Content;
use Typemill\Events\OnPagetreeLoaded;
use Typemill\Events\OnItemLoaded;
use Typemill\Events\OnMarkdownLoaded;
use Typemill\Events\OnPageReady;
class ControllerWebAuthor extends Controller
{
@@ -46,8 +51,10 @@ class ControllerWebAuthor extends Controller
# $draftNavigation = $navigation->getDraftNavigation($urlinfo, $langattr);
$draftNavigation = $navigation->setActiveNaviItems($draftNavigation, $keyPathArray);
$draftNavigation = $this->c->get('dispatcher')->dispatch(new OnPagetreeLoaded($draftNavigation), 'onPagetreeLoaded')->getData();
$item = $navigation->getItemWithKeyPath($draftNavigation, $keyPathArray);
$item = $this->c->get('dispatcher')->dispatch(new OnItemLoaded($item), 'onItemLoaded')->getData();
}
# $item->modified = ($item->published OR $item->drafted) ? filemtime($this->settings['contentFolder'] . $this->path) : false;
@@ -57,9 +64,11 @@ class ControllerWebAuthor extends Controller
$content = new Content($urlinfo['baseurl']);
$draftMarkdown = $content->getDraftMarkdown($item);
$draftMarkdown = $this->c->get('dispatcher')->dispatch(new OnMarkdownLoaded($draftMarkdown), 'onMarkdownLoaded')->getData();
$draftMarkdownHtml = $content->addDraftHtml($draftMarkdown);
return $this->c->get('view')->render($response, 'content/blox-editor.twig', [
'settings' => $this->settings,
'mainnavi' => $mainNavigation,
@@ -110,10 +119,11 @@ class ControllerWebAuthor extends Controller
# extend : $request->getAttribute('c_userrole')
$draftNavigation = $navigation->getDraftNavigation($urlinfo, $langattr);
$draftNavigation = $navigation->setActiveNaviItems($draftNavigation, $keyPathArray);
$draftNavigation = $this->c->get('dispatcher')->dispatch(new OnPagetreeLoaded($draftNavigation), 'onPagetreeLoaded')->getData();
$item = $navigation->getItemWithKeyPath($draftNavigation, $keyPathArray);
$item = $this->c->get('dispatcher')->dispatch(new OnItemLoaded($item), 'onItemLoaded')->getData();
}
# $item->modified = ($item->published OR $item->drafted) ? filemtime($this->settings['contentFolder'] . $this->path) : false;
@@ -123,6 +133,7 @@ class ControllerWebAuthor extends Controller
$content = new Content($urlinfo['baseurl']);
$draftMarkdown = $content->getDraftMarkdown($item);
$draftMarkdown = $this->c->get('dispatcher')->dispatch(new OnMarkdownLoaded($draftMarkdown), 'onMarkdownLoaded')->getData();
$draftMarkdownHtml = $content->addDraftHtml($draftMarkdown);
@@ -140,78 +151,5 @@ class ControllerWebAuthor extends Controller
'content' => $draftMarkdownHtml,
]
]);
# get params from call
# $this->uri = $request->getUri()->withUserInfo('');
# $this->params = isset($args['params']) ? ['url' => $this->uri->getBasePath() . '/' . $args['params']] : ['url' => $this->uri->getBasePath()];
# set structure
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 )); }
# we have to check ownership here to use it for permission-check in tempates
$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->structureDraft, $this->item->keyPathArray) : false;
# set the status for published and drafted
$this->setPublishStatus();
# set path
$this->setItemPath($this->item->fileType);
# add the modified date for the file
$this->item->modified = ($this->item->published OR $this->item->drafted) ? filemtime($this->settings['contentFolder'] . $this->path) : false;
# read content from file
if(!$this->setContent()){ return $this->renderIntern404($response, array( 'navigation' => $this->structure, 'settings' => $this->settings, 'content' => $this->errors )); }
$content = $this->content;
$title = false;
# if content is an array, then it is a draft
if(is_array($content))
{
# transform array to markdown
$parsedown = new ParsedownExtension($this->uri->getBaseUrl());
$content = $parsedown->arrayBlocksToMarkdown($content);
}
# if there is content
if($content != '')
{
# normalize linebreaks
$content = str_replace(array("\r\n", "\r"), "\n", $content);
$content = trim($content, "\n");
# and strip out title
if($content[0] == '#')
{
$contentParts = explode("\n", $content, 2);
$title = trim($contentParts[0], "# \t\n\r\0\x0B");
$content = trim($contentParts[1]);
}
}
return $this->renderIntern($response, 'editor/editor-raw.twig', array(
'acl' => $this->c->acl,
'mycontent' => $this->mycontent,
'navigation' => $this->structureDraft,
'homepage' => $this->homepage,
'title' => $title,
'content' => $content,
'item' => $this->item,
'settings' => $this->settings
));
}
}
}

View File

@@ -11,7 +11,6 @@ use Typemill\Models\Meta;
use Typemill\Events\OnPagetreeLoaded;
use Typemill\Events\OnBreadcrumbLoaded;
use Typemill\Events\OnItemLoaded;
use Typemill\Events\OnOriginalLoaded;
use Typemill\Events\OnMetaLoaded;
use Typemill\Events\OnMarkdownLoaded;
use Typemill\Events\OnContentArrayLoaded;

View File

@@ -368,6 +368,14 @@ class ControllerWebSystem extends Controller
$dispatcher = $this->c->get('dispatcher')
);
$pluginDefinitions = false;
$pluginname = strtolower(trim(str_replace('tm/', '', $urlinfo['route']), '/'));
if($pluginname && $pluginname != '' && isset($this->settings['plugins'][$pluginname]))
{
$extension = new Extension();
$pluginDefinitions = $extension->getPluginDefinition($pluginname);
}
return $this->c->get('view')->render($response, 'layouts/layoutSystemBlank.twig', [
'settings' => $this->settings,
'mainnavi' => $mainNavigation,
@@ -377,6 +385,8 @@ class ControllerWebSystem extends Controller
'labels' => $this->c->get('translations'),
'urlinfo' => $this->c->get('urlinfo'),
'acl' => $this->c->get('acl'),
'userroles' => $this->c->get('acl')->getRoles(),
'plugin' => $pluginDefinitions
]
]);
}

View File

@@ -0,0 +1,14 @@
<?php
namespace Typemill\Events;
use Symfony\Component\EventDispatcher\Event;
/**
* Event for breadcrumb.
*/
class OnPageRenamed extends BaseEvent
{
}

View File

@@ -4,9 +4,6 @@ namespace Typemill\Models;
use Typemill\Models\StorageWrapper;
############## REFACTOR, it is similar or part of navigation
class Sitemap
{
private $storage;
@@ -16,53 +13,15 @@ class Sitemap
$this->storage = new StorageWrapper('\Typemill\Models\Storage');
}
# 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($ping = false)
public function updateSitemap($navigation, $urlinfo)
{
$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 = $this->addUrlSet($sitemap, $urlinfo['baseurl']);
$sitemap .= $this->generateUrlSets($navigation);
$sitemap .= '</urlset>';
$this->writeCache->writeFile('cache', 'sitemap.xml', $sitemap);
if($ping && isset($this->settings['pingsitemap']) && $this->settings['pingsitemap'])
{
$sitemapUrl = $this->uri->getBaseUrl() . '/cache/sitemap.xml';
$pingGoogleUrl = 'http://www.google.com/ping?sitemap=' . urlencode($sitemapUrl);
$pingBingUrl = 'http://www.bing.com/ping?sitemap=' . urlencode($sitemapUrl);
$opts = array(
'http'=>array(
'method'=>"GET",
'ignore_errors' => true,
'timeout' => 5
)
);
$context = stream_context_create($opts);
$responseBing = file_get_contents($pingBingUrl, false, $context);
$responseGoogle = file_get_contents($pingGoogleUrl, false, $context);
}
$this->storage->writeFile('cacheFolder', '', 'sitemap.xml', $sitemap);
}
public function generateUrlSets($navigation)
@@ -71,22 +30,25 @@ class Sitemap
foreach($navigation as $item)
{
if($item->elementType == 'folder' && isset($item->noindex) && $item->noindex === true)
if($item->status == "published" OR $item->status == "modified")
{
$urlset .= $this->generateUrlSets($item->folderContent, $urlset);
}
elseif($item->elementType == 'folder')
{
$urlset = $this->addUrlSet($urlset, $item->urlAbs);
$urlset .= $this->generateUrlSets($item->folderContent, $urlset);
}
elseif(isset($item->noindex) && $item->noindex === true )
{
continue;
}
else
{
$urlset = $this->addUrlSet($urlset, $item->urlAbs);
if($item->elementType == 'folder' && isset($item->noindex) && $item->noindex === true)
{
$urlset .= $this->generateUrlSets($item->folderContent, $urlset);
}
elseif($item->elementType == 'folder')
{
$urlset = $this->addUrlSet($urlset, $item->urlAbs);
$urlset .= $this->generateUrlSets($item->folderContent, $urlset);
}
elseif(isset($item->noindex) && $item->noindex === true )
{
continue;
}
else
{
$urlset = $this->addUrlSet($urlset, $item->urlAbs);
}
}
}
return $urlset;

View File

@@ -2,11 +2,16 @@
namespace Typemill\Models;
use Typemill\Models\User;
use Valitron\Validator;
use Typemill\Models\User;
use Typemill\Models\StorageWrapper;
class Validation
{
# only used for recursive validation
public $errors = [];
/**
* Constructor with custom validation rules
*
@@ -186,6 +191,33 @@ class Validation
return true;
}, 'format is not valid.');
Validator::addRule('version', function($field, $value, array $params, array $fields)
{
if( version_compare( $value, '0.0.1', '>=' ) >= 0 )
{
return true;
}
return false;
}, 'not a valid version format.');
Validator::addRule('version_array', function($field, $value, array $params, array $fields)
{
foreach($value as $name => $version)
{
if(!preg_match("/^[A-Za-z0-9_\- ]+$/", $name))
{
return false;
}
if( version_compare( $version, '0.0.1', '>=' ) <= 0 )
{
return false;
}
}
return true;
}, 'not a valid version format.');
}
# return valitron standard object
@@ -315,6 +347,34 @@ class Validation
return $v->errors();
}
public function checkVersions(array $params)
{
$v = new Validator($params);
$v->rule('required', ['type', 'data']);
$v->rule('in', 'type', ['plugins', 'themes', 'system']);
if(!$v->validate())
{
return $v->errors();
}
if($params['type'] == 'plugins' OR $params['type'] == 'themes')
{
$v->rule('version_array', 'data');
}
else
{
$v->rule('version', 'data');
}
if(!$v->validate())
{
return $v->errors();
}
return true;
}
public function navigationSort(array $params)
{
$v = new Validator($params);
@@ -498,60 +558,6 @@ class Validation
}
}
public function usernameBREAK($username)
{
$v = new Validator($username);
$v->rule('alphaNum', 'username')->message("Only alpha-numeric characters allowed");
$v->rule('lengthBetween', 'username', 3, 20)->message("Length between 3 - 20");
return $this->validationResult($v);
}
/**
* validation for changing the password
*
* @param array $params with form data.
* @return obj $v the validation object passed to a result method.
*/
public function newPasswordOldBREAK(array $params)
{
$v = new Validator($params);
$v->rule('required', ['password', 'newpassword']);
$v->rule('lengthBetween', 'newpassword', 5, 20);
$v->rule('checkPassword', 'password')->message("Password is wrong");
return $this->validationResult($v);
}
/**
* validation for changing the password api case
*
* @param array $params with form data.
* @return obj $v the validation object passed to a result method.
*/
public function newPasswordBREAK(array $params)
{
$v = new Validator($params);
$v->rule('required', ['password', 'newpassword']);
$v->rule('lengthBetween', 'newpassword', 5, 20);
$v->rule('checkPassword', 'password')->message("Password is wrong");
if($v->validate())
{
return true;
}
return $v->errors();
}
/**
* validation for password recovery
*
@@ -569,41 +575,6 @@ class Validation
return $this->validationResult($v);
}
/**
* validation for system settings
*
* @param array $params with form data.
* @return obj $v the validation object passed to a result method.
*/
public function settingsBREAK(array $params, array $copyright, array $formats, $name = false)
{
$v = new Validator($params);
$v->rule('required', ['title', 'author', 'copyright', 'year', 'editor']);
$v->rule('lengthBetween', 'title', 2, 50);
$v->rule('lengthBetween', 'author', 2, 50);
$v->rule('noHTML', 'title');
# $v->rule('regex', 'title', '/^[\pL0-9_ \-]*$/u');
$v->rule('regex', 'author', '/^[\pL_ \-]*$/u');
$v->rule('integer', 'year');
$v->rule('length', 'year', 4);
$v->rule('length', 'langattr', 2);
$v->rule('in', 'editor', ['raw', 'visual']);
$v->rule('values_allowed', 'formats', $formats);
$v->rule('in', 'copyright', $copyright);
$v->rule('noHTML', 'restrictionnotice');
$v->rule('lengthBetween', 'restrictionnotice', 2, 1000 );
$v->rule('email', 'recoverfrom');
$v->rule('noHTML', 'recoversubject');
$v->rule('lengthBetween', 'recoversubject', 2, 80 );
$v->rule('noHTML', 'recovermessage');
$v->rule('lengthBetween', 'recovermessage', 2, 1000 );
$v->rule('iplist', 'trustedproxies');
return $this->validationResult($v, $name);
}
/**
* validation for content editor
@@ -762,6 +733,78 @@ class Validation
return true;
}
# validate a whole formdefinition with all values
public function recursiveValidation(array $formdefinitions, $input, $output = [])
{
# loop through form-definitions, ignores everything that is not defined in yaml
foreach($formdefinitions as $fieldname => $fielddefinitions)
{
if(is_array($fielddefinitions) && $fielddefinitions['type'] == 'fieldset')
{
$output = $this->recursiveValidation($fielddefinitions['fields'], $input, $output);
}
# do not store values for disabled fields
if(isset($fielddefinitions['disabled']) && $fielddefinitions['type'])
{
continue;
}
if(isset($input[$fieldname]))
{
$fieldvalue = $input[$fieldname];
# fix false or null values for selectboxes
if($fielddefinitions['type'] == "select" && ($fieldvalue === 'NULL' OR $fieldvalue === false))
{
$fieldvalue = NULL;
}
$validationresult = $this->field($fieldname, $fieldvalue, $fielddefinitions);
if($validationresult === true)
{
# MOVE THIS TO A SEPARATE FUNCTION SO YOU CAN STORE IMAGES ONLY IF ALL FIELDS SUCCESSFULLY VALIDATED
# images have special treatment, check ProcessImage-Model and ImageApiController
if($fielddefinitions['type'] == 'image')
{
# then check if file is there already: check for name and maybe correct image extension (if quality has been changed)
$storage = new StorageWrapper('\Typemill\Models\Storage');
$existingImagePath = $storage->checkImage($fieldvalue);
if($existingImagePath)
{
$fieldvalue = $existingImagePath;
}
else
{
# there is no published image with that name, so check if there is an unpublished image in tmp folder and publish it
$newImagePath = $storage->publishImage($fieldvalue);
if($newImagePath)
{
$fieldvalue = $newImagePath;
}
else
{
$fieldvalue = '';
}
}
}
$output[$fieldname] = $fieldvalue;
}
else
{
$this->errors[$fieldname] = $validationresult[$fieldname][0];
}
}
}
return $output;
}
/**
* result for validation
*
@@ -771,6 +814,8 @@ class Validation
public function checkArray($arrayvalues, $v)
{
die('I think checkArray not in use anymore');
foreach($arrayvalues as $key => $value)
{
if(is_array($value))
@@ -785,6 +830,8 @@ class Validation
public function validationResult($v, $name = false)
{
die("do not use validationResults in validation model anymore");
if($v->validate())
{
return true;

View File

@@ -3,8 +3,10 @@
namespace Typemill;
use \Symfony\Component\EventDispatcher\EventSubscriberInterface;
use DI\Container;
# use Typemill\Models\Fields;
# use Typemill\Models\WriteYaml;
use Typemill\Models\StorageWrapper;
use Typemill\Models\Extension;
use Typemill\Models\Validation;
use Typemill\Extensions\ParsedownExtension;
@@ -18,9 +20,13 @@ abstract class Plugin implements EventSubscriberInterface
protected $editorroute = false;
public function __construct($container)
public function __construct(Container $container)
{
/*
echo '<pre>';
echo '<h1>FIRST</h1>';
print_r($container);
*/
$this->container = $container;
$this->urlinfo = $this->container->get('urlinfo');
$this->route = $this->urlinfo['route'];
@@ -42,9 +48,110 @@ abstract class Plugin implements EventSubscriberInterface
return $this->container->get('settings');
}
protected function getPluginSettings($plugin)
protected function getPluginSettings($pluginname = false)
{
return $this->container->get('settings')['plugins'][$plugin];
# $pluginClass = debug_backtrace(!DEBUG_BACKTRACE_PROVIDE_OBJECT|DEBUG_BACKTRACE_IGNORE_ARGS,2)[1]['class'];
$pluginname = $this->getPluginName($pluginname);
if($pluginname && isset($this->container->get('settings')['plugins'][$pluginname]))
{
return $this->container->get('settings')['plugins'][$pluginname];
}
return false;
}
protected function getPluginData($filename, $pluginname = false)
{
$pluginname = $this->getPluginName($pluginname);
$storageClass = $this->container->get('settings')['storage'];
$storage = new StorageWrapper($storageClass);
$data = $storage->getFile('dataFolder', $pluginname, $filename);
return $data;
}
protected function getPluginYamlData($filename, $pluginname = false)
{
$pluginname = $this->getPluginName($pluginname);
$storageClass = $this->container->get('settings')['storage'];
$storage = new StorageWrapper($storageClass);
$data = $storage->getYaml('dataFolder', $pluginname, $filename);
return $data;
}
protected function storePluginData($filename, $pluginname = false)
{
$pluginname = $this->getPluginName($pluginname);
$storageClass = $this->container->get('settings')['storage'];
$storage = new StorageWrapper($storageClass);
$result = $storage->writeFile('dataFolder', $pluginname, $filename);
if($result)
{
return true;
}
return $storage->getError();
}
protected function storePluginYamlData(string $filename, array $data, $pluginname = false)
{
$pluginname = $this->getPluginName($pluginname);
# validation
$extension = new Extension();
$pluginDefinitions = $extension->getPluginDefinition($pluginname);
$formDefinitions = $pluginDefinitions['system']['fields'] ?? false;
if($formDefinitions)
{
# where can we add this method so we can use it everywhere?
# $formdefinitions = $this->addDatasets($formdefinitions);
$validate = new Validation();
$validatedOutput = $validate->recursiveValidation($formDefinitions, $data);
if(!empty($validate->errors))
{
return $validate->errors;
}
}
$storageClass = $this->container->get('settings')['storage'];
$storage = new StorageWrapper($storageClass);
$result = $storage->updateYaml('dataFolder', $pluginname, $filename, $data);
if($result)
{
return true;
}
return $storage->getError();
}
private function getPluginName($pluginname)
{
if(!$pluginname)
{
$classname = get_called_class();
if ($pos = strrpos($classname, '\\'))
{
$pluginname = strtolower(substr($classname, $pos + 1));
}
}
return $pluginname;
}
protected function urlinfo()
@@ -84,11 +191,23 @@ abstract class Plugin implements EventSubscriberInterface
$this->container->get('assets')->addJS($JS);
}
/*
protected function addEditorJS($JS)
{
$this->container->get('assets')->addEditorJS($JS);
}
protected function addEditorInlineJS($JS)
{
$this->container->get('assets')->addEditorInlineJS($JS);
}
protected function addEditorCSS($CSS)
{
$this->container->get('assets')->addEditorCSS($CSS);
}
*/
protected function addInlineJS($JS)
{
$this->container->get('assets')->addInlineJS($JS);
@@ -98,11 +217,6 @@ abstract class Plugin implements EventSubscriberInterface
{
$this->container->get('assets')->addSvgSymbol($symbol);
}
protected function addEditorInlineJS($JS)
{
$this->container->get('assets')->addEditorInlineJS($JS);
}
protected function addCSS($CSS)
{
@@ -114,11 +228,6 @@ abstract class Plugin implements EventSubscriberInterface
$this->container->get('assets')->addInlineCSS($CSS);
}
protected function addEditorCSS($CSS)
{
$this->container->get('assets')->addEditorCSS($CSS);
}
protected function getMeta()
{
return $this->container->get('assets')->meta;

View File

@@ -54,7 +54,7 @@ class Plugins
$pluginRoute['route'] = strtolower($pluginRoute['route']);
$routes[$routeType][] = $pluginRoute;
}
}
}
}
return $routes;

View File

@@ -3,6 +3,7 @@ const app = Vue.createApp({
<div class="w-full">
<ul>
<li v-for="(plugin,pluginname) in formDefinitions" class="w-full my-4 bg-stone-100">
<p v-if="versions[pluginname] !== undefined"><a href="https://plugins.typemill.net" class="block p-2 text-center bg-rose-500 text-white">Please update to version {{ versions[pluginname].version }}</a></p>
<div class="flex justify-between w-full px-8 py-3 border-b border-white" :class="getActiveClass(pluginname)">
<p class="py-2">License: {{ plugin.license }}</p>
<div class="flex">
@@ -90,12 +91,43 @@ const app = Vue.createApp({
userroles: false,
showModal: false,
modalMessage: 'default',
versions: false,
}
},
mounted() {
eventBus.$on('forminput', formdata => {
this.formData[this.current][formdata.name] = formdata.value;
});
var self = this;
var plugins = {};
for (var key in this.formDefinitions)
{
if (this.formDefinitions.hasOwnProperty(key))
{
plugins[key] = this.formDefinitions[key].version;
}
}
tmaxios.post('/api/v1/versioncheck',{
'url': data.urlinfo.route,
'type': 'plugins',
'data': plugins
})
.then(function (response)
{
if(response.data.plugins)
{
self.versions = response.data.plugins;
}
})
.catch(function (error)
{
self.messageClass = 'bg-rose-500';
self.message = error.response.data.message;
});
},
methods: {
getActiveClass: function(pluginname)

View File

@@ -49,4 +49,5 @@ const translatefilter = {
return data.labels[translation_key]
}
}
}
}

View File

@@ -1,6 +1,7 @@
const app = Vue.createApp({
template: `<Transition name="initial" appear>
<form class="inline-block w-full">
<p v-if="version.system !== undefined"><a href="https://typemill.net" class="block p-2 text-center bg-rose-500 text-white">Please update typemill to version {{ version.system }}</a></p>
<ul class="flex mt-4 mb-4">
<li v-for="tab in tabs" class="">
<button class="px-2 py-2 border-b-2 border-stone-200 hover:border-stone-700 transition duration-100" :class="(tab == currentTab) ? 'border-stone-700' : ''" @click.prevent="activateTab(tab)">{{ $filters.translate(tab) }}</button>
@@ -34,10 +35,15 @@ const app = Vue.createApp({
message: '',
messageClass: '',
errors: {},
version: false,
}
},
mounted() {
eventBus.$on('forminput', formdata => {
this.formData[formdata.name] = formdata.value;
});
for (var key in this.formDefinitions)
{
if (this.formDefinitions.hasOwnProperty(key))
@@ -47,10 +53,26 @@ const app = Vue.createApp({
}
}
eventBus.$on('forminput', formdata => {
this.formData[formdata.name] = formdata.value;
});
var self = this;
tmaxios.post('/api/v1/versioncheck',{
'url': data.urlinfo.route,
'type': 'system',
'data': this.formData.version
})
.then(function (response)
{
if(response.data.system)
{
self.version = response.data.system;
console.info(self.version);
}
})
.catch(function (error)
{
self.messageClass = 'bg-rose-500';
self.message = error.response.data.message;
});
},
methods: {
selectComponent: function(type)

View File

@@ -3,6 +3,7 @@ const app = Vue.createApp({
<div class="w-full">
<ul>
<li v-for="(theme,themename) in formDefinitions" class="w-full my-4 bg-stone-100">
<p v-if="versions[themename] !== undefined"><a href="https://themes.typemill.net" class="block p-2 text-center bg-rose-500 text-white">Please update to version {{ versions[themename].version }}</a></p>
<div class="flex justify-between w-full px-8 py-3 border-b border-white" :class="getActiveClass(themename)">
<p class="py-2">License: {{ theme.license }}</p>
<div class="flex">
@@ -93,6 +94,7 @@ const app = Vue.createApp({
message: '',
messageClass: '',
errors: {},
versions: false,
userroles: false,
showModal: false,
modalMessage: 'default',
@@ -104,6 +106,35 @@ const app = Vue.createApp({
});
this.deactivateThemes();
this.formData[this.theme].active = true;
var self = this;
var themes = {};
for (var key in this.formDefinitions)
{
if (this.formDefinitions.hasOwnProperty(key))
{
themes[key] = this.formDefinitions[key].version;
}
}
tmaxios.post('/api/v1/versioncheck',{
'url': data.urlinfo.route,
'type': 'themes',
'data': themes
})
.then(function (response)
{
if(response.data.themes)
{
self.versions = response.data.themes;
}
})
.catch(function (error)
{
self.messageClass = 'bg-rose-500';
self.message = error.response.data.message;
});
},
methods: {
deactivateThemes: function()

View File

@@ -39,8 +39,6 @@
</aside>
<article class="w-3/4 bg-stone-50 shadow-md p-8">
<h1 class="text-3xl font-bold mb-4">{{ translate('System') }} </h1>
<div id="system" v-cloak></div>
@@ -64,12 +62,13 @@
<script src="{{ base_url() }}/system/typemill/author/js/vue-eventbus.js?v={{ settings.version }}"></script>
<script src="{{ base_url() }}/system/typemill/author/js/vue-shared.js?v={{ settings.version }}"></script>
<script src="{{ base_url() }}/system/typemill/author/js/vue-medialib.js?v={{ settings.version }}"></script>
<script src="{{ base_url() }}/system/typemill/author/js/vue-forms.js?v={{ settings.version }}"></script>
{% block javascript %}{% endblock %}
{{ assets.renderJS() }}
<script src="{{ base_url() }}/system/typemill/author/js/vue-forms.js?v={{ settings.version }}"></script>
<script>
app.config.globalProperties.$filters = translatefilter;
app.mount('#system');

View File

@@ -11,6 +11,7 @@ use Typemill\Controllers\ControllerApiSystemPlugins;
use Typemill\Controllers\ControllerApiSystemExtensions;
use Typemill\Controllers\ControllerApiSystemLicense;
use Typemill\Controllers\ControllerApiSystemUsers;
use Typemill\Controllers\ControllerApiSystemVersions;
use Typemill\Controllers\ControllerApiImage;
use Typemill\Controllers\ControllerApiFile;
use Typemill\Controllers\ControllerApiAuthorArticle;
@@ -31,6 +32,7 @@ $app->group('/api/v1', function (RouteCollectorProxy $group) use ($acl) {
$group->post('/theme', ControllerApiSystemThemes::class . ':updateTheme')->setName('api.theme.set')->add(new ApiAuthorization($acl, 'system', 'update')); # admin
$group->post('/plugin', ControllerApiSystemPlugins::class . ':updatePlugin')->setName('api.plugin.set')->add(new ApiAuthorization($acl, 'system', 'update')); # admin
$group->post('/extensions', ControllerApiSystemExtensions::class . ':activateExtension')->setName('api.extension.activate')->add(new ApiAuthorization($acl, 'system', 'update')); # admin
$group->post('/versioncheck', ControllerApiSystemVersions::class . ':checkVersions')->setName('api.versioncheck')->add(new ApiAuthorization($acl, 'system', 'update')); # admin
$group->get('/users/getbynames', ControllerApiSystemUsers::class . ':getUsersByNames')->setName('api.usersbynames')->add(new ApiAuthorization($acl, 'user', 'update')); # admin
$group->get('/users/getbyemail', ControllerApiSystemUsers::class . ':getUsersByEmail')->setName('api.usersbyemail')->add(new ApiAuthorization($acl, 'user', 'update')); # admin
$group->get('/users/getbyrole', ControllerApiSystemUsers::class . ':getUsersByRole')->setName('api.usersbyrole')->add(new ApiAuthorization($acl, 'user', 'update')); # admin
@@ -85,23 +87,26 @@ $app->group('/api/v1', function (RouteCollectorProxy $group) use ($acl) {
})->add(new ApiAuthentication());
# api-routes from plugins
foreach($routes['api'] as $pluginRoute)
{
$method = $pluginRoute['httpMethod'] ?? false;
$route = $pluginRoute['route'] ?? false;
$class = $pluginRoute['class'] ?? false;
$name = $pluginRoute['name'] ?? false;
$resource = $pluginRoute['resource'] ?? false;
$privilege = $pluginRoute['privilege'] ?? false;
if(isset($routes['api']) && !empty($routes['api']))
{
foreach($routes['api'] as $pluginRoute)
{
$method = $pluginRoute['httpMethod'] ?? false;
$route = $pluginRoute['route'] ?? false;
$class = $pluginRoute['class'] ?? false;
$name = $pluginRoute['name'] ?? false;
$resource = $pluginRoute['resource'] ?? false;
$privilege = $pluginRoute['privilege'] ?? false;
if($resources && $privilege)
{
# protected api requires authentication and authorization
$app->{$method}($route, $class)->setName($name)->add(new ApiAuthorization($acl, $resource, $privilege))->add(new ApiAuthentication());
if($resources && $privilege)
{
# protected api requires authentication and authorization
$app->{$method}($route, $class)->setName($name)->add(new ApiAuthorization($acl, $resource, $privilege))->add(new ApiAuthentication());
}
else
{
# public api routes
$app->{$method}($route, $class)->setName($name);
}
}
else
{
# public api routes
$app->{$method}($route, $class)->setName($name);
}
}
}

View File

@@ -55,22 +55,25 @@ $app->redirect('/tm/', $routeParser->urlFor('auth.show'), 302);
$app->get('/media/files[/{params:.*}]', ControllerWebDownload::class . ':download')->setName('download.file');
# web-routes from plugins
foreach($routes['web'] as $pluginRoute)
{
$method = $pluginRoute['httpMethod'] ?? false;
$route = $pluginRoute['route'] ?? false;
$class = $pluginRoute['class'] ?? false;
$name = $pluginRoute['name'] ?? false;
$resource = $pluginRoute['resource'] ?? false;
$privilege = $pluginRoute['privilege'] ?? false;
if(isset($routes['web']) && !empty($routes['web']))
{
foreach($routes['web'] as $pluginRoute)
{
$method = $pluginRoute['httpMethod'] ?? false;
$route = $pluginRoute['route'] ?? false;
$class = $pluginRoute['class'] ?? false;
$name = $pluginRoute['name'] ?? false;
$resource = $pluginRoute['resource'] ?? false;
$privilege = $pluginRoute['privilege'] ?? false;
if($resources && $privilege)
{
$app->{$method}($route, $class)->setName($name)->add(new WebAuthorization($routeParser, $acl, $resource, $privilege))->add(new WebRedirectIfUnauthenticated($routeParser));
}
else
{
$app->{$method}($route, $class)->setName($name);
if($resources && $privilege)
{
$app->{$method}($route, $class)->setName($name)->add(new WebAuthorization($routeParser, $acl, $resource, $privilege))->add(new WebRedirectIfUnauthenticated($routeParser));
}
else
{
$app->{$method}($route, $class)->setName($name);
}
}
}

View File

@@ -8,6 +8,7 @@ use Slim\Views\TwigMiddleware;
use Slim\Psr7\Factory\UriFactory;
use Twig\Extension\DebugExtension;
use Symfony\Component\EventDispatcher\EventDispatcher;
use RKA\Middleware\ProxyDetection;
use Typemill\Assets;
use Typemill\Models\Settings;
use Typemill\Models\License;
@@ -358,8 +359,16 @@ $app->add($errorMiddleware);
$app->add(new SessionMiddleware($session_segments, $urlinfo['route']));
if(isset($settings['proxy']) && $settings['proxy'])
{
$trustedProxies = ( isset($settings['trustedproxies']) && !empty($settings['trustedproxies']) ) ? explode(",", $settings['trustedproxies']) : [];
$app->add(new ProxyDetection($trustedProxies));
}
$timer['middleware'] = microtime(true);
/************************
* ADD ROUTES *
************************/