diff --git a/cache/index.json b/cache/index.json new file mode 100644 index 0000000..e7650ad --- /dev/null +++ b/cache/index.json @@ -0,0 +1 @@ +{"http://localhost/typemill/welcome":{"title":"Welcome","content":" Great that you give Typemill a try!! Typemill is a simple Flat File Content Management System (CMS). We (the community) work hard to provide the best author experience with easy and intuitive authoring tools. But Typemill is still in early development and it is likely that not everything will work perfectly out of the box. If you miss something or if you have ideas for improvements, then post a new issue on GitHub.mb","url":"http://localhost/typemill/welcome"},"http://localhost/typemill/welcome/markdown-test":{"title":"Markdown Reference and Test Page","content":" Markdown is a simple and universal syntax for text formatting. More and more writers switch to markdown, because they can format their text during the writing process without using any format-buttons. Once they are familiar with the markdown syntax, they can write formatted text much easier and faster than with any standard HTML-editor. Developers love markdown, because it is much cleaner and saver than HTML. And they can easily convert markdown to a lot of other document formats like HTML and others. If you develop a theme for TYPEMILL, please take care that all elements on this page are designed properly. Table of Contents To create a table of contents, simply write ` in a separate line. It will be replaced with a table of contents like this automatically. Headlines Headlines are simply done with hash chars like this: First Level Headline Second Level Headline Third Level Headline Fourth Level Headline Fifth Level Headline Sixth Level Headline Third Level Headline A third headline is more decent and lower prioritized than a second level headline. Fourth Level Headline A fourth level headline is more decent and lower prioritized than a third level headline. Fifth Level Headline A fifth level headline is more decent and lower prioritized than a fourth level headline. Sixth Level Headline A sixth level headline is more decent and lower prioritized than a fifths level headline. Paragraph A paragraph is a simple text-block separated with a new line above and below. A paragraph is a simple text-block separated with a new line above and below. Soft Linebreak For a soft linebreak (eg. for dialoges in literature), add two spaces at the end of a line and use a simple return. She said: \"Hello\" He said: \"again\" For a soft linebreak (eg. for dialoges in literature), add two spaces at the end of a line and use a simple return. She said: \"Hello\" He said: \"again\" Emphasis For italic text use one asterix or one underscore. For bold text use two asterix or two underscores. For italic text use one asterix or one underscore. For bold text use two asterix or two underscores. Lists For an unordered list use a dash - like - this Or use one asterix * like * this For an ordered list use whatever number you want and add a dot: 1. like 1. this For an unordered list use a dash * like * this Or use one asterix * like * this For an ordered list use whatever number you want and add a dot: 1. like 2. this Horizontal Rule Easily created for example with three dashes like this: --- Easily created for example with three dashes like this: --- This is an ordinary Link. Links can also be relative. You can link to anchors like this anchor You can also add a title. You can even add ids or classes. Or you can use a shortcut like http://typemill.net. You can even use a download-link like This is an ordinary Link. Links can also be relative. You can link to anchors like this anchor You can also add a title. You can even add ids or classes. Or you can use a shortcut like http://typemill.net. highlight (ZIP, 2.71 MB) Images The same rules as with links, but with a ! With caption With caption that spans over several lines The same rules as with links, but with a ! With a caption that spans over two lines. Linked Images You can link an image with a nested syntax like this: You can link an image with a nested syntax like this: Image Position You can controll the image position with the classes .left, .right and .middle like this: With caption that spans over several lines With caption that spans over several lines With caption that spans over several lines The first image should float on the left side of this paragraph. This might not work with all themes. If you are a theme developer, please ensure that you support the image classes \"left\", \"right\" and \"center\". You can add these classes manually in the raw mode or you can assign them in the visual mode when you edit a picture (double click on it to open the dialog). Images in a separate line are rendered with the html5 elements figure and figcapture. With caption that spans over several lines The second image should float on the right side of this paragraph. This might not work with all themes. If you are a theme developer, please ensure that you support the image classes \"left\", \"right\" and \"center\". You can add these classes manually in the raw mode or you can assign them in the visual mode when you edit a picture (double click on it to open the dialog). Images in a separate line are rendered with the html5 elements figure and figcapture. With caption that spans over several lines The thirds image should be placed above this paragraph and centered to the middle of the content area. This might not work with all themes. If you are a theme developer, please ensure that you support the image classes \"left\", \"right\" and \"center\". You can add these classes manually in the raw mode or you can assign them in the visual mode when you edit a picture (double click on it to open the dialog). Images in a separate line are rendered with the html5 elements figure and figcapture. Blockquote There are always some women and men with wise wordsBut I usually don't read them, to be honest. There always some women and men with wise wordsBut I usually don't read them, to be honest. Footnotes ` You can write footnotes with markdown. Scroll down to the end of the page and look for the footnotes. Add the footnote text at the bottom of the page like this: ","url":"http://localhost/typemill/welcome/markdown-test"},"http://localhost/typemill/welcome/manage-access":{"title":"Manage Access","content":" Typemill has a build-in system to restrict access to pages or to the whole websites. You can activate both features in the system settings under the section \"access rights\". If you activate one of the features, then Typemill will use session cookies on all frontend pages. Learn all the details in the following video tutorial: Restrict Access for the Website This feature is perfect, if you want to lock down the whole website and only grant access for authenticated users. All non-authenticated users will be redirected to the login-page. There are two main use cases for this feature: * Launch the website later: You want to create your website first and launch it to the public later, for example if you have finished the website design or if you have polished your content. * Share website internally: You want to share your typemill website only with certain users, for example with the company stuff or only with the members of your it-unit. You can activate the feature with a simple checkbox under \"Website Restrictions\". Restrict Access for Pages If you need a more fine-tuned access and if you want to restrict access only for certain pages, then you can activate the feature \"Page Restrictions\". If you activate this checkbox, then you will find two new input fields in the meta-tab of each page: * Minimum role for access: Here you can select a miminum role that the user needs to view the page content. Be aware that the roles have a hierarchy, so if you choose the role \"author\", then the \"editor\" will also have access. * Usernames: Here you can add one or more usernames (separated with comma) that have access to this page. If you don't choose anything of it, then the page has no restrictions and everybody can see the content. You have some more features in the settings area: * Cut content: Per default only the title of a restricted page is visible to the public, the content is hidden. You can change this and cut the content wherever you want with a horizontal line. * Teaser: You can add a standard text with markdown that will be displayed instead of the content or after the content is cut. * Teaser-Box: You can optionally wrap the teaser in a box. You can also combine these features with the registration plugin and this way create a membership website with member-only content.","url":"http://localhost/typemill/welcome/manage-access"},"http://localhost/typemill/welcome/get-help":{"title":"Get Help","content":" If you need any help, then please read the documentation on typemill.net first. You can also check these video-tutorials about the basics to create a typemill website. If you found a bug or if you have a question, then please open a new issue on GitHub. Do you need professional help, an individual theme or a special plugin? You can hire us at Trendschau Digital. recording 2023 05 11 at 235818 (GIF, 1.30 MB) Contributions, donations and feedback for this open source project are always welcome. ","url":"http://localhost/typemill/welcome/get-help"},"http://localhost/typemill/welcome/setup-your-website":{"title":"Setup Your Website","content":" Typemill provides detailed settings, and you have access to nearly all settings in the author panel. Learn the basics in this short video: You will find all configurations and settings under the main navigation point settings with the following sub-navigation: * System settings * Theme settings * Plugin settings * User settings All settings are stored in the \\settings folder of Typemill. It is not recommended to edit the settings manually, because it might crash the system if done wrong. Developer Settings As of version 1.4.0 you will find some advanced developer settings in the author panel under settings. See the details below. ! Only for devs ! ! These options are for developers only. Make sure that you fully understand what happens. For example, you should never activate the error reporting on live systems because this is a security risk. * Error Reporting: You can switch the error reporting of the slim-framework on and off here. This can be helpful for bug-analysis, but you should NEVER switch it on (or keep it active) on a productive system. * Twig cache: You can activate the cache for the twig templates. This will speed up the page rendering a bit, but it can also produce a headace if you changed something in your theme. The best option is to clear the cache if something does not work. * Clear cache: This will clear the cache for Twig templates and delete all cache files of Typemill. If you clear the cache, then some details might not work or look strange, for example the navigation is set back to the original state. Everything will work again when the cache has been rebuild. This happens every 10 minutes. If you want to spead up the process, then refresh your browser cache with F12 on windows machines, because it will also trigger the recreation of the Typemill cache. * Image sizes: All images in the content area will be resized to 820px width. If you want to change it, then add another value in the width-field. If you additionally add a height for your images, then the images will be resized first and then cropped to the correct aspect ratio. * Proxy: If you run Typemill behind a proxy (which is a common usecase in companies), then you can activate the proxy detection. This will read the X-Forwarded-Proto, X-Forwarded-Host and X-Forwarded-Port Headers and return the html with the correct urls. Optionally you can also add a comma separated list of trusted IP-addresses.","url":"http://localhost/typemill/welcome/setup-your-website"},"http://localhost/typemill/welcome/write-content":{"title":"Write Content","content":" Typemill provides easy and intuitive authoring tools and we work hard to create a good author experience. With the interactive navigation you can create pages and structure your websites. The visual markdown editor will help you to create content in a wysiwyg mode. The publish bar gives you full control over the status of each page. Watch the following video tutorial to learn all the details. The Navigation You can create, structure and reorder all pages with the navigation on the left side. To structure your content, you can create new folders and files with the \"add item\" button. To reorder the pages, just drag an item and drop it wherever you want. Play around with it and you will notice, that it works pretty similar to the folder- and file-system of your laptop. And in fact, this is exactly what Typemill does in the background: It stores your content in files and folders on the server. However, there are some limitations when you try to reorder elements. For example, you cannot move a complete folder to another folder, because this would change all the urls of the pages inside that folder, which is a nightmare for readers and search engines. The Editor You can create and format your content with the Markdown syntax, that is similar to the markup syntax of Wikipedia. If you are not familiar with Markdown, then please read the short Markdown-tutorial in the documentation of Typemill. You can learn Markdown in less than 10 minutes and there is no easier and faster way to format your webpage. You will love it! Typemill provides two edit modes: The raw mode and the visual mode. You can switch between the modes in the publish-bar at the bottom of each page. The raw mode is the most robust way to create your content, because you write raw markdown into a simple textarea. The visual mode uses blocks and transforms each content block into a html-preview immediately. This means that you can directly see and check the formatted result. By default Typemill will use the visual mode. * You can change the default mode in the system settings. * You can also switch each format button on and off in the system settings. The Publish Bar The publish bar of Typemill is pretty intuitiv and sticks at the bottom of the screen so that you have always full control of the status of each page. Simply play around with it and you will quickly understand how it works. In short: * The green button \"online\" indicates, that your page is published and visible for your readers. * You can depublish a page by clicking the green \"online\" button. The button will turn gray with the label \"offline\" and the page is not visible for your readers anymore. * With the green button \"Publish\" you can either publish a page that is offline or you can publish some unpublished changes on your page. * The publish-button is gray and disabled, if the page is online and if there are no unpublished changes. * All buttons will change in real time, so you can always exactly see what is going on. * To provide an easy status-overview of the whole website, Typemill marks all pages in the navigation on the left side as published (green), changed (orange) and unpublished (red). Working with Drafts Ever tried to revise a published article in WordPress? Yes, it works, but if you click on \"save\", then all your changes are directly live. Typemill is much more flexible here and allows you to keep your original version live while you work on a drafted version in the background. This is how Typemill handles it: * In visual mode: Typemill stores your changes in a new draft automatically as soon as you save any content-block. * In raw mode: To store changes in a new draft, simply click on the \"save draft\"-button in the publish controller. * You can work on a draft as long as you want without changing the live version. Your changes go live if you click the button \"publish\". * In visual mode, you can also use the discard-button and go back to the published version.","url":"http://localhost/typemill/welcome/write-content"},"http://localhost/typemill/welcome/todos":{"title":"ToDos Version 2","content":" Visual Editor * FIXED: File is not published from tmp to media/files if you save the block. Raw Editor * DONE ready Medialib * DONE Posts * Setup Plugins * Asset Class Frontend * DONE * DONE: Test restrictions ToDos Biig blocks: * DONE: Media Library * DONE: Posts * DONE: Setup * DONE: Recover Password Small features: * DONE: Merge processAssets modell * DONE: Table of content duplicated for published pages * DONE: Session handling: csrf fail and session start error if restrictions are active * DONE: Image and files for meta * Backend fields * Proxy * Editor: Warn if open another block * Image generation on the fly * Assets * Bug: Navigation frontend if unpublished pages * Sitemap and ping * Captcha * Clear Cache * Security Log Cleanups: * Events * Error messages * Translations Select userroles * Userroles for file restriction: in vue-blox-components loaded via api * Userroles for userfields: in php model user getUserFields() * Userroles for meta: in php controller apiAuthorMeta getMeta() * Plugins and themes: in php model extension getThemeDefinitions() License Check * On activation in apiControllerExtension. It checks the license in yaml. * In plugin php code with setPremiumLicense * In static plugins, it checks manual premium list and method setPremiumLicense and more","url":"http://localhost/typemill/welcome/todos"},"http://localhost/typemill/cyanine-theme":{"title":"The Cyanine Theme","content":" Cyanine is the modern, lightweight and flexible standard theme for Typemill. You can activate a landingpage, setup different content sections for the landingpage and order them like you want. You can also change the colors, fonts and other details. To configure the theme, login to the system (/tm/login), go to the theme settings (/tm/themes) and choose the theme \"Cyanine\". If Cyanine does not fit to your needs, then you can also choose another theme in the theme store of Typemill.","url":"http://localhost/typemill/cyanine-theme"},"http://localhost/typemill/cyanine-theme/new":{"title":"ToDo","content":" Visual Editor Das ist ein Intro. Es gibt noch viel zu tun, aber das ist am Ende des Tages nicht so schlimm denn wir machen einfach weiter. * DONE: Fix toc component in new block * DONE: Fix hr component in new block * DONE: finish shortcode component * DONE: Fix inline formats * DONE: fix lenght of page * DONE: Fix design of new block at the end (background color) * DONE: Move Block * DONE: Fix headline design * DONE: Fix save on two enter * DONE: fix quote design * DONE: Fix toc preview * DONE: disable enable * DONE: Add load sign (from navigation) * SHIT!!! fiinish youtube component Navigation * DONE: fix status in navigation * fix error messages * DONE: refresh navigation after changes Publish Controller * DONE: Create * DONE: publish * DONE: unpublish * DONE: discard * DONE: delete * DONE: save draft * DONE: switch to raw Raw Editor * DONE: Meta Tabs * Setup Medialib * Setup","url":"http://localhost/typemill/cyanine-theme/new"},"http://localhost/typemill/cyanine-theme/landingpage":{"title":"The Landingpage","content":" Cyanine provides an optional landingpage with six segments: * Intro with the content of the home page and an additional link/button. * Info with individual markdown content. * Teaser with two elements. Each element has a headline, a text and a link/button. * Contrast with a headline, text-input and a link/button. The colors are inverted. * Navigation with the whole content of the website. You can change the depth of the navigation. * News with a link to a news-folder. It will display the three latest news in a card-design. Add a hero-image to each news-entry to show a teaser image. You can activate or deactivate the whole landingpage, order all elements and enable/disable each element individually.","url":"http://localhost/typemill/cyanine-theme/landingpage"},"http://localhost/typemill/cyanine-theme/content-elements":{"title":"Content Elements ","content":" Cyanine provides a lot of other settings for your content area. For example: * Add an edit-button for github, gitlab or other plattforms. * Show the author. * Show the publish date. * Show the chapter numbers in the navigation. The Cyanine theme supports all content elements like tables, images, notices or downloads. It also supports anchor-links next to headlines, so you can deep link to certain content sections of your page. You can activate the anchors in the system settings of Typemill.","url":"http://localhost/typemill/cyanine-theme/content-elements"},"http://localhost/typemill/cyanine-theme/colors-and-fonts":{"title":"Colors and Fonts","content":" First of all cyanine supports individual logos. If you want to use our logo, then please upload it in the system settings. Cyanine will automatically replace the title text with your logo. You can also upload your own favicon in the system settings. Cyanine allows you to change many colors. Please make sure that your color-combinations are readable and accessible. The following colors are editable: * Primary Theme Color: used for the body background and borders. * Secondary Theme Color: used for content background, font-colors on hover and more. * Primary Font Color: used for main text. * Secondary Font Color: used as contrast color for hovers in navigation and buttons. * Link Color: used for text-links. Keep accessibility in mind. * Thin Border Color: used for thin borders in navigations and tables. You can also change the font-family for * headlines * text * buttons and navigations Cyanine uses wide spread system fonts with fallbacks: * serif * sans-serif * courier * helvetica * avenir * athelas * georgia * times * bodoni * calisto * garamond * baskerville If the color- and font-settings are not enough for your purpose, then you can always overwrite the theme-css with your own styles in the theme settings.","url":"http://localhost/typemill/cyanine-theme/colors-and-fonts"},"http://localhost/typemill/cyanine-theme/footer":{"title":"3-Column Footer","content":" Cyanine provides a three column footer at the bottom of each page. You can use markdown for each column. Make sure that you use the correct headline-level (we suggest a headline level 3 or level 4 to keep the logical headline hierarchy in the document). You can, of course, also add link-lists or other elements. Check the website of Typemill for an example.","url":"http://localhost/typemill/cyanine-theme/footer"}} \ No newline at end of file diff --git a/content/00-welcome/05-todos.md b/content/00-welcome/05-todos.md index 318210d..927448e 100644 --- a/content/00-welcome/05-todos.md +++ b/content/00-welcome/05-todos.md @@ -39,19 +39,19 @@ Biig blocks: Small features: * DONE: Merge processAssets modell +* DONE: Table of content duplicated for published pages +* DONE: Session handling: csrf fail and session start error if restrictions are active +* DONE: Image and files for meta +* Backend fields +* Proxy +* Editor: Warn if open another block +* Image generation on the fly +* Assets +* Bug: Navigation frontend if unpublished pages * Sitemap and ping * Captcha * Clear Cache * Security Log -* Backend fields -* Proxy -* DONE: Session handling: csrf fail and session start error if restrictions are active -* Editor: Warn if open another block -* Image generation on the fly -* Assets -* Bug: Table of content duplicated for published pages -* Bug: Navigation frontend if unpublished pages -* Image and files for meta Cleanups: diff --git a/content/00-welcome/05-todos.txt b/content/00-welcome/05-todos.txt new file mode 100644 index 0000000..65129d4 --- /dev/null +++ b/content/00-welcome/05-todos.txt @@ -0,0 +1 @@ +["# ToDos Version 2","[TOC]","## Visual Editor","* FIXED: File is not published from tmp to media\/files if you save the block.","## Raw Editor","* DONE ready","## Medialib","* DONE","## Posts","* Setup","## Plugins","* Asset Class","## Frontend","* DONE\n* DONE: Test restrictions","## ToDos","Biig blocks:","* DONE: Media Library\n* DONE: Posts\n* DONE: Setup\n* DONE: Recover Password","Small features:","* DONE: Merge processAssets modell\n* DONE: Table of content duplicated for published pages\n* DONE: Session handling: csrf fail and session start error if restrictions are active\n* DONE: Image and files for meta\n* Backend fields\n* Proxy\n* Editor: Warn if open another block\n* Image generation on the fly\n* Assets\n* Bug: Navigation frontend if unpublished pages\n* Sitemap and ping\n* Captcha\n* Clear Cache\n* Security Log\n* Customfields not styled yet.","Cleanups:","* Events\n* Error messages\n* Translations","## Select userroles","* Userroles for file restriction: in vue-blox-components loaded via api\n* Userroles for userfields: in php model user getUserFields()\n* Userroles for meta: in php controller apiAuthorMeta getMeta()\n* Plugins and themes: in php model extension getThemeDefinitions()","## License Check","* On activation in apiControllerExtension. It checks the license in yaml.\n* In plugin php code with setPremiumLicense\n* In static plugins, it checks manual premium list and method setPremiumLicense and more "] \ No newline at end of file diff --git a/data/navigation/navi-draft.txt b/data/navigation/navi-draft.txt index 834136d..75c26a8 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:19:"00-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:"00";s:4:"name";s:13:"markdown test";s:4:"slug";s:13:"markdown-test";s:4:"path";s:31:"/00-welcome/00-markdown-test.md";s:15:"pathWithoutType";s:28:"/00-welcome/00-markdown-test";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: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: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:14:"02-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:"02";s:4:"name";s:8:"get help";s:4:"slug";s:8:"get-help";s:4:"path";s:26:"/00-welcome/02-get-help.md";s:15:"pathWithoutType";s:23:"/00-welcome/02-get-help";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: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:3;O:8:"stdClass":20:{s:12:"originalName";s:24:"03-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:"03";s:4:"name";s:18:"setup your website";s:4:"slug";s:18:"setup-your-website";s:4:"path";s:36:"/00-welcome/03-setup-your-website.md";s:15:"pathWithoutType";s:33:"/00-welcome/03-setup-your-website";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: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:4;O:8:"stdClass":20:{s:12:"originalName";s:19:"04-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:"04";s:4:"name";s:13:"write content";s:4:"slug";s:13:"write-content";s:4:"path";s:31:"/00-welcome/04-write-content.md";s:15:"pathWithoutType";s:28:"/00-welcome/04-write-content";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/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: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:5:{i:0;O:8:"stdClass":20:{s:12:"originalName";s:9:"00-new.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:3:"new";s:4:"slug";s:3:"new";s:4:"path";s:27:"/01-cyanine-theme/00-new.md";s:15:"pathWithoutType";s:24:"/01-cyanine-theme/00-new";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:18:"/cyanine-theme/new";s:6:"urlRel";s:27:"/typemill/cyanine-theme/new";s:6:"urlAbs";s:43:"http://localhost/typemill/cyanine-theme/new";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:17:"01-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:"01";s:4:"name";s:11:"landingpage";s:4:"slug";s:11:"landingpage";s:4:"path";s:35:"/01-cyanine-theme/01-landingpage.md";s:15:"pathWithoutType";s:32:"/01-cyanine-theme/01-landingpage";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: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:2;O:8:"stdClass":20:{s:12:"originalName";s:22:"02-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:"02";s:4:"name";s:16:"content elements";s:4:"slug";s:16:"content-elements";s:4:"path";s:40:"/01-cyanine-theme/02-content-elements.md";s:15:"pathWithoutType";s:37:"/01-cyanine-theme/02-content-elements";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: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;}i:3;O:8:"stdClass":20:{s:12:"originalName";s:22:"03-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:"03";s:4:"name";s:16:"colors and fonts";s:4:"slug";s:16:"colors-and-fonts";s:4:"path";s:40:"/01-cyanine-theme/03-colors-and-fonts.md";s:15:"pathWithoutType";s:37:"/01-cyanine-theme/03-colors-and-fonts";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/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:4;O:8:"stdClass":20:{s:12:"originalName";s:12:"04-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:"04";s:4:"name";s:6:"footer";s:4:"slug";s:6:"footer";s:4:"path";s:30:"/01-cyanine-theme/04-footer.md";s:15:"pathWithoutType";s:27:"/01-cyanine-theme/04-footer";s:3:"key";i:4;s:7:"keyPath";s:3:"1.4";s:12:"keyPathArray";a:2:{i:0;s:1:"1";i:1;s:1:"4";}s:7:"chapter";s:3:"2.5";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;}}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:19:"00-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:"00";s:4:"name";s:13:"markdown test";s:4:"slug";s:13:"markdown-test";s:4:"path";s:31:"/00-welcome/00-markdown-test.md";s:15:"pathWithoutType";s:28:"/00-welcome/00-markdown-test";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: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: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:14:"02-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:"02";s:4:"name";s:8:"get help";s:4:"slug";s:8:"get-help";s:4:"path";s:26:"/00-welcome/02-get-help.md";s:15:"pathWithoutType";s:23:"/00-welcome/02-get-help";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: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:3;O:8:"stdClass":20:{s:12:"originalName";s:24:"03-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:"03";s:4:"name";s:18:"setup your website";s:4:"slug";s:18:"setup-your-website";s:4:"path";s:36:"/00-welcome/03-setup-your-website.md";s:15:"pathWithoutType";s:33:"/00-welcome/03-setup-your-website";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: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:4;O:8:"stdClass":20:{s:12:"originalName";s:19:"04-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:"04";s:4:"name";s:13:"write content";s:4:"slug";s:13:"write-content";s:4:"path";s:31:"/00-welcome/04-write-content.md";s:15:"pathWithoutType";s:28:"/00-welcome/04-write-content";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/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:0;s:7:"noindex";b:0;}i:5;O:8:"stdClass":20:{s:12:"originalName";s:14:"05-todos.txtmd";s:11:"elementType";s:4:"file";s:6:"status";s:8:"modified";s:8:"fileType";s:3:"txt";s:5:"order";s:2:"05";s:4:"name";s:6:"To Dos";s:4:"slug";s:5:"todos";s:4:"path";s:26:"/00-welcome/05-todos.txtmd";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:5:{i:0;O:8:"stdClass":20:{s:12:"originalName";s:9:"00-new.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:3:"new";s:4:"slug";s:3:"new";s:4:"path";s:27:"/01-cyanine-theme/00-new.md";s:15:"pathWithoutType";s:24:"/01-cyanine-theme/00-new";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:18:"/cyanine-theme/new";s:6:"urlRel";s:27:"/typemill/cyanine-theme/new";s:6:"urlAbs";s:43:"http://localhost/typemill/cyanine-theme/new";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:17:"01-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:"01";s:4:"name";s:11:"landingpage";s:4:"slug";s:11:"landingpage";s:4:"path";s:35:"/01-cyanine-theme/01-landingpage.md";s:15:"pathWithoutType";s:32:"/01-cyanine-theme/01-landingpage";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: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:2;O:8:"stdClass":20:{s:12:"originalName";s:22:"02-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:"02";s:4:"name";s:16:"content elements";s:4:"slug";s:16:"content-elements";s:4:"path";s:40:"/01-cyanine-theme/02-content-elements.md";s:15:"pathWithoutType";s:37:"/01-cyanine-theme/02-content-elements";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: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;}i:3;O:8:"stdClass":20:{s:12:"originalName";s:22:"03-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:"03";s:4:"name";s:16:"colors and fonts";s:4:"slug";s:16:"colors-and-fonts";s:4:"path";s:40:"/01-cyanine-theme/03-colors-and-fonts.md";s:15:"pathWithoutType";s:37:"/01-cyanine-theme/03-colors-and-fonts";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/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:4;O:8:"stdClass":20:{s:12:"originalName";s:12:"04-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:"04";s:4:"name";s:6:"footer";s:4:"slug";s:6:"footer";s:4:"path";s:30:"/01-cyanine-theme/04-footer.md";s:15:"pathWithoutType";s:27:"/01-cyanine-theme/04-footer";s:3:"key";i:4;s:7:"keyPath";s:3:"1.4";s:12:"keyPathArray";a:2:{i:0;s:1:"1";i:1;s:1:"4";}s:7:"chapter";s:3:"2.5";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;}}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 359ca64..85722fa 100644 --- a/data/navigation/navi-extended.txt +++ b/data/navigation/navi-extended.txt @@ -38,7 +38,7 @@ navtitle: 'To Dos' hide: false noindex: false - path: /00-welcome/05-todos.md + path: /00-welcome/05-todos.txtmd keyPath: '0.5' /cyanine-theme: navtitle: 'cyanine theme' diff --git a/system/typemill/Assets.php b/system/typemill/Assets.php index ed4b0d1..5cd2338 100644 --- a/system/typemill/Assets.php +++ b/system/typemill/Assets.php @@ -192,7 +192,7 @@ class Assets { $this->JS[] = $axiosUrl; - $axios = ''; + $axios = ''; $this->JS[] = $axios; } } diff --git a/system/typemill/Controllers/Controller.php b/system/typemill/Controllers/Controller.php index b177230..1e2bd91 100644 --- a/system/typemill/Controllers/Controller.php +++ b/system/typemill/Controllers/Controller.php @@ -7,13 +7,6 @@ use Slim\Routing\RouteContext; use Typemill\Models\StorageWrapper; use Typemill\Events\OnTwigLoaded; -# use Psr\Container\ContainerInterface; -# use Typemill\Models\Folder; -# use Typemill\Models\WriteCache; -# use Typemill\Models\WriteYaml; -# use Typemill\Events\OnPageReady; -# use Typemill\Events\OnPagetreeLoaded; - abstract class Controller { # holds the container @@ -114,7 +107,7 @@ abstract class Controller # always add null as first option in selectboxes. $options = [null => null]; - if(is_array($field['options'])) + if(isset($field['options']) && is_array($field['options'])) { $options = array_merge($options, $field['options']); } diff --git a/system/typemill/Controllers/ControllerApiFile.php b/system/typemill/Controllers/ControllerApiFile.php index 63f43ea..ee4e09e 100644 --- a/system/typemill/Controllers/ControllerApiFile.php +++ b/system/typemill/Controllers/ControllerApiFile.php @@ -4,7 +4,7 @@ namespace Typemill\Controllers; use Psr\Http\Message\ServerRequestInterface as Request; use Psr\Http\Message\ResponseInterface as Response; -use Typemill\Models\ProcessAssets; +use Typemill\Models\Media; use Typemill\Models\StorageWrapper; class ControllerApiFile extends Controller @@ -204,7 +204,7 @@ class ControllerApiFile extends Controller } } - $fileProcessor = new ProcessAssets(); + $media = new Media(); $fileinfo = $fileProcessor->storeFile($params['file'], $params['name']); $filePath = str_replace('media/files', 'media/tmp', $fileinfo['url']); @@ -221,7 +221,7 @@ class ControllerApiFile extends Controller if(!$mtype OR !$this->checkAllowedMimeTypes($mtype, $extension)) { - $fileProcessor->clearTempFolder(); + $media->clearTempFolder(); $response->getBody()->write(json_encode([ 'message' => 'The mime-type is missing, not allowed or does not fit to the file extension.' @@ -231,14 +231,6 @@ class ControllerApiFile extends Controller } } - /* - # publish file directly, used for example by file field for meta-tabs - if(isset($params['publish']) && $params['publish']) - { - $fileProcessor->publishFile(); - } - */ - $response->getBody()->write(json_encode([ 'message' => 'File has been stored', 'fileinfo' => $fileinfo, diff --git a/system/typemill/Controllers/ControllerApiImage.php b/system/typemill/Controllers/ControllerApiImage.php index 695a79d..18a799e 100644 --- a/system/typemill/Controllers/ControllerApiImage.php +++ b/system/typemill/Controllers/ControllerApiImage.php @@ -4,7 +4,7 @@ namespace Typemill\Controllers; use Psr\Http\Message\ServerRequestInterface as Request; use Psr\Http\Message\ResponseInterface as Response; -use Typemill\Models\ProcessAssets; +use Typemill\Models\Media; use Typemill\Models\StorageWrapper; use Typemill\Extensions\ParsedownExtension; @@ -135,19 +135,19 @@ class ControllerApiImage extends Controller return $response->withHeader('Content-Type', 'application/json')->withStatus(400); } - $img = new ProcessAssets(); + $media = new Media(); if($this->settingActive('allowsvg')) { - $img->addAllowedExtension('svg'); + $media->addAllowedExtension('svg'); } # prepare the image - if(!$img->prepareImage($params['image'], $params['name'])) + if(!$media->prepareImage($params['image'], $params['name'])) { $response->getBody()->write(json_encode([ - 'message' => $img->errors[0], - 'fullerrors' => $img->errors, + 'message' => $media->errors[0], + 'fullerrors' => $media->errors, ])); return $response->withHeader('Content-Type', 'application/json')->withStatus(400); @@ -156,35 +156,35 @@ class ControllerApiImage extends Controller # check if image name already exisits in live folder and create an unique name (do not overwrite existing files) $storage = new StorageWrapper('\Typemill\Models\Storage'); $uniqueImageName = $storage->createUniqueImageName($img->getFilename(), $img->getExtension()); - $img->setFilename($uniqueImageName); + $media->setFilename($uniqueImageName); # store the original image - if(!$img->storeOriginalToTmp()) + if(!$media->storeOriginalToTmp()) { $response->getBody()->write(json_encode([ - 'message' => $img->errors[0], - 'fullerrors' => $img->errors, + 'message' => $media->errors[0], + 'fullerrors' => $media->errors, ])); return $response->withHeader('Content-Type', 'application/json')->withStatus(400); } # if image is not resizable (animated gif or svg) - if(!$img->isResizable()) + if(!$media->isResizable()) { - if($img->saveOriginalForAll()) + if($media->saveOriginalForAll()) { $response->getBody()->write(json_encode([ 'message' => 'Image saved successfully', - 'name' => 'media/live/' . $img->getFullName(), + 'name' => 'media/live/' . $media->getFullName(), ])); return $response->withHeader('Content-Type', 'application/json'); } $response->getBody()->write(json_encode([ - 'message' => $img->errors[0], - 'fullerrors' => $img->errors, + 'message' => $media->errors[0], + 'fullerrors' => $media->errors, ])); return $response->withHeader('Content-Type', 'application/json')->withStatus(400); @@ -193,36 +193,23 @@ class ControllerApiImage extends Controller # for all other image types, check if they should be transformed to webp if($this->settingActive('convertwebp')) { - $img->setExtension('webp'); + $media->setExtension('webp'); } - if(!$img->storeRenditionsToTmp($this->settings['images'])) + if(!$media->storeRenditionsToTmp($this->settings['images'])) { $response->getBody()->write(json_encode([ - 'message' => $img->errors[0], - 'fullerrors' => $img->errors, + 'message' => $media->errors[0], + 'fullerrors' => $media->errors, ])); return $response->withHeader('Content-Type', 'application/json')->withStatus(500); } -/* - if(isset($params['publish']) && $params['publish']) - { - if(!$img->publishImage($img->getFullName())) - { - $response->getBody()->write(json_encode([ - 'message' => $img->errors[0], - 'fullerrors' => $img->errors, - ])); - return $response->withHeader('Content-Type', 'application/json')->withStatus(500); - } - } -*/ $response->getBody()->write(json_encode([ 'message' => 'Image saved successfully', - 'name' => 'media/tmp/' . $img->getFullName(), + 'name' => 'media/tmp/' . $media->getFullName(), ])); return $response->withHeader('Content-Type', 'application/json'); @@ -317,14 +304,14 @@ class ControllerApiImage extends Controller $imageData64 = 'data:image/jpeg;base64,' . base64_encode($imageData); - $img = new ProcessAssets(); + $media = new Media(); # prepare the image - if(!$img->prepareImage($imageData64, $class . '-' . $videoID . '.jpg')) + if(!$media->prepareImage($imageData64, $class . '-' . $videoID . '.jpg')) { $response->getBody()->write(json_encode([ - 'message' => $img->errors[0], - 'fullerrors' => $img->errors, + 'message' => $media->errors[0], + 'fullerrors' => $media->errors, ])); return $response->withHeader('Content-Type', 'application/json')->withStatus(400); @@ -332,15 +319,15 @@ class ControllerApiImage extends Controller # check if image name already exisits in live folder and create an unique name (do not overwrite existing files) $storage = new StorageWrapper('\Typemill\Models\Storage'); - $uniqueImageName = $storage->createUniqueImageName($img->getFilename(), $img->getExtension()); - $img->setFilename($uniqueImageName); + $uniqueImageName = $storage->createUniqueImageName($media->getFilename(), $media->getExtension()); + $media->setFilename($uniqueImageName); # store the original image - if(!$img->storeOriginalToTmp()) + if(!$media->storeOriginalToTmp()) { $response->getBody()->write(json_encode([ - 'message' => $img->errors[0], - 'fullerrors' => $img->errors, + 'message' => $media->errors[0], + 'fullerrors' => $media->errors, ])); return $response->withHeader('Content-Type', 'application/json')->withStatus(400); @@ -349,25 +336,25 @@ class ControllerApiImage extends Controller # for all other image types, check if they should be transformed to webp if($this->settingActive('convertwebp')) { - $img->setExtension('webp'); + $media->setExtension('webp'); } # set to youtube size $sizes = $this->settings['images']; $sizes['live'] = ['width' => 560, 'height' => 315]; - if(!$img->storeRenditionsToTmp($sizes)) + if(!$media->storeRenditionsToTmp($sizes)) { $response->getBody()->write(json_encode([ - 'message' => $img->errors[0], - 'fullerrors' => $img->errors, + 'message' => $media->errors[0], + 'fullerrors' => $media->errors, ])); return $response->withHeader('Content-Type', 'application/json')->withStatus(500); } # now publish directly - $livePath = $storage->publishImage($img->getFullName()); + $livePath = $storage->publishImage($media->getFullName()); if($livePath) { diff --git a/system/typemill/Controllers/ControllerApiSystemExtensions.php b/system/typemill/Controllers/ControllerApiSystemExtensions.php index 1b557fc..bc51288 100644 --- a/system/typemill/Controllers/ControllerApiSystemExtensions.php +++ b/system/typemill/Controllers/ControllerApiSystemExtensions.php @@ -70,8 +70,8 @@ class ControllerApiSystemExtensions extends Controller $objectdata = []; if($params['type'] == 'plugins') { - $objectdata[$params['type']][$params['name']] = $this->settings[$params['type']][$params['name']]; - $objectdata[$params['type']][$params['name']]['active'] = $params['checked']; + $objectdata['plugins'][$params['name']] = $this->settings[$params['type']][$params['name']]; + $objectdata['plugins'][$params['name']]['active'] = $params['checked']; } elseif($params['type'] == 'themes') { diff --git a/system/typemill/Controllers/ControllerApiSystemPlugins.php b/system/typemill/Controllers/ControllerApiSystemPlugins.php index a9bd73d..86b7662 100644 --- a/system/typemill/Controllers/ControllerApiSystemPlugins.php +++ b/system/typemill/Controllers/ControllerApiSystemPlugins.php @@ -18,11 +18,12 @@ class ControllerApiSystemPlugins extends Controller $extension = new Extension(); $formdefinitions = $extension->getPluginDefinition($pluginname); + $formdefinitions = $this->addDatasets($formdefinitions['forms']['fields']); $plugindata = []; # validate input $validator = new Validation(); - $validatedOutput = $this->recursiveValidation($validator, $formdefinitions['forms']['fields'], $plugininput); + $validatedOutput = $this->recursiveValidation($validator, $formdefinitions, $plugininput); if(!empty($this->errors)) { $response->getBody()->write(json_encode([ diff --git a/system/typemill/Controllers/ControllerApiSystemThemes.php b/system/typemill/Controllers/ControllerApiSystemThemes.php index 646fefa..ea4e819 100644 --- a/system/typemill/Controllers/ControllerApiSystemThemes.php +++ b/system/typemill/Controllers/ControllerApiSystemThemes.php @@ -18,11 +18,12 @@ class ControllerApiSystemThemes extends Controller $extension = new Extension(); $formdefinitions = $extension->getThemeDefinition($themename); + $formdefinitions = $this->addDatasets($formdefinitions['forms']['fields']); $themedata = []; # validate input $validator = new Validation(); - $validatedOutput = $this->recursiveValidation($validator, $formdefinitions['forms']['fields'], $themeinput); + $validatedOutput = $this->recursiveValidation($validator, $formdefinitions, $themeinput); if(!empty($this->errors)) { $response->getBody()->write(json_encode([ diff --git a/system/typemill/Controllers/ControllerWebFrontend.php b/system/typemill/Controllers/ControllerWebFrontend.php index 06613d2..bb72454 100644 --- a/system/typemill/Controllers/ControllerWebFrontend.php +++ b/system/typemill/Controllers/ControllerWebFrontend.php @@ -17,6 +17,7 @@ use Typemill\Events\OnMarkdownLoaded; use Typemill\Events\OnContentArrayLoaded; use Typemill\Events\OnHtmlLoaded; use Typemill\Events\OnRestrictionsLoaded; +use Typemill\Events\OnPageReady; class ControllerWebFrontend extends Controller @@ -231,10 +232,7 @@ class ControllerWebFrontend extends Controller $assets->addMeta('twitter_card',''); } - - $route = empty($args) && isset($this->settings['themes'][$theme]['cover']) ? 'cover.twig' : 'index.twig'; - - return $this->c->get('view')->render($response, $route, [ + $pagedata = [ 'home' => false, 'navigation' => $liveNavigation, 'title' => $title, @@ -247,7 +245,15 @@ class ControllerWebFrontend extends Controller 'logo' => $logo, 'favicon' => $favicon, 'currentpage' => $currentpage - ]); + ]; + + $morepagedata = $this->c->get('dispatcher')->dispatch(new OnPageReady([]), 'onPageReady')->getData(); + + $pagedata = array_merge($pagedata, $morepagedata); + + $route = empty($args) && isset($this->settings['themes'][$theme]['cover']) ? 'cover.twig' : 'index.twig'; + + return $this->c->get('view')->render($response, $route, $pagedata); } diff --git a/system/typemill/Controllers/ControllerWebSystem.php b/system/typemill/Controllers/ControllerWebSystem.php index e97de6e..d38c46f 100644 --- a/system/typemill/Controllers/ControllerWebSystem.php +++ b/system/typemill/Controllers/ControllerWebSystem.php @@ -23,7 +23,8 @@ class ControllerWebSystem extends Controller $systemNavigation = $navigation->getSystemNavigation( $userrole = $request->getAttribute('c_userrole'), $acl = $this->c->get('acl'), - $urlinfo = $this->c->get('urlinfo') + $urlinfo = $this->c->get('urlinfo'), + $dispatcher = $this->c->get('dispatcher') ); $settingsModel = new Settings(); @@ -61,7 +62,8 @@ class ControllerWebSystem extends Controller $systemNavigation = $navigation->getSystemNavigation( $userrole = $request->getAttribute('c_userrole'), $acl = $this->c->get('acl'), - $urlinfo = $this->c->get('urlinfo') + $urlinfo = $this->c->get('urlinfo'), + $dispatcher = $this->c->get('dispatcher') ); $extension = new Extension(); @@ -112,7 +114,8 @@ class ControllerWebSystem extends Controller $systemNavigation = $navigation->getSystemNavigation( $userrole = $request->getAttribute('c_userrole'), $acl = $this->c->get('acl'), - $urlinfo = $this->c->get('urlinfo') + $urlinfo = $this->c->get('urlinfo'), + $dispatcher = $this->c->get('dispatcher'), ); $extension = new Extension(); @@ -162,7 +165,8 @@ class ControllerWebSystem extends Controller $systemNavigation = $navigation->getSystemNavigation( $userrole = $request->getAttribute('c_userrole'), $acl = $this->c->get('acl'), - $urlinfo = $this->c->get('urlinfo') + $urlinfo = $this->c->get('urlinfo'), + $dispatcher = $this->c->get('dispatcher'), ); $license = new License(); @@ -201,7 +205,8 @@ class ControllerWebSystem extends Controller $systemNavigation = $navigation->getSystemNavigation( $userrole = $request->getAttribute('c_userrole'), $acl = $this->c->get('acl'), - $urlinfo = $this->c->get('urlinfo') + $urlinfo = $this->c->get('urlinfo'), + $dispatcher = $this->c->get('dispatcher'), ); $username = $request->getAttribute('c_username'); @@ -238,7 +243,8 @@ class ControllerWebSystem extends Controller $systemNavigation = $navigation->getSystemNavigation( $userrole = $request->getAttribute('c_userrole'), $acl = $this->c->get('acl'), - $urlinfo = $this->c->get('urlinfo') + $urlinfo = $this->c->get('urlinfo'), + $dispatcher = $this->c->get('dispatcher'), ); $user = new User(); @@ -281,7 +287,8 @@ class ControllerWebSystem extends Controller $systemNavigation = $navigation->getSystemNavigation( $userrole = $request->getAttribute('c_userrole'), $acl = $this->c->get('acl'), - $urlinfo = $this->c->get('urlinfo') + $urlinfo = $this->c->get('urlinfo'), + $dispatcher = $this->c->get('dispatcher'), ); $user = new User(); @@ -322,7 +329,8 @@ class ControllerWebSystem extends Controller $systemNavigation = $navigation->getSystemNavigation( $userrole = $request->getAttribute('c_userrole'), $acl = $this->c->get('acl'), - $urlinfo = $this->c->get('urlinfo') + $urlinfo = $this->c->get('urlinfo'), + $dispatcher = $this->c->get('dispatcher'), ); return $this->c->get('view')->render($response, 'system/usernew.twig', [ diff --git a/system/typemill/Controllers/oldclasses.php b/system/typemill/Controllers/oldclasses.php deleted file mode 100644 index 58df960..0000000 --- a/system/typemill/Controllers/oldclasses.php +++ /dev/null @@ -1,593 +0,0 @@ -getScheme(); - $authority = $uri->getAuthority(); - $protocol = ($scheme ? $scheme . ':' : '') . ($authority ? '//' . $authority : ''); - - $this->basePath = $this->c->get('basePath'); - $this->currentPath = $uri->getPath(); - $this->fullBaseUrl = $protocol . $this->basePath; - $this->fullCurrentUrl = $protocol . $this->currentPath; - - $this->urlCollection = [ - 'basePath' => $this->basePath, - 'currentPath' => $this->currentPath, - 'fullBaseUrl' => $this->fullBaseUrl, - 'fullCurrentUrl' => $this->fullCurrentUrl - ]; - } - - # render page for frontend - protected function render($response, $route, $data) - { - # why commented this out?? - $data = $this->c->dispatcher->dispatch('onPageReady', new OnPageReady($data))->getData(); - - if(isset($_SESSION['old'])) - { - unset($_SESSION['old']); - } - - $response = $response->withoutHeader('Server'); - $response = $response->withAddedHeader('X-Powered-By', 'Typemill'); - - if(!isset($this->settings['headersoff']) or !$this->settings['headersoff']) - { - $response = $response->withAddedHeader('X-Content-Type-Options', 'nosniff'); - $response = $response->withAddedHeader('X-Frame-Options', 'SAMEORIGIN'); - $response = $response->withAddedHeader('X-XSS-Protection', '1;mode=block'); - $response = $response->withAddedHeader('Referrer-Policy', 'no-referrer-when-downgrade'); - if($this->c->request->getUri()->getScheme() == 'https') - { - $response = $response->withAddedHeader('Strict-Transport-Security', 'max-age=63072000'); - } - } - - return $this->c->view->render($response, $route, $data); - } - - # render 404 for frontend - protected function render404($response, $data = NULL) - { - return $this->c->view->render($response->withStatus(404), '/404.twig', $data); - } - - # render page for authors (admin-area) - protected function renderIntern($response, $route, $data) - { - if(isset($_SESSION['old'])) - { - unset($_SESSION['old']); - } - - $response = $response->withoutHeader('Server'); - $response = $response->withAddedHeader('X-Powered-By', 'Typemill'); - - if(!isset($this->settings['headersoff']) or !$this->settings['headersoff']) - { - $response = $response->withAddedHeader('X-Content-Type-Options', 'nosniff'); - $response = $response->withAddedHeader('X-Frame-Options', 'SAMEORIGIN'); - $response = $response->withAddedHeader('X-XSS-Protection', '1;mode=block'); - $response = $response->withAddedHeader('Referrer-Policy', 'no-referrer-when-downgrade'); - if($this->c->request->getUri()->getScheme() == 'https') - { - $response = $response->withAddedHeader('Strict-Transport-Security', 'max-age=63072000'); - } - } - - return $this->c->view->render($response, $route, $data); - } - - # render 404 for authors - protected function renderIntern404($response, $data = NULL) - { - return $this->c->view->render($response->withStatus(404), '/intern404.twig', $data); - } - - - - -########### MOVE TO GLOBAL API ?? - - public function clearCache($request, $response, $args) - { - $this->uri = $request->getUri()->withUserInfo(''); - $dir = $this->settings['basePath'] . 'cache'; - - $error = $this->writeCache->deleteCacheFiles($dir); - if($error) - { - return $response->withJson(['errors' => $error], 500); - } - - # create a new draft structure - $this->setFreshStructureDraft(); - - # create a new draft structure - $this->setFreshStructureLive(); - - # create a new draft structure - $this->setFreshNavigation(); - - # update the sitemap - $this->updateSitemap(); - - return $response->withJson(array('errors' => false)); - } - -############ CHECK IF NEEDED FOR API IMAGE ??? - - protected function saveImages($imageFields, $userInput, $userSettings, $files) - { - # initiate image processor with standard image sizes - $processImages = new ProcessImage($userSettings['images']); - - if(!$processImages->checkFolders('images')) - { - $this->c->flash->addMessage('error', 'Please make sure that your media folder exists and is writable.'); - return false; - } - - foreach($imageFields as $fieldName => $imageField) - { - if(isset($userInput[$fieldName])) - { - # handle single input with single file upload - $image = $files[$fieldName]; - - if($image->getError() === UPLOAD_ERR_OK) - { - # not the most elegant, but createImage expects a base64-encoded string. - $imageContent = $image->getStream()->getContents(); - $imageData = base64_encode($imageContent); - $imageSrc = 'data: ' . $image->getClientMediaType() . ';base64,' . $imageData; - - if($processImages->createImage($imageSrc, $image->getClientFilename(), $userSettings['images'], $overwrite = NULL)) - { - # returns image path to media library - $userInput[$fieldName] = $processImages->publishImage(); - } - } - } - } - return $userInput; - } - - -############ NAVIGATION ??? - - # reads the cached structure with published and non-published pages for the author - # setStructureDraft - protected function getStructureForAuthors($userrole, $username) - { - # get the cached structure - $this->structureDraft = $this->writeCache->getCache('cache', $this->structureDraftName); - - # if there is no cached structure - if(!$this->structureDraft) - { - return $this->setFreshStructureDraft(); - } - - return true; - } - - # creates a fresh structure with published and non-published pages for the author - # setFreshStrutureDraft - protected function createNewStructureForAuthors() - { - # scan the content of the folder - $pagetreeDraft = Folder::scanFolder($this->settings['rootPath'] . $this->settings['contentFolder'], $draft = true ); - - # if there is content, then get the content details - if(count($pagetreeDraft) > 0) - { - # get the extended structure files with changes like navigation title or hidden pages - $yaml = new writeYaml(); - $extended = $this->getExtended(); - - # create an array of object with the whole content of the folder and changes from extended file - $this->structureDraft = Folder::getFolderContentDetails($pagetreeDraft, $extended, $this->settings, $this->uri->getBaseUrl(), $this->uri->getBasePath()); - - # cache structure draft - $this->writeCache->updateCache('cache', $this->structureDraftName, 'lastCache.txt', $this->structureDraft); - - return true; - } - - return false; - } - - # reads the cached structure of published pages - # setStrutureLive - protected function getStructureForReaders() - { - # get the cached structure - $this->structureLive = $this->writeCache->getCache('cache', $this->structureLiveName); - - # if there is no cached structure - if(!$this->structureLive) - { - return $this->setFreshStructureLive(); - } - - return true; - } - - # creates a fresh structure with published pages - protected function setFreshStructureLive() - { - # scan the content of the folder - $pagetreeLive = Folder::scanFolder($this->settings['rootPath'] . $this->settings['contentFolder'], $draft = false ); - - # if there is content, then get the content details - if($pagetreeLive && count($pagetreeLive) > 0) - { - # get the extended structure files with changes like navigation title or hidden pages - $yaml = new writeYaml(); - $extended = $this->getExtended(); - - # create an array of object with the whole content of the folder and changes from extended file - $this->structureLive = Folder::getFolderContentDetails($pagetreeLive, $extended, $this->settings, $this->uri->getBaseUrl(), $this->uri->getBasePath()); - - # cache structure live - $this->writeCache->updateCache('cache', $this->structureLiveName, 'lastCache.txt', $this->structureLive); - - return true; - } - - return false; - } - - # reads the live navigation from cache (live structure without hidden pages) - protected function setNavigation() - { - # get the cached structure - $this->navigation = $this->writeCache->getCache('cache', 'navigation.txt'); - - # if there is no cached structure - if(!$this->navigation) - { - return $this->setFreshNavigation(); - } - - return true; - } - - # creates a fresh live navigation (live structure without hidden pages) - protected function setFreshNavigation() - { - - if(!$this->extended) - { - $extended = $this->getExtended(); - } - - if($this->containsHiddenPages($this->extended)) - { - if(!$this->structureLive) - { - $this->setStructureLive(); - } - - $structureLive = $this->c->dispatcher->dispatch('onPagetreeLoaded', new OnPagetreeLoaded($this->structureLive))->getData(); - $this->navigation = $this->createNavigation($structureLive); - - # cache navigation - $this->writeCache->updateCache('cache', 'navigation.txt', false, $this->navigation); - - return true; - } - - # make sure no old navigation file is left - $this->writeCache->deleteFileWithPath('cache' . DIRECTORY_SEPARATOR . 'navigation.txt'); - - return false; - } - - # create navigation from structure - protected function createNavigation($structureLive) - { - foreach ($structureLive as $key => $element) - { - if($element->hide === true) - { - unset($structureLive[$key]); - } - elseif(isset($element->folderContent)) - { - $structureLive[$key]->folderContent = $this->createNavigation($element->folderContent); - } - } - - return $structureLive; - } - - - # reads the cached structure with published and non-published pages for the author - protected function setStructureDraft() - { - # get the cached structure - $this->structureDraft = $this->writeCache->getCache('cache', $this->structureDraftName); - - # if there is no cached structure - if(!$this->structureDraft) - { - return $this->setFreshStructureDraft(); - } - - return true; - } - - # creates a fresh structure with published and non-published pages for the author - protected function setFreshStructureDraft() - { - # scan the content of the folder - $pagetreeDraft = Folder::scanFolder($this->settings['rootPath'] . $this->settings['contentFolder'], $draft = true ); - - # if there is content, then get the content details - if(count($pagetreeDraft) > 0) - { - # get the extended structure files with changes like navigation title or hidden pages - $yaml = new writeYaml(); - $extended = $this->getExtended(); - - # create an array of object with the whole content of the folder and changes from extended file - $this->structureDraft = Folder::getFolderContentDetails($pagetreeDraft, $extended, $this->settings, $this->uri->getBaseUrl(), $this->uri->getBasePath()); - - # cache structure draft - $this->writeCache->updateCache('cache', $this->structureDraftName, 'lastCache.txt', $this->structureDraft); - - return true; - } - - return false; - } - - # reads the cached structure of published pages - protected function setStructureLive() - { - # get the cached structure - $this->structureLive = $this->writeCache->getCache('cache', $this->structureLiveName); - - # if there is no cached structure - if(!$this->structureLive) - { - return $this->setFreshStructureLive(); - } - - return true; - } - - # creates a fresh structure with published pages - protected function setFreshStructureLive() - { - # scan the content of the folder - $pagetreeLive = Folder::scanFolder($this->settings['rootPath'] . $this->settings['contentFolder'], $draft = false ); - - # if there is content, then get the content details - if($pagetreeLive && count($pagetreeLive) > 0) - { - # get the extended structure files with changes like navigation title or hidden pages - $yaml = new writeYaml(); - $extended = $this->getExtended(); - - # create an array of object with the whole content of the folder and changes from extended file - $this->structureLive = Folder::getFolderContentDetails($pagetreeLive, $extended, $this->settings, $this->uri->getBaseUrl(), $this->uri->getBasePath()); - - # cache structure live - $this->writeCache->updateCache('cache', $this->structureLiveName, 'lastCache.txt', $this->structureLive); - - return true; - } - - return false; - } - - # reads the live navigation from cache (live structure without hidden pages) - protected function setNavigation() - { - # get the cached structure - $this->navigation = $this->writeCache->getCache('cache', 'navigation.txt'); - - # if there is no cached structure - if(!$this->navigation) - { - return $this->setFreshNavigation(); - } - - return true; - } - - # creates a fresh live navigation (live structure without hidden pages) - protected function setFreshNavigation() - { - - if(!$this->extended) - { - $extended = $this->getExtended(); - } - - if($this->containsHiddenPages($this->extended)) - { - if(!$this->structureLive) - { - $this->setStructureLive(); - } - - $structureLive = $this->c->dispatcher->dispatch('onPagetreeLoaded', new OnPagetreeLoaded($this->structureLive))->getData(); - $this->navigation = $this->createNavigation($structureLive); - - # cache navigation - $this->writeCache->updateCache('cache', 'navigation.txt', false, $this->navigation); - - return true; - } - - # make sure no old navigation file is left - $this->writeCache->deleteFileWithPath('cache' . DIRECTORY_SEPARATOR . 'navigation.txt'); - - return false; - } - - # create navigation from structure - protected function createNavigation($structureLive) - { - foreach ($structureLive as $key => $element) - { - if($element->hide === true) - { - unset($structureLive[$key]); - } - elseif(isset($element->folderContent)) - { - $structureLive[$key]->folderContent = $this->createNavigation($element->folderContent); - } - } - - return $structureLive; - } - - protected function getExtended() - { - $yaml = new writeYaml(); - - if(!$this->extended) - { - $this->extended = $yaml->getYaml('cache', 'structure-extended.yaml'); - } - - if(!$this->extended) - { - # scan the content of the folder - $pagetreeDraft = Folder::scanFolder($this->settings['rootPath'] . $this->settings['contentFolder'], $draft = true ); - - # if there is content, then get the content details - if(count($pagetreeDraft) == 0) - { - return false; - } - - # create an array of object with the whole content of the folder and changes from extended file - $structureDraft = Folder::getFolderContentDetails($pagetreeDraft, $extended = false, $this->settings, $this->uri->getBaseUrl(), $this->uri->getBasePath()); - - $this->extended = $this->createExtended($this->settings['rootPath'] . $this->settings['contentFolder'], $yaml, $structureDraft); - - $yaml->updateYaml('cache', 'structure-extended.yaml', $this->extended); - } - - return $this->extended; - } - - # creates a file that holds all hide flags and navigation titles - # reads all meta-files and creates an array with url => ['hide' => bool, 'navtitle' => 'bla'] - public function createExtended($contentPath, $yaml, $structureLive, $extended = NULL) - { - if(!$extended) - { - $extended = []; - } - - foreach ($structureLive as $key => $item) - { - # $filename = ($item->elementType == 'folder') ? DIRECTORY_SEPARATOR . 'index.yaml' : $item->pathWithoutType . '.yaml'; - $filename = $item->pathWithoutType . '.yaml'; - - if(file_exists($contentPath . $filename)) - { - # read file - $meta = $yaml->getYaml('content', $filename); - - $extended[$item->urlRelWoF]['hide'] = isset($meta['meta']['hide']) ? $meta['meta']['hide'] : false; - $extended[$item->urlRelWoF]['navtitle'] = isset($meta['meta']['navtitle']) ? $meta['meta']['navtitle'] : ''; - } - - if ($item->elementType == 'folder') - { - $extended = $this->createExtended($contentPath, $yaml, $item->folderContent, $extended); - } - } - return $extended; - } - - # only backoffice - protected function renameExtended($item, $newFolder) - { - # get the extended structure files with changes like navigation title or hidden pages - $yaml = new writeYaml(); - $extended = $yaml->getYaml('cache', 'structure-extended.yaml'); - - if(isset($extended[$item->urlRelWoF])) - { - $newUrl = $newFolder->urlRelWoF . '/' . $item->slug; - - $entry = $extended[$item->urlRelWoF]; - - unset($extended[$item->urlRelWoF]); - - $extended[$newUrl] = $entry; - $yaml->updateYaml('cache', 'structure-extended.yaml', $extended); - } - - return true; - } - - # only backoffice - protected function deleteFromExtended() - { - # get the extended structure files with changes like navigation title or hidden pages - $yaml = new writeYaml(); - $extended = $yaml->getYaml('cache', 'structure-extended.yaml'); - - if($this->item->elementType == "file" && isset($extended[$this->item->urlRelWoF])) - { - unset($extended[$this->item->urlRelWoF]); - $yaml->updateYaml('cache', 'structure-extended.yaml', $extended); - } - - if($this->item->elementType == "folder") - { - $changed = false; - - # delete all entries with that folder url - foreach($extended as $url => $entries) - { - if( strpos($url, $this->item->urlRelWoF) !== false ) - { - $changed = true; - unset($extended[$url]); - } - } - - if($changed) - { - $yaml->updateYaml('cache', 'structure-extended.yaml', $extended); - } - } - } - - - # checks if there is a hidden page, returns true on first find - protected function containsHiddenPages($extended) - { - foreach($extended as $element) - { - if(isset($element['hide']) && $element['hide'] === true) - { - return true; - } - } - return false; - } -} \ No newline at end of file diff --git a/system/typemill/Extensions/ParsedownExtension.php b/system/typemill/Extensions/ParsedownExtension.php index eb28b91..7f557f3 100644 --- a/system/typemill/Extensions/ParsedownExtension.php +++ b/system/typemill/Extensions/ParsedownExtension.php @@ -18,6 +18,8 @@ class ParsedownExtension extends \ParsedownExtra # show anchor next to headline? $this->showAnchor = isset($settings['headlineanchors']) ? $settings['headlineanchors'] : false; + $this->headlines = []; + # extend link schemes $urlschemes = ( isset($settings['urlschemes']) && !empty($settings['urlschemes']) ) ? explode(",", $settings['urlschemes']) : false; if($urlschemes) @@ -345,7 +347,7 @@ class ParsedownExtension extends \ParsedownExtra # Headlines - public $headlines = array(); + public $headlines = []; protected function blockHeader($Line) { @@ -372,6 +374,7 @@ class ParsedownExtension extends \ParsedownExtra if($this->showAnchor && $level > 1) { + # should we add more info like level so duplicate headline text is possible? $text = "[#](#h-$headline){.tm-heading-anchor}" . $text; } @@ -389,7 +392,11 @@ class ParsedownExtension extends \ParsedownExtra ) ); - $this->headlines[] = array('level' => $level, 'name' => $Block['element']['name'], 'attribute' => $Block['element']['attributes']['id'], 'text' => $tocText); + # fix: make sure no duplicates in headlines if user logged in and restrictions on + if(!isset($this->headlines[$headline])) + { + $this->headlines[$headline] = array('level' => $level, 'name' => $Block['element']['name'], 'attribute' => $Block['element']['attributes']['id'], 'text' => $tocText); + } return $Block; } @@ -406,11 +413,15 @@ class ParsedownExtension extends \ParsedownExtra } - # build the markup for table of contents + # build the markup for table of contents public function buildTOC($headlines) { $markup = '
'; - var_dump($folder); - die(); - - if(!$this->checkFolder($folder)) - { - if(!$this->createFolder($folder)) - { - return false; - } - } - - $filepath = $this->basepath . $folder . DIRECTORY_SEPARATOR . $filename; - - $openfile = @fopen($filepath, "w"); - if(!$openfile) - { - $this->error = "Could not open and read the file $filename in folder $folder."; - - return false; - } - - # serialize, json_decode - if($method && is_callable($method)) - { - $data = $method($data); - } - - $writefile = fwrite($openfile, $data); - if(!$writefile) - { - $this->error = "Could not write to the file $filename in folder $folder."; - - return false; - } - - fclose($openfile); - - return true; - } - - public function getFileBREAK($folder, $filename, $method = NULL) - { - if($this->checkFile($folder, $filename)) - { - # ??? should be with basepath??? - $fileContent = file_get_contents($folder . DIRECTORY_SEPARATOR . $filename); - - # use unserialise or json_decode - if($method && is_callable($method)) - { - $fileContent = $method($fileContent); - } - - return $fileContent; - } - - return false; - } - - public function renameFileBREAK($folder, $oldname, $newname) - { - $oldFilePath = $this->basepath . $folder . DIRECTORY_SEPARATOR . $oldname; - $newFilePath = $this->basepath . $folder . DIRECTORY_SEPARATOR . $newname; - - if(!file_exists($oldFilePath)) - { - return false; - } - - if(!rename($oldFilePath, $newFilePath)) - { - return false; - } - - return true; - } - - public function deleteFileBREAK($folder, $filename) - { - if($this->checkFile($folder, $filename)) - { - if(unlink($this->basepath . $folder . DIRECTORY_SEPARATOR . $filename)) - { - return true; - } - - $this->error = "We found the file but could not delete $filename"; - } - - return false; - } - - # used to sort the navigation / files - public function moveContentFileBREAK($item, $folderPath, $index, $date = null) - { - $filetypes = array('md', 'txt', 'yaml'); - - # set new order as string - $newOrder = ($index < 10) ? '0' . $index : $index; - - $newPath = $this->contentFolder . $folderPath . DIRECTORY_SEPARATOR . $newOrder . '-' . $item->slug; - - if($item->elementType == 'folder') - { - $oldPath = $this->contentFolder . $item->path; - - if(@rename($oldPath, $newPath)) - { - return true; - } - return false; - } - - # create old path but without filetype - $oldPath = substr($item->path, 0, strpos($item->path, ".")); - $oldPath = $this->contentFolder . $oldPath; - - $result = true; - - foreach($filetypes as $filetype) - { - $oldFilePath = $oldPath . '.' . $filetype; - $newFilePath = $newPath . '.' . $filetype; - - #check if file with filetype exists and rename - if($oldFilePath != $newFilePath && file_exists($oldFilePath)) - { - if(@rename($oldFilePath, $newFilePath)) - { - $result = $result; - } - else - { - $result = false; - } - } - } - - return $result; - } - - - - - - - - - - public function checkPath($folder) - { - $folderPath = $this->basepath . $folder; - - if(!is_dir($folderPath)) - { - if(@mkdir($folderPath, 0774, true)) - { - return true; - } - else - { - throw new \Exception("The folder '{$folderPath}' is missing and we could not create it. Please create the folder manually on your server."); -# return false; - } - } - - if(@is_writable($folderPath)) - { - return true; - } - else - { - throw new \Exception("Please make the folder '{$folderPath}' writable."); -# return false; - } - return true; - } - -/* - - public function checkFile($folder, $file) - { - if(!file_exists($this->basePath . $folder . DIRECTORY_SEPARATOR . $file)) - { - return false; - } - return true; - } - - public function checkFileWithPath($filepath) - { - if(!file_exists($this->basePath . $filepath)) - { - return false; - } - return true; - } - - public function writeFile($folder, $file, $data) - { - if($this->checkPath($folder)) - { - $filePath = $this->basePath . $folder . DIRECTORY_SEPARATOR . $file; - - $openFile = @fopen($filePath, "w"); - - if(!$openFile) - { - return false; - } - - fwrite($openFile, $data); - fclose($openFile); - - return true; - } - return false; - } - - public function getFile($folderName, $fileName) - { - if($this->checkFile($folderName, $fileName)) - { - $fileContent = file_get_contents($folderName . DIRECTORY_SEPARATOR . $fileName); - return $fileContent; - } - return false; - } - - public function getFileWithPath($filepath) - { - if($this->checkFileWithPath($filepath)) - { - $fileContent = file_get_contents($filepath); - return $fileContent; - } - return false; - } - - public function deleteFileWithPath($filepath) - { - if($this->checkFileWithPath($filepath)) - { - unlink($this->basePath . $filepath); - return true; - } - return false; - } - - public function renameFile($folder, $oldname, $newname) - { - - $oldFilePath = $this->basePath . $folder . DIRECTORY_SEPARATOR . $oldname; - $newFilePath = $this->basePath . $folder . DIRECTORY_SEPARATOR . $newname; - - if(!file_exists($oldFilePath)) - { - return false; - } - - if(@rename($oldFilePath, $newFilePath)) - { - return true; - } - - return false; - } - - */ } \ No newline at end of file diff --git a/system/typemill/Models/_OLDProcessFile.php b/system/typemill/Models/_OLDProcessFile.php deleted file mode 100644 index 3e3aa6d..0000000 --- a/system/typemill/Models/_OLDProcessFile.php +++ /dev/null @@ -1,69 +0,0 @@ -clearTempFolder(); - - $this->setPathInfo($name); - - $this->decode($file); - - $fullpath = $this->getFullPath(); - - if($this->filedata !== false && file_put_contents($fullpath, $this->filedata)) - { - $size = filesize($this->getFullPath()); - $size = $this->formatSizeUnits($size); - - $title = str_replace('-', ' ', $this->filename); - $title = $title . ' (' . strtoupper($this->extension) . ', ' . $size .')'; - - return [ - 'title' => $title, - 'name' => $this->filename, - 'extension' => $this->extension, - 'size' => $size, - 'url' => 'media/files/' . $this->getFullName() - ]; - } - - return false; - } - - - - - - - - - /** - * Moves the uploaded file to the upload directory. Only used for settings / NON VUE.JS uploads - * - * @param string $directory directory to which the file is moved - * @param UploadedFile $uploadedFile file uploaded file to move - * @return string filename of moved file - */ - public function moveUploadedFile(UploadedFile $uploadedFile, $overwrite = false, $name = false, $folder = NULL) - { - die('use processAssets instead of processFile'); - $this->setFileName($uploadedFile->getClientFilename(), 'file'); - - - if($name) - { - $this->setFileName($name . '.' . $this->extension, 'file', $overwrite); - } - - $uploadedFile->moveTo($this->fileFolder . $this->getFullName()); - - return $this->getFullName(); - } -} \ No newline at end of file diff --git a/system/typemill/Models/_OLDProcessImage.php b/system/typemill/Models/_OLDProcessImage.php deleted file mode 100644 index b0d8fe6..0000000 --- a/system/typemill/Models/_OLDProcessImage.php +++ /dev/null @@ -1,442 +0,0 @@ - true, 'jpg' => true, 'jpeg' => true, 'webp' => true]; - - protected $animated = false; - - protected $resizable = true; - - protected $sizes = []; - - public function prepareImage($image, $name) - { - die('use processAssets instead of processImages'); - - # change clear tmp folder and delete only old ones - $this->clearTempFolder(); - #$this->checkFolders('image'); - $this->decode($image); - $this->setPathInfo($name); - $this->checkAllowedExtension(); - - if(empty($this->errors)) - { - return true; - } - - return false; - } - - public function storeOriginalToTmp() - { - - die('use processAssets instead of processImages'); - - # $this->saveName(); - $this->saveOriginal(); - - if(empty($this->errors)) - { - return true; - } - - return false; - } - - public function storeRenditionsToTmp($sizes) - { - die('use processAssets instead of processImages'); - - - # transform image-stream into image - $image = $this->createImage(); - - $originalsize = $this->getImageSize($image); - - foreach($sizes as $destinationfolder => $desiredsize) - { - $desiredsize = $this->calculateSize($originalsize, $desiredsize); - - $resizedImage = $this->resizeImage($image, $desiredsize, $originalsize); - - $this->saveResizedImage($resizedImage, $destinationfolder, $this->extension); - - imagedestroy($resizedImage); - } - - imagedestroy($image); - - if(empty($this->errors)) - { - return true; - } - - return false; - } - - # add an allowed image extension like svg - public function addAllowedExtension(string $extension) - { - die('use processAssets instead of processImages'); - $this->allowedExtensions[$extension] = true; - } - - # force an image type like webp - public function setExtension(string $extension) - { - die('use processAssets instead of processImages'); - $this->extension = $extension; - } - - public function checkAllowedExtension() - { - die('use processAssets instead of processImages'); - if(!isset($this->allowedExtensions[$this->extension])) - { - $this->errors[] = 'Images with this extension are not allowed.'; - - return false; - } - - return true; - } - - # check if image should not be resized (animated gif and svg) - public function isResizable() - { - die('use processAssets instead of processImages'); - if($this->filetype == 'gif' && $this->detectAnimatedGif()) - { - $this->resizable = false; - } - - if($this->filetype == 'svg+xml') - { - $this->resizable = false; - } - - return $this->resizable; - } - - public function detectAnimatedGif() - { - die('use processAssets instead of processImages'); - $is_animated = preg_match('#(\x00\x21\xF9\x04.{4}\x00\x2C.*){2,}#s', $this->filedata); - if ($is_animated == 1) - { - $this->animated = true; - } - - return $this->animated; - } - - # save the original image to temp folder - public function saveOriginal($destinationfolder = 'ORIGINAL') - { - die('use processAssets instead of processImages'); - $path = $this->tmpFolder . $destinationfolder . '+' . $this->filename . '.' . $this->extension; - - if(!file_put_contents($path, $this->filedata)) - { - $this->errors[] = 'could not store the image in the temporary folder'; - } - } - - # save the original image for all sizes/folders - public function saveOriginalForAll() - { - die('use processAssets instead of processImages'); - $this->saveOriginal('LIVE'); - $this->saveOriginal('THUMBS'); - } - - public function createImage() - { - die('use processAssets instead of processImages'); - return imagecreatefromstring($this->filedata); - } - - public function getImageSize($image) - { - die('use processAssets instead of processImages'); - return ['width' => imagesx($image), 'height' => imagesy($image)]; - } - - public function calculateSize(array $originalsize, array $desiredsize) - { - die('use processAssets instead of processImages'); - # if desired size is bigger than the actual image, then drop the desired sizes and use the actual image size instead - if($desiredsize['width'] > $originalsize['width']) - { - return $originalsize; - } - - if(!isset($desiredsize['height'])) - { - $resizeFactor = $originalsize['width'] / $desiredsize['width']; - $desiredsize['height'] = round( ($originalsize['height'] / $resizeFactor), 0); - } - - return $desiredsize; - } - - public function resizeImage($image, array $desired, array $original) - { - die('use processAssets instead of processImages'); - # resize - $ratio = max($desired['width']/$original['width'], $desired['height']/$original['height']); - $h = $desired['height'] / $ratio; - $x = ($original['width'] - $desired['width'] / $ratio) / 2; - $y = ($original['height'] - $desired['height'] / $ratio) / 2; - $w = $desired['width'] / $ratio; - - $resizedImage = imagecreatetruecolor($desired['width'], $desired['height']); - - # preserve transparency - if($this->extension == "gif" or $this->extension == "png" or $this->extension == "webp") - { - imagecolortransparent($resizedImage, imagecolorallocatealpha($resizedImage, 0, 0, 0, 127)); - imagealphablending($resizedImage, false); - imagesavealpha($resizedImage, true); - } - - imagecopyresampled($resizedImage, $image, 0, 0, $x, $y, $desired['width'], $desired['height'], $w, $h); - - return $resizedImage; - } - - public function saveResizedImage($resizedImage, string $destinationfolder, string $extension) - { - die('use processAssets instead of processImages'); - $destinationfolder = strtoupper($destinationfolder); - - switch($extension) - { - case "png": - $storedImage = imagepng( $resizedImage, $this->tmpFolder . $destinationfolder . '+' . $this->filename . '.png', 9 ); - break; - case "gif": - $storedImage = imagegif( $resizedImage, $this->tmpFolder . $destinationfolder . '+' . $this->filename . '.gif' ); - break; - case "webp": - $storedImage = imagewebp( $resizedImage, $this->tmpFolder . $destinationfolder . '+' . $this->filename . '.webp', 80); - break; - case "jpg": - case "jpeg": - $storedImage = imagejpeg( $resizedImage, $this->tmpFolder . $destinationfolder . '+' . $this->filename . '.' . $extension, 80); - break; - default: - $storedImage = false; - } - - if(!$storedImage) - { - $failedImage = $this->tmpFolder . $destinationfolder . '+' . $this->filename . '.' . $extension; - - $this->errors[] = "Could not store the resized version $failedImage"; - - return false; - } - - return true; - } - - - - - - - - - - - - - - # in use ?? - public function deleteImageWithName($name) - { - die("processImage model deleteImageWithName please check method."); - # e.g. delete $name = 'logo...'; - - $name = basename($name); - - if($name != '' && !in_array($name, array(".",".."))) - { - foreach(glob($this->liveFolder . $name) as $file) - { - unlink($file); - } - foreach(glob($this->originalFolder . $name) as $file) - { - unlink($file); - } - foreach(glob($this->thumbFolder . $name) as $file) - { - unlink($file); - } - } - } - - # in use ?? - public function copyImage($name,$sourcefolder,$targetfolder) - { - die("processImage model copyImage please check method."); - - copy($sourcefolder . $name, $targetfolder . $name); - } - - - - - - - - - - - - - - - - /** - * Moves the uploaded file to the upload directory. Only used for settings / NON VUE.JS uploads - * - * @param string $directory directory to which the file is moved - * @param UploadedFile $uploadedFile file uploaded file to move - * @return string filename of moved file - */ - public function moveUploadedImage(UploadedFile $uploadedFile, $overwrite = false, $name = false, $folder = NULL) - { - die('use processAssets instead of processImages'); - $this->setFileName($uploadedFile->getClientFilename(), 'file'); - - if($name) - { - $this->setFileName($name . '.' . $this->extension, 'file', $overwrite); - } - - if(!$folder) - { - $folder = $this->liveFolder; - } - - $uploadedFile->moveTo($folder . $this->getFullName()); - - return $this->getFullName(); - } - - - - - - - - - - - -/* - # save the image name as txt to temp folder - public function saveName() - { - $path = $this->tmpFolder . $this->filename . '.txt'; - - if(!fopen($path, "w")) - { - $this->errors[] = 'could not store the filename in the temporary folder'; - } - } -*/ - - - - - public function generateThumbs() - { - die('use processAssets instead of processImages'); - # generate images from live folder to 'tmthumbs' - $liveImages = scandir($this->liveFolder); - - $result = false; - - foreach ($liveImages as $key => $name) - { - if (!in_array($name, array(".",".."))) - { - $result = $this->generateThumbFromImageFile($name); - } - } - return $result; - } - - public function generateThumbFromImageFile($filename) - { - die('use processAssets instead of processImages'); - $this->setFileName($filename, 'image', $overwrite = true); - - $image = $this->createImageFromPath($this->liveFolder . $filename, $this->extension); - - $originalSize = $this->getImageSize($image); - - $thumbSize = $this->desiredSizes['thumbs']; - - $thumb = $this->imageResize($image, $originalSize, ['thumbs' => $thumbSize ], $this->extension); - - $saveImage = $this->saveImage($this->thumbFolder, $thumb['thumbs'], $this->filename, $this->extension); - if($saveImage) - { - return true; - } - return false; - } - - # filename and imagepath can be a tmp-version after upload. - public function generateSizesFromImageFile($filename, $imagePath) - { - die('use processAssets instead of processImages'); - $this->setFileName($filename, 'image'); - - $image = $this->createImageFromPath($imagePath, $this->extension); - - $originalSize = $this->getImageSize($image); - - $resizedImages = $this->imageResize($image, $originalSize, $this->desiredSizes, $this->extension); - - return $resizedImages; - } - - public function grayscale($imagePath, $extension) - { - die('use processAssets instead of processImages'); - $image = $this->createImageFromPath($imagePath, $extension); - - imagefilter($image, IMG_FILTER_GRAYSCALE); - - return $image; - } - - public function createImageFromPath($imagePath, $extension) - { - die('use processAssets instead of processImages'); - switch($extension) - { - case 'gif': $image = imagecreatefromgif($imagePath); break; - case 'jpg' : - case 'jpeg': $image = imagecreatefromjpeg($imagePath); break; - case 'png': $image = imagecreatefrompng($imagePath); break; - case 'webp': $image = imagecreatefromwebp($imagePath); break; - default: return 'image type not supported'; - } - - return $image; - } -} \ No newline at end of file diff --git a/system/typemill/Plugin.php b/system/typemill/Plugin.php index e61a220..a627d2c 100644 --- a/system/typemill/Plugin.php +++ b/system/typemill/Plugin.php @@ -12,20 +12,29 @@ abstract class Plugin implements EventSubscriberInterface { protected $container; - protected $path; + protected $route; - protected $adminpath = false; + protected $adminroute = false; + + protected $editorroute = false; - /** - * Constructor - * - */ public function __construct($container) { $this->container = $container; $this->urlinfo = $this->container->get('urlinfo'); - $this->path = $this->urlinfo['currentpath']; + $this->route = $this->urlinfo['route']; + $this->route = ltrim($this->route, '/'); + + if(str_starts_with($this->route, 'tm/')) + { + $this->adminroute = true; + } + + if(str_starts_with($this->route, 'tm/content/')) + { + $this->editorroute = true; + } } protected function getSettings() diff --git a/system/typemill/Static/Settings.php b/system/typemill/Static/Settings.php deleted file mode 100644 index f767d19..0000000 --- a/system/typemill/Static/Settings.php +++ /dev/null @@ -1,198 +0,0 @@ -getYaml($objectType, $objectName, $objectName . '.yaml'); - - if($objectSettings) - { - return $objectSettings; - } - return false; - -/* - $rootpath = getcwd(); - $objectfile = $rootpath . DIRECTORY_SEPARATOR . $objectType . DIRECTORY_SEPARATOR . $objectName . DIRECTORY_SEPARATOR . $objectName . '.yaml'; - - if(file_exists($objectfile)) - { - $objectsettingsyaml = file_get_contents($objectfile); - $objectsettings = \Symfony\Component\Yaml\Yaml::parse($objectsettingsyaml); - - return $objectsettings; - } - - return false; - */ - } - - public static function updateSettings(array $newSettings, $storagepath = '\Typemill\Models\Storage') - { - echo debug_backtrace()[1]['function']; - die('use model updateSettings instead'); - - $storage = new StorageWrapper($storagepath); - - # only allow if usersettings already exists (setup has been done) - $userSettings = self::getUserSettings(); - - # merge usersettings with new settings - $settings = array_merge($userSettings, $newSettings); - - $storage->updateYaml('settingsFolder', '', 'settings.yaml', $settings); - } - - public static function getSettingsDefinitions($storagepath = '\Typemill\Models\Storage') - { - echo debug_backtrace()[1]['function']; - die('use model getSettingsDefinitions instead'); - - $storage = new StorageWrapper($storagepath); - - return $storage->getYaml('systemSettings', '', 'system.yaml'); - } - - public static function createSettings($storagepath = '\Typemill\Models\Storage') - { - echo debug_backtrace()[1]['function']; - die('use model createSettings instead'); - - $storage = new StorageWrapper($storagepath); - - $language = Translations::whichLanguage(); - - $initialSettings = $storage->updateYaml('settingsFolder', '', 'settings.yaml', [ - 'language' => $language - ]); - - if($initialSettings) - { - return true; - } - return false; - } -} \ No newline at end of file diff --git a/system/typemill/author/js/vue-medialib.js b/system/typemill/author/js/vue-medialib.js index f854432..430996a 100644 --- a/system/typemill/author/js/vue-medialib.js +++ b/system/typemill/author/js/vue-medialib.js @@ -208,10 +208,16 @@ const medialib = { var self = this; + var itempath = false; + if(typeof data.item !== "undefined") + { + itempath = data.item.pathWithoutType; + } + tmaxios.get('/api/v1/pagemedia',{ params: { 'url': data.urlinfo.route, - 'path': data.item.pathWithoutType + 'path': itempath } }) .then(function (response) @@ -339,10 +345,15 @@ const medialib = { var imageself = this; + var itempath = false; + if(typeof data.item !== "undefined") + { + itempath = data.item.pathWithoutType; + } tmaxios.get('/api/v1/images',{ params: { 'url': data.urlinfo.route, - 'path': data.item.pathWithoutType + 'path': itempath, } }) .then(function (response) diff --git a/system/typemill/routes/web.php b/system/typemill/routes/web.php index 88f48fd..eed8914 100644 --- a/system/typemill/routes/web.php +++ b/system/typemill/routes/web.php @@ -54,5 +54,34 @@ $app->redirect('/tm/', $routeParser->urlFor('auth.show'), 302); # downloads $app->get('/media/files[/{params:.*}]', ControllerWebDownload::class . ':download')->setName('download.file'); +foreach($routes as $pluginRoute) +{ + $method = $pluginRoute['httpMethod']; + $route = $pluginRoute['route']; + $class = $pluginRoute['class']; + # $resource = isset($pluginRoute['resource']) ? $pluginRoute['resource'] : NULL; + # $privilege = isset($pluginRoute['privilege']) ? $pluginRoute['privilege'] : NULL; + +# echo '
'; +# echo 'method: ' . $method . ' -> route: ' . $route . ' -> class: ' . $class; + + if(isset($pluginRoute['name'])) + { +# $app->{$method}($route, $class)->setName($pluginRoute['name'])->add(new accessMiddleware($container['router'], $container['acl'], $resource, $privilege)); + $app->{$method}($route, $class)->setName($pluginRoute['name']); + } + else + { +# $app->{$method}($route, $class)->add(new accessMiddleware($container['router'], $container['acl'], $resource, $privilege)); + $app->{$method}($route, $class); + } + + # if api and if authorization + # ->add(new ApiAuthorization($acl, 'account', 'view')); + + # if web and if authorization + # ->add(new WebAuthorization($acl, 'account', 'view')); +} +# die(); # website $app->get('/[{route:.*}]', ControllerWebFrontend::class . ':index')->setName('home'); \ No newline at end of file