diff --git a/cache/lastCache.txt b/cache/lastCache.txt index 70a6c3a..1adecce 100644 --- a/cache/lastCache.txt +++ b/cache/lastCache.txt @@ -1 +1 @@ -1537594730 \ No newline at end of file +1538860826 \ No newline at end of file diff --git a/content/00-typemill/00-use cases.md b/content/00-typemill/00-use-cases.md similarity index 100% rename from content/00-typemill/00-use cases.md rename to content/00-typemill/00-use-cases.md diff --git a/content/00-typemill/02-roadmap.md b/content/00-typemill/01-roadmap.md similarity index 99% rename from content/00-typemill/02-roadmap.md rename to content/00-typemill/01-roadmap.md index 1828d1f..012fe97 100644 --- a/content/00-typemill/02-roadmap.md +++ b/content/00-typemill/01-roadmap.md @@ -1,6 +1,6 @@ # Roadmap -There are a lot of plans for future releases of TYPEMILL, but it also follows the concept of simplicity. To prevent TYPEMILL from becomming a feature soup, it will strictly focus on the writers needs. +There are a lot of plans for future releases of TYPEMILL, but it also follows the concept of simplicity. To prevent TYPEMILL from becomming a feature soup, it will strictly focus on the writers needs. Here are some **milestones** of the past: diff --git a/content/00-typemill/01-features.md b/content/00-typemill/02-features.md similarity index 100% rename from content/00-typemill/01-features.md rename to content/00-typemill/02-features.md diff --git a/content/01-getting started/00-system requirements.md b/content/01-getting-started/00-system-requirements.md similarity index 100% rename from content/01-getting started/00-system requirements.md rename to content/01-getting-started/00-system-requirements.md diff --git a/content/01-getting started/02-installation.md b/content/01-getting-started/01-installation.md similarity index 100% rename from content/01-getting started/02-installation.md rename to content/01-getting-started/01-installation.md diff --git a/content/01-getting started/03-settings.md b/content/01-getting-started/02-settings.md similarity index 94% rename from content/01-getting started/03-settings.md rename to content/01-getting-started/02-settings.md index 3f0a3c1..8f4f131 100644 --- a/content/01-getting started/03-settings.md +++ b/content/01-getting-started/02-settings.md @@ -1,6 +1,6 @@ # Settings -As of Version 1.1.3 you can edit all settings in the new author panel of TYPEMILL. Just visit the url `yourwebsite.com/tm/login` and go to settings after the login. There you can edit: +As of Version 1.1.3 you can edit all settings in the new author panel of TYPEMILL. Just visit the url `yourwebsite.com/tm/login` and go to settings after the login. There you can edit: * The system (basic settings). * Themes (choose themes and configure it). @@ -13,6 +13,7 @@ All settings are stored in the `\settings` folder of TYPEMILL. It is not recomme There are some settings that are not available via the author panel. Most of them are not really useful, but if you are a developer and if you develop a theme or a plugin locally, you probably want to display a detailed error report. To do so, simply add the following line to the settings.yaml: + ```` displayErrorDetails: true ```` diff --git a/content/01-getting started/04-update.md b/content/01-getting-started/03-update.md similarity index 100% rename from content/01-getting started/04-update.md rename to content/01-getting-started/03-update.md diff --git a/content/01-getting started/index.md b/content/01-getting-started/index.md similarity index 100% rename from content/01-getting started/index.md rename to content/01-getting-started/index.md diff --git a/content/02-for writers/00-quick start.txt b/content/02-for writers/00-quick start.txt deleted file mode 100644 index 40e255f..0000000 --- a/content/02-for writers/00-quick start.txt +++ /dev/null @@ -1 +0,0 @@ -["# Quick Start for Writers","You are a pro and don't want to read the whole manual? No problem, this is a quick overview:","- **Setup**: Login to your system and setup the system, the themes and the plugins in the author panel.\n- **Content**: Organize your content in folders and markdown files and put them in the `\\content` folder of TYPEMILL. \n- **Markdown**: Use the Markdown syntax for your content files. Markdown Extra (e.g. tables, footnotes) is supported, too.\n- **Naming conventions**: Use prefixes like `01-` or `aa_` to sort your folders and files.\n- **Index files**: Add an `index.md` file to a folder to create content for the folder itself.\n- **F5**: After some changes, use the `F5` key to refresh the navigation manually.\n- **Lean back** and let TYPEMILL create a nice website for you.","\nThe TYPEMILL system ships with this user manual in the content folder. Check how the files are written and how the folders are organized."] \ No newline at end of file diff --git a/content/02-for writers/00-quick start.md b/content/02-for-writers/00-quick start.md similarity index 99% rename from content/02-for writers/00-quick start.md rename to content/02-for-writers/00-quick start.md index 5991c5f..ed0013d 100644 --- a/content/02-for writers/00-quick start.md +++ b/content/02-for-writers/00-quick start.md @@ -10,4 +10,5 @@ You are a pro and don't want to read the whole manual? No problem, this is a qui - **F5**: After some changes, use the `F5` key to refresh the navigation manually. - **Lean back** and let TYPEMILL create a nice website for you. + The TYPEMILL system ships with this user manual in the content folder. Check how the files are written and how the folders are organized. \ No newline at end of file diff --git a/content/02-for writers/01-author panel.md b/content/02-for-writers/01-author panel.md similarity index 100% rename from content/02-for writers/01-author panel.md rename to content/02-for-writers/01-author panel.md diff --git a/content/02-for writers/02-naming files and folders.md b/content/02-for-writers/02-naming files and folders.md similarity index 100% rename from content/02-for writers/02-naming files and folders.md rename to content/02-for-writers/02-naming files and folders.md diff --git a/content/02-for writers/03-folder structure.md b/content/02-for-writers/03-folder structure.md similarity index 100% rename from content/02-for writers/03-folder structure.md rename to content/02-for-writers/03-folder structure.md diff --git a/content/02-for writers/04-mardown.md b/content/02-for-writers/04-mardown.md similarity index 100% rename from content/02-for writers/04-mardown.md rename to content/02-for-writers/04-mardown.md diff --git a/content/02-for writers/05-google sitemap.md b/content/02-for-writers/05-google sitemap.md similarity index 100% rename from content/02-for writers/05-google sitemap.md rename to content/02-for-writers/05-google sitemap.md diff --git a/content/02-for writers/06-themes.md b/content/02-for-writers/06-themes.md similarity index 100% rename from content/02-for writers/06-themes.md rename to content/02-for-writers/06-themes.md diff --git a/content/02-for writers/07-plugins.md b/content/02-for-writers/07-plugins.md similarity index 100% rename from content/02-for writers/07-plugins.md rename to content/02-for-writers/07-plugins.md diff --git a/content/02-for writers/08-forgot password.md b/content/02-for-writers/08-forgot password.md similarity index 100% rename from content/02-for writers/08-forgot password.md rename to content/02-for-writers/08-forgot password.md diff --git a/content/02-for writers/index.md b/content/02-for-writers/index.md similarity index 100% rename from content/02-for writers/index.md rename to content/02-for-writers/index.md diff --git a/content/03-for theme developers/00-quick start.md b/content/03-for-theme-developers/00-quick start.md similarity index 100% rename from content/03-for theme developers/00-quick start.md rename to content/03-for-theme-developers/00-quick start.md diff --git a/content/03-for theme developers/01-theme structure.md b/content/03-for-theme-developers/01-theme structure.md similarity index 100% rename from content/03-for theme developers/01-theme structure.md rename to content/03-for-theme-developers/01-theme structure.md diff --git a/content/03-for theme developers/02-theme meta.md b/content/03-for-theme-developers/02-theme meta.md similarity index 100% rename from content/03-for theme developers/02-theme meta.md rename to content/03-for-theme-developers/02-theme meta.md diff --git a/content/03-for theme developers/03-asset tags.md b/content/03-for-theme-developers/03-asset tags.md similarity index 100% rename from content/03-for theme developers/03-asset tags.md rename to content/03-for-theme-developers/03-asset tags.md diff --git a/content/03-for theme developers/04-twig.md b/content/03-for-theme-developers/04-twig.md similarity index 100% rename from content/03-for theme developers/04-twig.md rename to content/03-for-theme-developers/04-twig.md diff --git a/content/03-for theme developers/05-theme variables/00-content.md b/content/03-for-theme-developers/05-theme variables/00-content.md similarity index 100% rename from content/03-for theme developers/05-theme variables/00-content.md rename to content/03-for-theme-developers/05-theme variables/00-content.md diff --git a/content/03-for theme developers/05-theme variables/01-title.md b/content/03-for-theme-developers/05-theme variables/01-title.md similarity index 100% rename from content/03-for theme developers/05-theme variables/01-title.md rename to content/03-for-theme-developers/05-theme variables/01-title.md diff --git a/content/03-for theme developers/05-theme variables/02-description.md b/content/03-for-theme-developers/05-theme variables/02-description.md similarity index 100% rename from content/03-for theme developers/05-theme variables/02-description.md rename to content/03-for-theme-developers/05-theme variables/02-description.md diff --git a/content/03-for theme developers/05-theme variables/03-image.md b/content/03-for-theme-developers/05-theme variables/03-image.md similarity index 100% rename from content/03-for theme developers/05-theme variables/03-image.md rename to content/03-for-theme-developers/05-theme variables/03-image.md diff --git a/content/03-for theme developers/05-theme variables/04-base url.md b/content/03-for-theme-developers/05-theme variables/04-base url.md similarity index 100% rename from content/03-for theme developers/05-theme variables/04-base url.md rename to content/03-for-theme-developers/05-theme variables/04-base url.md diff --git a/content/03-for theme developers/05-theme variables/05-item.md b/content/03-for-theme-developers/05-theme variables/05-item.md similarity index 100% rename from content/03-for theme developers/05-theme variables/05-item.md rename to content/03-for-theme-developers/05-theme variables/05-item.md diff --git a/content/03-for theme developers/05-theme variables/06-breadcrumb.md b/content/03-for-theme-developers/05-theme variables/06-breadcrumb.md similarity index 100% rename from content/03-for theme developers/05-theme variables/06-breadcrumb.md rename to content/03-for-theme-developers/05-theme variables/06-breadcrumb.md diff --git a/content/03-for theme developers/05-theme variables/07-navigation.md b/content/03-for-theme-developers/05-theme variables/07-navigation.md similarity index 100% rename from content/03-for theme developers/05-theme variables/07-navigation.md rename to content/03-for-theme-developers/05-theme variables/07-navigation.md diff --git a/content/03-for theme developers/05-theme variables/08-settings.md b/content/03-for-theme-developers/05-theme variables/08-settings.md similarity index 100% rename from content/03-for theme developers/05-theme variables/08-settings.md rename to content/03-for-theme-developers/05-theme variables/08-settings.md diff --git a/content/03-for theme developers/05-theme variables/index.md b/content/03-for-theme-developers/05-theme variables/index.md similarity index 100% rename from content/03-for theme developers/05-theme variables/index.md rename to content/03-for-theme-developers/05-theme variables/index.md diff --git a/content/03-for theme developers/index.md b/content/03-for-theme-developers/index.md similarity index 100% rename from content/03-for theme developers/index.md rename to content/03-for-theme-developers/index.md diff --git a/content/04-for plugin developers/00-intro.md b/content/04-for-plugin-developers/00-intro.md similarity index 100% rename from content/04-for plugin developers/00-intro.md rename to content/04-for-plugin-developers/00-intro.md diff --git a/content/04-for plugin developers/01-tutorial/00-cookie consent plugin.md b/content/04-for-plugin-developers/01-tutorial/00-cookie consent plugin.md similarity index 100% rename from content/04-for plugin developers/01-tutorial/00-cookie consent plugin.md rename to content/04-for-plugin-developers/01-tutorial/00-cookie consent plugin.md diff --git a/content/04-for plugin developers/01-tutorial/01-write the yaml file.md b/content/04-for-plugin-developers/01-tutorial/01-write the yaml file.md similarity index 100% rename from content/04-for plugin developers/01-tutorial/01-write the yaml file.md rename to content/04-for-plugin-developers/01-tutorial/01-write the yaml file.md diff --git a/content/04-for plugin developers/01-tutorial/02-write the php file.md b/content/04-for-plugin-developers/01-tutorial/02-write the php file.md similarity index 100% rename from content/04-for plugin developers/01-tutorial/02-write the php file.md rename to content/04-for-plugin-developers/01-tutorial/02-write the php file.md diff --git a/content/04-for plugin developers/01-tutorial/03-add methods.md b/content/04-for-plugin-developers/01-tutorial/03-add methods.md similarity index 100% rename from content/04-for plugin developers/01-tutorial/03-add methods.md rename to content/04-for-plugin-developers/01-tutorial/03-add methods.md diff --git a/content/04-for plugin developers/01-tutorial/04-create the structure.md b/content/04-for-plugin-developers/01-tutorial/04-create the structure.md similarity index 100% rename from content/04-for plugin developers/01-tutorial/04-create the structure.md rename to content/04-for-plugin-developers/01-tutorial/04-create the structure.md diff --git a/content/04-for plugin developers/01-tutorial/05-add twig template.md b/content/04-for-plugin-developers/01-tutorial/05-add twig template.md similarity index 100% rename from content/04-for plugin developers/01-tutorial/05-add twig template.md rename to content/04-for-plugin-developers/01-tutorial/05-add twig template.md diff --git a/content/04-for plugin developers/01-tutorial/06-add default values.md b/content/04-for-plugin-developers/01-tutorial/06-add default values.md similarity index 100% rename from content/04-for plugin developers/01-tutorial/06-add default values.md rename to content/04-for-plugin-developers/01-tutorial/06-add default values.md diff --git a/content/04-for plugin developers/01-tutorial/07-use variables in twig.md b/content/04-for-plugin-developers/01-tutorial/07-use variables in twig.md similarity index 100% rename from content/04-for plugin developers/01-tutorial/07-use variables in twig.md rename to content/04-for-plugin-developers/01-tutorial/07-use variables in twig.md diff --git a/content/04-for plugin developers/01-tutorial/08-make variables editable.md b/content/04-for-plugin-developers/01-tutorial/08-make variables editable.md similarity index 100% rename from content/04-for plugin developers/01-tutorial/08-make variables editable.md rename to content/04-for-plugin-developers/01-tutorial/08-make variables editable.md diff --git a/content/04-for plugin developers/01-tutorial/index.md b/content/04-for-plugin-developers/01-tutorial/index.md similarity index 100% rename from content/04-for plugin developers/01-tutorial/index.md rename to content/04-for-plugin-developers/01-tutorial/index.md diff --git a/content/04-for plugin developers/02-documentation/00-file structure.md b/content/04-for-plugin-developers/02-documentation/00-file structure.md similarity index 100% rename from content/04-for plugin developers/02-documentation/00-file structure.md rename to content/04-for-plugin-developers/02-documentation/00-file structure.md diff --git a/content/04-for plugin developers/02-documentation/01-configuration file.md b/content/04-for-plugin-developers/02-documentation/01-configuration file.md similarity index 100% rename from content/04-for plugin developers/02-documentation/01-configuration file.md rename to content/04-for-plugin-developers/02-documentation/01-configuration file.md diff --git a/content/04-for plugin developers/02-documentation/02-field overview.md b/content/04-for-plugin-developers/02-documentation/02-field overview.md similarity index 100% rename from content/04-for plugin developers/02-documentation/02-field overview.md rename to content/04-for-plugin-developers/02-documentation/02-field overview.md diff --git a/content/04-for plugin developers/02-documentation/03-basic php file.md b/content/04-for-plugin-developers/02-documentation/03-basic php file.md similarity index 100% rename from content/04-for plugin developers/02-documentation/03-basic php file.md rename to content/04-for-plugin-developers/02-documentation/03-basic php file.md diff --git a/content/04-for plugin developers/02-documentation/04-event overview.md b/content/04-for-plugin-developers/02-documentation/04-event overview.md similarity index 100% rename from content/04-for plugin developers/02-documentation/04-event overview.md rename to content/04-for-plugin-developers/02-documentation/04-event overview.md diff --git a/content/04-for plugin developers/02-documentation/05-method overview.md b/content/04-for-plugin-developers/02-documentation/05-method overview.md similarity index 100% rename from content/04-for plugin developers/02-documentation/05-method overview.md rename to content/04-for-plugin-developers/02-documentation/05-method overview.md diff --git a/content/04-for plugin developers/02-documentation/06-routes.md b/content/04-for-plugin-developers/02-documentation/06-routes.md similarity index 100% rename from content/04-for plugin developers/02-documentation/06-routes.md rename to content/04-for-plugin-developers/02-documentation/06-routes.md diff --git a/content/04-for plugin developers/02-documentation/07-middleware.md b/content/04-for-plugin-developers/02-documentation/07-middleware.md similarity index 100% rename from content/04-for plugin developers/02-documentation/07-middleware.md rename to content/04-for-plugin-developers/02-documentation/07-middleware.md diff --git a/content/04-for plugin developers/02-documentation/index.md b/content/04-for-plugin-developers/02-documentation/index.md similarity index 100% rename from content/04-for plugin developers/02-documentation/index.md rename to content/04-for-plugin-developers/02-documentation/index.md diff --git a/content/04-for plugin developers/index.md b/content/04-for-plugin-developers/index.md similarity index 100% rename from content/04-for plugin developers/index.md rename to content/04-for-plugin-developers/index.md diff --git a/content/05-info/00-release notes.md b/content/05-info/00-release-notes.md similarity index 100% rename from content/05-info/00-release notes.md rename to content/05-info/00-release-notes.md diff --git a/content/05-info/01-usage and licence.md b/content/05-info/01-usage-and-licence.md similarity index 100% rename from content/05-info/01-usage and licence.md rename to content/05-info/01-usage-and-licence.md diff --git a/content/05-info/02-Imprint and privacy.md b/content/05-info/02-Imprint-and-privacy.md similarity index 100% rename from content/05-info/02-Imprint and privacy.md rename to content/05-info/02-Imprint-and-privacy.md diff --git a/content/05-info/03-markdown test.md b/content/05-info/03-markdown-test.md similarity index 100% rename from content/05-info/03-markdown test.md rename to content/05-info/03-markdown-test.md diff --git a/system/Controllers/ContentApiController.php b/system/Controllers/ContentApiController.php index 47334e3..4c068df 100644 --- a/system/Controllers/ContentApiController.php +++ b/system/Controllers/ContentApiController.php @@ -11,7 +11,7 @@ use Typemill\Extensions\ParsedownExtension; class ContentApiController extends ContentController { public function publishArticle(Request $request, Response $response, $args) - { + { # get params from call $this->params = $request->getParams(); $this->uri = $request->getUri(); @@ -40,7 +40,10 @@ class ContentApiController extends ContentController # update the file $delete = $this->deleteContentFiles(['txt']); - # update the structure + # update the internal structure + $this->setStructure($draft = true, $cache = false); + + # update the public structure $this->setStructure($draft = false, $cache = false); return $response->withJson(['success'], 200); @@ -52,7 +55,7 @@ class ContentApiController extends ContentController } public function unpublishArticle(Request $request, Response $response, $args) - { + { # get params from call $this->params = $request->getParams(); $this->uri = $request->getUri(); @@ -99,6 +102,9 @@ class ContentApiController extends ContentController if($delete) { + # update the internal structure + $this->setStructure($draft = true, $cache = false); + # update the live structure $this->setStructure($draft = false, $cache = false); @@ -116,28 +122,50 @@ class ContentApiController extends ContentController $this->params = $request->getParams(); $this->uri = $request->getUri(); + # set url to base path initially + $url = $this->uri->getBaseUrl() . '/tm/content'; + # set structure if(!$this->setStructure($draft = true)){ return $response->withJson($this->errors, 404); } - # set item + # set item if(!$this->setItem()){ return $response->withJson($this->errors, 404); } - # update the file - $delete = $this->deleteContentFiles(['md','txt']); - + if($this->item->elementType == 'file') + { + $delete = $this->deleteContentFiles(['md','txt']); + } + elseif($this->item->elementType == 'folder') + { + $delete = $this->deleteContentFolder(); + } + if($delete) { + # check if it is a subfile or subfolder and set the redirect-url to the parent item + if(count($this->item->keyPathArray) > 1) + { + # get the parent item + $parentItem = Folder::getParentItem($this->structure, $this->item->keyPathArray); + + if($parentItem) + { + # an active file has been moved to another folder + $url .= $parentItem->urlRelWoF; + } + } + # update the live structure $this->setStructure($draft = false, $cache = false); - + #update the backend structure $this->setStructure($draft = true, $cache = false); - return $response->withJson(['success'], 200); + return $response->withJson(array('data' => $this->structure, 'errors' => false, 'url' => $url), 200); } else { - return $response->withJson(['errors' => ['message' => "Could not delete some files. Please check if the files exists and are writable"]], 404); + return $response->withJson(array('data' => $this->structure, 'errors' => $this->errors), 404); } } @@ -174,6 +202,9 @@ class ContentApiController extends ContentController /* update the file */ if($this->write->writeFile($this->settings['contentFolder'], $this->path, $contentJson)) { + # update the internal structure + $this->setStructure($draft = true, $cache = false); + return $response->withJson(['success'], 200); } else @@ -278,10 +309,171 @@ class ContentApiController extends ContentController return $response->withJson(array('data' => $internalStructure, 'errors' => false, 'url' => $url)); } + + public function createArticle(Request $request, Response $response, $args) + { + # get params from call + $this->params = $request->getParams(); + $this->uri = $request->getUri(); + + # url is only needed, if an active page is moved + $url = false; + + # set structure + if(!$this->setStructure($draft = true)){ return $response->withJson(array('data' => false, 'errors' => $this->errors, 'url' => $url), 404); } + + # validate input + if(!$this->validateNaviItem()){ return $response->withJson(array('data' => $this->structure, 'errors' => 'Special Characters not allowed. Length between 1 and 20 chars.', 'url' => $url), 422); } + + # get the ids (key path) for item, old folder and new folder + $folderKeyPath = explode('.', $this->params['folder_id']); + + # get the item from structure + $folder = Folder::getItemWithKeyPath($this->structure, $folderKeyPath); + if(!$folder){ return $response->withJson(array('data' => $this->structure, 'errors' => 'We could not find this page. Please refresh and try again.', 'url' => $url), 404); } + + # Rename all files within the folder to make sure, that namings and orders are correct + # get the content of the target folder + $folderContent = $folder->folderContent; + + # create the name for the new item + $nameParts = Folder::getStringParts($this->params['item_name']); + $name = implode("-", $nameParts); + $slug = $name; + + # initialize index + $index = 0; + + # initialise write object + $write = new Write(); + + # iterate through the whole content of the new folder + $writeError = false; + + foreach($folderContent as $folderItem) + { + # check, if the same name as new item, then return an error + if($folderItem->slug == $slug) + { + return $response->withJson(array('data' => $this->structure, 'errors' => 'There is already a page with this name. Please choose another name.', 'url' => $url), 404); + } + + if(!$write->moveElement($folderItem, $folder->path, $index)) + { + $writeError = true; + } + $index++; + } + + if($writeError){ return $response->withJson(array('data' => $this->structure, 'errors' => 'Something went wrong. Please refresh the page and check, if all folders and files are writable.', 'url' => $url), 404); } + + # add prefix number to the name + $namePath = $index > 9 ? $index . '-' . $name : '0' . $index . '-' . $name; + $folderPath = 'content' . $folder->path; + + if($this->params['type'] == 'file') + { + if(!$write->writeFile($folderPath, $namePath . '.txt', '')) + { + return $response->withJson(array('data' => $this->structure, 'errors' => 'We could not create the file. Please refresh the page and check, if all folders and files are writable.', 'url' => $url), 404); + } + } + elseif($this->params['type'] == 'folder') + { + if(!$write->checkPath($folderPath . DIRECTORY_SEPARATOR . $namePath)) + { + return $response->withJson(array('data' => $this->structure, 'errors' => 'We could not create the folder. Please refresh the page and check, if all folders and files are writable.', 'url' => $url), 404); + } + $write->writeFile($folderPath . DIRECTORY_SEPARATOR . $namePath, 'index.txt', ''); + } + + # update the structure for editor + $this->setStructure($draft = true, $cache = false); + + # get item for url and set it active again + if(isset($this->params['url'])) + { + $activeItem = Folder::getItemForUrl($this->structure, $this->params['url']); + } + + # activate this if you want to redirect after creating the page... + # $url = $this->uri->getBaseUrl() . '/tm/content' . $folder->urlRelWoF . '/' . $name; + + return $response->withJson(array('data' => $this->structure, 'errors' => false, 'url' => $url)); + } + + public function createBaseFolder(Request $request, Response $response, $args) + { + # get params from call + $this->params = $request->getParams(); + $this->uri = $request->getUri(); + + # url is only needed, if an active page is moved + $url = false; + + # set structure + if(!$this->setStructure($draft = true)){ return $response->withJson(array('data' => false, 'errors' => $this->errors, 'url' => $url), 404); } + + # validate input + #if(!$this->validateBaseFolder()){ return $response->withJson(array('data' => $this->structure, 'errors' => 'Special Characters not allowed. Length between 1 and 20 chars.', 'url' => $url), 422); } + + # create the name for the new item + $nameParts = Folder::getStringParts($this->params['item_name']); + $name = implode("-", $nameParts); + $slug = $name; + + # initialize index + $index = 0; + + # initialise write object + $write = new Write(); + + # iterate through the whole content of the new folder + $writeError = false; + + foreach($this->structure as $folder) + { + # check, if the same name as new item, then return an error + if($folder->slug == $slug) + { + return $response->withJson(array('data' => $this->structure, 'errors' => 'There is already a page with this name. Please choose another name.', 'url' => $url), 404); + } + + if(!$write->moveElement($folder, '', $index)) + { + $writeError = true; + } + $index++; + } + + if($writeError){ return $response->withJson(array('data' => $this->structure, 'errors' => 'Something went wrong. Please refresh the page and check, if all folders and files are writable.', 'url' => $url), 404); } + + # add prefix number to the name + $namePath = $index > 9 ? $index . '-' . $name : '0' . $index . '-' . $name; + $folderPath = 'content'; + + if(!$write->checkPath($folderPath . DIRECTORY_SEPARATOR . $namePath)) + { + return $response->withJson(array('data' => $this->structure, 'errors' => 'We could not create the folder. Please refresh the page and check, if all folders and files are writable.', 'url' => $url), 404); + } + $write->writeFile($folderPath . DIRECTORY_SEPARATOR . $namePath, 'index.txt', ''); + + # update the structure for editor + $this->setStructure($draft = true, $cache = false); + + # get item for url and set it active again + if(isset($this->params['url'])) + { + $activeItem = Folder::getItemForUrl($this->structure, $this->params['url']); + } + + return $response->withJson(array('data' => $this->structure, 'errors' => false, 'url' => $url)); + } + + public function createBlock(Request $request, Response $response, $args) { - /* get params from call */ $this->params = $request->getParams(); $this->uri = $request->getUri(); diff --git a/system/Controllers/ContentBackendController.php b/system/Controllers/ContentBackendController.php index 491cf0c..7eede3c 100644 --- a/system/Controllers/ContentBackendController.php +++ b/system/Controllers/ContentBackendController.php @@ -25,10 +25,10 @@ class ContentBackendController extends ContentController $this->params = isset($args['params']) ? ['url' => $this->uri->getBasePath() . '/' . $args['params']] : ['url' => $this->uri->getBasePath()]; # set structure - if(!$this->setStructure($draft = true)){ return $this->render404($response, array( 'navigation' => true, 'content' => $this->errors )); } + if(!$this->setStructure($draft = true)){ return $this->renderIntern404($response, array( 'navigation' => true, 'content' => $this->errors )); } # set item - if(!$this->setItem()){ return $this->render404($response, array( 'navigation' => $this->structure, 'settings' => $this->settings, 'content' => $this->errors )); } + if(!$this->setItem()){ return $this->renderIntern404($response, array( 'navigation' => $this->structure, 'settings' => $this->settings, 'content' => $this->errors )); } # get the breadcrumb (here we need it only to mark the actual item active in navigation) $breadcrumb = isset($this->item->keyPathArray) ? Folder::getBreadcrumb($this->structure, $this->item->keyPathArray) : false; diff --git a/system/Controllers/ContentController.php b/system/Controllers/ContentController.php index 18bc47e..7b20031 100644 --- a/system/Controllers/ContentController.php +++ b/system/Controllers/ContentController.php @@ -22,7 +22,7 @@ abstract class ContentController protected $uri; # holds the errors to output in frontend - protected $errors; + protected $errors = false; # holds a write object to write files protected $write; @@ -81,6 +81,11 @@ abstract class ContentController return $this->c->view->render($response->withStatus(404), '/404.twig', $data); } + protected function renderIntern404($response, $data = NULL) + { + return $this->c->view->render($response->withStatus(404), '/intern404.twig', $data); + } + protected function validateEditorInput() { $validate = new Validation(); @@ -106,6 +111,19 @@ abstract class ContentController } return true; } + + protected function validateNaviItem() + { + $validate = new Validation(); + $vResult = $validate->navigationItem($this->params); + + if(is_array($vResult)) + { + $this->errors = ['errors' => $vResult]; + return false; + } + return true; + } protected function setStructure($draft = false, $cache = true) { @@ -176,6 +194,7 @@ abstract class ContentController } elseif($item->elementType == 'folder') { + $item->pathWithoutItem = $item->path; $item->path = $item->path . DIRECTORY_SEPARATOR . 'index'; $item->pathWithoutType = $item->path; } @@ -221,24 +240,56 @@ abstract class ContentController } } - protected function deleteContentFiles($fileTypes) + protected function deleteContentFiles($fileTypes, $folder = false) { $basePath = $this->settings['rootPath'] . $this->settings['contentFolder']; - + foreach($fileTypes as $fileType) { - if(file_exists($basePath . $this->item->pathWithoutType . '.' . $fileType)) + if(file_exists($basePath . $this->item->pathWithoutType . '.' . $fileType) && !unlink($basePath . $this->item->pathWithoutType . '.' . $fileType) ) { - unlink($basePath . $this->item->pathWithoutType . '.' . $fileType); - - # if file could not be deleted - # $this->errors = ['errors' => ['message' => 'Could not delete files, please check, if files are writable.']]; - } + $this->errors = ['message' => 'We could not delete the file, please check, if the file is writable.']; + } + } + + if($this->errors) + { + return false; } return true; } + protected function deleteContentFolder() + { + $basePath = $this->settings['rootPath'] . $this->settings['contentFolder']; + $path = $basePath . $this->item->pathWithoutItem; + + if(file_exists($path)) + { + $files = array_diff(scandir($path), array('.', '..')); + + # check if there are folders first, then stop the operation + foreach ($files as $file) + { + if(is_dir(realpath($path) . DIRECTORY_SEPARATOR . $file)) + { + $this->errors = ['message' => 'Please delete the sub-folder first.']; + } + } + + if(!$this->errors) + { + foreach ($files as $file) + { + unlink(realpath($path) . DIRECTORY_SEPARATOR . $file); + } + return rmdir($path); + } + } + return false; + } + protected function setContent() { # if the file exists diff --git a/system/Models/Validation.php b/system/Models/Validation.php index d7620d7..a31583e 100644 --- a/system/Models/Validation.php +++ b/system/Models/Validation.php @@ -54,6 +54,16 @@ class Validation if(!$email){ return false; } return true; }, 'unknown'); + + Validator::addRule('noSpecialChars', function($field, $value, array $params, array $fields) + { + $format = '/[!@#$%^&*()_+=\[\]{};\':"\\|,.<>\/?]/'; + if ( preg_match($format, $value)) + { + return false; + } + return true; + }, 'contains special characters'); Validator::addRule('noHTML', function($field, $value, array $params, array $fields) { @@ -241,6 +251,33 @@ class Validation return $v->errors(); } } + + /** + * validation for new navigation items + * + * @param array $params with form data. + * @return true or $v->errors with array of errors to use in json-response + */ + + public function navigationItem(array $params) + { + $v = new Validator($params); + + $v->rule('required', ['folder_id', 'item_name', 'type', 'url']); + $v->rule('regex', 'folder_id', '/^[0-9.]+$/i'); + $v->rule('noSpecialChars', 'item_name'); + $v->rule('lengthBetween', 'item_name', 1, 20); + $v->rule('in', 'type', ['file', 'folder']); + + if($v->validate()) + { + return true; + } + else + { + return $v->errors(); + } + } /** * validation for dynamic fields ( settings for themes and plugins) diff --git a/system/Models/Write.php b/system/Models/Write.php index 992ac39..62079af 100644 --- a/system/Models/Write.php +++ b/system/Models/Write.php @@ -15,7 +15,7 @@ class Write public function checkPath($folder) { $folderPath = $this->basePath . $folder; - + if(!is_dir($folderPath)) { if(@mkdir($folderPath, 0774, true)) @@ -55,6 +55,7 @@ class Write if($this->checkPath($folder)) { $filePath = $this->basePath . $folder . DIRECTORY_SEPARATOR . $file; + $openFile = @fopen($filePath, "w"); if(!$openFile) @@ -79,7 +80,7 @@ class Write } return false; } - + public function moveElement($item, $folderPath, $index) { $filetypes = array('md', 'txt'); @@ -88,7 +89,7 @@ class Write $newOrder = ($index < 10) ? '0' . $index : $index; # create new path with foldername or filename but without file-type - $newPath = $this->basePath . 'content' . $folderPath . DIRECTORY_SEPARATOR . $newOrder . '-' . $item->name; + $newPath = $this->basePath . 'content' . $folderPath . DIRECTORY_SEPARATOR . $newOrder . '-' . str_replace(" ", "-", $item->name); if($item->elementType == 'folder') { @@ -125,58 +126,6 @@ class Write } } - return $result; - - /* - if($item->elementType == 'folder') - { - $newName = $newOrder . '-' . $item->name; - } - else - { - $newName = $newOrder . '-' . $item->name . '.' . $item->fileType; - } - - $oldPath = $this->basePath . 'content' . $item->path; - $newPath = $this->basePath . 'content' . $folderPath . DIRECTORY_SEPARATOR . $newName; - - if(@rename($oldPath, $newPath)) - { - $result = true; - } - - foreach($filetypes as $filetype) - { - #check if file exists - if(file_exists($oldPath)) - { - - } - } - - - # if it is a txt file, check, if there is a corresponding .md file and move it - if($result && $item->elementType == 'file' && $item->fileType == 'txt') - { - $result = false; - - $oldPath = substr($item->path, 0, strpos($item->path, ".")); - $oldPath = $this->basePath . 'content' . $oldPath . '.md'; - - if(file_exists($oldPath)) - { - $newName = $newOrder . '-' . $item->name . '.md'; - $newPath = $this->basePath . 'content' . $folderPath . DIRECTORY_SEPARATOR . $newName; - - if(@rename($oldPath, $newPath)) - { - $result = true; - } - } - } - - return $result; - */ - + return $result; } } \ No newline at end of file diff --git a/system/Routes/Api.php b/system/Routes/Api.php index f036712..9e70f72 100644 --- a/system/Routes/Api.php +++ b/system/Routes/Api.php @@ -6,9 +6,13 @@ use Typemill\Controllers\ContentApiController; use Typemill\Middleware\RestrictApiAccess; $app->get('/api/v1/themes', SettingsController::class . ':getThemeSettings')->setName('api.themes')->add(new RestrictApiAccess($container['router'])); + $app->post('/api/v1/article/publish', ContentApiController::class . ':publishArticle')->setName('api.article.publish')->add(new RestrictApiAccess($container['router'])); $app->delete('/api/v1/article/unpublish', ContentApiController::class . ':unpublishArticle')->setName('api.article.unpublish')->add(new RestrictApiAccess($container['router'])); +$app->post('/api/v1/article', ContentApiController::class . ':createArticle')->setName('api.article.create')->add(new RestrictApiAccess($container['router'])); $app->put('/api/v1/article', ContentApiController::class . ':updateArticle')->setName('api.article.update')->add(new RestrictApiAccess($container['router'])); $app->delete('/api/v1/article', ContentApiController::class . ':deleteArticle')->setName('api.article.delete')->add(new RestrictApiAccess($container['router'])); $app->post('/api/v1/article/sort', ContentApiController::class . ':sortArticle')->setName('api.article.sort')->add(new RestrictApiAccess($container['router'])); -// $app->post('/api/v1/block', ContentBackendController::class . ':createBlock')->setName('api.block.create')->add(new RestrictApiAccess($container['router'])); +$app->post('/api/v1/basefolder', ContentApiController::class . ':createBaseFolder')->setName('api.basefolder.create')->add(new RestrictApiAccess($container['router'])); + +// $app->post('/api/v1/block', ContentBackendController::class . ':createBlock')->setName('api.block.create')->add(new RestrictApiAccess($container['router'])); \ No newline at end of file diff --git a/system/author/css/fontello/config.json b/system/author/css/fontello/config.json index 1106f4f..08f747c 100644 --- a/system/author/css/fontello/config.json +++ b/system/author/css/fontello/config.json @@ -6,24 +6,6 @@ "units_per_em": 1000, "ascent": 850, "glyphs": [ - { - "uid": "5408be43f7c42bccee419c6be53fdef5", - "css": "doc-text", - "code": 61686, - "src": "fontawesome" - }, - { - "uid": "b091a8bd0fdade174951f17d936f51e4", - "css": "folder-empty", - "code": 61716, - "src": "fontawesome" - }, - { - "uid": "6533bdc16ab201eb3f3b27ce989cab33", - "css": "folder-open-empty", - "code": 61717, - "src": "fontawesome" - }, { "uid": "e99461abfef3923546da8d745372c995", "css": "cog", @@ -36,6 +18,18 @@ "code": 59393, "src": "fontawesome" }, + { + "uid": "8b9e6a8dd8f67f7c003ed8e7e5ee0857", + "css": "off", + "code": 59394, + "src": "fontawesome" + }, + { + "uid": "d7271d490b71df4311e32cdacae8b331", + "css": "home", + "code": 59395, + "src": "fontawesome" + }, { "uid": "e15f0d620a7897e2035c18c80142f6d9", "css": "link-ext", @@ -49,15 +43,21 @@ "src": "fontawesome" }, { - "uid": "8b9e6a8dd8f67f7c003ed8e7e5ee0857", - "css": "off", - "code": 59394, + "uid": "5408be43f7c42bccee419c6be53fdef5", + "css": "doc-text", + "code": 61686, "src": "fontawesome" }, { - "uid": "d7271d490b71df4311e32cdacae8b331", - "css": "home", - "code": 59395, + "uid": "b091a8bd0fdade174951f17d936f51e4", + "css": "folder-empty", + "code": 61716, + "src": "fontawesome" + }, + { + "uid": "44e04715aecbca7f266a17d5a7863c68", + "css": "plus", + "code": 59396, "src": "fontawesome" } ] diff --git a/system/author/css/fontello/css/fontello-codes.css b/system/author/css/fontello/css/fontello-codes.css index 723822a..fbf0885 100644 --- a/system/author/css/fontello/css/fontello-codes.css +++ b/system/author/css/fontello/css/fontello-codes.css @@ -3,8 +3,8 @@ .icon-picture:before { content: '\e801'; } /* '' */ .icon-off:before { content: '\e802'; } /* '' */ .icon-home:before { content: '\e803'; } /* '' */ +.icon-plus:before { content: '\e804'; } /* '' */ .icon-link-ext:before { content: '\f08e'; } /* '' */ .icon-resize-full-alt:before { content: '\f0b2'; } /* '' */ .icon-doc-text:before { content: '\f0f6'; } /* '' */ -.icon-folder-empty:before { content: '\f114'; } /* '' */ -.icon-folder-open-empty:before { content: '\f115'; } /* '' */ \ No newline at end of file +.icon-folder-empty:before { content: '\f114'; } /* '' */ \ No newline at end of file diff --git a/system/author/css/fontello/css/fontello-embedded.css b/system/author/css/fontello/css/fontello-embedded.css index 1eaf67f..0097a47 100644 --- a/system/author/css/fontello/css/fontello-embedded.css +++ b/system/author/css/fontello/css/fontello-embedded.css @@ -1,15 +1,15 @@ @font-face { font-family: 'fontello'; - src: url('../font/fontello.eot?91804628'); - src: url('../font/fontello.eot?91804628#iefix') format('embedded-opentype'), - url('../font/fontello.svg?91804628#fontello') format('svg'); + src: url('../font/fontello.eot?17418122'); + src: url('../font/fontello.eot?17418122#iefix') format('embedded-opentype'), + url('../font/fontello.svg?17418122#fontello') format('svg'); font-weight: normal; font-style: normal; } @font-face { font-family: 'fontello'; - src: url('data:application/octet-stream;base64,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') format('woff'), - url('data:application/octet-stream;base64,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BCVHI0cjYbAGJbAFJUmwAiVhuQgACABjYyMgWGIbIVljuAQAYiCwAFBYsEBgWWawAWNgIy4jICA8ijgjIVktsDossAAWILAIQyAuRyNHI2EgYLAgYGawAmIgsABQWLBAYFlmsAFjIyAgPIo4LbA7LCMgLkawAiVGUlggPFkusSsBFCstsDwsIyAuRrACJUZQWCA8WS6xKwEUKy2wPSwjIC5GsAIlRlJYIDxZIyAuRrACJUZQWCA8WS6xKwEUKy2wPiywNSsjIC5GsAIlRlJYIDxZLrErARQrLbA/LLA2K4ogIDywBCNCijgjIC5GsAIlRlJYIDxZLrErARQrsARDLrArKy2wQCywABawBCWwBCYgLkcjRyNhsAlDKyMgPCAuIzixKwEUKy2wQSyxCAQlQrAAFrAEJbAEJSAuRyNHI2EgsAQjQrAJQysgsGBQWCCwQFFYswIgAyAbswImAxpZQkIjIEewBEOwAmIgsABQWLBAYFlmsAFjYCCwASsgiophILACQ2BkI7ADQ2FkUFiwAkNhG7ADQ2BZsAMlsAJiILAAUFiwQGBZZrABY2GwAiVGYTgjIDwjOBshICBGI0ewASsjYTghWbErARQrLbBCLLA1Ky6xKwEUKy2wQyywNishIyAgPLAEI0IjOLErARQrsARDLrArKy2wRCywABUgR7AAI0KyAAEBFRQTLrAxKi2wRSywABUgR7AAI0KyAAEBFRQTLrAxKi2wRiyxAAEUE7AyKi2wRyywNCotsEgssAAWRSMgLiBGiiNhOLErARQrLbBJLLAII0KwSCstsEossgAAQSstsEsssgABQSstsEwssgEAQSstsE0ssgEBQSstsE4ssgAAQistsE8ssgABQistsFAssgEAQistsFEssgEBQistsFIssgAAPistsFMssgABPistsFQssgEAPistsFUssgEBPistsFYssgAAQCstsFcssgABQCstsFgssgEAQCstsFkssgEBQCstsFossgAAQystsFsssgABQystsFwssgEAQystsF0ssgEBQystsF4ssgAAPystsF8ssgABPystsGAssgEAPystsGEssgEBPystsGIssDcrLrErARQrLbBjLLA3K7A7Ky2wZCywNyuwPCstsGUssAAWsDcrsD0rLbBmLLA4Ky6xKwEUKy2wZyywOCuwOystsGgssDgrsDwrLbBpLLA4K7A9Ky2waiywOSsusSsBFCstsGsssDkrsDsrLbBsLLA5K7A8Ky2wbSywOSuwPSstsG4ssDorLrErARQrLbBvLLA6K7A7Ky2wcCywOiuwPCstsHEssDorsD0rLbByLLMJBAIDRVghGyMhWUIrsAhlsAMkUHiwARUwLQBLuADIUlixAQGOWbABuQgACABjcLEABUKyAAEAKrEABUKzCgIBCCqxAAVCsw4AAQgqsQAGQroCwAABAAkqsQAHQroAQAABAAkqsQMARLEkAYhRWLBAiFixA2REsSYBiFFYugiAAAEEQIhjVFixAwBEWVlZWbMMAgEMKrgB/4WwBI2xAgBEAAA=') format('truetype'); + src: url('data:application/octet-stream;base64,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') format('woff'), + url('data:application/octet-stream;base64,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') format('truetype'); } /* Chrome hack: SVG is rendered more smooth in Windozze. 100% magic, uncomment if you need it. */ /* Note, that will break hinting! In other OS-es font will be not as sharp as it could be */ @@ -17,7 +17,7 @@ @media screen and (-webkit-min-device-pixel-ratio:0) { @font-face { font-family: 'fontello'; - src: url('../font/fontello.svg?91804628#fontello') format('svg'); + src: url('../font/fontello.svg?17418122#fontello') format('svg'); } } */ @@ -56,8 +56,8 @@ .icon-picture:before { content: '\e801'; } /* '' */ .icon-off:before { content: '\e802'; } /* '' */ .icon-home:before { content: '\e803'; } /* '' */ +.icon-plus:before { content: '\e804'; } /* '' */ .icon-link-ext:before { content: '\f08e'; } /* '' */ .icon-resize-full-alt:before { content: '\f0b2'; } /* '' */ .icon-doc-text:before { content: '\f0f6'; } /* '' */ -.icon-folder-empty:before { content: '\f114'; } /* '' */ -.icon-folder-open-empty:before { content: '\f115'; } /* '' */ \ No newline at end of file +.icon-folder-empty:before { content: '\f114'; } /* '' */ \ No newline at end of file diff --git a/system/author/css/fontello/css/fontello-ie7-codes.css b/system/author/css/fontello/css/fontello-ie7-codes.css index a8de47a..0a6a63b 100644 --- a/system/author/css/fontello/css/fontello-ie7-codes.css +++ b/system/author/css/fontello/css/fontello-ie7-codes.css @@ -3,8 +3,8 @@ .icon-picture { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); } .icon-off { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); } .icon-home { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); } +.icon-plus { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); } .icon-link-ext { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); } .icon-resize-full-alt { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); } .icon-doc-text { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); } -.icon-folder-empty { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); } -.icon-folder-open-empty { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); } \ No newline at end of file +.icon-folder-empty { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); } \ No newline at end of file diff --git a/system/author/css/fontello/css/fontello-ie7.css b/system/author/css/fontello/css/fontello-ie7.css index 7e8782e..abec645 100644 --- a/system/author/css/fontello/css/fontello-ie7.css +++ b/system/author/css/fontello/css/fontello-ie7.css @@ -14,8 +14,8 @@ .icon-picture { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); } .icon-off { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); } .icon-home { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); } +.icon-plus { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); } .icon-link-ext { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); } .icon-resize-full-alt { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); } .icon-doc-text { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); } -.icon-folder-empty { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); } -.icon-folder-open-empty { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); } \ No newline at end of file +.icon-folder-empty { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); } \ No newline at end of file diff --git a/system/author/css/fontello/css/fontello.css b/system/author/css/fontello/css/fontello.css index 8e91c59..6f74739 100644 --- a/system/author/css/fontello/css/fontello.css +++ b/system/author/css/fontello/css/fontello.css @@ -1,11 +1,11 @@ @font-face { font-family: 'fontello'; - src: url('../font/fontello.eot?55717473'); - src: url('../font/fontello.eot?55717473#iefix') format('embedded-opentype'), - url('../font/fontello.woff2?55717473') format('woff2'), - url('../font/fontello.woff?55717473') format('woff'), - url('../font/fontello.ttf?55717473') format('truetype'), - url('../font/fontello.svg?55717473#fontello') format('svg'); + src: url('../font/fontello.eot?95383779'); + src: url('../font/fontello.eot?95383779#iefix') format('embedded-opentype'), + url('../font/fontello.woff2?95383779') format('woff2'), + url('../font/fontello.woff?95383779') format('woff'), + url('../font/fontello.ttf?95383779') format('truetype'), + url('../font/fontello.svg?95383779#fontello') format('svg'); font-weight: normal; font-style: normal; } @@ -15,7 +15,7 @@ @media screen and (-webkit-min-device-pixel-ratio:0) { @font-face { font-family: 'fontello'; - src: url('../font/fontello.svg?55717473#fontello') format('svg'); + src: url('../font/fontello.svg?95383779#fontello') format('svg'); } } */ @@ -59,8 +59,8 @@ .icon-picture:before { content: '\e801'; } /* '' */ .icon-off:before { content: '\e802'; } /* '' */ .icon-home:before { content: '\e803'; } /* '' */ +.icon-plus:before { content: '\e804'; } /* '' */ .icon-link-ext:before { content: '\f08e'; } /* '' */ .icon-resize-full-alt:before { content: '\f0b2'; } /* '' */ .icon-doc-text:before { content: '\f0f6'; } /* '' */ -.icon-folder-empty:before { content: '\f114'; } /* '' */ -.icon-folder-open-empty:before { content: '\f115'; } /* '' */ \ No newline at end of file +.icon-folder-empty:before { content: '\f114'; } /* '' */ \ No newline at end of file diff --git a/system/author/css/fontello/demo.html b/system/author/css/fontello/demo.html index d321c8a..a4e80b1 100644 --- a/system/author/css/fontello/demo.html +++ b/system/author/css/fontello/demo.html @@ -229,11 +229,11 @@ body { } @font-face { font-family: 'fontello'; - src: url('./font/fontello.eot?16979120'); - src: url('./font/fontello.eot?16979120#iefix') format('embedded-opentype'), - url('./font/fontello.woff?16979120') format('woff'), - url('./font/fontello.ttf?16979120') format('truetype'), - url('./font/fontello.svg?16979120#fontello') format('svg'); + src: url('./font/fontello.eot?67933592'); + src: url('./font/fontello.eot?67933592#iefix') format('embedded-opentype'), + url('./font/fontello.woff?67933592') format('woff'), + url('./font/fontello.ttf?67933592') format('truetype'), + url('./font/fontello.svg?67933592#fontello') format('svg'); font-weight: normal; font-style: normal; } @@ -304,13 +304,13 @@ body {
Sorry, but we did not find the page that you are looking for.
+ +{% endblock %} \ No newline at end of file diff --git a/system/author/js/vue-editor.js b/system/author/js/vue-editor.js index d04b002..68de5a6 100644 --- a/system/author/js/vue-editor.js +++ b/system/author/js/vue-editor.js @@ -168,10 +168,10 @@ let editor = new Vue({ self.modalWindow = "modal"; if(result.errors.message){ self.errors.message = result.errors.message }; } - else + else if(result.url) { self.modalWindow = "modal"; - window.location.replace(self.root + '/tm/content'); + window.location.replace(result.url); } } }, method, url, this.form ); diff --git a/system/author/js/vue-navi.js b/system/author/js/vue-navi.js index 8ef51ad..fab1675 100644 --- a/system/author/js/vue-navi.js +++ b/system/author/js/vue-navi.js @@ -1,6 +1,11 @@ const navcomponent = Vue.component('navigation', { template: '#navigation-template', - props: ['name', 'parent', 'active', 'filetype', 'element', 'folder', 'level', 'url', 'root', 'freeze'], + props: ['name', 'newItem', 'parent', 'active', 'filetype', 'elementtype', 'element', 'folder', 'level', 'url', 'root', 'freeze'], + data: function () { + return { + showForm: false + } + }, methods: { checkMove : function(evt) { @@ -26,14 +31,14 @@ const navcomponent = Vue.component('navigation', { 'item_id': evt.item.id, 'parent_id_from': evt.from.parentNode.id, 'parent_id_to': evt.to.parentNode.id, - 'index_old': evt.oldIndex, + 'index_old': evt.oldIndex, 'index_new': evt.newIndex, 'active': evt.item.firstChild.className, 'url': document.getElementById("path").value, 'csrf_name': document.getElementById("csrf_name").value, 'csrf_value': document.getElementById("csrf_value").value, }; - + if(locator.parent_id_from == locator.parent_id_to && locator.index_old == locator.index_new) { return @@ -82,15 +87,15 @@ const navcomponent = Vue.component('navigation', { level = level.split('.').length; return 'level-' + level; }, - getIcon : function(filetype) + getIcon : function(elementtype, filetype) { - if(filetype == 'file') + if(elementtype == 'file') { - return 'icon-doc-text' + return 'icon-doc-text ' + filetype } - if(filetype == 'folder') + if(elementtype == 'folder') { - return 'icon-folder-empty' + return 'icon-folder-empty ' + filetype } }, checkActive : function(active,parent) @@ -100,7 +105,64 @@ const navcomponent = Vue.component('navigation', { return 'active'; } return 'inactive'; - } + }, + toggleForm : function() + { + this.showForm = !this.showForm; + }, + addFile : function(type) + { + editor.errors.message = false; + + if(this.$root.$data.format.test(this.newItem) || !this.newItem || this.newItem.length > 20) + { + editor.errors.message = 'Special Characters are not allowed. Length between 1 and 20.'; + return; + } + + var newItem = { + 'folder_id': this.$el.id, + 'item_name': this.newItem, + 'type': type, + 'url': document.getElementById("path").value, + 'csrf_name': document.getElementById("csrf_name").value, + 'csrf_value': document.getElementById("csrf_value").value, + }; + + // evt.item.classList.add("load"); + + var self = this; + + self.$root.$data.freeze = true; + self.errors = {title: false, content: false, message: false}; + + var url = this.root + '/api/v1/article'; + var method = 'POST'; + + sendJson(function(response, httpStatus) + { + if(response) + { + self.$root.$data.freeze = false; + var result = JSON.parse(response); + + if(result.errors) + { + editor.errors.message = result.errors; + } + if(result.url) + { + window.location.replace(result.url); + } + if(result.data) + { + // evt.item.classList.remove("load"); + self.$root.$data.items = result.data; + self.showForm = false; + } + } + }, method, url, newItem ); + }, } }) @@ -109,12 +171,16 @@ let navi = new Vue({ components: { 'navcomponent': navcomponent, }, - data: { - title: "Navigation", - items: JSON.parse(document.getElementById("data-navi").dataset.navi), - root: document.getElementById("main").dataset.url, - freeze: false, - modalWindow: "modal hide", + data: function () { + return { + title: "Navigation", + items: JSON.parse(document.getElementById("data-navi").dataset.navi), + root: document.getElementById("main").dataset.url, + freeze: false, + modalWindow: "modal hide", + format: /[!@#$%^&*()_+=\[\]{};':"\\|,.<>\/?]/, + folderName: '', + } }, methods:{ onStart: function(evt){ @@ -129,5 +195,52 @@ let navi = new Vue({ hideModal: function(e){ this.modalWindow = "modal"; }, + addFolder: function() + { + editor.errors.message = false; + + if(this.format.test(this.folderName) || this.folderName < 1 || this.folderName.length > 20) + { + editor.errors.message = 'Special Characters are not allowed. Length between 1 and 20.'; + return; + } + + var newFolder = { + 'item_name': this.folderName, + 'url': document.getElementById("path").value, + 'csrf_name': document.getElementById("csrf_name").value, + 'csrf_value': document.getElementById("csrf_value").value, + }; + + var self = this; + + self.freeze = true; + self.errors = {title: false, content: false, message: false}; + + var url = this.root + '/api/v1/basefolder'; + var method = 'POST'; + + sendJson(function(response, httpStatus) + { + if(response) + { + self.freeze = false; + var result = JSON.parse(response); + + if(result.errors) + { + editor.errors.message = result.errors; + } + if(result.url) + { + window.location.replace(result.url); + } + if(result.data) + { + self.items = result.data; + } + } + }, method, url, newFolder ); + } } }) \ No newline at end of file diff --git a/system/author/layouts/layoutBlank.twig b/system/author/layouts/layoutBlank.twig new file mode 100644 index 0000000..cb4ad52 --- /dev/null +++ b/system/author/layouts/layoutBlank.twig @@ -0,0 +1,34 @@ + + + + +