diff --git a/composer.lock b/composer.lock index 8ddfaa8..e829438 100644 --- a/composer.lock +++ b/composer.lock @@ -852,16 +852,16 @@ }, { "name": "symfony/polyfill-ctype", - "version": "v1.20.0", + "version": "v1.22.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "f4ba089a5b6366e453971d3aad5fe8e897b37f41" + "reference": "c6c942b1ac76c82448322025e084cadc56048b4e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/f4ba089a5b6366e453971d3aad5fe8e897b37f41", - "reference": "f4ba089a5b6366e453971d3aad5fe8e897b37f41", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/c6c942b1ac76c82448322025e084cadc56048b4e", + "reference": "c6c942b1ac76c82448322025e084cadc56048b4e", "shasum": "" }, "require": { @@ -873,7 +873,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.20-dev" + "dev-main": "1.22-dev" }, "thanks": { "name": "symfony/polyfill", @@ -924,7 +924,7 @@ "type": "tidelift" } ], - "time": "2020-10-23T14:02:19+00:00" + "time": "2021-01-07T16:49:33+00:00" }, { "name": "symfony/yaml", diff --git a/content/00-welcome/00-setup.md b/content/00-welcome/00-setup.md index afd7322..f89e142 100644 --- a/content/00-welcome/00-setup.md +++ b/content/00-welcome/00-setup.md @@ -4,6 +4,8 @@ Congratulations! If you see this page, then the setup of the system has worked s If you face any problems during the installation, then please make sure, that your system supports these features: +--- + - PHP version 7+. - Apache server. - The module `mod_rewrite` and `htaccess`. diff --git a/system/Controllers/ArticleApiController.php b/system/Controllers/ArticleApiController.php index c0deeca..2f1ea7f 100644 --- a/system/Controllers/ArticleApiController.php +++ b/system/Controllers/ArticleApiController.php @@ -973,19 +973,24 @@ class ArticleApiController extends ContentController # fix footnotes in parsedown, might break with complicated footnotes $parsedown->setVisualMode(); + # flag for TOC + $toc = false; + + $tocMarkup = false; + # 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); + + # build toc here to avoid duplicated toc for live content + $tocMarkup = $parsedown->buildTOC($parsedown->headlines); } # needed for ToC links $relurl = '/tm/content/' . $this->settings['editor'] . '/' . $this->item->urlRel; - # flag for TOC - $toc = false; - # loop through mardkown-array and create html-blocks foreach($content as $key => $block) { @@ -1003,7 +1008,11 @@ class ArticleApiController extends ContentController if($toc) { - $tocMarkup = $parsedown->buildTOC($parsedown->headlines); + if(!$tocMarkup) + { + $tocMarkup = $parsedown->buildTOC($parsedown->headlines); + } + $content[$toc] = ['id' => $toc, 'html' => $tocMarkup]; } diff --git a/system/Controllers/MetaApiController.php b/system/Controllers/MetaApiController.php index b8403b9..a523b45 100644 --- a/system/Controllers/MetaApiController.php +++ b/system/Controllers/MetaApiController.php @@ -129,6 +129,18 @@ class MetaApiController extends ContentController $metascheme[$tabname][$fieldname] = true; $metadata[$tabname][$fieldname] = isset($pagemeta[$tabname][$fieldname]) ? $pagemeta[$tabname][$fieldname] : null; + + # check if there is a selectfield for userroles + if(isset($fielddefinitions['type']) && ($fielddefinitions['type'] == 'select' ) && isset($fielddefinitions['dataset']) && ($fielddefinitions['dataset'] == 'userroles' ) ) + { + $userroles = [null => null]; + foreach($this->c->acl->getRoles() as $userrole) + { + $userroles[$userrole] = $userrole; + } + $metadefinitions[$tabname]['fields'][$fieldname]['options'] = $userroles; + } + /* # special treatment for customfields if(isset($fielddefinitions['type']) && ($fielddefinitions['type'] == 'customfields' ) && $metadata[$tabname][$fieldname] ) @@ -189,7 +201,7 @@ class MetaApiController extends ContentController } # if item is a folder - if($this->item->elementType == "folder") + if($this->item->elementType == "folder" && isset($this->item->contains)) { $pagemeta['meta']['contains'] = isset($pagemeta['meta']['contains']) ? $pagemeta['meta']['contains'] : $this->item->contains; @@ -217,6 +229,18 @@ class MetaApiController extends ContentController } else { + + if($fieldDefinition && isset($fieldDefinition['type']) && ($fieldDefinition['type'] == 'select' ) && isset($fieldDefinition['dataset']) && ($fieldDefinition['dataset'] == 'userroles' ) ) + { + $userroles = [null => null]; + foreach($this->c->acl->getRoles() as $userrole) + { + $userroles[$userrole] = $userrole; + } + $fieldDefinition['options'] = $userroles; + } + + # validate user input for this field $result = $validate->objectField($fieldName, $fieldValue, $objectName, $fieldDefinition); diff --git a/system/Controllers/PageController.php b/system/Controllers/PageController.php index c970a2a..42d5f64 100644 --- a/system/Controllers/PageController.php +++ b/system/Controllers/PageController.php @@ -241,7 +241,7 @@ class PageController extends Controller $shortenedPage = $this->cutRestrictedContent($markdownBlocks); # check if there is customized content - $restrictionnotice = ( isset($this->settings['restrictionnotice']) && $this->settings['restrictionnotice'] != '' ) ? $this->settings['restrictionnotice'] : 'You are not allowed to access this content.'; + $restrictionnotice = $this->prepareRestrictionNotice(); # add notice to shortened content $shortenedPage[] = $restrictionnotice; @@ -478,7 +478,8 @@ class PageController extends Controller # check if page is restricted to certain user if(isset($meta['alloweduser']) && $meta['alloweduser'] && $meta['alloweduser'] !== '' ) { - if(isset($_SESSION['user']) && $_SESSION['user'] == $meta['alloweduser']) + $alloweduser = array_map('trim', explode(",", $meta['alloweduser'])); + if(isset($_SESSION['user']) && in_array($_SESSION['user'], $alloweduser)) { # user has access to the page, so there are no restrictions return false; @@ -539,4 +540,37 @@ class PageController extends Controller return $restrictedMarkdown; } + + protected function prepareRestrictionNotice() + { + if( isset($this->settings['restrictionnotice']) && $this->settings['restrictionnotice'] != '' ) + { + $restrictionNotice = $this->settings['restrictionnotice']; + } + else + { + $restrictionNotice = 'You are not allowed to access this content.'; + } + + if( isset($this->settings['wraprestrictionnotice']) && $this->settings['wraprestrictionnotice'] ) + { + # standardize line breaks + $text = str_replace(array("\r\n", "\r"), "\n", $restrictionNotice); + + # remove surrounding line breaks + $text = trim($text, "\n"); + + # split text into lines + $lines = explode("\n", $text); + + $restrictionNotice = ''; + + foreach($lines as $key => $line) + { + $restrictionNotice .= "!!!! " . $line . "\n"; + } + } + + return $restrictionNotice; + } } \ No newline at end of file diff --git a/system/Controllers/SettingsController.php b/system/Controllers/SettingsController.php index 24cd5e7..ad57c29 100644 --- a/system/Controllers/SettingsController.php +++ b/system/Controllers/SettingsController.php @@ -95,6 +95,7 @@ class SettingsController extends Controller 'pageaccess' => isset($newSettings['pageaccess']) ? true : null, 'hrdelimiter' => isset($newSettings['hrdelimiter']) ? true : null, 'restrictionnotice' => $newSettings['restrictionnotice'], + 'wraprestrictionnotice' => isset($newSettings['wraprestrictionnotice']) ? true : null, 'headlineanchors' => isset($newSettings['headlineanchors']) ? $newSettings['headlineanchors'] : null, 'displayErrorDetails' => isset($newSettings['displayErrorDetails']) ? true : null, 'twigcache' => isset($newSettings['twigcache']) ? true : null, diff --git a/system/Settings.php b/system/Settings.php index bc1f7ff..728d568 100644 --- a/system/Settings.php +++ b/system/Settings.php @@ -82,7 +82,7 @@ class Settings 'editor' => 'visual', 'formats' => ['markdown', 'headline', 'ulist', 'olist', 'table', 'quote', 'notice', 'image', 'video', 'file', 'toc', 'hr', 'definition', 'code'], 'contentFolder' => 'content', - 'version' => '1.4.3', + 'version' => '1.4.4', 'setup' => true, 'welcome' => true, 'images' => ['live' => ['width' => 820], 'thumbs' => ['width' => 250, 'height' => 150]], @@ -162,6 +162,7 @@ class Settings 'pageaccess' => true, 'hrdelimiter' => true, 'restrictionnotice' => true, + 'wraprestrictionnotice' => true, 'headlineanchors' => true, 'theme' => true, 'editor' => true, @@ -236,10 +237,6 @@ class Settings $acl->addResource(new Resource($resource)); } - # add administrator role - $acl->addRole(new Role('administrator')); - $acl->allow('administrator'); - # add all other roles dynamically foreach($roles as $role) { @@ -251,6 +248,10 @@ class Settings } } + # add administrator role + $acl->addRole(new Role('administrator')); + $acl->allow('administrator'); + return $acl; } } \ No newline at end of file diff --git a/system/author/js/typemillutils.js b/system/author/js/typemillutils.js index f0891fc..60e3c2e 100644 --- a/system/author/js/typemillutils.js +++ b/system/author/js/typemillutils.js @@ -19,13 +19,13 @@ let typemillUtilities = { addYoutubePlayButton: function(element) { - element.parentNode.classList.add("video-container"); - + element.classList.add("video-container"); + var youtubePlaybutton = document.createElement("button"); youtubePlaybutton.classList.add("play-video"); youtubePlaybutton.value = "Play"; - element.parentNode.appendChild(youtubePlaybutton); + element.appendChild(youtubePlaybutton); }, listenToClick: function(){ @@ -34,7 +34,7 @@ let typemillUtilities = { /* listen to youtube */ if (event.target.matches('.play-video')) { - var youtubeID = event.target.parentNode.getElementsByClassName('youtube')[0].id; + var youtubeID = event.target.parentNode.id; event.preventDefault(); event.stopPropagation(); diff --git a/system/author/js/vue-blox.js b/system/author/js/vue-blox.js index f59fa27..9c7d4f6 100644 --- a/system/author/js/vue-blox.js +++ b/system/author/js/vue-blox.js @@ -1,5 +1,16 @@ const eventBus = new Vue(); +Vue.filter('translate', function (value) { + if (!value) return '' + transvalue = value.replace(/[ ]/g,"_").replace(/[.]/g, "_").replace(/[,]/g, "_").replace(/[-]/g, "_").replace(/[,]/g,"_").toUpperCase() + translated_string = labels[transvalue] + if(!translated_string || translated_string.length === 0){ + return value + } else { + return labels[transvalue] + } +}) + const contentComponent = Vue.component('content-block', { props: ['body', 'load'], template: '