From 07770cb6dd01b833be1fe9a791136f8fa21d02b8 Mon Sep 17 00:00:00 2001 From: trendschau Date: Wed, 1 Nov 2023 20:30:16 +0100 Subject: [PATCH] Add translations and fix xss security issues --- composer.lock | 182 ++-- .../00-welcome/{05-todoss.md => 05-todos.md} | 2 +- .../{05-todoss.yaml => 05-todos.yaml} | 0 data/navigation/navi-draft.txt | 2 +- data/navigation/navi-extended.txt | 4 +- data/navigation/navi-live.txt | 1 + .../ControllerApiSystemExtensions.php | 2 +- .../typemill/Middleware/ApiAuthorization.php | 11 +- .../Middleware/SecurityMiddleware.php | 8 +- .../Middleware/ValidationErrorsMiddleware.php | 3 +- system/typemill/Models/Content.php | 25 +- system/typemill/Models/Extension.php | 5 +- system/typemill/Models/License.php | 9 +- system/typemill/Models/Media.php | 21 +- system/typemill/Models/Settings.php | 21 +- system/typemill/Models/Storage.php | 71 +- system/typemill/Models/User.php | 15 +- system/typemill/Models/Validation.php | 24 +- system/typemill/Static/License.php | 7 +- system/typemill/Static/Translations.php | 22 +- system/typemill/author/auth/login.twig | 4 +- system/typemill/author/js/vue-plugins.js | 2 +- system/typemill/author/js/vue-raw.js | 4 + system/typemill/author/translations/de.yaml | 654 ++++++++++----- system/typemill/author/translations/en.yaml | 666 ++++++++++----- system/typemill/author/translations/fr.yaml | 680 ++++++++++----- system/typemill/author/translations/it.yaml | 775 ++++++++++++------ system/typemill/author/translations/nl.yaml | 650 ++++++++++----- system/typemill/author/translations/ru.yaml | 678 ++++++++++----- 29 files changed, 3190 insertions(+), 1358 deletions(-) rename content/00-welcome/{05-todoss.md => 05-todos.md} (99%) rename content/00-welcome/{05-todoss.yaml => 05-todos.yaml} (100%) create mode 100644 data/navigation/navi-live.txt diff --git a/composer.lock b/composer.lock index ad19ab2..66e966e 100644 --- a/composer.lock +++ b/composer.lock @@ -342,20 +342,20 @@ }, { "name": "laminas/laminas-permissions-acl", - "version": "2.14.0", + "version": "2.16.0", "source": { "type": "git", "url": "https://github.com/laminas/laminas-permissions-acl.git", - "reference": "86cecb540cf8f2e088d70d8acef1fc9203ed5023" + "reference": "9f85ee3b1940cd5a1c4151ca16fdb738c162480b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-permissions-acl/zipball/86cecb540cf8f2e088d70d8acef1fc9203ed5023", - "reference": "86cecb540cf8f2e088d70d8acef1fc9203ed5023", + "url": "https://api.github.com/repos/laminas/laminas-permissions-acl/zipball/9f85ee3b1940cd5a1c4151ca16fdb738c162480b", + "reference": "9f85ee3b1940cd5a1c4151ca16fdb738c162480b", "shasum": "" }, "require": { - "php": "~8.0.0 || ~8.1.0 || ~8.2.0" + "php": "~8.1.0 || ~8.2.0 || ~8.3.0" }, "conflict": { "laminas/laminas-servicemanager": "<3.0", @@ -363,11 +363,11 @@ }, "require-dev": { "laminas/laminas-coding-standard": "~2.5.0", - "laminas/laminas-servicemanager": "^3.19", - "phpbench/phpbench": "^1.2", - "phpunit/phpunit": "^9.5.26", - "psalm/plugin-phpunit": "^0.18.0", - "vimeo/psalm": "^5.0" + "laminas/laminas-servicemanager": "^3.21", + "phpbench/phpbench": "^1.2.10", + "phpunit/phpunit": "^10.1.3", + "psalm/plugin-phpunit": "^0.18.4", + "vimeo/psalm": "^5.12" }, "suggest": { "laminas/laminas-servicemanager": "To support Laminas\\Permissions\\Acl\\Assertion\\AssertionManager plugin manager usage" @@ -402,20 +402,20 @@ "type": "community_bridge" } ], - "time": "2023-02-01T16:19:54+00:00" + "time": "2023-10-18T07:50:34+00:00" }, { "name": "laravel/serializable-closure", - "version": "v1.3.1", + "version": "v1.3.2", "source": { "type": "git", "url": "https://github.com/laravel/serializable-closure.git", - "reference": "e5a3057a5591e1cfe8183034b0203921abe2c902" + "reference": "076fe2cf128bd54b4341cdc6d49b95b34e101e4c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/e5a3057a5591e1cfe8183034b0203921abe2c902", - "reference": "e5a3057a5591e1cfe8183034b0203921abe2c902", + "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/076fe2cf128bd54b4341cdc6d49b95b34e101e4c", + "reference": "076fe2cf128bd54b4341cdc6d49b95b34e101e4c", "shasum": "" }, "require": { @@ -462,7 +462,7 @@ "issues": "https://github.com/laravel/serializable-closure/issues", "source": "https://github.com/laravel/serializable-closure" }, - "time": "2023-07-14T13:56:28+00:00" + "time": "2023-10-17T13:38:16+00:00" }, { "name": "nikic/fast-route", @@ -1514,25 +1514,93 @@ "time": "2022-01-02T05:14:45+00:00" }, { - "name": "symfony/event-dispatcher", - "version": "v6.0.19", + "name": "symfony/deprecation-contracts", + "version": "v3.3.0", "source": { "type": "git", - "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "2eaf8e63bc5b8cefabd4a800157f0d0c094f677a" + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/2eaf8e63bc5b8cefabd4a800157f0d0c094f677a", - "reference": "2eaf8e63bc5b8cefabd4a800157f0d0c094f677a", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/7c3aff79d10325257a001fcf92d991f24fc967cf", + "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf", "shasum": "" }, "require": { - "php": ">=8.0.2", - "symfony/event-dispatcher-contracts": "^2|^3" + "php": ">=8.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.4-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "files": [ + "function.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.3.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-05-23T14:45:45+00:00" + }, + { + "name": "symfony/event-dispatcher", + "version": "v6.3.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "adb01fe097a4ee930db9258a3cc906b5beb5cf2e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/adb01fe097a4ee930db9258a3cc906b5beb5cf2e", + "reference": "adb01fe097a4ee930db9258a3cc906b5beb5cf2e", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/event-dispatcher-contracts": "^2.5|^3" }, "conflict": { - "symfony/dependency-injection": "<5.4" + "symfony/dependency-injection": "<5.4", + "symfony/service-contracts": "<2.5" }, "provide": { "psr/event-dispatcher-implementation": "1.0", @@ -1545,13 +1613,9 @@ "symfony/error-handler": "^5.4|^6.0", "symfony/expression-language": "^5.4|^6.0", "symfony/http-foundation": "^5.4|^6.0", - "symfony/service-contracts": "^1.1|^2|^3", + "symfony/service-contracts": "^2.5|^3", "symfony/stopwatch": "^5.4|^6.0" }, - "suggest": { - "symfony/dependency-injection": "", - "symfony/http-kernel": "" - }, "type": "library", "autoload": { "psr-4": { @@ -1578,7 +1642,7 @@ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v6.0.19" + "source": "https://github.com/symfony/event-dispatcher/tree/v6.3.2" }, "funding": [ { @@ -1594,33 +1658,30 @@ "type": "tidelift" } ], - "time": "2023-01-01T08:36:10+00:00" + "time": "2023-07-06T06:56:43+00:00" }, { "name": "symfony/event-dispatcher-contracts", - "version": "v3.0.2", + "version": "v3.3.0", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher-contracts.git", - "reference": "7bc61cc2db649b4637d331240c5346dcc7708051" + "reference": "a76aed96a42d2b521153fb382d418e30d18b59df" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/7bc61cc2db649b4637d331240c5346dcc7708051", - "reference": "7bc61cc2db649b4637d331240c5346dcc7708051", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/a76aed96a42d2b521153fb382d418e30d18b59df", + "reference": "a76aed96a42d2b521153fb382d418e30d18b59df", "shasum": "" }, "require": { - "php": ">=8.0.2", + "php": ">=8.1", "psr/event-dispatcher": "^1" }, - "suggest": { - "symfony/event-dispatcher-implementation": "" - }, "type": "library", "extra": { "branch-alias": { - "dev-main": "3.0-dev" + "dev-main": "3.4-dev" }, "thanks": { "name": "symfony/contracts", @@ -1657,7 +1718,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.0.2" + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.3.0" }, "funding": [ { @@ -1673,24 +1734,27 @@ "type": "tidelift" } ], - "time": "2022-01-02T09:55:41+00:00" + "time": "2023-05-23T14:45:45+00:00" }, { "name": "symfony/finder", - "version": "v6.0.19", + "version": "v6.3.5", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "5cc9cac6586fc0c28cd173780ca696e419fefa11" + "reference": "a1b31d88c0e998168ca7792f222cbecee47428c4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/5cc9cac6586fc0c28cd173780ca696e419fefa11", - "reference": "5cc9cac6586fc0c28cd173780ca696e419fefa11", + "url": "https://api.github.com/repos/symfony/finder/zipball/a1b31d88c0e998168ca7792f222cbecee47428c4", + "reference": "a1b31d88c0e998168ca7792f222cbecee47428c4", "shasum": "" }, "require": { - "php": ">=8.0.2" + "php": ">=8.1" + }, + "require-dev": { + "symfony/filesystem": "^6.0" }, "type": "library", "autoload": { @@ -1718,7 +1782,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v6.0.19" + "source": "https://github.com/symfony/finder/tree/v6.3.5" }, "funding": [ { @@ -1734,7 +1798,7 @@ "type": "tidelift" } ], - "time": "2023-01-20T17:44:14+00:00" + "time": "2023-09-26T12:56:25+00:00" }, { "name": "symfony/polyfill-ctype", @@ -2065,20 +2129,21 @@ }, { "name": "symfony/yaml", - "version": "v6.0.19", + "version": "v6.3.7", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "deec3a812a0305a50db8ae689b183f43d915c884" + "reference": "9758b6c69d179936435d0ffb577c3708d57e38a8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/deec3a812a0305a50db8ae689b183f43d915c884", - "reference": "deec3a812a0305a50db8ae689b183f43d915c884", + "url": "https://api.github.com/repos/symfony/yaml/zipball/9758b6c69d179936435d0ffb577c3708d57e38a8", + "reference": "9758b6c69d179936435d0ffb577c3708d57e38a8", "shasum": "" }, "require": { - "php": ">=8.0.2", + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-ctype": "^1.8" }, "conflict": { @@ -2087,9 +2152,6 @@ "require-dev": { "symfony/console": "^5.4|^6.0" }, - "suggest": { - "symfony/console": "For validating YAML files using the lint command" - }, "bin": [ "Resources/bin/yaml-lint" ], @@ -2119,7 +2181,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v6.0.19" + "source": "https://github.com/symfony/yaml/tree/v6.3.7" }, "funding": [ { @@ -2135,7 +2197,7 @@ "type": "tidelift" } ], - "time": "2023-01-11T11:50:03+00:00" + "time": "2023-10-28T23:31:00+00:00" }, { "name": "twig/twig", diff --git a/content/00-welcome/05-todoss.md b/content/00-welcome/05-todos.md similarity index 99% rename from content/00-welcome/05-todoss.md rename to content/00-welcome/05-todos.md index b8d2e46..9baecea 100644 --- a/content/00-welcome/05-todoss.md +++ b/content/00-welcome/05-todos.md @@ -9,7 +9,7 @@ * DONE: License feature * DONE: Enhance with plugins -## Visual Editor +## Visual Editor * DONE: Refactor and redesign * DONE: Fix toc component in new block diff --git a/content/00-welcome/05-todoss.yaml b/content/00-welcome/05-todos.yaml similarity index 100% rename from content/00-welcome/05-todoss.yaml rename to content/00-welcome/05-todos.yaml diff --git a/data/navigation/navi-draft.txt b/data/navigation/navi-draft.txt index 545a364..b7f3496 100644 --- a/data/navigation/navi-draft.txt +++ b/data/navigation/navi-draft.txt @@ -1 +1 @@ -a:2:{i:0;O:8:"stdClass":22:{s:12:"originalName";s:10:"00-welcome";s:11:"elementType";s:6:"folder";s:8:"contains";s:5:"pages";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"00";s:4:"name";s:7:"welcome";s:4:"slug";s:7:"welcome";s:4:"path";s:11:"/00-welcome";s:15:"pathWithoutType";s:17:"/00-welcome/index";s:9:"urlRelWoF";s:8:"/welcome";s:6:"urlRel";s:17:"/typemill/welcome";s:6:"urlAbs";s:33:"http://localhost/typemill/welcome";s:3:"key";i:0;s:7:"keyPath";i:0;s:12:"keyPathArray";a:1:{i:0;s:1:"0";}s:7:"chapter";i:1;s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:13:"folderContent";a:6:{i:0;O:8:"stdClass":20:{s:12:"originalName";s:24:"00-setup-your-website.md";s:11:"elementType";s:4:"file";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"00";s:4:"name";s:18:"setup your website";s:4:"slug";s:18:"setup-your-website";s:4:"path";s:36:"/00-welcome/00-setup-your-website.md";s:15:"pathWithoutType";s:33:"/00-welcome/00-setup-your-website";s:3:"key";i:0;s:7:"keyPath";s:3:"0.0";s:12:"keyPathArray";a:2:{i:0;s:1:"0";i:1;s:1:"0";}s:7:"chapter";s:3:"1.1";s:9:"urlRelWoF";s:27:"/welcome/setup-your-website";s:6:"urlRel";s:36:"/typemill/welcome/setup-your-website";s:6:"urlAbs";s:52:"http://localhost/typemill/welcome/setup-your-website";s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:7:"noindex";b:0;}i:1;O:8:"stdClass":20:{s:12:"originalName";s:19:"01-manage-access.md";s:11:"elementType";s:4:"file";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"01";s:4:"name";s:13:"manage access";s:4:"slug";s:13:"manage-access";s:4:"path";s:31:"/00-welcome/01-manage-access.md";s:15:"pathWithoutType";s:28:"/00-welcome/01-manage-access";s:3:"key";i:1;s:7:"keyPath";s:3:"0.1";s:12:"keyPathArray";a:2:{i:0;s:1:"0";i:1;s:1:"1";}s:7:"chapter";s:3:"1.2";s:9:"urlRelWoF";s:22:"/welcome/manage-access";s:6:"urlRel";s:31:"/typemill/welcome/manage-access";s:6:"urlAbs";s:47:"http://localhost/typemill/welcome/manage-access";s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:7:"noindex";b:0;}i:2;O:8:"stdClass":20:{s:12:"originalName";s:19:"02-write-content.md";s:11:"elementType";s:4:"file";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"02";s:4:"name";s:13:"write content";s:4:"slug";s:13:"write-content";s:4:"path";s:31:"/00-welcome/02-write-content.md";s:15:"pathWithoutType";s:28:"/00-welcome/02-write-content";s:3:"key";i:2;s:7:"keyPath";s:3:"0.2";s:12:"keyPathArray";a:2:{i:0;s:1:"0";i:1;s:1:"2";}s:7:"chapter";s:3:"1.3";s:9:"urlRelWoF";s:22:"/welcome/write-content";s:6:"urlRel";s:31:"/typemill/welcome/write-content";s:6:"urlAbs";s:47:"http://localhost/typemill/welcome/write-content";s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:1;s:7:"noindex";b:0;}i:3;O:8:"stdClass":20:{s:12:"originalName";s:14:"03-get-help.md";s:11:"elementType";s:4:"file";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"03";s:4:"name";s:8:"get help";s:4:"slug";s:8:"get-help";s:4:"path";s:26:"/00-welcome/03-get-help.md";s:15:"pathWithoutType";s:23:"/00-welcome/03-get-help";s:3:"key";i:3;s:7:"keyPath";s:3:"0.3";s:12:"keyPathArray";a:2:{i:0;s:1:"0";i:1;s:1:"3";}s:7:"chapter";s:3:"1.4";s:9:"urlRelWoF";s:17:"/welcome/get-help";s:6:"urlRel";s:26:"/typemill/welcome/get-help";s:6:"urlAbs";s:42:"http://localhost/typemill/welcome/get-help";s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:7:"noindex";b:0;}i:4;O:8:"stdClass":20:{s:12:"originalName";s:19:"04-markdown-test.md";s:11:"elementType";s:4:"file";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"04";s:4:"name";s:13:"markdown test";s:4:"slug";s:13:"markdown-test";s:4:"path";s:31:"/00-welcome/04-markdown-test.md";s:15:"pathWithoutType";s:28:"/00-welcome/04-markdown-test";s:3:"key";i:4;s:7:"keyPath";s:3:"0.4";s:12:"keyPathArray";a:2:{i:0;s:1:"0";i:1;s:1:"4";}s:7:"chapter";s:3:"1.5";s:9:"urlRelWoF";s:22:"/welcome/markdown-test";s:6:"urlRel";s:31:"/typemill/welcome/markdown-test";s:6:"urlAbs";s:47:"http://localhost/typemill/welcome/markdown-test";s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:7:"noindex";b:0;}i:5;O:8:"stdClass":20:{s:12:"originalName";s:12:"05-todoss.md";s:11:"elementType";s:4:"file";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"05";s:4:"name";s:6:"To Dos";s:4:"slug";s:6:"todoss";s:4:"path";s:24:"/00-welcome/05-todoss.md";s:15:"pathWithoutType";s:21:"/00-welcome/05-todoss";s:3:"key";i:5;s:7:"keyPath";s:3:"0.5";s:12:"keyPathArray";a:2:{i:0;s:1:"0";i:1;s:1:"5";}s:7:"chapter";s:3:"1.6";s:9:"urlRelWoF";s:15:"/welcome/todoss";s:6:"urlRel";s:24:"/typemill/welcome/todoss";s:6:"urlAbs";s:40:"http://localhost/typemill/welcome/todoss";s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:7:"noindex";b:0;}}s:7:"noindex";b:0;}i:1;O:8:"stdClass":22:{s:12:"originalName";s:16:"01-cyanine-theme";s:11:"elementType";s:6:"folder";s:8:"contains";s:5:"pages";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"01";s:4:"name";s:13:"cyanine theme";s:4:"slug";s:13:"cyanine-theme";s:4:"path";s:17:"/01-cyanine-theme";s:15:"pathWithoutType";s:23:"/01-cyanine-theme/index";s:9:"urlRelWoF";s:14:"/cyanine-theme";s:6:"urlRel";s:23:"/typemill/cyanine-theme";s:6:"urlAbs";s:39:"http://localhost/typemill/cyanine-theme";s:3:"key";i:1;s:7:"keyPath";i:1;s:12:"keyPathArray";a:1:{i:0;s:1:"1";}s:7:"chapter";i:2;s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:13:"folderContent";a:4:{i:0;O:8:"stdClass":20:{s:12:"originalName";s:17:"00-landingpage.md";s:11:"elementType";s:4:"file";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"00";s:4:"name";s:11:"landingpage";s:4:"slug";s:11:"landingpage";s:4:"path";s:35:"/01-cyanine-theme/00-landingpage.md";s:15:"pathWithoutType";s:32:"/01-cyanine-theme/00-landingpage";s:3:"key";i:0;s:7:"keyPath";s:3:"1.0";s:12:"keyPathArray";a:2:{i:0;s:1:"1";i:1;s:1:"0";}s:7:"chapter";s:3:"2.1";s:9:"urlRelWoF";s:26:"/cyanine-theme/landingpage";s:6:"urlRel";s:35:"/typemill/cyanine-theme/landingpage";s:6:"urlAbs";s:51:"http://localhost/typemill/cyanine-theme/landingpage";s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:7:"noindex";b:1;}i:1;O:8:"stdClass":20:{s:12:"originalName";s:22:"01-colors-and-fonts.md";s:11:"elementType";s:4:"file";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"01";s:4:"name";s:16:"colors and fonts";s:4:"slug";s:16:"colors-and-fonts";s:4:"path";s:40:"/01-cyanine-theme/01-colors-and-fonts.md";s:15:"pathWithoutType";s:37:"/01-cyanine-theme/01-colors-and-fonts";s:3:"key";i:1;s:7:"keyPath";s:3:"1.1";s:12:"keyPathArray";a:2:{i:0;s:1:"1";i:1;s:1:"1";}s:7:"chapter";s:3:"2.2";s:9:"urlRelWoF";s:31:"/cyanine-theme/colors-and-fonts";s:6:"urlRel";s:40:"/typemill/cyanine-theme/colors-and-fonts";s:6:"urlAbs";s:56:"http://localhost/typemill/cyanine-theme/colors-and-fonts";s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:7:"noindex";b:0;}i:2;O:8:"stdClass":20:{s:12:"originalName";s:12:"02-footer.md";s:11:"elementType";s:4:"file";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"02";s:4:"name";s:6:"footer";s:4:"slug";s:6:"footer";s:4:"path";s:30:"/01-cyanine-theme/02-footer.md";s:15:"pathWithoutType";s:27:"/01-cyanine-theme/02-footer";s:3:"key";i:2;s:7:"keyPath";s:3:"1.2";s:12:"keyPathArray";a:2:{i:0;s:1:"1";i:1;s:1:"2";}s:7:"chapter";s:3:"2.3";s:9:"urlRelWoF";s:21:"/cyanine-theme/footer";s:6:"urlRel";s:30:"/typemill/cyanine-theme/footer";s:6:"urlAbs";s:46:"http://localhost/typemill/cyanine-theme/footer";s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:7:"noindex";b:0;}i:3;O:8:"stdClass":20:{s:12:"originalName";s:22:"03-content-elements.md";s:11:"elementType";s:4:"file";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"03";s:4:"name";s:16:"content elements";s:4:"slug";s:16:"content-elements";s:4:"path";s:40:"/01-cyanine-theme/03-content-elements.md";s:15:"pathWithoutType";s:37:"/01-cyanine-theme/03-content-elements";s:3:"key";i:3;s:7:"keyPath";s:3:"1.3";s:12:"keyPathArray";a:2:{i:0;s:1:"1";i:1;s:1:"3";}s:7:"chapter";s:3:"2.4";s:9:"urlRelWoF";s:31:"/cyanine-theme/content-elements";s:6:"urlRel";s:40:"/typemill/cyanine-theme/content-elements";s:6:"urlAbs";s:56:"http://localhost/typemill/cyanine-theme/content-elements";s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:7:"noindex";b:0;}}s:7:"noindex";b:0;}} \ No newline at end of file +a:2:{i:0;O:8:"stdClass":22:{s:12:"originalName";s:10:"00-welcome";s:11:"elementType";s:6:"folder";s:8:"contains";s:5:"pages";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"00";s:4:"name";s:7:"welcome";s:4:"slug";s:7:"welcome";s:4:"path";s:11:"/00-welcome";s:15:"pathWithoutType";s:17:"/00-welcome/index";s:9:"urlRelWoF";s:8:"/welcome";s:6:"urlRel";s:17:"/typemill/welcome";s:6:"urlAbs";s:33:"http://localhost/typemill/welcome";s:3:"key";i:0;s:7:"keyPath";i:0;s:12:"keyPathArray";a:1:{i:0;s:1:"0";}s:7:"chapter";i:1;s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:13:"folderContent";a:6:{i:0;O:8:"stdClass":20:{s:12:"originalName";s:24:"00-setup-your-website.md";s:11:"elementType";s:4:"file";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"00";s:4:"name";s:18:"setup your website";s:4:"slug";s:18:"setup-your-website";s:4:"path";s:36:"/00-welcome/00-setup-your-website.md";s:15:"pathWithoutType";s:33:"/00-welcome/00-setup-your-website";s:3:"key";i:0;s:7:"keyPath";s:3:"0.0";s:12:"keyPathArray";a:2:{i:0;s:1:"0";i:1;s:1:"0";}s:7:"chapter";s:3:"1.1";s:9:"urlRelWoF";s:27:"/welcome/setup-your-website";s:6:"urlRel";s:36:"/typemill/welcome/setup-your-website";s:6:"urlAbs";s:52:"http://localhost/typemill/welcome/setup-your-website";s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:7:"noindex";b:0;}i:1;O:8:"stdClass":20:{s:12:"originalName";s:19:"01-manage-access.md";s:11:"elementType";s:4:"file";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"01";s:4:"name";s:13:"manage access";s:4:"slug";s:13:"manage-access";s:4:"path";s:31:"/00-welcome/01-manage-access.md";s:15:"pathWithoutType";s:28:"/00-welcome/01-manage-access";s:3:"key";i:1;s:7:"keyPath";s:3:"0.1";s:12:"keyPathArray";a:2:{i:0;s:1:"0";i:1;s:1:"1";}s:7:"chapter";s:3:"1.2";s:9:"urlRelWoF";s:22:"/welcome/manage-access";s:6:"urlRel";s:31:"/typemill/welcome/manage-access";s:6:"urlAbs";s:47:"http://localhost/typemill/welcome/manage-access";s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:7:"noindex";b:0;}i:2;O:8:"stdClass":20:{s:12:"originalName";s:19:"02-write-content.md";s:11:"elementType";s:4:"file";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"02";s:4:"name";s:13:"write content";s:4:"slug";s:13:"write-content";s:4:"path";s:31:"/00-welcome/02-write-content.md";s:15:"pathWithoutType";s:28:"/00-welcome/02-write-content";s:3:"key";i:2;s:7:"keyPath";s:3:"0.2";s:12:"keyPathArray";a:2:{i:0;s:1:"0";i:1;s:1:"2";}s:7:"chapter";s:3:"1.3";s:9:"urlRelWoF";s:22:"/welcome/write-content";s:6:"urlRel";s:31:"/typemill/welcome/write-content";s:6:"urlAbs";s:47:"http://localhost/typemill/welcome/write-content";s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:1;s:7:"noindex";b:0;}i:3;O:8:"stdClass":20:{s:12:"originalName";s:14:"03-get-help.md";s:11:"elementType";s:4:"file";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"03";s:4:"name";s:8:"get help";s:4:"slug";s:8:"get-help";s:4:"path";s:26:"/00-welcome/03-get-help.md";s:15:"pathWithoutType";s:23:"/00-welcome/03-get-help";s:3:"key";i:3;s:7:"keyPath";s:3:"0.3";s:12:"keyPathArray";a:2:{i:0;s:1:"0";i:1;s:1:"3";}s:7:"chapter";s:3:"1.4";s:9:"urlRelWoF";s:17:"/welcome/get-help";s:6:"urlRel";s:26:"/typemill/welcome/get-help";s:6:"urlAbs";s:42:"http://localhost/typemill/welcome/get-help";s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:7:"noindex";b:0;}i:4;O:8:"stdClass":20:{s:12:"originalName";s:19:"04-markdown-test.md";s:11:"elementType";s:4:"file";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"04";s:4:"name";s:13:"markdown test";s:4:"slug";s:13:"markdown-test";s:4:"path";s:31:"/00-welcome/04-markdown-test.md";s:15:"pathWithoutType";s:28:"/00-welcome/04-markdown-test";s:3:"key";i:4;s:7:"keyPath";s:3:"0.4";s:12:"keyPathArray";a:2:{i:0;s:1:"0";i:1;s:1:"4";}s:7:"chapter";s:3:"1.5";s:9:"urlRelWoF";s:22:"/welcome/markdown-test";s:6:"urlRel";s:31:"/typemill/welcome/markdown-test";s:6:"urlAbs";s:47:"http://localhost/typemill/welcome/markdown-test";s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:7:"noindex";b:0;}i:5;O:8:"stdClass":20:{s:12:"originalName";s:11:"05-todos.md";s:11:"elementType";s:4:"file";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"05";s:4:"name";s:6:"To Dos";s:4:"slug";s:5:"todos";s:4:"path";s:23:"/00-welcome/05-todos.md";s:15:"pathWithoutType";s:20:"/00-welcome/05-todos";s:3:"key";i:5;s:7:"keyPath";s:3:"0.5";s:12:"keyPathArray";a:2:{i:0;s:1:"0";i:1;s:1:"5";}s:7:"chapter";s:3:"1.6";s:9:"urlRelWoF";s:14:"/welcome/todos";s:6:"urlRel";s:23:"/typemill/welcome/todos";s:6:"urlAbs";s:39:"http://localhost/typemill/welcome/todos";s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:7:"noindex";b:0;}}s:7:"noindex";b:0;}i:1;O:8:"stdClass":22:{s:12:"originalName";s:16:"01-cyanine-theme";s:11:"elementType";s:6:"folder";s:8:"contains";s:5:"pages";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"01";s:4:"name";s:13:"cyanine theme";s:4:"slug";s:13:"cyanine-theme";s:4:"path";s:17:"/01-cyanine-theme";s:15:"pathWithoutType";s:23:"/01-cyanine-theme/index";s:9:"urlRelWoF";s:14:"/cyanine-theme";s:6:"urlRel";s:23:"/typemill/cyanine-theme";s:6:"urlAbs";s:39:"http://localhost/typemill/cyanine-theme";s:3:"key";i:1;s:7:"keyPath";i:1;s:12:"keyPathArray";a:1:{i:0;s:1:"1";}s:7:"chapter";i:2;s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:13:"folderContent";a:4:{i:0;O:8:"stdClass":20:{s:12:"originalName";s:17:"00-landingpage.md";s:11:"elementType";s:4:"file";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"00";s:4:"name";s:11:"landingpage";s:4:"slug";s:11:"landingpage";s:4:"path";s:35:"/01-cyanine-theme/00-landingpage.md";s:15:"pathWithoutType";s:32:"/01-cyanine-theme/00-landingpage";s:3:"key";i:0;s:7:"keyPath";s:3:"1.0";s:12:"keyPathArray";a:2:{i:0;s:1:"1";i:1;s:1:"0";}s:7:"chapter";s:3:"2.1";s:9:"urlRelWoF";s:26:"/cyanine-theme/landingpage";s:6:"urlRel";s:35:"/typemill/cyanine-theme/landingpage";s:6:"urlAbs";s:51:"http://localhost/typemill/cyanine-theme/landingpage";s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:7:"noindex";b:1;}i:1;O:8:"stdClass":20:{s:12:"originalName";s:22:"01-colors-and-fonts.md";s:11:"elementType";s:4:"file";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"01";s:4:"name";s:16:"colors and fonts";s:4:"slug";s:16:"colors-and-fonts";s:4:"path";s:40:"/01-cyanine-theme/01-colors-and-fonts.md";s:15:"pathWithoutType";s:37:"/01-cyanine-theme/01-colors-and-fonts";s:3:"key";i:1;s:7:"keyPath";s:3:"1.1";s:12:"keyPathArray";a:2:{i:0;s:1:"1";i:1;s:1:"1";}s:7:"chapter";s:3:"2.2";s:9:"urlRelWoF";s:31:"/cyanine-theme/colors-and-fonts";s:6:"urlRel";s:40:"/typemill/cyanine-theme/colors-and-fonts";s:6:"urlAbs";s:56:"http://localhost/typemill/cyanine-theme/colors-and-fonts";s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:7:"noindex";b:0;}i:2;O:8:"stdClass":20:{s:12:"originalName";s:12:"02-footer.md";s:11:"elementType";s:4:"file";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"02";s:4:"name";s:6:"footer";s:4:"slug";s:6:"footer";s:4:"path";s:30:"/01-cyanine-theme/02-footer.md";s:15:"pathWithoutType";s:27:"/01-cyanine-theme/02-footer";s:3:"key";i:2;s:7:"keyPath";s:3:"1.2";s:12:"keyPathArray";a:2:{i:0;s:1:"1";i:1;s:1:"2";}s:7:"chapter";s:3:"2.3";s:9:"urlRelWoF";s:21:"/cyanine-theme/footer";s:6:"urlRel";s:30:"/typemill/cyanine-theme/footer";s:6:"urlAbs";s:46:"http://localhost/typemill/cyanine-theme/footer";s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:7:"noindex";b:0;}i:3;O:8:"stdClass":20:{s:12:"originalName";s:22:"03-content-elements.md";s:11:"elementType";s:4:"file";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"03";s:4:"name";s:16:"content elements";s:4:"slug";s:16:"content-elements";s:4:"path";s:40:"/01-cyanine-theme/03-content-elements.md";s:15:"pathWithoutType";s:37:"/01-cyanine-theme/03-content-elements";s:3:"key";i:3;s:7:"keyPath";s:3:"1.3";s:12:"keyPathArray";a:2:{i:0;s:1:"1";i:1;s:1:"3";}s:7:"chapter";s:3:"2.4";s:9:"urlRelWoF";s:31:"/cyanine-theme/content-elements";s:6:"urlRel";s:40:"/typemill/cyanine-theme/content-elements";s:6:"urlAbs";s:56:"http://localhost/typemill/cyanine-theme/content-elements";s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:7:"noindex";b:0;}}s:7:"noindex";b:0;}} \ No newline at end of file diff --git a/data/navigation/navi-extended.txt b/data/navigation/navi-extended.txt index 60aef1f..17de291 100644 --- a/data/navigation/navi-extended.txt +++ b/data/navigation/navi-extended.txt @@ -34,11 +34,11 @@ noindex: false path: /00-welcome/04-markdown-test.md keyPath: '0.4' -/welcome/todoss: +/welcome/todos: navtitle: 'To Dos' hide: false noindex: false - path: /00-welcome/05-todoss.md + path: /00-welcome/05-todos.md keyPath: '0.5' /cyanine-theme: navtitle: 'cyanine theme' diff --git a/data/navigation/navi-live.txt b/data/navigation/navi-live.txt new file mode 100644 index 0000000..b7f3496 --- /dev/null +++ b/data/navigation/navi-live.txt @@ -0,0 +1 @@ +a:2:{i:0;O:8:"stdClass":22:{s:12:"originalName";s:10:"00-welcome";s:11:"elementType";s:6:"folder";s:8:"contains";s:5:"pages";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"00";s:4:"name";s:7:"welcome";s:4:"slug";s:7:"welcome";s:4:"path";s:11:"/00-welcome";s:15:"pathWithoutType";s:17:"/00-welcome/index";s:9:"urlRelWoF";s:8:"/welcome";s:6:"urlRel";s:17:"/typemill/welcome";s:6:"urlAbs";s:33:"http://localhost/typemill/welcome";s:3:"key";i:0;s:7:"keyPath";i:0;s:12:"keyPathArray";a:1:{i:0;s:1:"0";}s:7:"chapter";i:1;s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:13:"folderContent";a:6:{i:0;O:8:"stdClass":20:{s:12:"originalName";s:24:"00-setup-your-website.md";s:11:"elementType";s:4:"file";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"00";s:4:"name";s:18:"setup your website";s:4:"slug";s:18:"setup-your-website";s:4:"path";s:36:"/00-welcome/00-setup-your-website.md";s:15:"pathWithoutType";s:33:"/00-welcome/00-setup-your-website";s:3:"key";i:0;s:7:"keyPath";s:3:"0.0";s:12:"keyPathArray";a:2:{i:0;s:1:"0";i:1;s:1:"0";}s:7:"chapter";s:3:"1.1";s:9:"urlRelWoF";s:27:"/welcome/setup-your-website";s:6:"urlRel";s:36:"/typemill/welcome/setup-your-website";s:6:"urlAbs";s:52:"http://localhost/typemill/welcome/setup-your-website";s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:7:"noindex";b:0;}i:1;O:8:"stdClass":20:{s:12:"originalName";s:19:"01-manage-access.md";s:11:"elementType";s:4:"file";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"01";s:4:"name";s:13:"manage access";s:4:"slug";s:13:"manage-access";s:4:"path";s:31:"/00-welcome/01-manage-access.md";s:15:"pathWithoutType";s:28:"/00-welcome/01-manage-access";s:3:"key";i:1;s:7:"keyPath";s:3:"0.1";s:12:"keyPathArray";a:2:{i:0;s:1:"0";i:1;s:1:"1";}s:7:"chapter";s:3:"1.2";s:9:"urlRelWoF";s:22:"/welcome/manage-access";s:6:"urlRel";s:31:"/typemill/welcome/manage-access";s:6:"urlAbs";s:47:"http://localhost/typemill/welcome/manage-access";s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:7:"noindex";b:0;}i:2;O:8:"stdClass":20:{s:12:"originalName";s:19:"02-write-content.md";s:11:"elementType";s:4:"file";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"02";s:4:"name";s:13:"write content";s:4:"slug";s:13:"write-content";s:4:"path";s:31:"/00-welcome/02-write-content.md";s:15:"pathWithoutType";s:28:"/00-welcome/02-write-content";s:3:"key";i:2;s:7:"keyPath";s:3:"0.2";s:12:"keyPathArray";a:2:{i:0;s:1:"0";i:1;s:1:"2";}s:7:"chapter";s:3:"1.3";s:9:"urlRelWoF";s:22:"/welcome/write-content";s:6:"urlRel";s:31:"/typemill/welcome/write-content";s:6:"urlAbs";s:47:"http://localhost/typemill/welcome/write-content";s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:1;s:7:"noindex";b:0;}i:3;O:8:"stdClass":20:{s:12:"originalName";s:14:"03-get-help.md";s:11:"elementType";s:4:"file";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"03";s:4:"name";s:8:"get help";s:4:"slug";s:8:"get-help";s:4:"path";s:26:"/00-welcome/03-get-help.md";s:15:"pathWithoutType";s:23:"/00-welcome/03-get-help";s:3:"key";i:3;s:7:"keyPath";s:3:"0.3";s:12:"keyPathArray";a:2:{i:0;s:1:"0";i:1;s:1:"3";}s:7:"chapter";s:3:"1.4";s:9:"urlRelWoF";s:17:"/welcome/get-help";s:6:"urlRel";s:26:"/typemill/welcome/get-help";s:6:"urlAbs";s:42:"http://localhost/typemill/welcome/get-help";s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:7:"noindex";b:0;}i:4;O:8:"stdClass":20:{s:12:"originalName";s:19:"04-markdown-test.md";s:11:"elementType";s:4:"file";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"04";s:4:"name";s:13:"markdown test";s:4:"slug";s:13:"markdown-test";s:4:"path";s:31:"/00-welcome/04-markdown-test.md";s:15:"pathWithoutType";s:28:"/00-welcome/04-markdown-test";s:3:"key";i:4;s:7:"keyPath";s:3:"0.4";s:12:"keyPathArray";a:2:{i:0;s:1:"0";i:1;s:1:"4";}s:7:"chapter";s:3:"1.5";s:9:"urlRelWoF";s:22:"/welcome/markdown-test";s:6:"urlRel";s:31:"/typemill/welcome/markdown-test";s:6:"urlAbs";s:47:"http://localhost/typemill/welcome/markdown-test";s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:7:"noindex";b:0;}i:5;O:8:"stdClass":20:{s:12:"originalName";s:11:"05-todos.md";s:11:"elementType";s:4:"file";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"05";s:4:"name";s:6:"To Dos";s:4:"slug";s:5:"todos";s:4:"path";s:23:"/00-welcome/05-todos.md";s:15:"pathWithoutType";s:20:"/00-welcome/05-todos";s:3:"key";i:5;s:7:"keyPath";s:3:"0.5";s:12:"keyPathArray";a:2:{i:0;s:1:"0";i:1;s:1:"5";}s:7:"chapter";s:3:"1.6";s:9:"urlRelWoF";s:14:"/welcome/todos";s:6:"urlRel";s:23:"/typemill/welcome/todos";s:6:"urlAbs";s:39:"http://localhost/typemill/welcome/todos";s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:7:"noindex";b:0;}}s:7:"noindex";b:0;}i:1;O:8:"stdClass":22:{s:12:"originalName";s:16:"01-cyanine-theme";s:11:"elementType";s:6:"folder";s:8:"contains";s:5:"pages";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"01";s:4:"name";s:13:"cyanine theme";s:4:"slug";s:13:"cyanine-theme";s:4:"path";s:17:"/01-cyanine-theme";s:15:"pathWithoutType";s:23:"/01-cyanine-theme/index";s:9:"urlRelWoF";s:14:"/cyanine-theme";s:6:"urlRel";s:23:"/typemill/cyanine-theme";s:6:"urlAbs";s:39:"http://localhost/typemill/cyanine-theme";s:3:"key";i:1;s:7:"keyPath";i:1;s:12:"keyPathArray";a:1:{i:0;s:1:"1";}s:7:"chapter";i:2;s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:13:"folderContent";a:4:{i:0;O:8:"stdClass":20:{s:12:"originalName";s:17:"00-landingpage.md";s:11:"elementType";s:4:"file";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"00";s:4:"name";s:11:"landingpage";s:4:"slug";s:11:"landingpage";s:4:"path";s:35:"/01-cyanine-theme/00-landingpage.md";s:15:"pathWithoutType";s:32:"/01-cyanine-theme/00-landingpage";s:3:"key";i:0;s:7:"keyPath";s:3:"1.0";s:12:"keyPathArray";a:2:{i:0;s:1:"1";i:1;s:1:"0";}s:7:"chapter";s:3:"2.1";s:9:"urlRelWoF";s:26:"/cyanine-theme/landingpage";s:6:"urlRel";s:35:"/typemill/cyanine-theme/landingpage";s:6:"urlAbs";s:51:"http://localhost/typemill/cyanine-theme/landingpage";s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:7:"noindex";b:1;}i:1;O:8:"stdClass":20:{s:12:"originalName";s:22:"01-colors-and-fonts.md";s:11:"elementType";s:4:"file";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"01";s:4:"name";s:16:"colors and fonts";s:4:"slug";s:16:"colors-and-fonts";s:4:"path";s:40:"/01-cyanine-theme/01-colors-and-fonts.md";s:15:"pathWithoutType";s:37:"/01-cyanine-theme/01-colors-and-fonts";s:3:"key";i:1;s:7:"keyPath";s:3:"1.1";s:12:"keyPathArray";a:2:{i:0;s:1:"1";i:1;s:1:"1";}s:7:"chapter";s:3:"2.2";s:9:"urlRelWoF";s:31:"/cyanine-theme/colors-and-fonts";s:6:"urlRel";s:40:"/typemill/cyanine-theme/colors-and-fonts";s:6:"urlAbs";s:56:"http://localhost/typemill/cyanine-theme/colors-and-fonts";s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:7:"noindex";b:0;}i:2;O:8:"stdClass":20:{s:12:"originalName";s:12:"02-footer.md";s:11:"elementType";s:4:"file";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"02";s:4:"name";s:6:"footer";s:4:"slug";s:6:"footer";s:4:"path";s:30:"/01-cyanine-theme/02-footer.md";s:15:"pathWithoutType";s:27:"/01-cyanine-theme/02-footer";s:3:"key";i:2;s:7:"keyPath";s:3:"1.2";s:12:"keyPathArray";a:2:{i:0;s:1:"1";i:1;s:1:"2";}s:7:"chapter";s:3:"2.3";s:9:"urlRelWoF";s:21:"/cyanine-theme/footer";s:6:"urlRel";s:30:"/typemill/cyanine-theme/footer";s:6:"urlAbs";s:46:"http://localhost/typemill/cyanine-theme/footer";s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:7:"noindex";b:0;}i:3;O:8:"stdClass":20:{s:12:"originalName";s:22:"03-content-elements.md";s:11:"elementType";s:4:"file";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"03";s:4:"name";s:16:"content elements";s:4:"slug";s:16:"content-elements";s:4:"path";s:40:"/01-cyanine-theme/03-content-elements.md";s:15:"pathWithoutType";s:37:"/01-cyanine-theme/03-content-elements";s:3:"key";i:3;s:7:"keyPath";s:3:"1.3";s:12:"keyPathArray";a:2:{i:0;s:1:"1";i:1;s:1:"3";}s:7:"chapter";s:3:"2.4";s:9:"urlRelWoF";s:31:"/cyanine-theme/content-elements";s:6:"urlRel";s:40:"/typemill/cyanine-theme/content-elements";s:6:"urlAbs";s:56:"http://localhost/typemill/cyanine-theme/content-elements";s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:7:"noindex";b:0;}}s:7:"noindex";b:0;}} \ No newline at end of file diff --git a/system/typemill/Controllers/ControllerApiSystemExtensions.php b/system/typemill/Controllers/ControllerApiSystemExtensions.php index bfdd64b..21d31c4 100644 --- a/system/typemill/Controllers/ControllerApiSystemExtensions.php +++ b/system/typemill/Controllers/ControllerApiSystemExtensions.php @@ -60,7 +60,7 @@ class ControllerApiSystemExtensions extends Controller if(!isset($licenseScope[$definitions['license']])) { $response->getBody()->write(json_encode([ - 'message' => Translations::translate('Activation failed because you need a valid ') . $definitions['license'] . Translations::translate('-license for this and your website must run under the domain of your license.'), + 'message' => Translations::translate('Activation failed because you need a valid ') . $definitions['license'] . Translations::translate('-license and your website must run under the domain of your license.'), ])); return $response->withHeader('Content-Type', 'application/json')->withStatus(400); diff --git a/system/typemill/Middleware/ApiAuthorization.php b/system/typemill/Middleware/ApiAuthorization.php index f24209a..935511f 100644 --- a/system/typemill/Middleware/ApiAuthorization.php +++ b/system/typemill/Middleware/ApiAuthorization.php @@ -7,6 +7,7 @@ use Slim\Routing\RouteParser; use Psr\Http\Message\ServerRequestInterface as Request; use Psr\Http\Server\RequestHandlerInterface as RequestHandler; use Slim\Psr7\Response; +use Typemill\Static\Translations; class ApiAuthorization implements MiddlewareInterface { @@ -21,9 +22,13 @@ class ApiAuthorization implements MiddlewareInterface { if(!$this->acl->isAllowed($request->getAttribute('c_userrole'), $this->resource, $this->action)) { - $message = 'Permission denied. Your are an ' . $request->getAttribute('c_userrole') . ' and you cannot ' . $this->action . ' this ' . $this->resource; - $response = new Response(); - + $message = Translations::translate('Permission denied') . '. '; + $message .= Translations::translate('Your are an '); + $message .= $request->getAttribute('c_userrole'); + $message .= Translations::translate(' and you cannot '); + $message .= $this->action . Translations::translate(' this ') . $this->resource; + + $response = new Response(); $response->getBody()->write(json_encode([ 'message' => $message ])); diff --git a/system/typemill/Middleware/SecurityMiddleware.php b/system/typemill/Middleware/SecurityMiddleware.php index 4c0895c..2e9d1c7 100644 --- a/system/typemill/Middleware/SecurityMiddleware.php +++ b/system/typemill/Middleware/SecurityMiddleware.php @@ -34,6 +34,13 @@ class securityMiddleware implements MiddlewareInterface $params = $request->getParsedBody(); $referer = $request->getHeader('HTTP_REFERER'); + if(!$referer OR $referer == '') + { + $response = new Response(); + + return $response->withHeader('Location', $this->router->urlFor('auth.login'))->withStatus(302); + } + # simple bot check with honeypot if( (isset($params['personal-honey-mail'])) @@ -49,7 +56,6 @@ class securityMiddleware implements MiddlewareInterface $response = new Response(); return $response->withHeader('Location', $referer[0])->withStatus(302); -# return $response->withHeader('Location', $this->router->urlFor('auth.login'))->withStatus(302); } # check captcha diff --git a/system/typemill/Middleware/ValidationErrorsMiddleware.php b/system/typemill/Middleware/ValidationErrorsMiddleware.php index 74c8a79..084c949 100644 --- a/system/typemill/Middleware/ValidationErrorsMiddleware.php +++ b/system/typemill/Middleware/ValidationErrorsMiddleware.php @@ -5,6 +5,7 @@ namespace Typemill\Middleware; use Psr\Http\Message\ServerRequestInterface as Request; use Psr\Http\Server\RequestHandlerInterface as RequestHandler; use Slim\Views\Twig; +use Typemill\Static\Translations; class ValidationErrorsMiddleware { @@ -26,7 +27,7 @@ class ValidationErrorsMiddleware if(isset($_SESSION['phrase'])) { - $this->view->getEnvironment()->addGlobal('errors', ['captcha' => 'the captcha is wrong, please try again']); + $this->view->getEnvironment()->addGlobal('errors', ['captcha' => Translations::translate('the captcha is wrong, please try again')]); unset($_SESSION['phrase']); } diff --git a/system/typemill/Models/Content.php b/system/typemill/Models/Content.php index 1435d76..0323a93 100644 --- a/system/typemill/Models/Content.php +++ b/system/typemill/Models/Content.php @@ -170,6 +170,8 @@ class Content $toc_id = false; + $this->parsedown->setSafeMode(true); + foreach($markdownArray as $key => $markdown) { if($markdown == "[TOC]") @@ -187,6 +189,9 @@ class Content ]; } + $this->parsedown->setSafeMode(false); + + if($toc_id) { # generate the toc markup @@ -201,6 +206,8 @@ class Content public function getDraftHtml($markdownArray) { + $this->parsedown->setSafeMode(true); + foreach($markdownArray as $key => $block) { # parse markdown-file to content-array @@ -210,17 +217,31 @@ class Content $content[$key] = $this->parsedown->markup($contentArray); } + $this->parsedown->setSafeMode(false); + return $content; } public function getContentArray($markdown) { - return $this->parsedown->text($markdown); + $this->parsedown->setSafeMode(true); + + $contentArray = $this->parsedown->text($markdown); + + $this->parsedown->setSafeMode(false); + + return $contentArray; } public function getContentHtml($contentArray) { - return $this->parsedown->markup($contentArray); + $this->parsedown->setSafeMode(true); + + $markdown = $this->parsedown->markup($contentArray); + + $this->parsedown->setSafeMode(false); + + return $markdown; } public function arrayBlocksToMarkdown($arrayBlocks) diff --git a/system/typemill/Models/Extension.php b/system/typemill/Models/Extension.php index c07fc04..bbec91e 100644 --- a/system/typemill/Models/Extension.php +++ b/system/typemill/Models/Extension.php @@ -3,6 +3,7 @@ namespace Typemill\Models; use Typemill\Models\StorageWrapper; +use Typemill\Static\Translations; class Extension { @@ -65,9 +66,9 @@ class Extension # add standard-textarea for custom css $themeSettings['forms']['fields']['customcss'] = [ 'type' => 'codearea', - 'label' => 'Custom CSS', + 'label' => Translations::translate('Custom CSS'), 'class' => 'codearea', - 'description' => 'You can overwrite the theme-css with your own css here.' + 'description' => Translations::translate('You can overwrite the theme-css with your own css here.') ]; # add image preview file diff --git a/system/typemill/Models/License.php b/system/typemill/Models/License.php index f662716..a6e1129 100644 --- a/system/typemill/Models/License.php +++ b/system/typemill/Models/License.php @@ -3,6 +3,7 @@ namespace Typemill\Models; use Typemill\Models\StorageWrapper; +use Typemill\Static\Translations; class License { @@ -87,14 +88,14 @@ class License if(!$licensedata) { - $this->message = 'no license found'; + $this->message = Translations::translate('no license found'); return false; } if(!isset($licensedata['license'],$licensedata['email'],$licensedata['domain'],$licensedata['plan'],$licensedata['payed_until'],$licensedata['signature'])) { - $this->message = 'License data incomplete'; + $this->message = Translations::translate('License data incomplete'); return false; } @@ -140,7 +141,7 @@ class License } else { - $this->message = 'There was an error checking the license signature'; + $this->message = Translations::translate('There was an error checking the license signature'); return false; } @@ -178,7 +179,7 @@ class License if(substr($http_response_header[0], -6) != "200 OK") { - $this->message = 'the license server responded with: ' . $http_response_header[0]; + $this->message = Translations::translate('the license server responded with: ') . $http_response_header[0]; return false; } diff --git a/system/typemill/Models/Media.php b/system/typemill/Models/Media.php index 8e00188..d9d6f1c 100644 --- a/system/typemill/Models/Media.php +++ b/system/typemill/Models/Media.php @@ -6,6 +6,7 @@ use Typemill\Models\Folder; use Typemill\Models\StorageWrapper; use Typemill\Models\SvgSanitizer; use Typemill\Static\Slug; +use Typemill\Static\Translations; class Media { @@ -74,7 +75,7 @@ class Media $pathinfo = pathinfo($name); if(!$pathinfo) { - $this->errors[] = 'Could not read pathinfo.'; + $this->errors[] = Translations::translate('Could not read pathinfo') . '.'; return false; } @@ -84,7 +85,7 @@ class Media if(!$this->extension OR !$this->filename) { - $this->errors[] = 'Extension or filename are missing.'; + $this->errors[] = Translations::translate('Extension or filename are missing') . '.'; return false; } @@ -98,7 +99,7 @@ class Media if(!isset($fileParts[0]) OR !isset($fileParts[1])) { - $this->errors[] = 'Could not decode image or file, probably not a base64 encoding.'; + $this->errors[] = Translations::translate('Could not decode image or file, probably not a base64 encoding') . '.'; return false; } @@ -200,7 +201,7 @@ class Media $loaded = $svg->loadSVG($this->filedata); if($loaded === false) { - $this->errors[] = 'We could not load the svg file, it is probably corrupted.'; + $this->errors[] = Translations::translate('We could not load the svg file, it is probably corrupted.'); return false; } @@ -208,7 +209,7 @@ class Media $sanitized = $svg->saveSVG(); if($sanitized === false) { - $this->errors[] = 'We could not create a sanitized version of the svg, it probably has invalid content.'; + $this->errors[] = Translations::translate('We could not create a sanitized version of the svg, it probably has invalid content.'); return false; } @@ -317,7 +318,7 @@ class Media { if(!isset($this->allowedExtensions[$this->extension])) { - $this->errors[] = 'Images with this extension are not allowed.'; + $this->errors[] = Translations::translate('Images with this extension are not allowed.'); return false; } @@ -329,7 +330,7 @@ class Media $loaded = $svg->loadSVG($this->filedata); if($loaded === false) { - $this->errors[] = 'We could not load the svg file, it is probably corrupted.'; + $this->errors[] = Translations::translate('We could not load the svg file, it is probably corrupted.'); return false; } @@ -337,7 +338,7 @@ class Media $sanitized = $svg->saveSVG(); if($sanitized === false) { - $this->errors[] = 'We could not create a sanitized version of the svg, it probably has invalid content.'; + $this->errors[] = Translations::translate('We could not create a sanitized version of the svg, it probably has invalid content.'); return false; } @@ -382,7 +383,7 @@ class Media $result = file_put_contents($path, $this->filedata); if($result === false) { - $this->errors[] = 'could not store the image in the temporary folder'; + $this->errors[] = Translations::translate('could not store the image in the temporary folder'); } } @@ -478,7 +479,7 @@ class Media { $failedImage = $this->tmpFolder . $destinationfolder . '+' . $this->filename . '.' . $extension; - $this->errors[] = "Could not store the resized version $failedImage"; + $this->errors[] = Translations::translate('Could not store the resized version') . ' ' . $failedImage; return false; } diff --git a/system/typemill/Models/Settings.php b/system/typemill/Models/Settings.php index 641ff40..1cb79ed 100644 --- a/system/typemill/Models/Settings.php +++ b/system/typemill/Models/Settings.php @@ -176,8 +176,25 @@ class Settings } public function getSettingsDefinitions() - { - return $this->storage->getYaml('systemSettings', '', 'system.yaml'); + { + $settingsDefinitions = $this->storage->getYaml('systemSettings', '', 'system.yaml'); + + if(!isset($settingsDefinitions['fieldsetsystem']['fields']['language'])) + { + die('languages in settings-definitions are missing'); + } + + # get languages dynamically from existing translation-files + $languages = Translations::getLanguages(); + $langs = []; + foreach($languages as $language) + { + $langs[$language] = $language; + } + + $settingsDefinitions['fieldsetsystem']['fields']['language']['options'] = $langs; + + return $settingsDefinitions; } public function createSettings() diff --git a/system/typemill/Models/Storage.php b/system/typemill/Models/Storage.php index 93d509d..9a70412 100644 --- a/system/typemill/Models/Storage.php +++ b/system/typemill/Models/Storage.php @@ -3,6 +3,7 @@ namespace Typemill\Models; use Typemill\Static\Helpers; +use Typemill\Static\Translations; class Storage { @@ -110,7 +111,7 @@ class Storage { # do not allow direct access to basepath files - $this->error = "Access to basepath is not allowed."; + $this->error = Translations::translate('Access to basepath is not allowed.'); return false; } @@ -118,7 +119,7 @@ class Storage return $path; } - $this->error = "We could not find a folderPath for $location"; + $this->error = Translations::translate('We could not find a folderPath for') . ' ' . $location; return false; } @@ -129,7 +130,7 @@ class Storage if(!is_dir($folderpath) OR !is_writable($folderpath)) { - $this->error = "The folder $folderpath does not exist or is not writable."; + $this->error = $folderpath . ' ' . Translations::translate('does not exist or is not writable') . '.'; return false; } @@ -148,7 +149,7 @@ class Storage if(!mkdir($folderpath, 0755, true)) { - $this->error = "Could not create folder $folderpath."; + $this->error = Translations::translate('Could not create folder') . ' ' . $folderpath; return false; } @@ -160,7 +161,7 @@ class Storage { if(!isset($this->isWritable[$location])) { - $this->error = "It is not allowed to write into $location"; + $this->error = Translations::translate('It is not allowed to write into') . ' ' . $location; return false; } @@ -174,12 +175,12 @@ class Storage return true; } - $this->error = "We found the folder but could not delete $filepath"; + $this->error = Translations::translate('We found the folder but could not delete') . ' ' . $filepath; return false; } - $this->error = "The path $filepath is not a folder."; + $this->error = $filepath . ' ' .Translations::translate('is not a folder') . '.'; return false; } @@ -195,7 +196,7 @@ class Storage return true; } - $this->error = "We found the folder but could not delete $filepath"; + $this->error = Translations::translate('We found the folder but could not delete it') . ' ' . $filepath; return false; } @@ -209,7 +210,7 @@ class Storage if(!is_dir($folderdir . $folderpath)) { - $this->error = "$folderpath is not a directory"; + $this->error = $folderpath . ' ' . Translations::translate('is not a directory'); return false; } @@ -227,7 +228,7 @@ class Storage { if(!unlink($fullfilepath)) { - $this->error = "Could not delete file $fullfilepath."; + $this->error = Translations::translate('Could not delete file') . ' ' . $fullfilepath; return false; } @@ -237,7 +238,7 @@ class Storage if(!rmdir($folderdir . $folderpath)) { - $this->error = "Could not delete folder $folderpath."; + $this->error = Translations::translate('Could not delete folder') . ' ' . $folderpath; return false; } @@ -251,7 +252,7 @@ class Storage if(!file_exists($filepath)) { - $this->error = "The file $filepath does not exist."; + $this->error = $filepath . ' ' . Translations::translate('does not exist'); return false; } @@ -285,7 +286,7 @@ class Storage if(!file_exists($filepath)) { - $this->error = "The file $filepath does not exist."; + $this->error = $filepath . ' ' . Translations::translate('does not exist'); return false; } @@ -297,7 +298,7 @@ class Storage { if(!isset($this->isWritable[$location])) { - $this->error = "It is not allowed to write into $location"; + $this->error = Translations::translate('It is not allowed to write into') . ' ' . $location; return false; } @@ -320,7 +321,7 @@ class Storage $openfile = @fopen($filepath, "w"); if(!$openfile) { - $this->error = "Could not open and read the file $filepath"; + $this->error = Translations::translate('Could not open and read the file') . ' ' . $filepath; return false; } @@ -334,7 +335,7 @@ class Storage $writefile = fwrite($openfile, $data); if(!$writefile) { - $this->error = "Could not write to the file $filepath"; + $this->error = Translations::translate('Could not write to the file') . ' ' . $filepath; return false; } @@ -348,7 +349,7 @@ class Storage { if(!isset($this->isWritable[$location])) { - $this->error = "It is not allowed to write into $location"; + $this->error = Translations::translate('It is not allowed to write into') . ' ' . $location; return false; } @@ -378,7 +379,7 @@ class Storage { if(!isset($this->isWritable[$location])) { - $this->error = "It is not allowed to write into $location"; + $this->error = Translations::translate('It is not allowed to write into') . ' ' . $location; return false; } @@ -392,12 +393,12 @@ class Storage return true; } - $this->error = "We found the file but could not delete $filepath"; + $this->error = Translations::translate('We found the file but could not delete') . ' ' . $filepath; return false; } - $this->error = "We did not find a file with that name"; + $this->error = Translations::translate('We did not find a file with that name'); # we do not want to stop delete operation just because a file was not there, so return a message and true. return true; @@ -471,7 +472,7 @@ class Storage { if(!isset($this->isWritable[$location])) { - $this->error = "It is not allowed to write into $location"; + $this->error = Translations::translate('It is not allowed to write into') . ' ' . $location; return false; } @@ -510,7 +511,7 @@ class Storage $pathinfo = pathinfo($name); if(!$pathinfo) { - $this->error = 'Could not read pathinfo.'; + $this->error = Translations::translate('Could not read pathinfo') . '.'; return false; } @@ -520,14 +521,14 @@ class Storage if(!$extension OR !$imagename) { - $this->error = "Extension or name for image is missing."; + $this->error = Translations::translate('Extension or name for image is missing') . '.'; return false; } $imagesInTmp = glob($this->tmpFolder . "*$imagename.*"); if(empty($imagesInTmp) OR !$imagesInTmp) { - $this->error = "We did not find the image in the tmp-folder or could not read it."; + $this->error = Translations::translate('We did not find the image in the tmp-folder or could not read it') . '.'; return false; } @@ -552,7 +553,7 @@ class Storage if(!$result) { - $this->error = "We could not store the original image"; + $this->error = Translations::translate('We could not store the original image') . '.'; } break; @@ -563,13 +564,13 @@ class Storage } if(!rename($imagepath, $this->liveFolder . $filename)) { - $this->error = "We could not store the live image to the live folder"; + $this->error = Translations::translate('We could not store the live image to the live folder'); } break; case 'thumbs': if(!rename($imagepath, $this->thumbsFolder . $filename)) { - $this->error = "We could not store the thumb to the thumb folder"; + $this->error = Translations::translate('We could not store the thumb to the thumb folder'); } break; } @@ -593,7 +594,7 @@ class Storage $pathinfo = pathinfo($imagepath); if(!$pathinfo) { - $this->error = 'Could not read pathinfo.'; + $this->error = Translations::translate('Could not read pathinfo'); return false; } @@ -711,7 +712,7 @@ class Storage if(!$storedImage) { - $this->errors[] = "Could not store the custom size of $imageName"; + $this->errors[] = Translations::translate('Could not store the custom size of') . ' ' . $imageName; return false; } @@ -726,12 +727,12 @@ class Storage if(!file_exists($this->liveFolder . $name) OR !unlink($this->liveFolder . $name)) { - $this->error .= "We could not delete the live image. "; + $this->error .= Translations::translate('We could not delete the live image.') . ' '; } if(!file_exists($this->thumbsFolder . $name) OR !unlink($this->thumbsFolder . $name)) { - $this->error .= "We could not delete the thumb image. "; + $this->error .= Translations::translate('We could not delete the thumb image.') . ' '; } # delete custom images (resized and grayscaled) array_map('unlink', glob("some/dir/*.txt")); @@ -742,7 +743,7 @@ class Storage # you could check if extension is the same here if(!unlink($image)) { - $this->error = "We could not delete the original image in $this->originalFolder $image. "; + $this->error = Translations::translate('We could not delete the original image in') . ' ' . $this->originalFolder; } } @@ -751,7 +752,7 @@ class Storage # you could check if extension is the same here if(!unlink($image)) { - $this->error .= "we could not delete a custom image (grayscale or resized). "; + $this->error .= Translations::translate('we could not delete a custom image (grayscale or resized).') . ' '; } } @@ -772,7 +773,7 @@ class Storage $pathinfo = pathinfo($name); if(!$pathinfo) { - $this->error = 'Could not read pathinfo.'; + $this->error = Translations::translate('Could not read pathinfo'); return false; } @@ -782,7 +783,7 @@ class Storage if(!file_exists($this->tmpFolder . $filename)) { - $this->error = "We did not find the file in the tmp-folder or could not read it."; + $this->error = Translations::translate('We did not find the file in the tmp-folder or could not read it') . '.'; return false; } diff --git a/system/typemill/Models/User.php b/system/typemill/Models/User.php index cdf1920..5b09f23 100644 --- a/system/typemill/Models/User.php +++ b/system/typemill/Models/User.php @@ -3,6 +3,7 @@ namespace Typemill\Models; use Typemill\Models\StorageWrapper; +use Typemill\Static\Translations; class User { @@ -26,7 +27,7 @@ class User if(!$this->user) { - $this->error = 'User not found'; + $this->error = Translations::translate('User not found'); return false; } @@ -43,7 +44,7 @@ class User if(!$this->user) { - $this->error = 'User not found.'; + $this->error = Translations::translate('User not found'); return false; } @@ -76,7 +77,7 @@ class User # check if users directory exists if(!is_dir($this->userDir)) { - $this->error = "Directory $this->userDir does not exist."; + $this->error = $this->userDir . Translations::translate('does not exist'); return false; } @@ -168,8 +169,8 @@ class User # only roles who can edit content need profile image and description if($acl->isAllowed($userrole, 'mycontent', 'create')) { - $newfield['image'] = ['label' => 'Profile-Image', 'type' => 'image']; - $newfield['description'] = ['label' => 'Author-Description (Markdown)', 'type' => 'textarea']; + $newfield['image'] = ['label' => Translations::translate('Profile-Image'), 'type' => 'image']; + $newfield['description'] = ['label' => Translations::translate('Author-Description (Markdown)'), 'type' => 'textarea']; $userfields = array_slice($userfields, 0, 1, true) + $newfield + array_slice($userfields, 1, NULL, true); # array_splice($fields,1,0,$newfield); @@ -188,10 +189,10 @@ class User $options[$role] = $role; } - $userfields['userrole'] = ['label' => 'Role', 'type' => 'select', 'options' => $options]; + $userfields['userrole'] = ['label' => Translations::translate('Role'), 'type' => 'select', 'options' => $options]; # can activate api access - $userfields['apiaccess'] = ['label' => 'API access', 'checkboxlabel' => 'Activate API access for this user. Use username and password for api calls.', 'type' => 'checkbox']; + $userfields['apiaccess'] = ['label' => Translations::translate('API access'), 'checkboxlabel' => Translations::translate('Activate API access for this user. Use username and password for api calls'), 'type' => 'checkbox']; } return $userfields; diff --git a/system/typemill/Models/Validation.php b/system/typemill/Models/Validation.php index 27953c0..15cec97 100644 --- a/system/typemill/Models/Validation.php +++ b/system/typemill/Models/Validation.php @@ -156,18 +156,32 @@ class Validation Validator::addRule('markdownSecure', function($field, $value, array $params, array $fields) { - /* strip out code blocks and blockquotes */ + # strip out code blocks $value = preg_replace('/`{4,}[\s\S]+?`{4,}/', '', $value); $value = preg_replace('/`{3,}[\s\S]+?`{3,}/', '', $value); $value = preg_replace('/`{2,}[\s\S]+?`{2,}/', '', $value); $value = preg_replace('/`{1,}[\s\S]+?`{1,}/', '', $value); - $value = preg_replace('/>[\s\S]+?[\n\r]/', '', $value); + + # check blockquotes + preg_match_all('/^ ?>[\s\S]+?[\n\r]/m', $value, $matches); + foreach($matches as $match) + { + $content = $match[0] ?? false; + if($content && (strip_tags($content) !== $content) ) + { + return false; + } + } + # strip out blockquotes + $value = preg_replace('/^ ?>[\s\S]+?[\n\r]/m', '', $value); + if ( $value == strip_tags($value) ) { return true; } - return false; + return false; + }, 'not secure. For code please use markdown `inline-code` or ````fenced code blocks````.'); Validator::addRule('checkLicense', function($field, $value, array $params, array $fields) @@ -532,7 +546,7 @@ class Validation $v->rule('markdownSecure', 'title'); $v->rule('markdownSecure', 'body'); } - + if($v->validate()) { return true; @@ -629,7 +643,7 @@ class Validation if($v->validate()) { return true; - } + } return $v->errors(); } diff --git a/system/typemill/Static/License.php b/system/typemill/Static/License.php index cf0d2bf..7676ce6 100644 --- a/system/typemill/Static/License.php +++ b/system/typemill/Static/License.php @@ -2,6 +2,7 @@ namespace Typemill\Static; use Typemill\Models\StorageWrapper; +use Typemill\Static\Translations; class License { @@ -24,12 +25,12 @@ class License if(!$licensedata) { - return ['result' => false, 'message' => 'no license found']; + return ['result' => false, 'message' => Translations::translate('no license found')]; } if(!isset($licensedata['license'],$licensedata['email'],$licensedata['domain'],$licensedata['plan'],$licensedata['payed_until'],$licensedata['signature'])) { - return ['result' => false, 'message' => 'License data not complete']; + return ['result' => false, 'message' => Translations::translate('License data not complete')]; } $licenseStatus = self::validateLicense($licensedata); @@ -38,7 +39,7 @@ class License if($licenseStatus === false) { - return ['result' => false, 'message' => 'License data are invalid']; + return ['result' => false, 'message' => Translations::translate('License data are invalid')]; } elseif($licenseStatus === true) { diff --git a/system/typemill/Static/Translations.php b/system/typemill/Static/Translations.php index f52f8ba..1c49d9d 100644 --- a/system/typemill/Static/Translations.php +++ b/system/typemill/Static/Translations.php @@ -77,13 +77,7 @@ class Translations public static function whichLanguage() { # Check which languages are available - $langs = []; - $path = __DIR__ . '/author/languages/*.yaml'; - - foreach (glob($path) as $filename) - { - $langs[] = basename($filename,'.yaml'); - } + $langs = self::getLanguages(); # Detect browser language $accept_lang = isset($_SERVER['HTTP_ACCEPT_LANGUAGE']) ? substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2) : false; @@ -92,6 +86,20 @@ class Translations return $lang; } + public static function getLanguages() + { + # Check which languages are available + $langs = []; + $path = __DIR__ . '/../author/translations/*.yaml'; + + foreach (glob($path) as $filename) + { + $langs[] = basename($filename,'.yaml'); + } + + return $langs; + } + # this just returns the string so you can use translate-function in system files. Everything that is wrapped in translate function will be added to translation files public static function translate(string $string) { diff --git a/system/typemill/author/auth/login.twig b/system/typemill/author/auth/login.twig index 170b6df..5f96aa4 100644 --- a/system/typemill/author/auth/login.twig +++ b/system/typemill/author/auth/login.twig @@ -76,8 +76,8 @@
-

Welcome back!

-

Login to the author area or go to the homepage

+

{{ translate('Welcome back') }}!

+

{{ translate('Login to the author area or go to the') }} {{ translate('homepage') }}

diff --git a/system/typemill/author/js/vue-plugins.js b/system/typemill/author/js/vue-plugins.js index 9f46876..f596fda 100644 --- a/system/typemill/author/js/vue-plugins.js +++ b/system/typemill/author/js/vue-plugins.js @@ -5,7 +5,7 @@ const app = Vue.createApp({
  • Please update to version {{ versions[pluginname].version }}

    -

    License: {{ plugin.license }}

    +

    {{ $filters.translate('License') }}: {{ plugin.license }}