diff --git a/system/typemill/Controllers/ControllerSystemApi.php b/system/typemill/Controllers/ControllerApiGlobals.php similarity index 83% rename from system/typemill/Controllers/ControllerSystemApi.php rename to system/typemill/Controllers/ControllerApiGlobals.php index 45397fe..68ae64d 100644 --- a/system/typemill/Controllers/ControllerSystemApi.php +++ b/system/typemill/Controllers/ControllerApiGlobals.php @@ -5,17 +5,8 @@ namespace Typemill\Controllers; use Psr\Http\Message\ServerRequestInterface as Request; use Psr\Http\Message\ResponseInterface as Response; -class ControllerSystemApi extends ControllerData +class ControllerApiGlobal extends ControllerData { - public function getSettings(Request $request, Response $response) - { - $response->getBody()->write(json_encode([ - 'settings' => $this->settings - ])); - - return $response->withHeader('Content-Type', 'application/json')->withStatus(200); - } - public function getSystemNavi(Request $request, Response $response) { # won't work because api has no session, instead you have to pass user @@ -34,4 +25,13 @@ class ControllerSystemApi extends ControllerData return $response->withHeader('Content-Type', 'application/json')->withStatus(200); } + + public function getTranslations(Request $request, Response $response) + { + $response->getBody()->write(json_encode([ + 'translations' => $this->c->get('translations'), + ])); + + return $response->withHeader('Content-Type', 'application/json')->withStatus(200); + } } \ No newline at end of file diff --git a/system/typemill/Controllers/ControllerApiSystemPlugins.php b/system/typemill/Controllers/ControllerApiSystemPlugins.php new file mode 100644 index 0000000..92e8d9b --- /dev/null +++ b/system/typemill/Controllers/ControllerApiSystemPlugins.php @@ -0,0 +1,54 @@ +c->get('acl')->isAllowed($request->getAttribute('userrole'), 'system', 'update')) + { + $response->getBody()->write(json_encode([ + 'message' => 'You are not allowed to update settings.' + ])); + + return $response->withHeader('Content-Type', 'application/json')->withStatus(403); + } + + $params = $request->getParsedBody(); + $pluginname = $params['plugin']; + $plugininput = $params['settings']; + $yaml = new Yaml('\Typemill\Models\Storage'); + $formdefinitions = $yaml->getYaml('plugins' . DIRECTORY_SEPARATOR . $pluginname, $pluginname . '.yaml'); + + # validate input + $validator = new Validation(); + $this->recursiveValidation($formdefinitions['forms']['fields'], $plugininput, $validator, $themeOrPlugin = 'plugins', $name = $pluginname); + + if(!empty($this->errors)) + { + $response->getBody()->write(json_encode([ + 'message' => 'Please correct tbe errors in form.', + 'errors' => $this->errors + ])); + + return $response->withHeader('Content-Type', 'application/json')->withStatus(400); + } + + # store updated settings here + $yaml->updateYaml('settings', 'settings.yaml', $this->settings); + + $response->getBody()->write(json_encode([ + 'message' => 'settings have been saved', + ])); + + return $response->withHeader('Content-Type', 'application/json')->withStatus(200); + } +} \ No newline at end of file diff --git a/system/typemill/Controllers/ControllerApiSystemSettings.php b/system/typemill/Controllers/ControllerApiSystemSettings.php new file mode 100644 index 0000000..6d6b11d --- /dev/null +++ b/system/typemill/Controllers/ControllerApiSystemSettings.php @@ -0,0 +1,76 @@ +c->get('acl')->isAllowed($request->getAttribute('userrole'), 'system', 'update')) + { + $response->getBody()->write(json_encode([ + 'message' => 'You are not allowed to update settings.' + ])); + + return $response->withHeader('Content-Type', 'application/json')->withStatus(403); + } + + $response->getBody()->write(json_encode([ + 'settings' => $this->settings + ])); + + return $response->withHeader('Content-Type', 'application/json')->withStatus(200); + } + + public function updateSettings(Request $request, Response $response) + { + # minimum permission are admin rights + if(!$this->c->get('acl')->isAllowed($request->getAttribute('userrole'), 'system', 'update')) + { + $response->getBody()->write(json_encode([ + 'message' => 'You are not allowed to update settings.' + ])); + + return $response->withHeader('Content-Type', 'application/json')->withStatus(403); + } + + $params = $request->getParsedBody(); + $settingsinput = $params['settings']; + $yaml = new Yaml('\Typemill\Models\Storage'); + $formdefinitions = $yaml->getYaml('system/typemill/settings', 'system.yaml'); + + # validate input + $validator = new Validation(); + $this->recursiveValidation($formdefinitions, $settingsinput, $validator); + + if(!empty($this->errors)) + { + $response->getBody()->write(json_encode([ + 'message' => 'Please correct errors in form.', + 'errors' => $this->errors + ])); + + return $response->withHeader('Content-Type', 'application/json')->withStatus(400); + } + + # store updated settings here + $yaml->updateYaml('settings', 'settings.yaml', $this->settings); + + $response->getBody()->write(json_encode([ + 'message' => 'settings have been saved', + ])); + + return $response->withHeader('Content-Type', 'application/json')->withStatus(200); + } +} \ No newline at end of file diff --git a/system/typemill/Controllers/ControllerApiSystemThemes.php b/system/typemill/Controllers/ControllerApiSystemThemes.php new file mode 100644 index 0000000..b1d5e3f --- /dev/null +++ b/system/typemill/Controllers/ControllerApiSystemThemes.php @@ -0,0 +1,54 @@ +c->get('acl')->isAllowed($request->getAttribute('userrole'), 'system', 'update')) + { + $response->getBody()->write(json_encode([ + 'message' => 'You are not allowed to update settings.' + ])); + + return $response->withHeader('Content-Type', 'application/json')->withStatus(403); + } + + $params = $request->getParsedBody(); + $themename = $params['theme']; + $themeinput = $params['settings']; + $yaml = new Yaml('\Typemill\Models\Storage'); + $formdefinitions = $yaml->getYaml('themes' . DIRECTORY_SEPARATOR . $themename, $themename . '.yaml'); + + # validate input + $validator = new Validation(); + $this->recursiveValidation($formdefinitions['forms']['fields'], $themeinput, $validator, $themeOrPlugin = 'themes', $name = $themename); + + if(!empty($this->errors)) + { + $response->getBody()->write(json_encode([ + 'message' => 'Please correct tbe errors in form.', + 'errors' => $this->errors + ])); + + return $response->withHeader('Content-Type', 'application/json')->withStatus(400); + } + + # store updated settings here + $yaml->updateYaml('settings', 'settings.yaml', $this->settings); + + $response->getBody()->write(json_encode([ + 'message' => 'settings have been saved', + ])); + + return $response->withHeader('Content-Type', 'application/json')->withStatus(200); + } +} \ No newline at end of file diff --git a/system/typemill/Controllers/ControllerApiSystemUsers.php b/system/typemill/Controllers/ControllerApiSystemUsers.php new file mode 100644 index 0000000..bfdf7f0 --- /dev/null +++ b/system/typemill/Controllers/ControllerApiSystemUsers.php @@ -0,0 +1,337 @@ +c->get('acl')->isAllowed($request->getAttribute('userrole'), 'system', 'update')) + { + $response->getBody()->write(json_encode([ + 'message' => 'You are not allowed to update settings.' + ])); + + return $response->withHeader('Content-Type', 'application/json')->withStatus(403); + } + + $usernames = $request->getQueryParams()['usernames'] ?? false; + $user = new User(); + $userdata = []; + + if($usernames) + { + foreach($usernames as $username) + { + $existinguser = $user->setUser($username); + if($existinguser) + { + $userdata[] = $user->getUserData(); + } + } + } + + $response->getBody()->write(json_encode([ + 'userdata' => $userdata + ])); + + return $response->withHeader('Content-Type', 'application/json')->withStatus(200); + } + + # returns userdata + public function getUsersByEmail($request, $response, $args) + { + # minimum permission are admin rights + if(!$this->c->get('acl')->isAllowed($request->getAttribute('userrole'), 'system', 'update')) + { + $response->getBody()->write(json_encode([ + 'message' => 'You are not allowed to update settings.' + ])); + + return $response->withHeader('Content-Type', 'application/json')->withStatus(403); + } + + $email = $request->getQueryParams()['email'] ?? false; + $user = new User(); + $userdata = []; + + $usernames = $user->findUsersByEmail($email); + + if($usernames) + { + foreach($usernames as $username) + { + $user->setUser($username); + $userdata[] = $user->getUserData(); + } + } + + $response->getBody()->write(json_encode([ + 'userdata' => $userdata + ])); + + return $response->withHeader('Content-Type', 'application/json')->withStatus(200); + } + + #returns userdata + public function getUsersByRole($request, $response, $args) + { + # minimum permission are admin rights + if(!$this->c->get('acl')->isAllowed($request->getAttribute('userrole'), 'system', 'update')) + { + $response->getBody()->write(json_encode([ + 'message' => 'You are not allowed to update settings.' + ])); + + return $response->withHeader('Content-Type', 'application/json')->withStatus(403); + } + + $role = $request->getQueryParams()['role'] ?? false; + $user = new User(); + $userdata = []; + + $usernames = $user->findUsersByRole($role); + + if($usernames) + { + foreach($usernames as $username) + { + $user->setUser($username); + $userdata[] = $user->getUserData(); + } + } + + $response->getBody()->write(json_encode([ + 'userdata' => $userdata + ])); + + return $response->withHeader('Content-Type', 'application/json')->withStatus(200); + } + + public function updateUser($request, $response, $args) + { + $params = $request->getParsedBody(); + $userdata = $params['userdata'] ?? false; + $username = $params['userdata']['username'] ?? false; + $isAdmin = $this->c->get('acl')->isAllowed($request->getAttribute('userrole'), 'userlist', 'write'); + + if(!$userdata OR !$username) + { + $response->getBody()->write(json_encode([ + 'message' => 'Userdata and username is required.' + ])); + + return $response->withHeader('Content-Type', 'application/json')->withStatus(422); + } + + # if a non-admin-user tries to update another account + if(!$isAdmin AND ($username !== $request->getAttribute('username')) ) + { + $response->getBody()->write(json_encode([ + 'message' => 'You are not allowed to update another user.' + ])); + + return $response->withHeader('Content-Type', 'application/json')->withStatus(403); + } + + # make sure that invalid password input is stripped out + if(isset($userdata['password']) && $userdata['password'] == '' ) + { + unset($userdata['password']); + unset($userdata['newpassword']); + } + + $user = new User(); + + # make sure you set a user with password when you update, otherwise it will delete the password completely + $user->setUserWithPassword($username); + + $userfields = $this->getUserFields($request->getAttribute('userrole')); + + # validate input + $validator = new Validation(); + + # loop through form-definitions, ignores everything that is not defined in yaml + foreach($userfields as $fieldname => $fielddefinitions) + { + # if there is no value for a field + if(!isset($userdata[$fieldname])) + { + continue; + } + + # ignore readonly-fields + if(isset($fielddefinitions['readonly']) && ($fielddefinitions['readonly'] !== false) ) + { + continue; + } + + # new password needs special validation + if($fieldname == 'password') + { + $validationresult = $validator->newPassword($userdata); + + if($validationresult === true) + { + # encrypt new password + $newpassword = $user->generatePassword($userdata['newpassword']); + + # if input is valid, overwrite value in original user + $user->setValue('password', $newpassword); + } + else + { + $this->errors[$fieldname] = $validationresult[$fieldname][0]; + } + } + else + { + # standard validation + $validationresult = $validator->field($fieldname, $userdata[$fieldname], $fielddefinitions); + + if($validationresult === true) + { + # if input is valid, overwrite value in original user + $user->setValue($fieldname, $userdata[$fieldname]); + } + else + { + $this->errors[$fieldname] = $validationresult[$fieldname][0]; + } + } + } + + if(!empty($this->errors)) + { + $response->getBody()->write(json_encode([ + 'message' => 'Please correct tbe errors in form.', + 'errors' => $this->errors + ])); + + return $response->withHeader('Content-Type', 'application/json')->withStatus(400); + } + + if(!$user->updateUser()) + { + $response->getBody()->write(json_encode([ + 'message' => $user->getError() + ])); + + return $response->withHeader('Content-Type', 'application/json')->withStatus(422); + } + + $response->getBody()->write(json_encode([ + 'message' => 'User has been updated.' + ])); + + return $response->withHeader('Content-Type', 'application/json'); + } + +/* + public function updateUser($request, $response, $args) + { + # check if user is allowed to view (edit) userlist and other users + if(!$this->c->acl->isAllowed($_SESSION['role'], 'userlist', 'write')) + { + # if an editor tries to update other userdata than its own + if($_SESSION['user'] !== $userdata['username']) + { + return $response->withRedirect($this->c->router->pathFor('user.account')); + } + + # non admins cannot change their userrole, so set it to session-value + $userdata['userrole'] = $_SESSION['role']; + } + + + + $params = $request->getParams(); + $userdata = $params['user']; + $user = new User(); + $validate = new Validation(); + $userroles = $this->c->acl->getRoles(); + + $redirectRoute = ($userdata['username'] == $_SESSION['user']) ? $this->c->router->pathFor('user.account') : $this->c->router->pathFor('user.show', ['username' => $userdata['username']]); + + # validate standard fields for users + if($validate->existingUser($userdata, $userroles)) + { + # validate custom input fields and return images + $userfields = $this->getUserFields($userdata['userrole']); + $imageFields = $this->validateInput('users', 'user', $userdata, $validate, $userfields); + + if(!empty($imageFields)) + { + $images = $request->getUploadedFiles(); + + if(isset($images['user'])) + { + # set image size + $settings = $this->c->get('settings'); + $imageSizes = $settings['images']; + $imageSizes['live'] = ['width' => 500, 'height' => 500]; + $settings->replace(['images' => $imageSizes]); + $imageresult = $this->saveImages($imageFields, $userdata, $settings, $images['user']); + + if(isset($_SESSION['slimFlash']['error'])) + { + return $response->withRedirect($redirectRoute); + } + elseif(isset($imageresult['username'])) + { + $userdata = $imageresult; + } + } + } + + # check for errors and redirect to path, if errors found + if(isset($_SESSION['errors'])) + { + $this->c->flash->addMessage('error', 'Please correct the errors'); + return $response->withRedirect($redirectRoute); + } + + if(empty($userdata['password']) AND empty($userdata['newpassword'])) + { + # make sure no invalid passwords go into model + unset($userdata['password']); + unset($userdata['newpassword']); + + $user->updateUser($userdata); + $this->c->flash->addMessage('info', 'Saved all changes'); + return $response->withRedirect($redirectRoute); + } + elseif($validate->newPassword($userdata)) + { + $userdata['password'] = $userdata['newpassword']; + unset($userdata['newpassword']); + + $user->updateUser($userdata); + $this->c->flash->addMessage('info', 'Saved all changes'); + return $response->withRedirect($redirectRoute); + } + } + + # change error-array for formbuilder + $errors = $_SESSION['errors']; + unset($_SESSION['errors']); + $_SESSION['errors']['user'] = $errors;# + + $this->c->flash->addMessage('error', 'Please correct your input'); + return $response->withRedirect($redirectRoute); + } + } + */ +} \ No newline at end of file diff --git a/system/typemill/Controllers/ControllerData.php b/system/typemill/Controllers/ControllerData.php index 2a883ce..62ccb81 100644 --- a/system/typemill/Controllers/ControllerData.php +++ b/system/typemill/Controllers/ControllerData.php @@ -12,6 +12,8 @@ use Typemill\Events\OnSystemnaviLoaded; class ControllerData extends Controller { + protected $errors = []; + protected function getMainNavigation($userrole) { $yaml = new Yaml('\Typemill\Models\Storage'); @@ -27,11 +29,11 @@ class ControllerData extends Controller if($acl->isAllowed($userrole, $naviitem['aclresource'], $naviitem['aclprivilege'])) { # not nice: check if the navi-item is active (e.g if segments like "content" or "system" is in current url) - if($name == 'content' && strpos($this->settings['routepath'], 'tm/content')) + if($name == 'content' && strpos($this->c->get('urlinfo')['route'], 'tm/content')) { $naviitem['active'] = true; } - elseif($name == 'account' && strpos($this->settings['routepath'], 'tm/account')) + elseif($name == 'account' && strpos($this->c->get('urlinfo')['route'], 'tm/account')) { $naviitem['active'] = true; } @@ -74,7 +76,7 @@ class ControllerData extends Controller { # check if the navi-item is active (e.g if segments like "content" or "system" is in current url) # a bit fragile because url-segment and name/key in systemnavi.yaml and plugins have to be the same - if(strpos($this->settings['routepath'], 'tm/' . $name)) + if(strpos($this->c->get('urlinfo')['route'], 'tm/' . $name)) { $naviitem['active'] = true; } @@ -87,4 +89,185 @@ class ControllerData extends Controller return $allowedsystemnavi; } + + protected function getThemeDetails() + { + $themes = $this->getThemes(); + + $themeDetails = []; + foreach($themes as $themeName) + { + $themeDetails[$themeName] = $this->getThemeDefinition($themeName); + } + + return $themeDetails; + } + + protected function getThemes() + { + $themeFolder = $this->c->get('settings')['rootPath'] . DIRECTORY_SEPARATOR . $this->c->get('settings')['themeFolder']; + $themeFolderC = scandir($themeFolder); + $themes = []; + foreach ($themeFolderC as $key => $theme) + { + if (!in_array($theme, [".",".."])) + { + if (is_dir($themeFolder . DIRECTORY_SEPARATOR . $theme)) + { + $themes[] = $theme; + } + } + } + + return $themes; + } + + protected function getThemeDefinition($themeName) + { + $yaml = new Yaml('\Typemill\Models\Storage'); + + $themeSettings = $yaml->getYaml('themes' . DIRECTORY_SEPARATOR . $themeName, $themeName . '.yaml'); + + # add standard-textarea for custom css + $themeSettings['forms']['fields']['customcss'] = [ + 'type' => 'textarea', + 'label' => 'Custom CSS', + 'rows' => 10, + 'class' => 'codearea', + 'description' => 'You can overwrite the theme-css with your own css here.' + ]; + + # add image preview file + $themeSettings['preview'] = 'http://localhost/typemill/themes/' . $themeName . '/' . $themeName . '.png'; + + return $themeSettings; + } + + protected function getPluginDetails() + { + $plugins = $this->getPlugins(); + + $pluginDetails = []; + foreach($plugins as $pluginName) + { + $pluginDetails[$pluginName] = $this->getPluginDefinition($pluginName); + } + + return $pluginDetails; + } + + protected function getPlugins() + { + $pluginFolder = $this->c->get('settings')['rootPath'] . DIRECTORY_SEPARATOR . $this->c->get('settings')['pluginFolder']; + $pluginFolderC = scandir($pluginFolder); + $plugins = []; + foreach ($pluginFolderC as $key => $plugin) + { + if (!in_array($plugin, [".",".."])) + { + if (is_dir($pluginFolder . DIRECTORY_SEPARATOR . $plugin)) + { + $plugins[] = $plugin; + } + } + } + + return $plugins; + } + + protected function getPluginDefinition($pluginName) + { + $yaml = new Yaml('\Typemill\Models\Storage'); + + $pluginSettings = $yaml->getYaml('plugins' . DIRECTORY_SEPARATOR . $pluginName, $pluginName . '.yaml'); + + return $pluginSettings; + } + + protected function getUserFields($userrole,$inspectorrole = NULL) + { + if(!$inspectorrole) + { + # if there is no inspector-role we assume that it is the same role like the userrole + # for example account is always visible by the same user + # edit user can be done by another user like admin. + $inspectorrole = $userrole; + } + + $yaml = new Yaml('\Typemill\Models\Storage'); + + $userfields = $yaml->getYaml('system/typemill/settings', 'user.yaml'); + + # if a plugin with a role has been deactivated, then users with the role throw an error, so set them back to member... + if(!$this->c->get('acl')->hasRole($userrole)) + { + $userrole = 'member'; + } + + # dispatch fields; + #$fields = $this->c->dispatcher->dispatch('onUserfieldsLoaded', new OnUserfieldsLoaded($fields))->getData(); + + # only roles who can edit content need profile image and description + if($this->c->get('acl')->isAllowed($userrole, 'mycontent', 'create')) + { + $newfield['image'] = ['label' => 'Profile-Image', 'type' => 'image']; + $newfield['description'] = ['label' => 'Author-Description (Markdown)', 'type' => 'textarea']; + + $userfields = array_slice($userfields, 0, 1, true) + $newfield + array_slice($userfields, 1, NULL, true); + # array_splice($fields,1,0,$newfield); + } + + # Only admin can change userroles + if($this->c->get('acl')->isAllowed($inspectorrole, 'userlist', 'write')) + { + $definedroles = $this->c->get('acl')->getRoles(); + $options = []; + + # we need associative array to make select-field with key/value work + foreach($definedroles as $role) + { + $options[$role] = $role; + } + + $userfields['userrole'] = ['label' => 'Role', 'type' => 'select', 'options' => $options]; + } + + return $userfields; + } + + protected function recursiveValidation($formdefinitions, $input, $validator, $themeOrPlugin = false, $name = false) + { + # loop through form-definitions, ignores everything that is not defined in yaml + foreach($formdefinitions as $fieldname => $fielddefinitions) + { + if(is_array($fielddefinitions) && $fielddefinitions['type'] == 'fieldset') + { + $this->recursiveValidation($fielddefinitions['fields'], $input, $validator, $themeOrPlugin, $name); + } + + $fieldvalue = isset($input[$fieldname]) ? $input[$fieldname] : false; + + if($fieldvalue) + { + $validationresult = $validator->field($fieldname, $fieldvalue, $fielddefinitions); + + if($validationresult === true) + { + # if input is valid, overwrite value in original settings + if($themeOrPlugin) + { + $this->settings[$themeOrPlugin][$name][$fieldname] = $fieldvalue; + } + else + { + $this->settings[$fieldname] = $fieldvalue; + } + } + else + { + $this->errors[$fieldname] = $validationresult[$fieldname][0]; + } + } + } + } } \ No newline at end of file diff --git a/system/typemill/Controllers/ControllerSystem.php b/system/typemill/Controllers/ControllerSystem.php deleted file mode 100644 index 140268b..0000000 --- a/system/typemill/Controllers/ControllerSystem.php +++ /dev/null @@ -1,1254 +0,0 @@ -c->get('settings'); - $defaultSettings = \Typemill\Settings::getDefaultSettings(); - $copyright = $this->getCopyright(); - $languages = $this->getLanguages(); - $locale = isset($_SERVER['HTTP_ACCEPT_LANGUAGE']) ? substr($_SERVER["HTTP_ACCEPT_LANGUAGE"],0,2) : 'en'; - $route = $request->getAttribute('route'); - $navigation = $this->getMainNavigation(); - - # set navigation active - $navigation['System']['active'] = true; - - return $this->render($response, 'settings/system.twig', array( - 'settings' => $settings, - 'acl' => $this->c->acl, - 'navigation' => $navigation, - 'copyright' => $copyright, - 'languages' => $languages, - 'locale' => $locale, - 'formats' => $defaultSettings['formats'], - 'route' => $route->getName() - )); - - */ - -/* ENDPOINTS - - -> settings -> get - -> systemnavi -> get - -> mainnavi -> get - -> - -*/ - $user = new User(); - $user->setUser($_SESSION['username']); - $userdata = $user->getUserData(); - - $yaml = new Yaml('\Typemill\Models\Storage'); - $system = $yaml->getYaml('system/typemill/settings', 'system.yaml'); - - return $this->c->get('view')->render($response, 'system/system.twig', [ - 'basicauth' => $user->getBasicAuth(), - 'settings' => $this->settings, - 'mainnavi' => $this->getMainNavigation($userdata['userrole']), - 'systemnavi' => $this->getSystemNavigation($userdata['userrole']), - 'jsdata' => [ - 'settings' => $this->settings, - 'system' => $system, - ] - - # main navigation - # sidebar navigation - # settings area - - #'captcha' => $this->checkIfAddCaptcha(), - ]); - } - - -/* - public function showBlank($request, $response, $args) - { - $user = new User(); - $settings = $this->c->get('settings'); - $route = $request->getAttribute('route'); - $navigation = $this->getMainNavigation(); - - $content = '
I am the showBlank method from the settings controller
In most cases I have been called from a plugin. But if you see this content, then the plugin does not work or has forgotten to inject its own content.
'; - - return $this->render($response, 'settings/blank.twig', array( - 'settings' => $settings, - 'acl' => $this->c->acl, - 'navigation' => $navigation, - 'content' => $content, - 'route' => $route->getName() - )); - } - - - public function saveSettings($request, $response, $args) - { - if($request->isPost()) - { - - if( $request->getattribute('csrf_result') === false ) - { - $this->c->flash->addMessage('error', 'The form has a timeout, please try again.'); - return $response->withRedirect($this->c->router->pathFor('settings.show')); - } - - $settings = \Typemill\Settings::getUserSettings(); - $defaultSettings = \Typemill\Settings::getDefaultSettings(); - $params = $request->getParams(); - $files = $request->getUploadedFiles(); - $newSettings = isset($params['settings']) ? $params['settings'] : false; - $validate = new Validation(); - $processImage = new ProcessImage(); - - if($newSettings) - { - # check for image settings - $imgwidth = isset($newSettings['images']['live']['width']) ? $newSettings['images']['live']['width'] : false; - $imgheight = isset($newSettings['images']['live']['height']) ? $newSettings['images']['live']['height'] : false; - - # make sure only allowed fields are stored - $newSettings = array( - 'title' => $newSettings['title'], - 'author' => $newSettings['author'], - 'copyright' => $newSettings['copyright'], - 'year' => $newSettings['year'], - 'language' => $newSettings['language'], - 'langattr' => $newSettings['langattr'], - 'editor' => $newSettings['editor'], - 'formats' => $newSettings['formats'], - 'access' => isset($newSettings['access']) ? true : null, - 'pageaccess' => isset($newSettings['pageaccess']) ? true : null, - 'hrdelimiter' => isset($newSettings['hrdelimiter']) ? true : null, - 'restrictionnotice' => $newSettings['restrictionnotice'], - 'wraprestrictionnotice' => isset($newSettings['wraprestrictionnotice']) ? true : null, - 'headlineanchors' => isset($newSettings['headlineanchors']) ? $newSettings['headlineanchors'] : null, - 'displayErrorDetails' => isset($newSettings['displayErrorDetails']) ? true : null, - 'twigcache' => isset($newSettings['twigcache']) ? true : null, - 'proxy' => isset($newSettings['proxy']) ? true : null, - 'trustedproxies' => $newSettings['trustedproxies'], - 'headersoff' => isset($newSettings['headersoff']) ? true : null, - 'urlschemes' => $newSettings['urlschemes'], - 'svg' => isset($newSettings['svg']) ? true : null, - 'recoverpw' => isset($newSettings['recoverpw']) ? true : null, - 'recoverfrom' => $newSettings['recoverfrom'], - 'recoversubject' => $newSettings['recoversubject'], - 'recovermessage' => $newSettings['recovermessage'], - 'securitylog' => isset($newSettings['securitylog']) ? true : null, - 'oldslug' => isset($newSettings['oldslug']) ? true : null, - 'refreshcache' => isset($newSettings['refreshcache']) ? true : null, - 'pingsitemap' => isset($newSettings['pingsitemap']) ? true : null, - ); - - # https://www.slimframework.com/docs/v3/cookbook/uploading-files.html; - - $copyright = $this->getCopyright(); - - $validate->settings($newSettings, $copyright, $defaultSettings['formats'], 'settings'); - - # use custom image settings - if( $imgwidth && ctype_digit($imgwidth) && (strlen($imgwidth) < 5) ) - { - $newSettings['images']['live']['width'] = $imgwidth; - } - if( $imgheight && ctype_digit($imgheight) && (strlen($imgheight) < 5) ) - { - $newSettings['images']['live']['height'] = $imgheight; - } - } - else - { - $this->c->flash->addMessage('error', 'Wrong Input'); - return $response->withRedirect($this->c->router->pathFor('settings.show')); - } - - if(isset($_SESSION['errors'])) - { - $this->c->flash->addMessage('error', 'Please correct the errors'); - return $response->withRedirect($this->c->router->pathFor('settings.show')); - } - - if(!$processImage->checkFolders()) - { - $this->c->flash->addMessage('error', 'Please make sure that your media folder exists and is writable.'); - return $response->withRedirect($this->c->router->pathFor('settings.show')); - } - - # handle single input with single file upload - $logo = $files['settings']['logo']; - $allowed = ['jpg', 'jpeg', 'png', 'svg']; - if($logo->getError() === UPLOAD_ERR_OK) - { - $extension = pathinfo($logo->getClientFilename(), PATHINFO_EXTENSION); - if(!in_array(strtolower($extension), $allowed)) - { - $_SESSION['errors']['settings']['logo'] = array('Only jpg, jpeg, png and svg allowed'); - $this->c->flash->addMessage('error', 'Please correct the errors'); - return $response->withRedirect($this->c->router->pathFor('settings.show')); - } - - foreach($allowed as $logoextension) - { - $processImage->deleteImage('logo.' . $logoextension); - } - - $newSettings['logo'] = $processImage->moveUploadedImage($logo, $overwrite = true, $name = 'logo'); - $processImage->copyImage('logo.' . $logoextension, $processImage->liveFolder, $processImage->thumbFolder); - } - elseif(isset($params['settings']['deletelogo']) && $params['settings']['deletelogo'] == 'delete') - { - foreach($allowed as $logoextension) - { - $processImage->deleteImage('logo.' . $logoextension); - } - $newSettings['logo'] = ''; - } - else - { - $newSettings['logo'] = isset($settings['logo']) ? $settings['logo'] : ''; - } - - # handle single input with single file upload - $favicon = $files['settings']['favicon']; - if ($favicon->getError() === UPLOAD_ERR_OK) - { - $extension = pathinfo($favicon->getClientFilename(), PATHINFO_EXTENSION); - if(strtolower($extension) != 'png') - { - $_SESSION['errors']['settings']['favicon'] = array('Only .png-files allowed'); - $this->c->flash->addMessage('error', 'Please correct the errors'); - return $response->withRedirect($this->c->router->pathFor('settings.show')); - } - - $processFavImage = new ProcessImage([ - '16' => ['width' => 16, 'height' => 16], - '32' => ['width' => 32, 'height' => 32], - '72' => ['width' => 72, 'height' => 72], - '114' => ['width' => 114, 'height' => 114], - '144' => ['width' => 144, 'height' => 144], - '180' => ['width' => 180, 'height' => 180], - ]); - $favicons = $processFavImage->generateSizesFromImageFile('favicon.png', $favicon->file); - - foreach($favicons as $key => $favicon) - { - imagepng( $favicon, $processFavImage->fileFolder . 'favicon-' . $key . '.png' ); - } - - $newSettings['favicon'] = 'favicon'; - } - elseif(isset($params['settings']['deletefav']) && $params['settings']['deletefav'] == 'delete') - { - $processFiles = new ProcessFile(); - $processFiles->deleteFileWithName('favicon-*.png'); - $newSettings['favicon'] = ''; - } - else - { - $newSettings['favicon'] = isset($settings['favicon']) ? $settings['favicon'] : ''; - } - - # store updated settings - \Typemill\Settings::updateSettings(array_merge($settings, $newSettings)); - - $this->c->flash->addMessage('info', 'Settings are stored'); - return $response->withRedirect($this->c->router->pathFor('settings.show')); - } - } - - /********************* - ** THEME SETTINGS ** - *********************/ - -/* - public function showThemes($request, $response, $args) - { - $userSettings = $this->c->get('settings'); - $themes = $this->getThemes(); - $themedata = array(); - $fieldsModel = new Fields($this->c); - - foreach($themes as $themeName) - { - # if theme is active, list it first - if($userSettings['theme'] == $themeName) - { - $themedata = array_merge(array($themeName => null), $themedata); - } - else - { - $themedata[$themeName] = null; - } - - $themeSettings = \Typemill\Settings::getObjectSettings('themes', $themeName); - - # add standard-textarea for custom css - $themeSettings['forms']['fields']['customcss'] = ['type' => 'textarea', 'label' => 'Custom CSS', 'rows' => 10, 'class' => 'codearea', 'description' => 'You can overwrite the theme-css with your own css here.']; - - # load custom css-file - $write = new write(); - $customcss = $write->getFile('cache', $themeName . '-custom.css'); - $themeSettings['settings']['customcss'] = $customcss; - - - if($themeSettings) - { - # store them as default theme data with author, year, default settings and field-definitions - $themedata[$themeName] = $themeSettings; - } - - if(isset($themeSettings['forms']['fields'])) - { - $fields = $fieldsModel->getFields($userSettings, 'themes', $themeName, $themeSettings); - - # overwrite original theme form definitions with enhanced form objects - $themedata[$themeName]['forms']['fields'] = $fields; - } - - # add the preview image - $img = getcwd() . DIRECTORY_SEPARATOR . 'themes' . DIRECTORY_SEPARATOR . $themeName . DIRECTORY_SEPARATOR . $themeName; - - $image = false; - if(file_exists($img . '.jpg')) - { - $image = $themeName . '.jpg'; - } - if(file_exists($img . '.png')) - { - $image = $themeName . '.png'; - } - - $themedata[$themeName]['img'] = $image; - } - - # add the users for navigation - $route = $request->getAttribute('route'); - $navigation = $this->getMainNavigation(); - - # set navigation active - $navigation['Themes']['active'] = true; - - return $this->render($response, 'settings/themes.twig', array( - 'settings' => $userSettings, - 'acl' => $this->c->acl, - 'navigation' => $navigation, - 'themes' => $themedata, - 'route' => $route->getName() - )); - } - - public function showPlugins($request, $response, $args) - { - $userSettings = $this->c->get('settings'); - $plugins = array(); - $fieldsModel = new Fields($this->c); - $fields = array(); - - # iterate through the plugins in the stored user settings - foreach($userSettings['plugins'] as $pluginName => $pluginUserSettings) - { - # add plugin to plugin Data, if active, set it first - # if plugin is active, list it first - if($userSettings['plugins'][$pluginName]['active'] == true) - { - $plugins = array_merge(array($pluginName => null), $plugins); - } - else - { - $plugins[$pluginName] = Null; - } - - # Check if the user has deleted a plugin. Then delete it in the settings and store the updated settings. - if(!is_dir($userSettings['rootPath'] . 'plugins' . DIRECTORY_SEPARATOR . $pluginName)) - { - # remove the plugin settings and store updated settings - \Typemill\Settings::removePluginSettings($pluginName); - continue; - } - - # load the original plugin definitions from the plugin folder (author, version and stuff) - $pluginOriginalSettings = \Typemill\Settings::getObjectSettings('plugins', $pluginName); - if($pluginOriginalSettings) - { - # store them as default plugin data with plugin author, plugin year, default settings and field-definitions - $plugins[$pluginName] = $pluginOriginalSettings; - } - - # check, if the plugin has been disabled in the form-session-data - if(isset($_SESSION['old']) && !isset($_SESSION['old'][$pluginName]['active'])) - { - $plugins[$pluginName]['settings']['active'] = false; - } - - # if the plugin defines forms and fields, so that the user can edit the plugin settings in the frontend - if(isset($pluginOriginalSettings['forms']['fields'])) - { - # get all the fields and prefill them with the dafault-data, the user-data or old input data - $fields = $fieldsModel->getFields($userSettings, 'plugins', $pluginName, $pluginOriginalSettings); - - # overwrite original plugin form definitions with enhanced form objects - $plugins[$pluginName]['forms']['fields'] = $fields; - } - } - - $route = $request->getAttribute('route'); - $navigation = $this->getMainNavigation(); - - # set navigation active - $navigation['Plugins']['active'] = true; - - return $this->render($response, 'settings/plugins.twig', array( - 'settings' => $userSettings, - 'acl' => $this->c->acl, - 'navigation' => $navigation, - 'plugins' => $plugins, - 'route' => $route->getName() - )); - } - - /************************************* - ** SAVE THEME- AND PLUGIN-SETTINGS ** - *************************************/ - - /* - public function saveThemes($request, $response, $args) - { - if($request->isPost()) - { - if( $request->getattribute('csrf_result') === false ) - { - $this->c->flash->addMessage('error', 'The form has a timeout, please try again.'); - return $response->withRedirect($this->c->router->pathFor('themes.show')); - } - - $userSettings = \Typemill\Settings::getUserSettings(); - $params = $request->getParams(); - $themeName = isset($params['theme']) ? $params['theme'] : false; - $userInput = isset($params[$themeName]) ? $params[$themeName] : false; - $validate = new Validation(); - $themeSettings = \Typemill\Settings::getObjectSettings('themes', $themeName); - - if(isset($themeSettings['settings']['images'])) - { - # get the default settings - $defaultSettings = \Typemill\Settings::getDefaultSettings(); - - # merge the default image settings with the theme image settings, delete all others (image settings from old theme) - $userSettings['images'] = array_merge($defaultSettings['images'], $themeSettings['settings']['images']); - } - - # set theme name and delete theme settings from user settings for the case, that the new theme has no settings - $userSettings['theme'] = $themeName; - - # extract the custom css from user input - $customcss = isset($userInput['customcss']) ? $userInput['customcss'] : false; - - # delete custom css from userinput - unset($userInput['customcss']); - - $write = new write(); - - # make sure no file is set if there is no custom css - if(!$customcss OR $customcss == '') - { - # delete the css file if exists - $write->deleteFileWithPath('cache' . DIRECTORY_SEPARATOR . $themeName . '-custom.css'); - } - else - { - if ( $customcss != strip_tags($customcss) ) - { - $_SESSION['errors'][$themeName]['customcss'][] = 'custom css contains html'; - } - else - { - # store css - $write = new write(); - $write->writeFile('cache', $themeName . '-custom.css', $customcss); - } - } - - if($userInput) - { - # validate the user-input and return image-fields if they are defined - $imageFields = $this->validateInput('themes', $themeName, $userInput, $validate); - - # set user input as theme settings - $userSettings['themes'][$themeName] = $userInput; - } - - # handle images - $images = $request->getUploadedFiles(); - - if(!isset($_SESSION['errors']) && isset($images[$themeName])) - { - $userInput = $this->saveImages($imageFields, $userInput, $userSettings, $images[$themeName]); - - # set user input as theme settings - $userSettings['themes'][$themeName] = $userInput; - } - - # check for errors and redirect to path, if errors found - if(isset($_SESSION['errors'])) - { - $this->c->flash->addMessage('error', 'Please correct the errors'); - return $response->withRedirect($this->c->router->pathFor('themes.show')); - } - - # store updated settings - \Typemill\Settings::updateSettings($userSettings); - - $this->c->flash->addMessage('info', 'Settings are stored'); - return $response->withRedirect($this->c->router->pathFor('themes.show')); - } - } - - public function savePlugins($request, $response, $args) - { - if($request->isPost()) - { - - if( $request->getattribute('csrf_result') === false ) - { - $this->c->flash->addMessage('error', 'The form has a timeout, please try again.'); - return $response->withRedirect($this->c->router->pathFor('plugins.show')); - } - - $userSettings = \Typemill\Settings::getUserSettings(); - $pluginSettings = array(); - $userInput = $request->getParams(); - $validate = new Validation(); - - # use the stored user settings and iterate over all original plugin settings, so we do not forget any... - foreach($userSettings['plugins'] as $pluginName => $pluginUserSettings) - { - # if there are no input-data for this plugin, then use the stored plugin settings - if(!isset($userInput[$pluginName])) - { - $pluginSettings[$pluginName] = $pluginUserSettings; - } - else - { - # fetch the original settings from the folder to get the field definitions - $originalSettings = \Typemill\Settings::getObjectSettings('plugins', $pluginName); - - # check if the plugin has dependencies - if(isset($userInput[$pluginName]['active']) && isset($originalSettings['dependencies'])) - { - foreach($originalSettings['dependencies'] as $dependency) - { - if(!isset($userInput[$dependency]['active']) OR !$userInput[$dependency]['active']) - { - $this->c->flash->addMessage('error', 'Activate the plugin ' . $dependency . ' before you activate the plugin ' . $pluginName); - return $response->withRedirect($this->c->router->pathFor('plugins.show')); - } - } - } - - # validate the user-input - $imageFields = $this->validateInput('plugins', $pluginName, $userInput[$pluginName], $validate, $originalSettings); - - # use the input data - $pluginSettings[$pluginName] = $userInput[$pluginName]; - } - - # handle images - $images = $request->getUploadedFiles(); - - if(!isset($_SESSION['errors']) && isset($images[$pluginName])) - { - $userInput[$pluginName] = $this->saveImages($imageFields, $userInput[$pluginName], $userSettings, $images[$pluginName]); - - # set user input as theme settings - $pluginSettings[$pluginName] = $userInput[$pluginName]; - } - - # deactivate the plugin, if there is no active flag - if(!isset($userInput[$pluginName]['active'])) - { - $pluginSettings[$pluginName]['active'] = false; - } - } - - if(isset($_SESSION['errors'])) - { - $this->c->flash->addMessage('error', 'Please correct the errors below'); - } - else - { - # if everything is valid, add plugin settings to base settings again - $userSettings['plugins'] = $pluginSettings; - - # store updated settings - \Typemill\Settings::updateSettings($userSettings); - - $this->c->flash->addMessage('info', 'Settings are stored'); - } - - return $response->withRedirect($this->c->router->pathFor('plugins.show')); - } - } - - /*********************** - ** USER MANAGEMENT ** - ***********************/ - - public function showAccount($request, $response, $args) - { - $username = $_SESSION['user']; - - $validate = new Validation(); - - if($validate->username($username)) - { - # get settings - $settings = $this->c->get('settings'); - - # get user with userdata - $user = new User(); - $userdata = $user->getSecureUser($username); - - # instantiate field-builder - $fieldsModel = new Fields($this->c); - - # get the field-definitions - $fieldDefinitions = $this->getUserFields($userdata['userrole']); - - # prepare userdata for field-builder - $userSettings['users']['user'] = $userdata; - - # generate the input form - $userform = $fieldsModel->getFields($userSettings, 'users', 'user', $fieldDefinitions); - - $route = $request->getAttribute('route'); - $navigation = $this->getMainNavigation(); - - # set navigation active - $navigation['Account']['active'] = true; - - return $this->render($response, 'settings/user.twig', array( - 'settings' => $settings, - 'acl' => $this->c->acl, - 'navigation' => $navigation, - 'usersettings' => $userSettings, // needed for image url in form, will overwrite settings for field-template - 'userform' => $userform, // field model, needed to generate frontend-field - 'userdata' => $userdata, // needed to fill form with data -# 'userrole' => false, // not needed ? -# 'username' => $args['username'], // not needed ? - 'route' => $route->getName() // needed to set link active - )); - } - - $this->c->flash->addMessage('error', 'User does not exists'); - return $response->withRedirect($this->c->router->pathFor('home')); - } - - public function showUser($request, $response, $args) - { - # if user has no rights to watch userlist, then redirect to - if(!$this->c->acl->isAllowed($_SESSION['role'], 'userlist', 'view') && $_SESSION['user'] !== $args['username'] ) - { - return $response->withRedirect($this->c->router->pathFor('user.show', ['username' => $_SESSION['user']] )); - } - - # get settings - $settings = $this->c->get('settings'); - - # get user with userdata - $user = new User(); - $userdata = $user->getSecureUser($args['username']); - - if(!$userdata) - { - $this->c->flash->addMessage('error', 'User does not exists'); - return $response->withRedirect($this->c->router->pathFor('user.account')); - } - - # instantiate field-builder - $fieldsModel = new Fields($this->c); - - # get the field-definitions - $fieldDefinitions = $this->getUserFields($userdata['userrole']); - - # prepare userdata for field-builder - $userSettings['users']['user'] = $userdata; - - # generate the input form - $userform = $fieldsModel->getFields($userSettings, 'users', 'user', $fieldDefinitions); - - $route = $request->getAttribute('route'); - $navigation = $this->getMainNavigation(); - - # set navigation active - $navigation['Users']['active'] = true; - - if(isset($userdata['lastlogin'])) - { - $userdata['lastlogin'] = date("d.m.Y H:i:s", $userdata['lastlogin']); - } - - return $this->render($response, 'settings/user.twig', array( - 'settings' => $settings, - 'acl' => $this->c->acl, - 'navigation' => $navigation, - 'usersettings' => $userSettings, // needed for image url in form, will overwrite settings for field-template - 'userform' => $userform, // field model, needed to generate frontend-field - 'userdata' => $userdata, // needed to fill form with data - 'route' => $route->getName() // needed to set link active - )); - } - - public function listUser($request, $response) - { - $user = new User(); - $users = $user->getUsers(); - $userdata = array(); - $route = $request->getAttribute('route'); - $settings = $this->c->get('settings'); - $navigation = $this->getMainNavigation(); - - # set navigation active - $navigation['Users']['active'] = true; - - # set standard template - $template = 'settings/userlist.twig'; - - # use vue template for many users - $totalusers = count($users); - - if($totalusers > 10) - { - $template = 'settings/userlistvue.twig'; - } - else - { - foreach($users as $username) - { - $newuser = $user->getSecureUser($username); - if($newuser) - { - $userdata[] = $newuser; - } - } - } - - return $this->render($response, $template, array( - 'settings' => $settings, - 'acl' => $this->c->acl, - 'navigation' => $navigation, - 'users' => $users, - 'userdata' => $userdata, - 'userroles' => $this->c->acl->getRoles(), - 'route' => $route->getName() - )); - } - - #returns userdata - public function getUsersByNames($request, $response, $args) - { - $params = $request->getParams(); - $user = new User(); - $userdata = []; - - if(isset($params['usernames'])) - { - foreach($params['usernames'] as $username) - { - $existinguser = $user->getSecureUser($username); - if($existinguser) - { - $userdata[] = $existinguser; - } - } - } - - return $response->withJson(['userdata' => $userdata]); - } - - # returns userdata - public function getUsersByEmail($request, $response, $args) - { - $params = $request->getParams(); - $user = new User(); - - $userdata = $user->findUsersByEmail($params['email']); - - return $response->withJson(['userdata' => $userdata ]); - } - - #returns userdata - public function getUsersByRole($request, $response, $args) - { - $params = $request->getParams(); - $user = new User(); - - $userdata = $user->findUsersByRole($params['role']); - - return $response->withJson(['userdata' => $userdata ]); - } - - public function newUser($request, $response, $args) - { - $user = new User(); - $users = $user->getUsers(); - $userroles = $this->c->acl->getRoles(); - $route = $request->getAttribute('route'); - $settings = $this->c->get('settings'); - $navigation = $this->getMainNavigation(); - - # set navigation active - $navigation['Users']['active'] = true; - - return $this->render($response, 'settings/usernew.twig', array( - 'settings' => $settings, - 'acl' => $this->c->acl, - 'navigation' => $navigation, - 'users' => $users, - 'userrole' => $userroles, - 'route' => $route->getName() - )); - } - - public function createUser($request, $response, $args) - { - if($request->isPost()) - { - if( $request->getattribute('csrf_result') === false ) - { - $this->c->flash->addMessage('error', 'The form has a timeout, please try again.'); - return $response->withRedirect($this->c->router->pathFor('user.new')); - } - - $params = $request->getParams(); - $user = new User(); - $validate = new Validation(); - $userroles = $this->c->acl->getRoles(); - - if($validate->newUser($params, $userroles)) - { - $userdata = array( - 'username' => $params['username'], - 'email' => $params['email'], - 'userrole' => $params['userrole'], - 'password' => $params['password']); - - $user->createUser($userdata); - - $this->c->flash->addMessage('info', 'Welcome, there is a new user!'); - return $response->withRedirect($this->c->router->pathFor('user.list')); - } - - $this->c->flash->addMessage('error', 'Please correct your input'); - return $response->withRedirect($this->c->router->pathFor('user.new')); - } - } - - public function updateUser($request, $response, $args) - { - - if($request->isPost()) - { - if( $request->getattribute('csrf_result') === false ) - { - $this->c->flash->addMessage('error', 'The form has a timeout, please try again.'); - return $response->withRedirect($this->c->router->pathFor('user.account')); - } - - $params = $request->getParams(); - $userdata = $params['user']; - $user = new User(); - $validate = new Validation(); - $userroles = $this->c->acl->getRoles(); - - $redirectRoute = ($userdata['username'] == $_SESSION['user']) ? $this->c->router->pathFor('user.account') : $this->c->router->pathFor('user.show', ['username' => $userdata['username']]); - - # check if user is allowed to view (edit) userlist and other users - if(!$this->c->acl->isAllowed($_SESSION['role'], 'userlist', 'write')) - { - # if an editor tries to update other userdata than its own */ - if($_SESSION['user'] !== $userdata['username']) - { - return $response->withRedirect($this->c->router->pathFor('user.account')); - } - - # non admins cannot change their userrole, so set it to session-value - $userdata['userrole'] = $_SESSION['role']; - } - - # validate standard fields for users - if($validate->existingUser($userdata, $userroles)) - { - # validate custom input fields and return images - $userfields = $this->getUserFields($userdata['userrole']); - $imageFields = $this->validateInput('users', 'user', $userdata, $validate, $userfields); - - if(!empty($imageFields)) - { - $images = $request->getUploadedFiles(); - - if(isset($images['user'])) - { - # set image size - $settings = $this->c->get('settings'); - $imageSizes = $settings['images']; - $imageSizes['live'] = ['width' => 500, 'height' => 500]; - $settings->replace(['images' => $imageSizes]); - $imageresult = $this->saveImages($imageFields, $userdata, $settings, $images['user']); - - if(isset($_SESSION['slimFlash']['error'])) - { - return $response->withRedirect($redirectRoute); - } - elseif(isset($imageresult['username'])) - { - $userdata = $imageresult; - } - } - } - - # check for errors and redirect to path, if errors found */ - if(isset($_SESSION['errors'])) - { - $this->c->flash->addMessage('error', 'Please correct the errors'); - return $response->withRedirect($redirectRoute); - } - - if(empty($userdata['password']) AND empty($userdata['newpassword'])) - { - # make sure no invalid passwords go into model - unset($userdata['password']); - unset($userdata['newpassword']); - - $user->updateUser($userdata); - $this->c->flash->addMessage('info', 'Saved all changes'); - return $response->withRedirect($redirectRoute); - } - elseif($validate->newPassword($userdata)) - { - $userdata['password'] = $userdata['newpassword']; - unset($userdata['newpassword']); - - $user->updateUser($userdata); - $this->c->flash->addMessage('info', 'Saved all changes'); - return $response->withRedirect($redirectRoute); - } - } - - # change error-array for formbuilder - $errors = $_SESSION['errors']; - unset($_SESSION['errors']); - $_SESSION['errors']['user'] = $errors;# - - $this->c->flash->addMessage('error', 'Please correct your input'); - return $response->withRedirect($redirectRoute); - } - } - - public function deleteUser($request, $response, $args) - { - if($request->isPost()) - { - if( $request->getattribute('csrf_result') === false ) - { - $this->c->flash->addMessage('error', 'The form has a timeout, please try again.'); - return $response->withRedirect($this->c->router->pathFor('user.account')); - } - - $params = $request->getParams(); - $validate = new Validation(); - $user = new User(); - - # check if user is allowed to view (edit) userlist and other users - if(!$this->c->acl->isAllowed($_SESSION['role'], 'userlist', 'write')) - { - # if an editor tries to delete other user than its own - if($_SESSION['user'] !== $params['username']) - { - return $response->withRedirect($this->c->router->pathFor('user.account')); - } - } - - if($validate->username($params['username'])) - { - $userdata = $user->getSecureUser($params['username']); - if(!$userdata) - { - $this->c->flash->addMessage('error', 'Ups, we did not find that user'); - return $response->withRedirect($this->c->router->pathFor('user.show', ['username' => $params['username']])); - } - - $user->deleteUser($params['username']); - - $this->c->dispatcher->dispatch('onUserDeleted', new OnUserDeleted($userdata)); - - # if user deleted his own account - if($_SESSION['user'] == $params['username']) - { - session_destroy(); - return $response->withRedirect($this->c->router->pathFor('auth.show')); - } - - $this->c->flash->addMessage('info', 'Say goodbye, the user is gone!'); - return $response->withRedirect($this->c->router->pathFor('user.list')); - } - - $this->c->flash->addMessage('error', 'Ups, it is not a valid username'); - return $response->withRedirect($this->c->router->pathFor('user.show', ['username' => $params['username']])); - } - } - - 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)); - } - - private function getUserFields($role) - { - # if a plugin with a role has been deactivated, then users with the role throw an error, so set them back to member... - if(!$this->c->acl->hasRole($role)) - { - $role = 'member'; - } - - $fields = []; - $fields['username'] = ['label' => 'Username (read only)', 'type' => 'text', 'readonly' => true]; - $fields['firstname'] = ['label' => 'First Name', 'type' => 'text']; - $fields['lastname'] = ['label' => 'Last Name', 'type' => 'text']; - $fields['email'] = ['label' => 'E-Mail', 'type' => 'text', 'required' => true]; - $fields['userrole'] = ['label' => 'Role', 'type' => 'text', 'readonly' => true]; - $fields['password'] = ['label' => 'Actual Password', 'type' => 'password']; - $fields['newpassword'] = ['label' => 'New Password', 'type' => 'password']; - - # dispatch fields; - $fields = $this->c->dispatcher->dispatch('onUserfieldsLoaded', new OnUserfieldsLoaded($fields))->getData(); - - # only roles who can edit content need profile image and description - if($this->c->acl->isAllowed($role, 'mycontent', 'create')) - { - $newfield['image'] = ['label' => 'Profile-Image', 'type' => 'image']; - $newfield['description'] = ['label' => 'Author-Description (Markdown)', 'type' => 'textarea']; - - $fields = array_slice($fields, 0, 1, true) + $newfield + array_slice($fields, 1, NULL, true); - # array_splice($fields,1,0,$newfield); - } - - # Only admin can change userroles - if($this->c->acl->isAllowed($_SESSION['role'], 'userlist', 'write')) - { - $userroles = $this->c->acl->getRoles(); - $options = []; - - # we need associative array to make select-field with key/value work - foreach($userroles as $userrole) - { - $options[$userrole] = $userrole; - } - - $fields['userrole'] = ['label' => 'Role', 'type' => 'select', 'options' => $options]; - } - - $userform = []; - $userform['forms']['fields'] = $fields; - return $userform; - } - - private function getThemes() - { - $themeFolder = $this->c->get('settings')['rootPath'] . $this->c->get('settings')['themeFolder']; - $themeFolderC = scandir($themeFolder); - $themes = array(); - foreach ($themeFolderC as $key => $theme) - { - if (!in_array($theme, array(".",".."))) - { - if (is_dir($themeFolder . DIRECTORY_SEPARATOR . $theme)) - { - $themes[] = $theme; - } - } - } - return $themes; - } - - private function getCopyright() - { - return array( - "©", - "CC-BY", - "CC-BY-NC", - "CC-BY-NC-ND", - "CC-BY-NC-SA", - "CC-BY-ND", - "CC-BY-SA", - "None" - ); - } - - private function getLanguages() - { - return array( - 'en' => 'English', - 'ru' => 'Russian', - 'nl' => 'Dutch, Flemish', - 'de' => 'German', - 'it' => 'Italian', - 'fr' => 'French', - ); - } - - private function validateInput($objectType, $objectName, $userInput, $validate, $originalSettings = NULL) - { - if(!$originalSettings) - { - # fetch the original settings from the folder (plugin or theme) to get the field definitions - $originalSettings = \Typemill\Settings::getObjectSettings($objectType, $objectName); - } - - # images get special treatment - $imageFieldDefinitions = array(); - - if(isset($originalSettings['forms']['fields'])) - { - /* flaten the multi-dimensional array with fieldsets to a one-dimensional array */ - $originalFields = array(); - foreach($originalSettings['forms']['fields'] as $fieldName => $fieldValue) - { - if(isset($fieldValue['fields'])) - { - foreach($fieldValue['fields'] as $subFieldName => $subFieldValue) - { - $originalFields[$subFieldName] = $subFieldValue; - } - } - else - { - $originalFields[$fieldName] = $fieldValue; - } - } - - # if plugin is not active, then skip required - $skiprequired = false; - if($objectType == 'plugins' && !isset($userInput['active'])) - { - $skiprequired = true; - } - - /* take the user input data and iterate over all fields and values */ - foreach($userInput as $fieldName => $fieldValue) - { - /* get the corresponding field definition from original plugin settings */ - $fieldDefinition = isset($originalFields[$fieldName]) ? $originalFields[$fieldName] : false; - - if($fieldDefinition) - { - - # check if the field is a select field with dataset = userroles - if(isset($fieldDefinition['type']) && ($fieldDefinition['type'] == 'select' ) && isset($fieldDefinition['dataset']) && ($fieldDefinition['dataset'] == 'userroles' ) ) - { - $userroles = [null => null]; - foreach($this->c->acl->getRoles() as $userrole) - { - $userroles[$userrole] = $userrole; - } - $fieldDefinition['options'] = $userroles; - } - - /* validate user input for this field */ - $validate->objectField($fieldName, $fieldValue, $objectName, $fieldDefinition, $skiprequired); - - if($fieldDefinition['type'] == 'image') - { - # we want to return all images-fields for further processing - $imageFieldDefinitions[$fieldName] = $fieldDefinition; - } - } - if(!$fieldDefinition && $objectType != 'users' && $fieldName != 'active') - { - $_SESSION['errors'][$objectName][$fieldName] = array('This field is not defined!'); - } - } - } - - return $imageFieldDefinitions; - } - - 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; - } - -} \ No newline at end of file diff --git a/system/typemill/Controllers/ControllerWeb.php b/system/typemill/Controllers/ControllerWeb.php deleted file mode 100644 index 5275030..0000000 --- a/system/typemill/Controllers/ControllerWeb.php +++ /dev/null @@ -1,73 +0,0 @@ -add twig'; - - $settings = $this->settings; - - $csrf = isset($_SESSION) ? $this->c->get('csrf') : false; - - $this->c->set('view', function() use ($settings, $csrf) - { - $twig = Twig::create( - [ - # path to templates - $settings['rootPath'] . $settings['authorFolder'], - $settings['rootPath'] . DIRECTORY_SEPARATOR . 'themes' . DIRECTORY_SEPARATOR . $settings['theme'], - ], - [ - # settings - 'cache' => ( isset($settings['twigcache']) && $settings['twigcache'] ) ? $settings['rootPath'] . '/cache/twig' : false, - 'debug' => isset($settings['displayErrorDetails']) - ] - ); - - # placeholder for flash and errors, will be filled later with middleware - $twig->getEnvironment()->addGlobal('errors', NULL); - $twig->getEnvironment()->addGlobal('flash', NULL); - - # add extensions - $twig->addExtension(new \Twig\Extension\DebugExtension()); - # $twig->addExtension(new \Nquire\Extensions\TwigUserExtension()); - if($csrf) - { - $twig->addExtension(new \Typemill\Extensions\TwigCsrfExtension($csrf)); - } - - return $twig; - }); - - protected function setUrlCollection($uri) - { - $scheme = $uri->getScheme(); - $authority = $uri->getAuthority(); - $protocol = ($scheme ? $scheme . ':' : '') . ($authority ? '//' . $authority : ''); - - $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 - ]; - } - - $this->c->get('dispatcher')->dispatch(new OnTwigLoaded(false), 'onTwigLoaded'); -*/ - } -} \ No newline at end of file diff --git a/system/typemill/Controllers/ControllerWebSystem.php b/system/typemill/Controllers/ControllerWebSystem.php new file mode 100644 index 0000000..eab55ed --- /dev/null +++ b/system/typemill/Controllers/ControllerWebSystem.php @@ -0,0 +1,497 @@ +getYaml('system/typemill/settings', 'system.yaml'); + $translations = $this->c->get('translations'); + + # add full url for sitemap to settings + $this->settings['sitemap'] = $this->c->get('urlinfo')['baseurl'] . '/cache/sitemap.xml'; + + return $this->c->get('view')->render($response, 'system/system.twig', [ +# 'basicauth' => $user->getBasicAuth(), + 'settings' => $this->settings, + 'mainnavi' => $this->getMainNavigation($request->getAttribute('userrole')), + 'systemnavi' => $this->getSystemNavigation($request->getAttribute('userrole')), + 'jsdata' => [ + 'settings' => $this->settings, + 'system' => $systemfields, + 'labels' => $translations, + 'urlinfo' => $this->c->get('urlinfo') + ] + #'captcha' => $this->checkIfAddCaptcha(), + ]); + } + + public function showThemes($request, $response, $args) + { + $yaml = new Yaml('\Typemill\Models\Storage'); + $translations = $this->c->get('translations'); + $themeSettings = $this->getThemeDetails(); + + $themedata = []; + + foreach($this->settings['themes'] as $themename => $themeinputs) + { + $themedata[$themename] = $themeinputs; + $themedata[$themename]['customcss'] = $yaml->getFile('cache', $themename . '-custom.css'); + } + + return $this->c->get('view')->render($response, 'system/themes.twig', [ + 'settings' => $this->settings, + 'mainnavi' => $this->getMainNavigation($request->getAttribute('userrole')), + 'systemnavi' => $this->getSystemNavigation($request->getAttribute('userrole')), + 'jsdata' => [ + 'settings' => $themedata, + 'themes' => $themeSettings, + 'labels' => $translations, + 'urlinfo' => $this->c->get('urlinfo') + ] + ]); + } + + public function showPlugins($request, $response, $args) + { +# $yaml = new Yaml('\Typemill\Models\Storage'); + $translations = $this->c->get('translations'); + $pluginSettings = $this->getPluginDetails(); + + $plugindata = []; + + foreach($this->settings['plugins'] as $pluginname => $plugininputs) + { + $plugindata[$pluginname] = $plugininputs; + } + + return $this->c->get('view')->render($response, 'system/plugins.twig', [ + 'settings' => $this->settings, + 'mainnavi' => $this->getMainNavigation($request->getAttribute('userrole')), + 'systemnavi' => $this->getSystemNavigation($request->getAttribute('userrole')), + 'jsdata' => [ + 'settings' => $plugindata, + 'plugins' => $pluginSettings, + 'labels' => $translations, + 'urlinfo' => $this->c->get('urlinfo') + ] + ]); + } + + public function showUsers($request, $response, $args) + { + $translations = $this->c->get('translations'); + $user = new User(); + $usernames = $user->getAllUsers(); + $userdata = []; + + $count = 0; + foreach($usernames as $username) + { + if($count == 10) break; + $user->setUser($username); + $userdata[] = $user->getUserData(); + $count++; + } + + return $this->c->get('view')->render($response, 'system/users.twig', [ + 'settings' => $this->settings, + 'mainnavi' => $this->getMainNavigation($request->getAttribute('userrole')), + 'systemnavi' => $this->getSystemNavigation($request->getAttribute('userrole')), + 'jsdata' => [ + 'totalusers' => count($usernames), + 'usernames' => $usernames, + 'userdata' => $userdata, + 'userroles' => $this->c->get('acl')->getRoles(), + 'labels' => $translations, + 'urlinfo' => $this->c->get('urlinfo') + ] + ]); + } + + public function showAccount($request, $response, $args) + { + + $translations = $this->c->get('translations'); + $username = $request->getAttribute('username'); + $user = new User(); + + $user->setUser($username); + $userdata = $user->getUserData(); + $userfields = $this->getUserFields($userdata['userrole']); + + return $this->c->get('view')->render($response, 'system/account.twig', [ + 'settings' => $this->settings, + 'mainnavi' => $this->getMainNavigation($request->getAttribute('userrole')), + 'systemnavi' => $this->getSystemNavigation($request->getAttribute('userrole')), + 'jsdata' => [ + 'userdata' => $userdata, + 'userfields' => $userfields, + 'userroles' => $this->c->get('acl')->getRoles(), + 'labels' => $translations, + 'urlinfo' => $this->c->get('urlinfo') + ] + ]); + } + + +/* + public function showBlank($request, $response, $args) + { + $user = new User(); + $settings = $this->c->get('settings'); + $route = $request->getAttribute('route'); + $navigation = $this->getMainNavigation(); + + $content = 'I am the showBlank method from the settings controller
In most cases I have been called from a plugin. But if you see this content, then the plugin does not work or has forgotten to inject its own content.
'; + + return $this->render($response, 'settings/blank.twig', array( + 'settings' => $settings, + 'acl' => $this->c->acl, + 'navigation' => $navigation, + 'content' => $content, + 'route' => $route->getName() + )); + } + + + + + + public function showUser($request, $response, $args) + { + # if user has no rights to watch userlist, then redirect to + if(!$this->c->acl->isAllowed($_SESSION['role'], 'userlist', 'view') && $_SESSION['user'] !== $args['username'] ) + { + return $response->withRedirect($this->c->router->pathFor('user.show', ['username' => $_SESSION['user']] )); + } + + # get settings + $settings = $this->c->get('settings'); + + # get user with userdata + $user = new User(); + $userdata = $user->getSecureUser($args['username']); + + if(!$userdata) + { + $this->c->flash->addMessage('error', 'User does not exists'); + return $response->withRedirect($this->c->router->pathFor('user.account')); + } + + # instantiate field-builder + $fieldsModel = new Fields($this->c); + + # get the field-definitions + $fieldDefinitions = $this->getUserFields($userdata['userrole']); + + # prepare userdata for field-builder + $userSettings['users']['user'] = $userdata; + + # generate the input form + $userform = $fieldsModel->getFields($userSettings, 'users', 'user', $fieldDefinitions); + + $route = $request->getAttribute('route'); + $navigation = $this->getMainNavigation(); + + # set navigation active + $navigation['Users']['active'] = true; + + if(isset($userdata['lastlogin'])) + { + $userdata['lastlogin'] = date("d.m.Y H:i:s", $userdata['lastlogin']); + } + + return $this->render($response, 'settings/user.twig', array( + 'settings' => $settings, + 'acl' => $this->c->acl, + 'navigation' => $navigation, + 'usersettings' => $userSettings, // needed for image url in form, will overwrite settings for field-template + 'userform' => $userform, // field model, needed to generate frontend-field + 'userdata' => $userdata, // needed to fill form with data + 'route' => $route->getName() // needed to set link active + )); + } + + + public function newUser($request, $response, $args) + { + $user = new User(); + $users = $user->getUsers(); + $userroles = $this->c->acl->getRoles(); + $route = $request->getAttribute('route'); + $settings = $this->c->get('settings'); + $navigation = $this->getMainNavigation(); + + # set navigation active + $navigation['Users']['active'] = true; + + return $this->render($response, 'settings/usernew.twig', array( + 'settings' => $settings, + 'acl' => $this->c->acl, + 'navigation' => $navigation, + 'users' => $users, + 'userrole' => $userroles, + 'route' => $route->getName() + )); + } + + public function createUser($request, $response, $args) + { + if($request->isPost()) + { + if( $request->getattribute('csrf_result') === false ) + { + $this->c->flash->addMessage('error', 'The form has a timeout, please try again.'); + return $response->withRedirect($this->c->router->pathFor('user.new')); + } + + $params = $request->getParams(); + $user = new User(); + $validate = new Validation(); + $userroles = $this->c->acl->getRoles(); + + if($validate->newUser($params, $userroles)) + { + $userdata = array( + 'username' => $params['username'], + 'email' => $params['email'], + 'userrole' => $params['userrole'], + 'password' => $params['password']); + + $user->createUser($userdata); + + $this->c->flash->addMessage('info', 'Welcome, there is a new user!'); + return $response->withRedirect($this->c->router->pathFor('user.list')); + } + + $this->c->flash->addMessage('error', 'Please correct your input'); + return $response->withRedirect($this->c->router->pathFor('user.new')); + } + } + + public function updateUser($request, $response, $args) + { + + if($request->isPost()) + { + if( $request->getattribute('csrf_result') === false ) + { + $this->c->flash->addMessage('error', 'The form has a timeout, please try again.'); + return $response->withRedirect($this->c->router->pathFor('user.account')); + } + + $params = $request->getParams(); + $userdata = $params['user']; + $user = new User(); + $validate = new Validation(); + $userroles = $this->c->acl->getRoles(); + + $redirectRoute = ($userdata['username'] == $_SESSION['user']) ? $this->c->router->pathFor('user.account') : $this->c->router->pathFor('user.show', ['username' => $userdata['username']]); + + # check if user is allowed to view (edit) userlist and other users + if(!$this->c->acl->isAllowed($_SESSION['role'], 'userlist', 'write')) + { + # if an editor tries to update other userdata than its own + if($_SESSION['user'] !== $userdata['username']) + { + return $response->withRedirect($this->c->router->pathFor('user.account')); + } + + # non admins cannot change their userrole, so set it to session-value + $userdata['userrole'] = $_SESSION['role']; + } + + # validate standard fields for users + if($validate->existingUser($userdata, $userroles)) + { + # validate custom input fields and return images + $userfields = $this->getUserFields($userdata['userrole']); + $imageFields = $this->validateInput('users', 'user', $userdata, $validate, $userfields); + + if(!empty($imageFields)) + { + $images = $request->getUploadedFiles(); + + if(isset($images['user'])) + { + # set image size + $settings = $this->c->get('settings'); + $imageSizes = $settings['images']; + $imageSizes['live'] = ['width' => 500, 'height' => 500]; + $settings->replace(['images' => $imageSizes]); + $imageresult = $this->saveImages($imageFields, $userdata, $settings, $images['user']); + + if(isset($_SESSION['slimFlash']['error'])) + { + return $response->withRedirect($redirectRoute); + } + elseif(isset($imageresult['username'])) + { + $userdata = $imageresult; + } + } + } + + # check for errors and redirect to path, if errors found + if(isset($_SESSION['errors'])) + { + $this->c->flash->addMessage('error', 'Please correct the errors'); + return $response->withRedirect($redirectRoute); + } + + if(empty($userdata['password']) AND empty($userdata['newpassword'])) + { + # make sure no invalid passwords go into model + unset($userdata['password']); + unset($userdata['newpassword']); + + $user->updateUser($userdata); + $this->c->flash->addMessage('info', 'Saved all changes'); + return $response->withRedirect($redirectRoute); + } + elseif($validate->newPassword($userdata)) + { + $userdata['password'] = $userdata['newpassword']; + unset($userdata['newpassword']); + + $user->updateUser($userdata); + $this->c->flash->addMessage('info', 'Saved all changes'); + return $response->withRedirect($redirectRoute); + } + } + + # change error-array for formbuilder + $errors = $_SESSION['errors']; + unset($_SESSION['errors']); + $_SESSION['errors']['user'] = $errors;# + + $this->c->flash->addMessage('error', 'Please correct your input'); + return $response->withRedirect($redirectRoute); + } + } + + public function deleteUser($request, $response, $args) + { + if($request->isPost()) + { + if( $request->getattribute('csrf_result') === false ) + { + $this->c->flash->addMessage('error', 'The form has a timeout, please try again.'); + return $response->withRedirect($this->c->router->pathFor('user.account')); + } + + $params = $request->getParams(); + $validate = new Validation(); + $user = new User(); + + # check if user is allowed to view (edit) userlist and other users + if(!$this->c->acl->isAllowed($_SESSION['role'], 'userlist', 'write')) + { + # if an editor tries to delete other user than its own + if($_SESSION['user'] !== $params['username']) + { + return $response->withRedirect($this->c->router->pathFor('user.account')); + } + } + + if($validate->username($params['username'])) + { + $userdata = $user->getSecureUser($params['username']); + if(!$userdata) + { + $this->c->flash->addMessage('error', 'Ups, we did not find that user'); + return $response->withRedirect($this->c->router->pathFor('user.show', ['username' => $params['username']])); + } + + $user->deleteUser($params['username']); + + $this->c->dispatcher->dispatch('onUserDeleted', new OnUserDeleted($userdata)); + + # if user deleted his own account + if($_SESSION['user'] == $params['username']) + { + session_destroy(); + return $response->withRedirect($this->c->router->pathFor('auth.show')); + } + + $this->c->flash->addMessage('info', 'Say goodbye, the user is gone!'); + return $response->withRedirect($this->c->router->pathFor('user.list')); + } + + $this->c->flash->addMessage('error', 'Ups, it is not a valid username'); + return $response->withRedirect($this->c->router->pathFor('user.show', ['username' => $params['username']])); + } + } + + 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)); + } + + + 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; + } + */ + +} \ No newline at end of file diff --git a/system/typemill/Extensions/TwigUrlExtension.php b/system/typemill/Extensions/TwigUrlExtension.php index 0242db0..a8056f0 100644 --- a/system/typemill/Extensions/TwigUrlExtension.php +++ b/system/typemill/Extensions/TwigUrlExtension.php @@ -6,19 +6,11 @@ use Twig\Extension\AbstractExtension; class TwigUrlExtension extends AbstractExtension { - protected $uri; - protected $basepath; - protected $scheme; - protected $authority; - protected $protocol; + protected $urlinfo; - public function __construct($uri, $basepath) + public function __construct($urlinfo) { - $this->uri = $uri; - $this->basepath = $basepath; - $this->scheme = $uri->getScheme(); - $this->authority = $uri->getAuthority(); - $this->protocol = ($this->scheme ? $this->scheme . ':' : '') . ($this->authority ? '//' . $this->authority : ''); + $this->urlinfo = $urlinfo; } public function getFunctions() @@ -32,16 +24,16 @@ class TwigUrlExtension extends AbstractExtension public function baseUrl() { - return $this->protocol . $this->basepath; + return $this->urlinfo['baseurl']; } public function currentUrl() { - return $this->protocol . $this->uri->getPath(); + return $this->urlinfo['currenturl']; } public function currentPath() { - return $this->uri->getPath(); + return $this->urlinfo['route']; } } \ No newline at end of file diff --git a/system/typemill/Middleware/JsonBodyParser.php b/system/typemill/Middleware/JsonBodyParser.php index 89a720f..f3d79de 100644 --- a/system/typemill/Middleware/JsonBodyParser.php +++ b/system/typemill/Middleware/JsonBodyParser.php @@ -11,8 +11,6 @@ class JsonBodyParser implements MiddlewareInterface { public function process(Request $request, RequestHandler $handler) :response { - #echo '{{theme.description}}
+{{ errors[name] }}
+{{ $filters.translate(description) }}
+{{ errors[name] }}
+{{ $filters.translate(description) }}
+{{ errors[name] }}
+{{ $filters.translate(description) }}
+{{ errors[name] }}
+{{ $filters.translate(description) }}
+{{ errors[name] }}
+{{ $filters.translate(description) }}
+{{ errors[name] }}
+{{ $filters.translate(description) }}
+{{ errors[name] }}
+{{ $filters.translate(description) }}
+{{ errors[name] }}
+{{ $filters.translate(description) }}
+{{ errors[name] }}
+{{ $filters.translate(description) }}
+{{ errors[name] }}
+{{ $filters.translate(description) }}
+{{ errors[name] }}
+{{ $filters.translate(description) }}
+{{ errors[name] }}
+{{ $filters.translate(description) }}
+{{ errors[name] }}
+{{ $filters.translate(description) }}
+{{ $filters.translate('upload an image') }}
'+ +{{ $filters.translate(description) }}
{{ $filters.translate('upload') }}
+{{theme.description}}
+Username | +Userrole | +Edit | +|
---|---|---|---|
{{ user.username }} | +{{ user.userrole }} | +{{ user.email }} | +edit | +
{{theme.description}}
+