mirror of
https://github.com/typemill/typemill.git
synced 2025-07-25 00:02:28 +02:00
Version 1.3.8: User Rights
This commit is contained in:
@@ -10,6 +10,7 @@ RewriteEngine On
|
||||
# Protect your system files from prying eyes
|
||||
RewriteRule ^(system\/author\/) - [L]
|
||||
RewriteRule ^(system) - [F,L]
|
||||
RewriteRule ^(data) - [F,L]
|
||||
RewriteRule ^(content) - [F,L]
|
||||
RewriteRule ^(settings) - [F,L]
|
||||
RewriteRule ^(.*)?\.yml$ - [F,L]
|
||||
|
1
cache/index.json
vendored
Normal file
1
cache/index.json
vendored
Normal file
File diff suppressed because one or more lines are too long
@@ -14,6 +14,27 @@ use Typemill\Events\OnSystemnaviLoaded;
|
||||
|
||||
class SettingsController extends Controller
|
||||
{
|
||||
|
||||
public function showBlank($request, $response, $args)
|
||||
{
|
||||
$user = new User();
|
||||
$settings = $this->c->get('settings');
|
||||
# $users = $user->getUsers();
|
||||
$route = $request->getAttribute('route');
|
||||
$navigation = $this->getNavigation();
|
||||
|
||||
$content = '<h1>Hello</h1>';
|
||||
|
||||
return $this->render($response, 'settings/blank.twig', array(
|
||||
'settings' => $settings,
|
||||
'acl' => $this->c->acl,
|
||||
'navigation' => $navigation,
|
||||
'content' => $content,
|
||||
# 'users' => $users,
|
||||
'route' => $route->getName()
|
||||
));
|
||||
}
|
||||
|
||||
/*********************
|
||||
** BASIC SETTINGS **
|
||||
*********************/
|
||||
@@ -26,13 +47,15 @@ class SettingsController extends Controller
|
||||
$copyright = $this->getCopyright();
|
||||
$languages = $this->getLanguages();
|
||||
$locale = isset($_SERVER['HTTP_ACCEPT_LANGUAGE']) ? substr($_SERVER["HTTP_ACCEPT_LANGUAGE"],0,2) : 'en';
|
||||
$users = $user->getUsers();
|
||||
$route = $request->getAttribute('route');
|
||||
$navigation = $this->getNavigation();
|
||||
|
||||
# set navigation active
|
||||
$navigation['System']['active'] = true;
|
||||
|
||||
# set option for registered website
|
||||
$options = ['' => 'all', 'registered' => 'registered users only'];
|
||||
|
||||
return $this->render($response, 'settings/system.twig', array(
|
||||
'settings' => $settings,
|
||||
'acl' => $this->c->acl,
|
||||
@@ -41,7 +64,7 @@ class SettingsController extends Controller
|
||||
'languages' => $languages,
|
||||
'locale' => $locale,
|
||||
'formats' => $defaultSettings['formats'],
|
||||
'users' => $users,
|
||||
'access' => $options,
|
||||
'route' => $route->getName()
|
||||
));
|
||||
}
|
||||
@@ -68,7 +91,8 @@ class SettingsController extends Controller
|
||||
'year' => $newSettings['year'],
|
||||
'language' => $newSettings['language'],
|
||||
'langattr' => $newSettings['langattr'],
|
||||
'editor' => $newSettings['editor'],
|
||||
'editor' => $newSettings['editor'],
|
||||
'access' => $newSettings['access'],
|
||||
'formats' => $newSettings['formats'],
|
||||
'headlineanchors' => isset($newSettings['headlineanchors']) ? $newSettings['headlineanchors'] : null,
|
||||
);
|
||||
|
@@ -20,6 +20,12 @@ class accessController
|
||||
|
||||
public function __invoke(Request $request, Response $response, $next)
|
||||
{
|
||||
|
||||
if($this->resource == NULL && $this->privilege == NULL)
|
||||
{
|
||||
return $next($request, $response);
|
||||
}
|
||||
|
||||
if(!isset($_SESSION['login']))
|
||||
{
|
||||
return $response->withRedirect($this->router->pathFor('auth.show'));
|
||||
|
@@ -79,6 +79,10 @@ if($settings['settings']['setup'])
|
||||
{
|
||||
$app->get('/[{params:.*}]', SetupController::class . ':redirect');
|
||||
}
|
||||
elseif(isset($settings['settings']['access']) && $settings['settings']['access'] != '')
|
||||
{
|
||||
$app->get('/[{params:.*}]', PageController::class . ':index')->setName('home')->add(new accessController($container['router'], $container['acl'], 'user', 'view'));
|
||||
}
|
||||
else
|
||||
{
|
||||
$app->get('/[{params:.*}]', PageController::class . ':index')->setName('home');
|
||||
|
@@ -111,7 +111,7 @@ class Settings
|
||||
}
|
||||
|
||||
# Detect browser language
|
||||
$accept_lang = substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2);
|
||||
$accept_lang = isset($_SERVER['HTTP_ACCEPT_LANGUAGE']) ? substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2) : false;
|
||||
$lang = in_array($accept_lang, $langs) ? $accept_lang : 'en';
|
||||
|
||||
return $lang;
|
||||
@@ -158,6 +158,7 @@ class Settings
|
||||
'startpage' => true,
|
||||
'author' => true,
|
||||
'year' => true,
|
||||
'access' => true,
|
||||
'headlineanchors' => true,
|
||||
'theme' => true,
|
||||
'editor' => true,
|
||||
@@ -169,7 +170,7 @@ class Settings
|
||||
'themes' => true,
|
||||
'latestVersion' => true,
|
||||
'logo' => true,
|
||||
'favicon' => true,
|
||||
'favicon' => true
|
||||
];
|
||||
|
||||
# cleanup the existing usersettings
|
||||
|
@@ -165,7 +165,11 @@ const contentComponent = Vue.component('content-block', {
|
||||
},
|
||||
submitBlock: function(){
|
||||
var emptyline = /^\s*$(?:\r\n?|\n)/gm;
|
||||
|
||||
/* allow empty lines for these components */
|
||||
if(this.componentType == "code-component" || this.componentType == "math-component" || this.componentType == "notice-component"){ }
|
||||
|
||||
/* add new line with markup for these components */
|
||||
else if(this.componentType == "ulist-component" || this.componentType == "olist-component")
|
||||
{
|
||||
var listend = (this.componentType == "ulist-component") ? '* \n' : '1. \n';
|
||||
@@ -194,6 +198,7 @@ const contentComponent = Vue.component('content-block', {
|
||||
}
|
||||
}
|
||||
}
|
||||
/* save or close for all other components */
|
||||
else if(this.compmarkdown.search(emptyline) > -1)
|
||||
{
|
||||
var checkempty = this.compmarkdown.replace(/(\r\n|\n|\r|\s)/gm,"");
|
||||
@@ -1014,21 +1019,21 @@ const tableComponent = Vue.component('table-component', {
|
||||
'</colgroup>' +
|
||||
'<tbody>' +
|
||||
'<tr v-for="(row, rowindex) in table">' +
|
||||
'<td v-if="rowindex === 0" v-for="(value,colindex) in row" contenteditable="false" class="noteditable" @click="switchcolumnbar(value)">{{value}} ' +
|
||||
'<td v-if="rowindex === 0" v-for="(value,colindex) in row" contenteditable="false" class="noteditable" @click="switchcolumnbar(value)" @keydown.13.prevent="enter">{{value}} ' +
|
||||
'<div v-if="columnbar === value" class="columnaction">' +
|
||||
'<div class="actionline" @click="addrightcolumn(value)">{{ \'add right column\'|translate }}</div>' +
|
||||
'<div class="actionline" @click="addleftcolumn(value)">{{ \'add left column\'|translate }}</div>' +
|
||||
'<div class="actionline" @click="deletecolumn(value)">{{ \'delete column\'|translate }}</div>' +
|
||||
'</div>' +
|
||||
'</td>' +
|
||||
'<th v-if="rowindex === 1" v-for="(value,colindex) in row" :contenteditable="colindex !== 0 ? true : false" @click="switchrowbar(value)" @blur="updatedata($event,colindex,rowindex)" :class="colindex !== 0 ? editable : noteditable">' +
|
||||
'<th v-if="rowindex === 1" v-for="(value,colindex) in row" :contenteditable="colindex !== 0 ? true : false" @click="switchrowbar(value)" @keydown.13.prevent="enter" @blur="updatedata($event,colindex,rowindex)" :class="colindex !== 0 ? editable : noteditable">' +
|
||||
'<div v-if="colindex === 0 && rowbar === value" class="rowaction">' +
|
||||
'<div class="actionline" @click="addaboverow(value)">{{ \'add row above\'|translate }}</div>' +
|
||||
'<div class="actionline" @click="addbelowrow(value)">{{ \'add row below\'|translate }}</div>' +
|
||||
'<div class="actionline" @click="deleterow(value)">{{ \'delete row\'|translate }}</div>' +
|
||||
'</div>' +
|
||||
'{{ value }}</th>' +
|
||||
'<td v-if="rowindex > 1" v-for="(value,colindex) in row" :contenteditable="colindex !== 0 ? true : false" @click="switchrowbar(value)" @blur="updatedata($event,colindex,rowindex)" :class="colindex !== 0 ? editable : noteditable">' +
|
||||
'<td v-if="rowindex > 1" v-for="(value,colindex) in row" :contenteditable="colindex !== 0 ? true : false" @click="switchrowbar(value)" @keydown.13.prevent="enter" @blur="updatedata($event,colindex,rowindex)" :class="colindex !== 0 ? editable : noteditable">' +
|
||||
'<div v-if="colindex === 0 && rowbar === value" class="rowaction">' +
|
||||
'<div class="actionline" @click="addaboverow(value)">{{ \'add row above\'|translate }}</div>' +
|
||||
'<div class="actionline" @click="addbelowrow(value)">{{ \'add row below\'|translate }}</div>' +
|
||||
@@ -1073,6 +1078,10 @@ const tableComponent = Vue.component('table-component', {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
enter: function()
|
||||
{
|
||||
return false;
|
||||
},
|
||||
updatedata: function(event,col,row)
|
||||
{
|
||||
this.table[row][col] = event.target.innerText;
|
||||
@@ -1215,7 +1224,7 @@ const definitionComponent = Vue.component('definition-component', {
|
||||
'<svg class="icon icon-arrows-v"><use xlink:href="#icon-arrows-v"></use></svg>' +
|
||||
'<input type="text" class="definitionTerm" v-bind:placeholder="\'term\'|translate" :value="definition.term" :disabled="disabled" @input="updateterm($event,dindex)" @blur="updateMarkdown">' +
|
||||
'<svg class="icon icon-dots-two-vertical"><use xlink:href="#icon-dots-two-vertical"></use></svg>' +
|
||||
'<textarea class="definitionDescription" v-bind:placeholder="\'description\'|translate" v-html="definition.description" :disabled="disabled" @input="updatedescription($event, dindex)" @blur="updateMarkdown"></textarea>' +
|
||||
'<textarea class="definitionDescription" v-bind:placeholder="\'description\'|translate" v-html="definition.description" :disabled="disabled" @input="updatedescription($event, dindex)" @keydown.13.prevent="enter" @blur="updateMarkdown"></textarea>' +
|
||||
'<button class="delDL" @click.prevent="deleteDefinition(dindex)"><svg class="icon icon-minus"><use xlink:href="#icon-minus"></use></svg></button>' +
|
||||
'</div>' +
|
||||
'</draggable>' +
|
||||
@@ -1249,6 +1258,10 @@ const definitionComponent = Vue.component('definition-component', {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
enter: function()
|
||||
{
|
||||
return false;
|
||||
},
|
||||
updateterm: function(event, dindex)
|
||||
{
|
||||
this.definitionList[dindex].term = event.target.value;
|
||||
|
@@ -74,6 +74,12 @@
|
||||
<footer></footer>
|
||||
</div>
|
||||
<!-- <script src="{{ base_url }}/system/author/js/color-picker.min.js?20200505"></script> -->
|
||||
<script src="{{ base_url }}/system/author/js/axios.min.js?20200226"></script>
|
||||
<script>
|
||||
const myaxios = axios.create();
|
||||
myaxios.defaults.baseURL = "{{ base_url }}";
|
||||
</script>
|
||||
<script src="{{ base_url }}/system/author/js/vue.min.js?20200614"></script>
|
||||
<script src="{{ base_url }}/system/author/js/author.js?20200614"></script>
|
||||
<script src="{{ base_url }}/system/author/js/typemillutils.js?20200614"></script>
|
||||
<script>
|
||||
|
14
system/author/settings/blank.twig
Normal file
14
system/author/settings/blank.twig
Normal file
@@ -0,0 +1,14 @@
|
||||
{% extends 'layouts/layout.twig' %}
|
||||
{% block title %}Blank{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div class="formWrapper">
|
||||
|
||||
<section class="settings">
|
||||
{{ content }}
|
||||
</section>
|
||||
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
@@ -69,6 +69,16 @@
|
||||
</div><div class="medium">
|
||||
<label for="settings[sitemap]">{{ __('Google Sitemap') }} <small>({{ __('Readonly') }})</small></label>
|
||||
<input type="text" name="settings[sitemap]" id="sitemap" readonly value="{{ base_url }}/cache/sitemap.xml" />
|
||||
</div><div class="medium{{ errors.settings.access ? ' error' : '' }}">
|
||||
<label for="settings[access]">{{ __('Website visible for') }}</label>
|
||||
<select name="settings[access]" id="access">
|
||||
{% for key,option in access %}
|
||||
<option value="{{ key }}"{% if (key == old.settings.access or key == settings.access) %} selected{% endif %}>{{ __(option) }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
{% if errors.settings.access %}
|
||||
<span class="error">{{ errors.settings.access | first }}</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
<hr>
|
||||
<header class="headline">
|
||||
|
@@ -172,6 +172,13 @@ $path = $uri->getPath();
|
||||
$container['flash'] = false;
|
||||
$container['csrf'] = false;
|
||||
|
||||
# if website is restricted to registered user
|
||||
if(isset($settings['settings']['access']) && $settings['settings']['access'] == 'registered')
|
||||
{
|
||||
# activate session for all routes
|
||||
$session_segments = [$path];
|
||||
}
|
||||
|
||||
foreach($session_segments as $segment)
|
||||
{
|
||||
if(substr( $path, 0, strlen($segment) ) === $segment)
|
||||
|
@@ -398,6 +398,12 @@ button.play-video::after {
|
||||
right: 0;
|
||||
top: 0;
|
||||
}
|
||||
.contentnav.collapse .folder > ul{
|
||||
display: none;
|
||||
}
|
||||
.contentnav .folder.active > ul,.contentnav .folder.activeParent > ul{
|
||||
display: block;
|
||||
}
|
||||
.burgerbutton{
|
||||
display: inline-block;
|
||||
font-size: 2em;
|
||||
|
@@ -211,10 +211,14 @@ forms:
|
||||
type: fieldset
|
||||
legend: Navigations and Chapters
|
||||
fields:
|
||||
collapseNav:
|
||||
type: checkbox
|
||||
label: Collapse navigation
|
||||
checkboxlabel: Collapse and expand navigation?
|
||||
chapnum:
|
||||
type: checkbox
|
||||
label: Show Chapter Numbers
|
||||
checkboxlabel: Count chapters in navigation?
|
||||
label: Chapter Numbers
|
||||
checkboxlabel: Show chapter numbers in navigation?
|
||||
|
||||
fieldsetfooter:
|
||||
type: fieldset
|
||||
|
@@ -119,6 +119,30 @@
|
||||
|
||||
<script src="{{ base_url }}/system/author/js/typemillutils.js?20200418"></script>
|
||||
<script>typemillUtilities.start();</script>
|
||||
|
||||
{% if settings.themes.cyanine.collapseNav %}
|
||||
<script>
|
||||
var expandButton = document.getElementById("expander");
|
||||
if(expandButton)
|
||||
{
|
||||
expandButton.addEventListener('click', function(e)
|
||||
{
|
||||
var contentnav = document.getElementById("contentnav");
|
||||
|
||||
contentnav.classList.toggle("collapse");
|
||||
|
||||
if(contentnav.classList.contains("collapse"))
|
||||
{
|
||||
expandButton.innerHTML = "expand navigation";
|
||||
}
|
||||
else
|
||||
{
|
||||
expandButton.innerHTML = "collapse navigation";
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
{% endif %}
|
||||
|
||||
{{ assets.renderJS() }}
|
||||
|
||||
|
@@ -5,7 +5,7 @@
|
||||
<div class="w-100 mw8 center grid-container">
|
||||
|
||||
<aside class="grid-header ph3 pv3">
|
||||
|
||||
|
||||
<header>
|
||||
|
||||
<div class="logo">
|
||||
@@ -22,6 +22,14 @@
|
||||
|
||||
</header>
|
||||
|
||||
{% if widgets %}
|
||||
{% for index,widget in widgets %}
|
||||
<div id="{{ index }}" class="mt4-l mt3">
|
||||
{{ widget }}
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
</aside>
|
||||
|
||||
<div class="grid-main ph3 ph4-l pv3 lh-copy f4 fw3">
|
||||
@@ -105,9 +113,9 @@
|
||||
|
||||
</div>
|
||||
|
||||
<aside class="grid-sidebar ph3 pv4">
|
||||
<aside class="grid-sidebar ph3 pv3">
|
||||
|
||||
<nav class="contentnav" aria-label="Menu">
|
||||
<nav id="contentnav" class="contentnav{{ settings.themes.cyanine.collapseNav ? ' collapse' : '' }}" aria-label="Menu">
|
||||
|
||||
<!-- burger menu controlled by invisible checkbox -->
|
||||
<input type="checkbox" id="burger" class="dn">
|
||||
|
@@ -30,6 +30,10 @@
|
||||
|
||||
{% import _self as macros %}
|
||||
|
||||
{% if settings.themes.cyanine.collapseNav %}
|
||||
<button id="expander" class=" dn db-l link pointer w-100 bg-secondary ba b--tertiary pa2 mb1 f7">expand navigation</button>
|
||||
{% endif %}
|
||||
|
||||
<ul class="list pa0 menu {{ settings.themes.cyanine.fontnavi }}">
|
||||
{{ macros.loop_over(navigation, settings.themes.cyanine.chapnum ) }}
|
||||
</ul>
|
Reference in New Issue
Block a user