summaryrefslogtreecommitdiffstats
path: root/settings
diff options
context:
space:
mode:
authorblizzz <blizzz@arthur-schiwon.de>2017-06-29 20:02:09 +0200
committerGitHub <noreply@github.com>2017-06-29 20:02:09 +0200
commit72d3bfcf56c40e24cbd706dfddb627d21ad8ad54 (patch)
tree3f565f387f05dd52fed8fa3e297bf776cee194df /settings
parent57c5a15e418dac9491403aba8266a97b7fadc064 (diff)
parent010a3c09f2c589f15dc885694fdb0f7febdb25d8 (diff)
downloadnextcloud-server-72d3bfcf56c40e24cbd706dfddb627d21ad8ad54.tar.gz
nextcloud-server-72d3bfcf56c40e24cbd706dfddb627d21ad8ad54.zip
Merge pull request #4890 from nextcloud/unify-settings
Unify settings
Diffstat (limited to 'settings')
-rw-r--r--settings/Controller/AdminSettingsController.php61
-rw-r--r--settings/Controller/CommonSettingsTrait.php126
-rw-r--r--settings/Controller/PersonalSettingsController.php106
-rw-r--r--settings/css/settings.css8
-rw-r--r--settings/js/settings/authtoken-init.js7
-rw-r--r--settings/js/settings/personalInfo.js (renamed from settings/js/personal.js)46
-rw-r--r--settings/personal.php281
-rw-r--r--settings/routes.php3
-rw-r--r--settings/templates/settings/additional.php (renamed from settings/templates/admin/additional.php)0
-rw-r--r--settings/templates/settings/admin/additional-mail.php (renamed from settings/templates/admin/additional-mail.php)0
-rw-r--r--settings/templates/settings/admin/encryption.php (renamed from settings/templates/admin/encryption.php)0
-rw-r--r--settings/templates/settings/admin/server.development.notice.php (renamed from settings/templates/admin/server.development.notice.php)0
-rw-r--r--settings/templates/settings/admin/server.php (renamed from settings/templates/admin/server.php)0
-rw-r--r--settings/templates/settings/admin/sharing.php (renamed from settings/templates/admin/sharing.php)0
-rw-r--r--settings/templates/settings/admin/tipstricks.php (renamed from settings/templates/admin/tipstricks.php)0
-rw-r--r--settings/templates/settings/empty.php25
-rw-r--r--settings/templates/settings/frame.php (renamed from settings/templates/admin/frame.php)32
-rw-r--r--settings/templates/settings/personal/personal.info.php316
-rw-r--r--settings/templates/settings/personal/security.php68
-rw-r--r--settings/templates/settings/personal/sync-clients.php59
20 files changed, 756 insertions, 382 deletions
diff --git a/settings/Controller/AdminSettingsController.php b/settings/Controller/AdminSettingsController.php
index 6c915be6f94..33d9cb2c2a3 100644
--- a/settings/Controller/AdminSettingsController.php
+++ b/settings/Controller/AdminSettingsController.php
@@ -28,19 +28,17 @@ use OCP\AppFramework\Controller;
use OCP\AppFramework\Http\TemplateResponse;
use OCP\INavigationManager;
use OCP\IRequest;
-use OCP\Settings\IIconSection;
use OCP\Settings\IManager as ISettingsManager;
-use OCP\Settings\ISection;
use OCP\Template;
/**
* @package OC\Settings\Controller
*/
class AdminSettingsController extends Controller {
+ use CommonSettingsTrait;
+
/** @var INavigationManager */
private $navigationManager;
- /** @var ISettingsManager */
- private $settingsManager;
/**
* @param string $appName
@@ -67,32 +65,20 @@ class AdminSettingsController extends Controller {
*/
public function index($section) {
$this->navigationManager->setActiveEntry('admin');
-
- $templateParams = [];
- $templateParams = array_merge($templateParams, $this->getNavigationParameters($section));
- $templateParams = array_merge($templateParams, $this->getSettings($section));
-
- return new TemplateResponse('settings', 'admin/frame', $templateParams);
+ return $this->getIndexResponse('admin', $section);
}
/**
* @param string $section
* @return array
*/
- private function getSettings($section) {
- $html = '';
+ protected function getSettings($section) {
$settings = $this->settingsManager->getAdminSettings($section);
- foreach ($settings as $prioritizedSettings) {
- foreach ($prioritizedSettings as $setting) {
- /** @var \OCP\Settings\ISettings $setting */
- $form = $setting->getForm();
- $html .= $form->renderAs('')->render();
- }
- }
+ $formatted = $this->formatSettings($settings);
if($section === 'additional') {
- $html .= $this->getLegacyForms();
+ $formatted['content'] .= $this->getLegacyForms();
}
- return ['content' => $html];
+ return $formatted;
}
/**
@@ -119,42 +105,11 @@ class AdminSettingsController extends Controller {
);
}, $forms);
- $out = new Template('settings', 'admin/additional');
+ $out = new Template('settings', 'settings/additional');
$out->assign('forms', $forms);
return $out->fetchPage();
}
- /**
- * @param string $currentSection
- * @return array
- */
- private function getNavigationParameters($currentSection) {
- $sections = $this->settingsManager->getAdminSections();
- $templateParameters = [];
- /** @var \OC\Settings\Section[] $prioritizedSections */
- foreach($sections as $prioritizedSections) {
- foreach ($prioritizedSections as $section) {
- if (empty($this->settingsManager->getAdminSettings($section->getID()))) {
- continue;
- }
-
- $icon = '';
- if ($section instanceof IIconSection) {
- $icon = $section->getIcon();
- }
-
- $templateParameters[] = [
- 'anchor' => $section->getID(),
- 'section-name' => $section->getName(),
- 'active' => $section->getID() === $currentSection,
- 'icon' => $icon,
- ];
- }
- }
- return [
- 'forms' => $templateParameters
- ];
- }
}
diff --git a/settings/Controller/CommonSettingsTrait.php b/settings/Controller/CommonSettingsTrait.php
new file mode 100644
index 00000000000..ac316aa7f48
--- /dev/null
+++ b/settings/Controller/CommonSettingsTrait.php
@@ -0,0 +1,126 @@
+<?php
+/**
+ * @copyright Copyright (c) 2017 Arthur Schiwon <blizzz@arthur-schiwon.de>
+ *
+ * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OC\Settings\Controller;
+
+use OCP\AppFramework\Http\TemplateResponse;
+use OCP\Settings\IManager as ISettingsManager;
+use OCP\Settings\IIconSection;
+use OCP\Settings\ISettings;
+
+trait CommonSettingsTrait {
+ /** @var ISettingsManager */
+ private $settingsManager;
+
+ /**
+ * @param string $currentSection
+ * @return array
+ */
+ private function getNavigationParameters($currentType, $currentSection) {
+ $templateParameters = [
+ 'personal' => $this->formatPersonalSections($currentType, $currentSection),
+ 'admin' => []
+ ];
+
+ if(\OC_User::isAdminUser(\OC_User::getUser())) {
+ $templateParameters['admin'] = $this->formatAdminSections($currentType, $currentSection);
+ }
+
+ return [
+ 'forms' => $templateParameters
+ ];
+ }
+
+ protected function formatSections($sections, $currentSection, $type, $currentType) {
+ $templateParameters = [];
+ /** @var \OCP\Settings\ISection[] $prioritizedSections */
+ foreach($sections as $prioritizedSections) {
+ foreach ($prioritizedSections as $section) {
+ if($type === 'admin') {
+ $settings = $this->settingsManager->getAdminSettings($section->getID());
+ } else if($type === 'personal') {
+ $settings = $this->settingsManager->getPersonalSettings($section->getID());
+ }
+ if (empty($settings)) {
+ continue;
+ }
+
+ $icon = '';
+ if ($section instanceof IIconSection) {
+ $icon = $section->getIcon();
+ }
+
+ $active = $section->getID() === $currentSection
+ && $type === $currentType;
+
+ $templateParameters[] = [
+ 'anchor' => $section->getID(),
+ 'section-name' => $section->getName(),
+ 'active' => $active,
+ 'icon' => $icon,
+ ];
+ }
+ }
+ return $templateParameters;
+ }
+
+ protected function formatPersonalSections($currentType, $currentSections) {
+ $sections = $this->settingsManager->getPersonalSections();
+ $templateParameters = $this->formatSections($sections, $currentSections, 'personal', $currentType);
+
+ return $templateParameters;
+ }
+
+ protected function formatAdminSections($currentType, $currentSections) {
+ $sections = $this->settingsManager->getAdminSections();
+ $templateParameters = $this->formatSections($sections, $currentSections, 'admin', $currentType);
+
+ return $templateParameters;
+ }
+
+ /**
+ * @param ISettings[] $settings
+ * @return array
+ */
+ private function formatSettings($settings) {
+ $html = '';
+ foreach ($settings as $prioritizedSettings) {
+ foreach ($prioritizedSettings as $setting) {
+ /** @var \OCP\Settings\ISettings $setting */
+ $form = $setting->getForm();
+ $html .= $form->renderAs('')->render();
+ }
+ }
+ return ['content' => $html];
+ }
+
+ private function getIndexResponse($type, $section) {
+ $templateParams = [];
+ $templateParams = array_merge($templateParams, $this->getNavigationParameters($type, $section));
+ $templateParams = array_merge($templateParams, $this->getSettings($section));
+
+ return new TemplateResponse('settings', 'settings/frame', $templateParams);
+ }
+
+ abstract protected function getSettings($section);
+}
diff --git a/settings/Controller/PersonalSettingsController.php b/settings/Controller/PersonalSettingsController.php
new file mode 100644
index 00000000000..7e2d62961b7
--- /dev/null
+++ b/settings/Controller/PersonalSettingsController.php
@@ -0,0 +1,106 @@
+<?php
+/**
+ * @copyright Copyright (c) 2017 Arthur Schiwon <blizzz@arthur-schiwon.de>
+ *
+ * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OC\Settings\Controller;
+
+use OCP\AppFramework\Controller;
+use OCP\AppFramework\Http\TemplateResponse;
+use OCP\INavigationManager;
+use OCP\IRequest;
+use OCP\Settings\IManager as ISettingsManager;
+use OCP\Template;
+
+class PersonalSettingsController extends Controller {
+ use CommonSettingsTrait;
+
+ /** @var INavigationManager */
+ private $navigationManager;
+
+ public function __construct(
+ $appName,
+ IRequest $request,
+ INavigationManager $navigationManager,
+ ISettingsManager $settingsManager
+ ) {
+ parent::__construct($appName, $request);
+ $this->navigationManager = $navigationManager;
+ $this->settingsManager = $settingsManager;
+ }
+
+ /**
+ * @param string $section
+ * @return TemplateResponse
+ *
+ * @NoCSRFRequired
+ * @NoAdminRequired
+ * @NoSubadminRequired
+ */
+ public function index($section) {
+ $this->navigationManager->setActiveEntry('personal');
+ return $this->getIndexResponse('personal', $section);
+
+ }
+
+ /**
+ * @param string $section
+ * @return array
+ */
+ protected function getSettings($section) {
+ $settings = $this->settingsManager->getPersonalSettings($section);
+ $formatted = $this->formatSettings($settings);
+ if($section === 'additional') {
+ $formatted['content'] .= $this->getLegacyForms();
+ }
+ return $formatted;
+ }
+
+ /**
+ * @return bool|string
+ */
+ private function getLegacyForms() {
+ $forms = \OC_App::getForms('personal');
+
+ $forms = array_map(function ($form) {
+ if (preg_match('%(<h2(?P<class>[^>]*)>.*?</h2>)%i', $form, $regs)) {
+ $sectionName = str_replace('<h2' . $regs['class'] . '>', '', $regs[0]);
+ $sectionName = str_replace('</h2>', '', $sectionName);
+ $anchor = strtolower($sectionName);
+ $anchor = str_replace(' ', '-', $anchor);
+
+ return array(
+ 'anchor' => $anchor,
+ 'section-name' => $sectionName,
+ 'form' => $form
+ );
+ }
+ return array(
+ 'form' => $form
+ );
+ }, $forms);
+
+ $out = new Template('settings', 'settings/additional');
+ $out->assign('forms', $forms);
+
+ return $out->fetchPage();
+ }
+}
diff --git a/settings/css/settings.css b/settings/css/settings.css
index 0d68a3b622d..4786af4733f 100644
--- a/settings/css/settings.css
+++ b/settings/css/settings.css
@@ -1296,3 +1296,11 @@ doesnotexist:-o-prefocus, .strengthify-wrapper {
margin-bottom: 12px;
opacity: .7;
}
+
+.settings-caption {
+ font-weight: bold;
+ line-height: 44px;
+ padding: 0 12px;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+}
diff --git a/settings/js/settings/authtoken-init.js b/settings/js/settings/authtoken-init.js
new file mode 100644
index 00000000000..953727e39dc
--- /dev/null
+++ b/settings/js/settings/authtoken-init.js
@@ -0,0 +1,7 @@
+$(document).ready(function () {
+ var collection = new OC.Settings.AuthTokenCollection();
+ var view = new OC.Settings.AuthTokenView({
+ collection: collection
+ });
+ view.reload();
+});
diff --git a/settings/js/personal.js b/settings/js/settings/personalInfo.js
index effce9de07e..306994a7094 100644
--- a/settings/js/personal.js
+++ b/settings/js/settings/personalInfo.js
@@ -4,6 +4,7 @@
* Copyright (c) 2011, Robin Appelman <icewind1991@gmail.com>
* 2013, Morris Jobke <morris.jobke@gmail.com>
* 2016, Christoph Wurst <christoph@owncloud.com>
+ * 2017, Arthur Schiwon <blizzz@arthur-schiwon.de>
* This file is licensed under the Affero General Public License version 3 or later.
* See the COPYING-README file.
*/
@@ -394,51 +395,6 @@ $(document).ready(function () {
$('#removeavatar').removeClass('hidden').addClass('inlineblock');
}
});
-
-
- // Show token views
- var collection = new OC.Settings.AuthTokenCollection();
- var view = new OC.Settings.AuthTokenView({
- collection: collection
- });
- view.reload();
-
- // 'redirect' to anchor sections
- // anchors are lost on redirects (e.g. while solving the 2fa challenge) otherwise
- // example: /settings/person?section=devices will result in /settings/person?#devices
- if (!window.location.hash) {
- var query = OC.parseQueryString(location.search);
- if (query && query.section) {
- OC.Util.History.replaceState({});
- window.location.hash = query.section;
- }
- }
});
-if (!OC.Encryption) {
- OC.Encryption = {};
-}
-
-OC.Encryption.msg = {
- start: function (selector, msg) {
- var spinner = '<img src="' + OC.imagePath('core', 'loading-small.gif') + '">';
- $(selector)
- .html(msg + ' ' + spinner)
- .removeClass('success')
- .removeClass('error')
- .stop(true, true)
- .show();
- },
- finished: function (selector, data) {
- if (data.status === "success") {
- $(selector).html(data.data.message)
- .addClass('success')
- .stop(true, true)
- .delay(3000);
- } else {
- $(selector).html(data.data.message).addClass('error');
- }
- }
-};
-
OC.Settings.updateAvatar = updateAvatar;
diff --git a/settings/personal.php b/settings/personal.php
deleted file mode 100644
index fcccbc50556..00000000000
--- a/settings/personal.php
+++ /dev/null
@@ -1,281 +0,0 @@
-<?php
-/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- * @author Bart Visscher <bartv@thisnet.nl>
- * @author Björn Schießle <bjoern@schiessle.org>
- * @author Christopher Schäpers <kondou@ts.unde.re>
- * @author Christoph Wurst <christoph@owncloud.com>
- * @author Georg Ehrke <georg@owncloud.com>
- * @author Jakob Sack <mail@jakobsack.de>
- * @author Jan-Christoph Borchardt <hey@jancborchardt.net>
- * @author Joas Schilling <coding@schilljs.com>
- * @author Lukas Reschke <lukas@statuscode.ch>
- * @author Marvin Thomas Rabe <mrabe@marvinrabe.de>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <robin@icewind.nl>
- * @author Roeland Jago Douma <roeland@famdouma.nl>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- * @author Vincent Petry <pvince81@owncloud.com>
- * @author Volkan Gezer <volkangezer@gmail.com>
- *
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
- */
-
-OC_Util::checkLoggedIn();
-
-$defaults = \OC::$server->getThemingDefaults();
-$certificateManager = \OC::$server->getCertificateManager();
-$accountManager = new \OC\Accounts\AccountManager(
- \OC::$server->getDatabaseConnection(),
- \OC::$server->getEventDispatcher(),
- \OC::$server->getJobList()
-);
-$config = \OC::$server->getConfig();
-$urlGenerator = \OC::$server->getURLGenerator();
-
-// Highlight navigation entry
-OC_Util::addScript('settings', 'authtoken');
-OC_Util::addScript('settings', 'authtoken_collection');
-OC_Util::addScript('settings', 'authtoken_view');
-OC_Util::addScript('settings', 'usersettings');
-OC_Util::addScript('settings', 'federationsettingsview');
-OC_Util::addScript('settings', 'federationscopemenu');
-OC_Util::addScript('settings', 'personal');
-OC_Util::addScript('settings', 'certificates');
-OC_Util::addStyle( 'settings', 'settings' );
-\OC_Util::addVendorScript('strengthify/jquery.strengthify');
-\OC_Util::addVendorStyle('strengthify/strengthify');
-\OC_Util::addScript('files', 'jquery.fileupload');
-\OC_Util::addVendorScript('jcrop/js/jquery.Jcrop');
-\OC_Util::addVendorStyle('jcrop/css/jquery.Jcrop');
-
-\OC::$server->getEventDispatcher()->dispatch('OC\Settings\Personal::loadAdditionalScripts');
-
-// Highlight navigation entry
-OC::$server->getNavigationManager()->setActiveEntry('personal');
-
-$storageInfo=OC_Helper::getStorageInfo('/');
-
-$user = OC::$server->getUserManager()->get(OC_User::getUser());
-
-$forceLanguage = $config->getSystemValue('force_language', false);
-if ($forceLanguage === false) {
- $userLang=$config->getUserValue( OC_User::getUser(), 'core', 'lang', \OC::$server->getL10NFactory()->findLanguage() );
- $languageCodes = \OC::$server->getL10NFactory()->findAvailableLanguages();
-
- // array of common languages
- $commonLangCodes = array(
- 'en', 'es', 'fr', 'de', 'de_DE', 'ja', 'ar', 'ru', 'nl', 'it', 'pt_BR', 'pt_PT', 'da', 'fi_FI', 'nb_NO', 'sv', 'tr', 'zh_CN', 'ko'
- );
-
- $languages=array();
- $commonLanguages = array();
- foreach($languageCodes as $lang) {
- $l = \OC::$server->getL10N('settings', $lang);
- // TRANSLATORS this is the language name for the language switcher in the personal settings and should be the localized version
- $potentialName = (string) $l->t('__language_name__');
- if($l->getLanguageCode() === $lang && substr($potentialName, 0, 1) !== '_') {//first check if the language name is in the translation file
- $ln = array('code' => $lang, 'name' => $potentialName);
- } elseif ($lang === 'en') {
- $ln = ['code' => $lang, 'name' => 'English (US)'];
- }else{//fallback to language code
- $ln=array('code'=>$lang, 'name'=>$lang);
- }
-
- // put appropriate languages into appropriate arrays, to print them sorted
- // used language -> common languages -> divider -> other languages
- if ($lang === $userLang) {
- $userLang = $ln;
- } elseif (in_array($lang, $commonLangCodes)) {
- $commonLanguages[array_search($lang, $commonLangCodes)]=$ln;
- } else {
- $languages[]=$ln;
- }
- }
-
- // if user language is not available but set somehow: show the actual code as name
- if (!is_array($userLang)) {
- $userLang = [
- 'code' => $userLang,
- 'name' => $userLang,
- ];
- }
-
- ksort($commonLanguages);
-
- // sort now by displayed language not the iso-code
- usort( $languages, function ($a, $b) {
- if ($a['code'] === $a['name'] && $b['code'] !== $b['name']) {
- // If a doesn't have a name, but b does, list b before a
- return 1;
- }
- if ($a['code'] !== $a['name'] && $b['code'] === $b['name']) {
- // If a does have a name, but b doesn't, list a before b
- return -1;
- }
- // Otherwise compare the names
- return strcmp($a['name'], $b['name']);
- });
-}
-
-//links to clients
-$clients = array(
- 'desktop' => $config->getSystemValue('customclient_desktop', $defaults->getSyncClientUrl()),
- 'android' => $config->getSystemValue('customclient_android', $defaults->getAndroidClientUrl()),
- 'ios' => $config->getSystemValue('customclient_ios', $defaults->getiOSClientUrl())
-);
-
-// only show root certificate import if external storages are enabled
-$enableCertImport = false;
-$externalStorageEnabled = \OC::$server->getAppManager()->isEnabledForUser('files_external');
-if ($externalStorageEnabled) {
- /** @var \OCA\Files_External\Service\BackendService $backendService */
- $backendService = \OC_Mount_Config::$app->getContainer()->query('\OCA\Files_External\Service\BackendService');
- $enableCertImport = $backendService->isUserMountingAllowed();
-}
-
-
-// Return template
-$l = \OC::$server->getL10N('settings');
-$tmpl = new OC_Template( 'settings', 'personal', 'user');
-$tmpl->assign('usage', OC_Helper::humanFileSize($storageInfo['used']));
-if ($storageInfo['quota'] === \OCP\Files\FileInfo::SPACE_UNLIMITED) {
- $totalSpace = $l->t('Unlimited');
-} else {
- $totalSpace = OC_Helper::humanFileSize($storageInfo['total']);
-}
-
-$uid = $user->getUID();
-$userData = $accountManager->getUser($user);
-
-$tmpl->assign('total_space', $totalSpace);
-$tmpl->assign('usage_relative', $storageInfo['relative']);
-$tmpl->assign('quota', $storageInfo['quota']);
-$tmpl->assign('clients', $clients);
-$tmpl->assign('email', $userData[\OC\Accounts\AccountManager::PROPERTY_EMAIL]['value']);
-if ($forceLanguage === false) {
- $tmpl->assign('languages', $languages);
- $tmpl->assign('commonlanguages', $commonLanguages);
- $tmpl->assign('activelanguage', $userLang);
-}
-$tmpl->assign('passwordChangeSupported', OC_User::canUserChangePassword(OC_User::getUser()));
-$tmpl->assign('displayNameChangeSupported', OC_User::canUserChangeDisplayName(OC_User::getUser()));
-$tmpl->assign('displayName', $userData[\OC\Accounts\AccountManager::PROPERTY_DISPLAYNAME]['value']);
-
-$tmpl->assign('phone', $userData[\OC\Accounts\AccountManager::PROPERTY_PHONE]['value']);
-$tmpl->assign('website', $userData[\OC\Accounts\AccountManager::PROPERTY_WEBSITE]['value']);
-$tmpl->assign('twitter', $userData[\OC\Accounts\AccountManager::PROPERTY_TWITTER]['value']);
-$tmpl->assign('address', $userData[\OC\Accounts\AccountManager::PROPERTY_ADDRESS]['value']);
-
-$tmpl->assign('avatarScope', $userData[\OC\Accounts\AccountManager::PROPERTY_AVATAR]['scope']);
-$tmpl->assign('displayNameScope', $userData[\OC\Accounts\AccountManager::PROPERTY_DISPLAYNAME]['scope']);
-$tmpl->assign('phoneScope', $userData[\OC\Accounts\AccountManager::PROPERTY_PHONE]['scope']);
-$tmpl->assign('emailScope', $userData[\OC\Accounts\AccountManager::PROPERTY_EMAIL]['scope']);
-$tmpl->assign('websiteScope', $userData[\OC\Accounts\AccountManager::PROPERTY_WEBSITE]['scope']);
-$tmpl->assign('twitterScope', $userData[\OC\Accounts\AccountManager::PROPERTY_TWITTER]['scope']);
-$tmpl->assign('addressScope', $userData[\OC\Accounts\AccountManager::PROPERTY_ADDRESS]['scope']);
-
-$tmpl->assign('websiteVerification', $userData[\OC\Accounts\AccountManager::PROPERTY_WEBSITE]['verified']);
-$tmpl->assign('twitterVerification', $userData[\OC\Accounts\AccountManager::PROPERTY_TWITTER]['verified']);
-$tmpl->assign('emailVerification', $userData[\OC\Accounts\AccountManager::PROPERTY_EMAIL]['verified']);
-
-$needVerifyMessage = [\OC\Accounts\AccountManager::PROPERTY_EMAIL, \OC\Accounts\AccountManager::PROPERTY_WEBSITE, \OC\Accounts\AccountManager::PROPERTY_TWITTER];
-
-foreach ($needVerifyMessage as $property) {
-
- switch ($userData[$property]['verified']) {
- case \OC\Accounts\AccountManager::VERIFIED:
- $message = $l->t('Verifying');
- break;
- case \OC\Accounts\AccountManager::VERIFICATION_IN_PROGRESS:
- $message = $l->t('Verifying …');
- break;
- default:
- $message = $l->t('Verify');
- }
-
- $tmpl->assign($property . 'Message', $message);
-}
-
-$tmpl->assign('avatarChangeSupported', OC_User::canUserChangeAvatar(OC_User::getUser()));
-$tmpl->assign('certs', $certificateManager->listCertificates());
-$tmpl->assign('showCertificates', $enableCertImport);
-$tmpl->assign('urlGenerator', $urlGenerator);
-
-$federatedFileSharingEnabled = \OC::$server->getAppManager()->isEnabledForUser('federatedfilesharing');
-$lookupServerUploadEnabled = false;
-if ($federatedFileSharingEnabled) {
- $federatedFileSharing = new \OCA\FederatedFileSharing\AppInfo\Application();
- $shareProvider = $federatedFileSharing->getFederatedShareProvider();
- $lookupServerUploadEnabled = $shareProvider->isLookupServerUploadEnabled();
-}
-
-$tmpl->assign('lookupServerUploadEnabled', $lookupServerUploadEnabled);
-
-// Get array of group ids for this user
-$groups = \OC::$server->getGroupManager()->getUserIdGroups(OC_User::getUser());
-$groups2 = array_map(function($group) { return $group->getGID(); }, $groups);
-sort($groups2);
-$tmpl->assign('groups', $groups2);
-
-// add hardcoded forms from the template
-$formsAndMore = [];
-$formsAndMore[]= ['anchor' => 'personal-settings', 'section-name' => $l->t('Personal info')];
-$formsAndMore[]= ['anchor' => 'security', 'section-name' => $l->t('Security')];
-$formsAndMore[]= ['anchor' => 'clientsbox', 'section-name' => $l->t('Sync clients')];
-
-$forms=OC_App::getForms('personal');
-
-
-// add bottom hardcoded forms from the template
-if ($enableCertImport) {
- $certificatesTemplate = new OC_Template('settings', 'certificates');
- $certificatesTemplate->assign('type', 'personal');
- $certificatesTemplate->assign('uploadRoute', 'settings.Certificate.addPersonalRootCertificate');
- $certificatesTemplate->assign('certs', $certificateManager->listCertificates());
- $certificatesTemplate->assign('urlGenerator', $urlGenerator);
- $forms[] = $certificatesTemplate->fetchPage();
-}
-
-$formsMap = array_map(function($form){
- if (preg_match('%(<h2(?P<class>[^>]*)>.*?</h2>)%i', $form, $regs)) {
- $sectionName = str_replace('<h2'.$regs['class'].'>', '', $regs[0]);
- $sectionName = str_replace('</h2>', '', $sectionName);
- if (strpos($regs['class'], 'data-anchor-name') !== false) {
- preg_match('%.*data-anchor-name="(?P<anchor>[^"]*)"%i', $regs['class'], $matches);
- $anchor = $matches['anchor'];
- } else {
- $anchor = strtolower($sectionName);
- $anchor = str_replace(' ', '-', $anchor);
- }
-
- return array(
- 'anchor' => $anchor,
- 'section-name' => $sectionName,
- 'form' => $form
- );
- }
- return array(
- 'form' => $form
- );
-}, $forms);
-
-$formsAndMore = array_merge($formsAndMore, $formsMap);
-
-$tmpl->assign('forms', $formsAndMore);
-$tmpl->printPage();
diff --git a/settings/routes.php b/settings/routes.php
index 048febaa129..12da950ed2f 100644
--- a/settings/routes.php
+++ b/settings/routes.php
@@ -65,6 +65,7 @@ $application->registerRoutes($this, [
['name' => 'Certificate#removePersonalRootCertificate', 'url' => '/settings/personal/certificate/{certificateIdentifier}', 'verb' => 'DELETE'],
['name' => 'Certificate#addSystemRootCertificate', 'url' => '/settings/admin/certificate', 'verb' => 'POST'],
['name' => 'Certificate#removeSystemRootCertificate', 'url' => '/settings/admin/certificate/{certificateIdentifier}', 'verb' => 'DELETE'],
+ ['name' => 'PersonalSettings#index', 'url' => '/settings/user/{section}', 'verb' => 'GET', 'defaults' => ['section' => 'personal-info']],
['name' => 'AdminSettings#index', 'url' => '/settings/admin/{section}', 'verb' => 'GET', 'defaults' => ['section' => 'server']],
['name' => 'AdminSettings#form', 'url' => '/settings/admin/{section}', 'verb' => 'GET'],
['name' => 'ChangePassword#changePersonalPassword', 'url' => '/settings/personal/changepassword', 'verb' => 'POST'],
@@ -82,8 +83,6 @@ $application->registerRoutes($this, [
// Settings pages
$this->create('settings_help', '/settings/help')
->actionInclude('settings/help.php');
-$this->create('settings_personal', '/settings/personal')
- ->actionInclude('settings/personal.php');
$this->create('settings_users', '/settings/users')
->actionInclude('settings/users.php');
// Settings ajax actions
diff --git a/settings/templates/admin/additional.php b/settings/templates/settings/additional.php
index 2ad2c5af4e5..2ad2c5af4e5 100644
--- a/settings/templates/admin/additional.php
+++ b/settings/templates/settings/additional.php
diff --git a/settings/templates/admin/additional-mail.php b/settings/templates/settings/admin/additional-mail.php
index bce7e5adeee..bce7e5adeee 100644
--- a/settings/templates/admin/additional-mail.php
+++ b/settings/templates/settings/admin/additional-mail.php
diff --git a/settings/templates/admin/encryption.php b/settings/templates/settings/admin/encryption.php
index 1d956a8f7c1..1d956a8f7c1 100644
--- a/settings/templates/admin/encryption.php
+++ b/settings/templates/settings/admin/encryption.php
diff --git a/settings/templates/admin/server.development.notice.php b/settings/templates/settings/admin/server.development.notice.php
index f58258fc0ae..f58258fc0ae 100644
--- a/settings/templates/admin/server.development.notice.php
+++ b/settings/templates/settings/admin/server.development.notice.php
diff --git a/settings/templates/admin/server.php b/settings/templates/settings/admin/server.php
index 8d00d37fe80..8d00d37fe80 100644
--- a/settings/templates/admin/server.php
+++ b/settings/templates/settings/admin/server.php
diff --git a/settings/templates/admin/sharing.php b/settings/templates/settings/admin/sharing.php
index 38071a4bee9..38071a4bee9 100644
--- a/settings/templates/admin/sharing.php
+++ b/settings/templates/settings/admin/sharing.php
diff --git a/settings/templates/admin/tipstricks.php b/settings/templates/settings/admin/tipstricks.php
index c18c7f25f39..c18c7f25f39 100644
--- a/settings/templates/admin/tipstricks.php
+++ b/settings/templates/settings/admin/tipstricks.php
diff --git a/settings/templates/settings/empty.php b/settings/templates/settings/empty.php
new file mode 100644
index 00000000000..0ed8a873d3c
--- /dev/null
+++ b/settings/templates/settings/empty.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * @copyright Copyright (c) 2017 Arthur Schiwon <blizzz@arthur-schiwon.de>
+ *
+ * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+ # used for Personal/Additional settings as fallback for legacy settings
+?>
diff --git a/settings/templates/admin/frame.php b/settings/templates/settings/frame.php
index 2b234f4cd9b..80737bc6f91 100644
--- a/settings/templates/admin/frame.php
+++ b/settings/templates/settings/frame.php
@@ -30,9 +30,39 @@ script('files', 'jquery.fileupload');
<div id="app-navigation">
<ul>
+ <li class="settings-caption">Personal</li>
<?php
- foreach($_['forms'] as $form) {
+ foreach($_['forms']['personal'] as $form) {
if (isset($form['anchor'])) {
+ $anchor = \OC::$server->getURLGenerator()->linkToRoute('settings.PersonalSettings.index', ['section' => $form['anchor']]);
+ $class = 'nav-icon-' . $form['anchor'];
+ $sectionName = $form['section-name'];
+ $active = $form['active'] ? ' class="active"' : '';
+ ?>
+ <li <?php print_unescaped($form['active'] ? ' class="active"' : ''); ?>>
+ <a href="<?php p($anchor); ?>">
+ <?php if (!empty($form['icon'])) { ?>
+ <img alt="" src="<?php print_unescaped($form['icon']); ?>">
+ <span><?php p($form['section-name']); ?></span>
+ <?php } else { ?>
+ <span class="no-icon"><?php p($form['section-name']); ?></span>
+ <?php } ?>
+ </a>
+ </li>
+ <?php
+ }
+ }
+ ?>
+
+ <?php
+ if(!empty($_['forms']['admin'])) {
+ ?>
+ <li class="settings-caption">Administration</li>
+ <?php
+ }
+ foreach($_['forms']['admin'] as $form) {
+ if (isset($form['anchor'])) {
+
$anchor = \OC::$server->getURLGenerator()->linkToRoute('settings.AdminSettings.index', ['section' => $form['anchor']]);
$class = 'nav-icon-' . $form['anchor'];
$sectionName = $form['section-name'];
diff --git a/settings/templates/settings/personal/personal.info.php b/settings/templates/settings/personal/personal.info.php
new file mode 100644
index 00000000000..db14a4de986
--- /dev/null
+++ b/settings/templates/settings/personal/personal.info.php
@@ -0,0 +1,316 @@
+<?php
+/**
+ * @copyright Copyright (c) 2017 Arthur Schiwon <blizzz@arthur-schiwon.de>
+ *
+ * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/** @var \OCP\IL10N $l */
+/** @var array $_ */
+
+script('settings', [
+ 'usersettings',
+ 'federationsettingsview',
+ 'federationscopemenu',
+ 'settings/personalInfo',
+]);
+vendor_script('strengthify/jquery.strengthify');
+vendor_style('strengthify/strengthify');
+vendor_script('jcrop/js/jquery.Jcrop');
+vendor_style('jcrop/css/jquery.Jcrop');
+
+?>
+
+<div id="quota" class="section">
+ <div style="width:<?php p($_['usage_relative']);?>%"
+ <?php if($_['usage_relative'] > 80): ?> class="quota-warning" <?php endif; ?>>
+ <p id="quotatext">
+ <?php if ($_['quota'] === \OCP\Files\FileInfo::SPACE_UNLIMITED): ?>
+ <?php print_unescaped($l->t('You are using <strong>%s</strong> of <strong>%s</strong>',
+ [$_['usage'], $_['total_space']]));?>
+ <?php else: ?>
+ <?php print_unescaped($l->t('You are using <strong>%s</strong> of <strong>%s</strong> (<strong>%s %%</strong>)',
+ [$_['usage'], $_['total_space'], $_['usage_relative']]));?>
+ <?php endif ?>
+ </p>
+ </div>
+</div>
+
+<div id="personal-settings">
+ <div id="personal-settings-avatar-container">
+ <form id="avatarform" class="section" method="post" action="<?php p(\OC::$server->getURLGenerator()->linkToRoute('core.avatar.postAvatar')); ?>">
+ <h2>
+ <label><?php p($l->t('Profile picture')); ?></label>
+ <span class="icon-password"/>
+ </h2>
+ <div id="displayavatar">
+ <div class="avatardiv"></div>
+ <div class="warning hidden"></div>
+ <?php if ($_['avatarChangeSupported']): ?>
+ <label for="uploadavatar" class="inlineblock button icon-upload svg" id="uploadavatarbutton" title="<?php p($l->t('Upload new')); ?>"></label>
+ <div class="inlineblock button icon-folder svg" id="selectavatar" title="<?php p($l->t('Select from Files')); ?>"></div>
+ <div class="hidden button icon-delete svg" id="removeavatar" title="<?php p($l->t('Remove image')); ?>"></div>
+ <input type="file" name="files[]" id="uploadavatar" class="hiddenuploadfield">
+ <p><em><?php p($l->t('png or jpg, max. 20 MB')); ?></em></p>
+ <?php else: ?>
+ <?php p($l->t('Picture provided by original account')); ?>
+ <?php endif; ?>
+ </div>
+
+ <div id="cropper" class="hidden">
+ <div class="inner-container">
+ <div class="inlineblock button" id="abortcropperbutton"><?php p($l->t('Cancel')); ?></div>
+ <div class="inlineblock button primary" id="sendcropperbutton"><?php p($l->t('Choose as profile picture')); ?></div>
+ </div>
+ </div>
+ <span class="icon-checkmark hidden"/>
+ <?php if($_['lookupServerUploadEnabled']) { ?>
+ <input type="hidden" id="avatarscope" value="<?php p($_['avatarScope']) ?>">
+ <?php } ?>
+ </form>
+ </div>
+
+ <div id="personal-settings-container">
+ <div class="personal-settings-setting-box">
+ <form id="displaynameform" class="section">
+ <h2>
+ <label for="displayname"><?php p($l->t('Full name')); ?></label>
+ <span class="icon-password"/>
+ </h2>
+ <input type="text" id="displayname" name="displayname"
+ <?php if(!$_['displayNameChangeSupported']) { print_unescaped('class="hidden"'); } ?>
+ value="<?php p($_['displayName']) ?>"
+ autocomplete="on" autocapitalize="none" autocorrect="off" />
+ <?php if(!$_['displayNameChangeSupported']) { ?>
+ <span><?php if(isset($_['displayName']) && !empty($_['displayName'])) { p($_['displayName']); } else { p($l->t('No display name set')); } ?></span>
+ <?php } ?>
+ <span class="icon-checkmark hidden"/>
+ <?php if($_['lookupServerUploadEnabled']) { ?>
+ <input type="hidden" id="displaynamescope" value="<?php p($_['displayNameScope']) ?>">
+ <?php } ?>
+ </form>
+ </div>
+ <div class="personal-settings-setting-box">
+ <form id="emailform" class="section">
+ <h2>
+ <label for="email"><?php p($l->t('Email')); ?></label>
+ <span class="icon-password"/>
+ </h2>
+ <div class="verify <?php if ($_['email'] === '' || $_['emailScope'] !== 'public') p('hidden'); ?>">
+ <img id="verify-email" title="<?php p($_['emailMessage']); ?>" data-status="<?php p($_['emailVerification']) ?>" src="
+ <?php
+ switch($_['emailVerification']) {
+ case \OC\Accounts\AccountManager::VERIFICATION_IN_PROGRESS:
+ p(image_path('core', 'actions/verifying.svg'));
+ break;
+ case \OC\Accounts\AccountManager::VERIFIED:
+ p(image_path('core', 'actions/verified.svg'));
+ break;
+ default:
+ p(image_path('core', 'actions/verify.svg'));
+ }
+ ?>">
+ </div>
+ <input type="email" name="email" id="email" value="<?php p($_['email']); ?>"
+ <?php if(!$_['displayNameChangeSupported']) { print_unescaped('class="hidden"'); } ?>
+ placeholder="<?php p($l->t('Your email address')); ?>"
+ autocomplete="on" autocapitalize="none" autocorrect="off" />
+ <?php if(!$_['displayNameChangeSupported']) { ?>
+ <span><?php if(isset($_['email']) && !empty($_['email'])) { p($_['email']); } else { p($l->t('No email address set')); }?></span>
+ <?php } ?>
+ <?php if($_['displayNameChangeSupported']) { ?>
+ <br />
+ <em><?php p($l->t('For password reset and notifications')); ?></em>
+ <?php } ?>
+ <span class="icon-checkmark hidden"/>
+ <?php if($_['lookupServerUploadEnabled']) { ?>
+ <input type="hidden" id="emailscope" value="<?php p($_['emailScope']) ?>">
+ <?php } ?>
+ </form>
+ </div>
+ <?php if($_['lookupServerUploadEnabled']) { ?>
+ <div class="personal-settings-setting-box">
+ <form id="phoneform" class="section">
+ <h2>
+ <label for="phone"><?php p($l->t('Phone number')); ?></label>
+ <span class="icon-password"/>
+ </h2>
+ <input type="tel" id="phone" name="phone"
+ value="<?php p($_['phone']) ?>"
+ placeholder="<?php p($l->t('Your phone number')); ?>"
+ autocomplete="on" autocapitalize="none" autocorrect="off" />
+ <span class="icon-checkmark hidden"/>
+ <input type="hidden" id="phonescope" value="<?php p($_['phoneScope']) ?>">
+ </form>
+ </div>
+ <div class="personal-settings-setting-box">
+ <form id="addressform" class="section">
+ <h2>
+ <label for="address"><?php p($l->t('Address')); ?></label>
+ <span class="icon-password"/>
+ </h2>
+ <input type="text" id="address" name="address"
+ placeholder="<?php p($l->t('Your postal address')); ?>"
+ value="<?php p($_['address']) ?>"
+ autocomplete="on" autocapitalize="none" autocorrect="off" />
+ <span class="icon-checkmark hidden"/>
+ <input type="hidden" id="addressscope" value="<?php p($_['addressScope']) ?>">
+ </form>
+ </div>
+ <div class="personal-settings-setting-box">
+ <form id="websiteform" class="section">
+ <h2>
+ <label for="website"><?php p($l->t('Website')); ?></label>
+ <span class="icon-password"/>
+ </h2>
+ <div class="verify <?php if ($_['website'] === '' || $_['websiteScope'] !== 'public') p('hidden'); ?>">
+ <img id="verify-website" title="<?php p($_['websiteMessage']); ?>" data-status="<?php p($_['websiteVerification']) ?>" src="
+ <?php
+ switch($_['websiteVerification']) {
+ case \OC\Accounts\AccountManager::VERIFICATION_IN_PROGRESS:
+ p(image_path('core', 'actions/verifying.svg'));
+ break;
+ case \OC\Accounts\AccountManager::VERIFIED:
+ p(image_path('core', 'actions/verified.svg'));
+ break;
+ default:
+ p(image_path('core', 'actions/verify.svg'));
+ }
+ ?>"
+ <?php if($_['websiteVerification'] === \OC\Accounts\AccountManager::VERIFICATION_IN_PROGRESS || $_['websiteVerification'] === \OC\Accounts\AccountManager::NOT_VERIFIED) print_unescaped(' class="verify-action"') ?>
+ >
+ <div class="verification-dialog popovermenu bubble menu">
+ <div class="verification-dialog-content">
+ <p class="explainVerification"></p>
+ <p class="verificationCode"></p>
+ <p><?php p($l->t('It can take up to 24 hours before the account is displayed as verified.'));?></p>
+ </div>
+ </div>
+ </div>
+ <input type="text" name="website" id="website" value="<?php p($_['website']); ?>"
+ placeholder="<?php p($l->t('Link https://…')); ?>"
+ autocomplete="on" autocapitalize="none" autocorrect="off" />
+ <span class="icon-checkmark hidden"/>
+ <input type="hidden" id="websitescope" value="<?php p($_['websiteScope']) ?>">
+ </form>
+ </div>
+ <div class="personal-settings-setting-box">
+ <form id="twitterform" class="section">
+ <h2>
+ <label for="twitter"><?php p($l->t('Twitter')); ?></label>
+ <span class="icon-password"/>
+ </h2>
+ <div class="verify <?php if ($_['twitter'] === '' || $_['twitterScope'] !== 'public') p('hidden'); ?>">
+ <img id="verify-twitter" title="<?php p($_['twitterMessage']); ?>" data-status="<?php p($_['twitterVerification']) ?>" src="
+ <?php
+ switch($_['twitterVerification']) {
+ case \OC\Accounts\AccountManager::VERIFICATION_IN_PROGRESS:
+ p(image_path('core', 'actions/verifying.svg'));
+ break;
+ case \OC\Accounts\AccountManager::VERIFIED:
+ p(image_path('core', 'actions/verified.svg'));
+ break;
+ default:
+ p(image_path('core', 'actions/verify.svg'));
+ }
+ ?>"
+ <?php if($_['twitterVerification'] === \OC\Accounts\AccountManager::VERIFICATION_IN_PROGRESS || $_['twitterVerification'] === \OC\Accounts\AccountManager::NOT_VERIFIED) print_unescaped(' class="verify-action"') ?>
+ >
+ <div class="verification-dialog popovermenu bubble menu">
+ <div class="verification-dialog-content">
+ <p class="explainVerification"></p>
+ <p class="verificationCode"></p>
+ <p><?php p($l->t('It can take up to 24 hours before the account is displayed as verified.'));?></p>
+ </div>
+ </div>
+ </div>
+ <input type="text" name="twitter" id="twitter" value="<?php p($_['twitter']); ?>"
+ placeholder="<?php p($l->t('Twitter handle @…')); ?>"
+ autocomplete="on" autocapitalize="none" autocorrect="off" />
+ <span class="icon-checkmark hidden"/>
+ <input type="hidden" id="twitterscope" value="<?php p($_['twitterScope']) ?>">
+ </form>
+ </div>
+ <?php } ?>
+ <span class="msg"></span>
+ </div>
+</div>
+
+<div id="groups" class="section">
+ <h2><?php p($l->t('Groups')); ?></h2>
+ <p><?php p($l->t('You are member of the following groups:')); ?></p>
+ <p>
+ <?php p(implode(', ', $_['groups'])); ?>
+ </p>
+</div>
+
+<?php
+if($_['passwordChangeSupported']) {
+ script('jquery-showpassword');
+ ?>
+ <form id="passwordform" class="section">
+ <h2 class="inlineblock"><?php p($l->t('Password'));?></h2>
+ <div id="password-error-msg" class="msg success inlineblock" style="display: none;">Saved</div>
+ <br>
+ <label for="pass1" class="hidden-visually"><?php p($l->t('Current password')); ?>: </label>
+ <input type="password" id="pass1" name="oldpassword"
+ placeholder="<?php p($l->t('Current password'));?>"
+ autocomplete="off" autocapitalize="none" autocorrect="off" />
+ <div class="personal-show-container">
+ <label for="pass2" class="hidden-visually"><?php p($l->t('New password'));?>: </label>
+ <input type="password" id="pass2" name="newpassword"
+ placeholder="<?php p($l->t('New password')); ?>"
+ data-typetoggle="#personal-show"
+ autocomplete="off" autocapitalize="none" autocorrect="off" />
+ <input type="checkbox" id="personal-show" name="show" /><label for="personal-show" class="personal-show-label"></label>
+ </div>
+ <input id="passwordbutton" type="submit" value="<?php p($l->t('Change password')); ?>" />
+ <br/>
+ </form>
+ <?php
+}
+?>
+
+<?php if (isset($_['activelanguage'])) { ?>
+<form id="language" class="section">
+ <h2>
+ <label for="languageinput"><?php p($l->t('Language'));?></label>
+ </h2>
+ <select id="languageinput" name="lang" data-placeholder="<?php p($l->t('Language'));?>">
+ <option value="<?php p($_['activelanguage']['code']);?>">
+ <?php p($_['activelanguage']['name']);?>
+ </option>
+ <?php foreach($_['commonlanguages'] as $language):?>
+ <option value="<?php p($language['code']);?>">
+ <?php p($language['name']);?>
+ </option>
+ <?php endforeach;?>
+ <optgroup label="––––––––––"></optgroup>
+ <?php foreach($_['languages'] as $language):?>
+ <option value="<?php p($language['code']);?>">
+ <?php p($language['name']);?>
+ </option>
+ <?php endforeach;?>
+ </select>
+ <a href="https://www.transifex.com/nextcloud/nextcloud/"
+ target="_blank" rel="noreferrer">
+ <em><?php p($l->t('Help translate'));?></em>
+ </a>
+</form>
+<?php } ?>
diff --git a/settings/templates/settings/personal/security.php b/settings/templates/settings/personal/security.php
new file mode 100644
index 00000000000..3a324bf8d21
--- /dev/null
+++ b/settings/templates/settings/personal/security.php
@@ -0,0 +1,68 @@
+<?php
+/**
+ * @copyright Copyright (c) 2017 Arthur Schiwon <blizzz@arthur-schiwon.de>
+ *
+ * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+script('settings', [
+ 'authtoken',
+ 'authtoken_collection',
+ 'authtoken_view',
+ 'settings/authtoken-init'
+]);
+
+?>
+
+
+<div id="security" class="section">
+ <h2><?php p($l->t('Security'));?></h2>
+ <p class="settings-hint hidden-when-empty"><?php p($l->t('Web, desktop and mobile clients currently logged in to your account.'));?></p>
+ <table class="icon-loading">
+ <thead class="token-list-header">
+ <tr>
+ <th><?php p($l->t('Device'));?></th>
+ <th><?php p($l->t('Last activity'));?></th>
+ <th></th>
+ </tr>
+ </thead>
+ <tbody class="token-list">
+ </tbody>
+ </table>
+ <div id="app-password-form">
+ <input id="app-password-name" type="text" placeholder="<?php p($l->t('App name')); ?>">
+ <button id="add-app-password" class="button"><?php p($l->t('Create new app password')); ?></button>
+ </div>
+ <div id="app-password-result" class="hidden">
+ <span>
+ <?php p($l->t('Use the credentials below to configure your app or device.')); ?>
+ <?php p($l->t('For security reasons this password will only be shown once.')); ?>
+ </span>
+ <div class="app-password-row">
+ <span class="app-password-label"><?php p($l->t('Username')); ?></span>
+ <input id="new-app-login-name" type="text" readonly="readonly"/>
+ </div>
+ <div class="app-password-row">
+ <span class="app-password-label"><?php p($l->t('Password')); ?></span>
+ <input id="new-app-password" type="text" readonly="readonly"/>
+ <a class="clipboardButton icon icon-clippy" data-clipboard-target="#new-app-password"></a>
+ <button id="app-password-hide" class="button"><?php p($l->t('Done')); ?></button>
+ </div>
+ </div>
+</div>
diff --git a/settings/templates/settings/personal/sync-clients.php b/settings/templates/settings/personal/sync-clients.php
new file mode 100644
index 00000000000..ac76ef4f592
--- /dev/null
+++ b/settings/templates/settings/personal/sync-clients.php
@@ -0,0 +1,59 @@
+<?php
+/**
+ * @copyright Copyright (c) 2017 Arthur Schiwon <blizzz@arthur-schiwon.de>
+ *
+ * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/** @var array $_ */
+
+?>
+
+<div id="clientsbox" class="section clientsbox">
+ <h2><?php p($l->t('Get the apps to sync your files'));?></h2>
+ <a href="<?php p($_['clients']['desktop']); ?>" rel="noreferrer" target="_blank">
+ <img src="<?php print_unescaped(image_path('core', 'desktopapp.svg')); ?>"
+ alt="<?php p($l->t('Desktop client'));?>" />
+ </a>
+ <a href="<?php p($_['clients']['android']); ?>" rel="noreferrer" target="_blank">
+ <img src="<?php print_unescaped(image_path('core', 'googleplay.png')); ?>"
+ alt="<?php p($l->t('Android app'));?>" />
+ </a>
+ <a href="<?php p($_['clients']['ios']); ?>" rel="noreferrer" target="_blank">
+ <img src="<?php print_unescaped(image_path('core', 'appstore.svg')); ?>"
+ alt="<?php p($l->t('iOS app'));?>" />
+ </a>
+
+ <p>
+ <?php print_unescaped(str_replace(
+ [
+ '{contributeopen}',
+ '{linkclose}',
+ ],
+ [
+ '<a href="https://nextcloud.com/contribute" target="_blank" rel="noreferrer">',
+ '</a>',
+ ],
+ $l->t('If you want to support the project {contributeopen}join development{linkclose} or {contributeopen}spread the word{linkclose}!'))); ?>
+ </p>
+
+ <?php if(OC_APP::isEnabled('firstrunwizard')) {?>
+ <p><a class="button" href="#" id="showWizard"><?php p($l->t('Show First Run Wizard again'));?></a></p>
+ <?php }?>
+</div>