From 4ee9e21a4f5e177f3815c89d309af5a005bd88c3 Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Fri, 11 Oct 2019 11:55:02 -0400 Subject: [PATCH 1/4] Make Router::getModuleClass throw exceptions - Add new MethodNotAllowedModule - Add new Module->determineClass catch blocks - Update Module and Router tests --- src/App/Module.php | 54 ++++++++------- src/App/Router.php | 19 +++-- src/Module/HTTPException/MethodNotAllowed.php | 15 ++++ .../{ => HTTPException}/PageNotFound.php | 2 +- tests/src/App/ModuleTest.php | 4 +- tests/src/App/RouterTest.php | 69 ++++++++++++++++--- 6 files changed, 122 insertions(+), 41 deletions(-) create mode 100644 src/Module/HTTPException/MethodNotAllowed.php rename src/Module/{ => HTTPException}/PageNotFound.php (85%) diff --git a/src/App/Module.php b/src/App/Module.php index 9a24c5554..33a9b2fc2 100644 --- a/src/App/Module.php +++ b/src/App/Module.php @@ -7,7 +7,10 @@ use Friendica\BaseObject; use Friendica\Core; use Friendica\LegacyModule; use Friendica\Module\Home; -use Friendica\Module\PageNotFound; +use Friendica\Module\HTTPException\MethodNotAllowed; +use Friendica\Module\HTTPException\PageNotFound; +use Friendica\Network\HTTPException\MethodNotAllowedException; +use Friendica\Network\HTTPException\NotFoundException; use Psr\Log\LoggerInterface; /** @@ -144,38 +147,43 @@ class Module { $printNotAllowedAddon = false; + $module_class = null; /** * ROUTING * * From the request URL, routing consists of obtaining the name of a BaseModule-extending class of which the * post() and/or content() static methods can be respectively called to produce a data change or an output. **/ - $module_class = $router->getModuleClass($args->getCommand()); - - // Then we try addon-provided modules that we wrap in the LegacyModule class - if (!$module_class && Core\Addon::isEnabled($this->module) && file_exists("addon/{$this->module}/{$this->module}.php")) { - //Check if module is an app and if public access to apps is allowed or not - $privateapps = $config->get('config', 'private_addons', false); - if ((!local_user()) && Core\Hook::isAddonApp($this->module) && $privateapps) { - $printNotAllowedAddon = true; - } else { - include_once "addon/{$this->module}/{$this->module}.php"; - if (function_exists($this->module . '_module')) { - LegacyModule::setModuleFile("addon/{$this->module}/{$this->module}.php"); - $module_class = LegacyModule::class; + try { + $module_class = $router->getModuleClass($args->getCommand()); + } catch (MethodNotAllowedException $e) { + $module_class = MethodNotAllowed::class; + } catch (NotFoundException $e) { + // Then we try addon-provided modules that we wrap in the LegacyModule class + if (Core\Addon::isEnabled($this->module) && file_exists("addon/{$this->module}/{$this->module}.php")) { + //Check if module is an app and if public access to apps is allowed or not + $privateapps = $config->get('config', 'private_addons', false); + if ((!local_user()) && Core\Hook::isAddonApp($this->module) && $privateapps) { + $printNotAllowedAddon = true; + } else { + include_once "addon/{$this->module}/{$this->module}.php"; + if (function_exists($this->module . '_module')) { + LegacyModule::setModuleFile("addon/{$this->module}/{$this->module}.php"); + $module_class = LegacyModule::class; + } } } - } - /* Finally, we look for a 'standard' program module in the 'mod' directory - * We emulate a Module class through the LegacyModule class - */ - if (!$module_class && file_exists("mod/{$this->module}.php")) { - LegacyModule::setModuleFile("mod/{$this->module}.php"); - $module_class = LegacyModule::class; - } + /* Finally, we look for a 'standard' program module in the 'mod' directory + * We emulate a Module class through the LegacyModule class + */ + if (!$module_class && file_exists("mod/{$this->module}.php")) { + LegacyModule::setModuleFile("mod/{$this->module}.php"); + $module_class = LegacyModule::class; + } - $module_class = !isset($module_class) ? PageNotFound::class : $module_class; + $module_class = $module_class ?: PageNotFound::class; + } return new Module($this->module, $module_class, $this->isBackend, $printNotAllowedAddon); } diff --git a/src/App/Router.php b/src/App/Router.php index 1bdfdcab1..f723321ac 100644 --- a/src/App/Router.php +++ b/src/App/Router.php @@ -8,7 +8,8 @@ use FastRoute\Dispatcher; use FastRoute\RouteCollector; use FastRoute\RouteParser\Std; use Friendica\Core\Hook; -use Friendica\Network\HTTPException\InternalServerErrorException; +use Friendica\Core\L10n; +use Friendica\Network\HTTPException; /** * Wrapper for FastRoute\Router @@ -57,7 +58,7 @@ class Router * * @return self The router instance with the loaded routes * - * @throws InternalServerErrorException In case of invalid configs + * @throws HTTPException\InternalServerErrorException In case of invalid configs */ public function addRoutes(array $routes) { @@ -71,7 +72,7 @@ class Router } elseif ($this->isRoute($config)) { $routeCollector->addRoute($config[1], $route, $config[0]); } else { - throw new InternalServerErrorException("Wrong route config for route '" . print_r($route, true) . "'"); + throw new HTTPException\InternalServerErrorException("Wrong route config for route '" . print_r($route, true) . "'"); } } @@ -96,7 +97,7 @@ class Router } elseif ($this->isRoute($config)) { $routeCollector->addRoute($config[1], $route, $config[0]); }else { - throw new InternalServerErrorException("Wrong route config for route '" . print_r($route, true) . "'"); + throw new HTTPException\InternalServerErrorException("Wrong route config for route '" . print_r($route, true) . "'"); } } }); @@ -155,7 +156,11 @@ class Router * * @param string $cmd The path component of the request URL without the query string * - * @return string|null A Friendica\BaseModule-extending class name if a route rule matched + * @return string A Friendica\BaseModule-extending class name if a route rule matched + * + * @throws HTTPException\InternalServerErrorException + * @throws HTTPException\MethodNotAllowedException If a rule matched but the method didn't + * @throws HTTPException\NotFoundException If no rule matched */ public function getModuleClass($cmd) { @@ -171,6 +176,10 @@ class Router $routeInfo = $dispatcher->dispatch($this->httpMethod, $cmd); if ($routeInfo[0] === Dispatcher::FOUND) { $moduleClass = $routeInfo[1]; + } elseif ($routeInfo[0] === Dispatcher::METHOD_NOT_ALLOWED) { + throw new HTTPException\MethodNotAllowedException(L10n::t('Method not allowed for this module. Allowed method(s): %s', implode(', ', $routeInfo[1]))); + } else { + throw new HTTPException\NotFoundException(L10n::t('Page not found.')); } return $moduleClass; diff --git a/src/Module/HTTPException/MethodNotAllowed.php b/src/Module/HTTPException/MethodNotAllowed.php new file mode 100644 index 000000000..8d2d280a5 --- /dev/null +++ b/src/Module/HTTPException/MethodNotAllowed.php @@ -0,0 +1,15 @@ +determineModule(new App\Arguments(), []); + $moduleNew = $module->determineModule(new App\Arguments()); $this->assertNotSame($moduleNew, $module); } diff --git a/tests/src/App/RouterTest.php b/tests/src/App/RouterTest.php index 2ed8574c4..2fcc02ff5 100644 --- a/tests/src/App/RouterTest.php +++ b/tests/src/App/RouterTest.php @@ -4,13 +4,15 @@ namespace Friendica\Test\src\App; use Friendica\App\Router; use Friendica\Module; +use Friendica\Network\HTTPException\MethodNotAllowedException; +use Friendica\Network\HTTPException\NotFoundException; use PHPUnit\Framework\TestCase; class RouterTest extends TestCase { public function testGetModuleClass() { - $router = new Router(['GET']); + $router = new Router(['REQUEST_METHOD' => 'GET']); $routeCollector = $router->getRouteCollector(); $routeCollector->addRoute(['GET'], '/', 'IndexModuleClassName'); @@ -22,23 +24,70 @@ class RouterTest extends TestCase $routeCollector->addRoute(['POST', 'PUT', 'PATCH', 'DELETE', 'HEAD'], '/unsupported', 'UnsupportedMethodModuleClassName'); $this->assertEquals('IndexModuleClassName', $router->getModuleClass('/')); - $this->assertEquals('TestModuleClassName', $router->getModuleClass('/test')); - $this->assertNull($router->getModuleClass('/tes')); - $this->assertEquals('TestSubModuleClassName', $router->getModuleClass('/test/sub')); - $this->assertEquals('OptionalModuleClassName', $router->getModuleClass('/optional')); $this->assertEquals('OptionalModuleClassName', $router->getModuleClass('/optional/option')); - $this->assertNull($router->getModuleClass('/optional/opt')); - $this->assertEquals('VariableModuleClassName', $router->getModuleClass('/variable/123abc')); - $this->assertNull($router->getModuleClass('/variable')); - $this->assertEquals('OptionalVariableModuleClassName', $router->getModuleClass('/optionalvariable')); $this->assertEquals('OptionalVariableModuleClassName', $router->getModuleClass('/optionalvariable/123abc')); + } - $this->assertNull($router->getModuleClass('/unsupported')); + public function testGetModuleClassNotFound() + { + $this->expectException(NotFoundException::class); + + $router = new Router(['REQUEST_METHOD' => 'GET']); + + $router->getModuleClass('/unsupported'); + } + + public function testGetModuleClassNotFoundTypo() + { + $this->expectException(NotFoundException::class); + + $router = new Router(['REQUEST_METHOD' => 'GET']); + + $routeCollector = $router->getRouteCollector(); + $routeCollector->addRoute(['GET'], '/test', 'TestModuleClassName'); + + $router->getModuleClass('/tes'); + } + + public function testGetModuleClassNotFoundOptional() + { + $this->expectException(NotFoundException::class); + + $router = new Router(['REQUEST_METHOD' => 'GET']); + + $routeCollector = $router->getRouteCollector(); + $routeCollector->addRoute(['GET'], '/optional[/option]', 'OptionalModuleClassName'); + + $router->getModuleClass('/optional/opt'); + } + + public function testGetModuleClassNotFoundVariable() + { + $this->expectException(NotFoundException::class); + + $router = new Router(['REQUEST_METHOD' => 'GET']); + + $routeCollector = $router->getRouteCollector(); + $routeCollector->addRoute(['GET'], '/variable/{var}', 'VariableModuleClassName'); + + $router->getModuleClass('/variable'); + } + + public function testGetModuleClassMethodNotAllowed() + { + $this->expectException(MethodNotAllowedException::class); + + $router = new Router(['REQUEST_METHOD' => 'POST']); + + $routeCollector = $router->getRouteCollector(); + $routeCollector->addRoute(['GET'], '/test', 'TestModuleClassName'); + + $router->getModuleClass('/test'); } public function dataRoutes() From 02f02d44dc46fc4a0813833ca3fa9e5ebc724d09 Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Fri, 11 Oct 2019 12:37:24 -0400 Subject: [PATCH 2/4] Move mod/manage to src/Module/Delegation - Move templates/manage to templates/delegation - Update navigation links - Update CSS classes --- doc/Addons.md | 2 +- doc/de/Addons.md | 2 +- mod/manage.php | 137 ---------------------- src/Content/Nav.php | 6 +- src/Module/Delegation.php | 136 +++++++++++++++++++++ static/routes.config.php | 1 + view/templates/delegation.tpl | 37 ++++++ view/templates/manage.tpl | 33 ------ view/templates/nav.tpl | 2 +- view/theme/duepuntozero/style.css | 6 +- view/theme/duepuntozero/templates/nav.tpl | 2 +- view/theme/frio/css/style.css | 4 +- view/theme/frio/templates/nav.tpl | 10 +- view/theme/quattro/dark/style.css | 2 +- view/theme/quattro/green/style.css | 2 +- view/theme/quattro/lilac/style.css | 2 +- view/theme/quattro/quattro.less | 2 +- view/theme/quattro/templates/nav.tpl | 2 +- view/theme/smoothly/style.css | 2 +- view/theme/smoothly/templates/nav.tpl | 2 +- view/theme/vier/plus.css | 2 +- view/theme/vier/plusminus.css | 2 +- view/theme/vier/style.css | 6 +- view/theme/vier/templates/nav.tpl | 2 +- view/theme/vier/theme.php | 2 +- 25 files changed, 204 insertions(+), 202 deletions(-) delete mode 100644 mod/manage.php create mode 100644 src/Module/Delegation.php create mode 100644 view/templates/delegation.tpl delete mode 100644 view/templates/manage.tpl diff --git a/doc/Addons.md b/doc/Addons.md index 47d16085a..0382cee49 100644 --- a/doc/Addons.md +++ b/doc/Addons.md @@ -533,7 +533,7 @@ Here is a complete list of all hook callbacks with file locations (as of 24-Sep- Hook::callAll("parse_link", $arr); -### mod/manage.php +### src/Module/Delegation.php Hook::callAll('home_init', $ret); diff --git a/doc/de/Addons.md b/doc/de/Addons.md index 35ce0e28b..3cbbb4b0b 100644 --- a/doc/de/Addons.md +++ b/doc/de/Addons.md @@ -256,7 +256,7 @@ Eine komplette Liste aller Hook-Callbacks mit den zugehörigen Dateien (am 01-Ap Hook::callAll("parse_link", $arr); -### mod/manage.php +### src/Module/Delegation.php Hook::callAll('home_init', $ret); diff --git a/mod/manage.php b/mod/manage.php deleted file mode 100644 index a1ca87e96..000000000 --- a/mod/manage.php +++ /dev/null @@ -1,137 +0,0 @@ -user; - - if(!empty($_SESSION['submanage'])) { - $user = DBA::selectFirst('user', [], ['uid' => $_SESSION['submanage']]); - if (DBA::isResult($user)) { - $uid = intval($user['uid']); - $orig_record = $user; - } - } - - $identity = (!empty($_POST['identity']) ? intval($_POST['identity']) : 0); - if (!$identity) { - return; - } - - $limited_id = 0; - $original_id = $uid; - - $manage = DBA::select('manage', ['mid'], ['uid' => $uid]); - while ($m = DBA::fetch($manage)) { - if ($identity == $m['mid']) { - $limited_id = $m['mid']; - break; - } - } - DBA::close($manage); - - if ($limited_id) { - $user = DBA::selectFirst('user', [], ['uid' => $limited_id]); - } else { - // Check if the target user is one of our children - $user = DBA::selectFirst('user', [], ['uid' => $identity, 'parent-uid' => $orig_record['uid']]); - - // Check if the target user is one of our siblings - if (!DBA::isResult($user) && ($orig_record['parent-uid'] != 0)) { - $user = DBA::selectFirst('user', [], ['uid' => $identity, 'parent-uid' => $orig_record['parent-uid']]); - } - - // Check if it's our parent - if (!DBA::isResult($user) && ($orig_record['parent-uid'] != 0) && ($orig_record['parent-uid'] == $identity)) { - $user = DBA::selectFirst('user', [], ['uid' => $identity]); - } - - // Finally check if it's out own user - if (!DBA::isResult($user) && ($orig_record['uid'] != 0) && ($orig_record['uid'] == $identity)) { - $user = DBA::selectFirst('user', [], ['uid' => $identity]); - } - - } - - if (!DBA::isResult($user)) { - return; - } - - Session::clear(); - - Session::setAuthenticatedForUser($a, $user, true, true); - - if ($limited_id) { - $_SESSION['submanage'] = $original_id; - } - - $ret = []; - Hook::callAll('home_init', $ret); - - $a->internalRedirect('profile/' . $a->user['nickname']); - // NOTREACHED -} - -function manage_content(App $a) { - - if (!local_user()) { - notice(L10n::t('Permission denied.') . EOL); - return; - } - - if (!empty($_GET['identity'])) { - $_POST['identity'] = $_GET['identity']; - manage_post($a); - return; - } - - $identities = $a->identities; - - //getting additinal information for each identity - foreach ($identities as $key => $id) { - $thumb = DBA::selectFirst('contact', ['thumb'], ['uid' => $id['uid'] , 'self' => true]); - if (!DBA::isResult($thumb)) { - continue; - } - - $identities[$key]['thumb'] = $thumb['thumb']; - - $identities[$key]['selected'] = ($id['nickname'] === $a->user['nickname']); - - $condition = ["`uid` = ? AND `msg` != '' AND NOT (`type` IN (?, ?)) AND NOT `seen`", $id['uid'], NOTIFY_INTRO, NOTIFY_MAIL]; - $params = ['distinct' => true, 'expression' => 'parent']; - $notifications = DBA::count('notify', $condition, $params); - - $params = ['distinct' => true, 'expression' => 'convid']; - $notifications += DBA::count('mail', ['uid' => $id['uid'], 'seen' => false], $params); - - $notifications += DBA::count('intro', ['blocked' => false, 'ignore' => false, 'uid' => $id['uid']]); - - $identities[$key]['notifications'] = $notifications; - } - - $o = Renderer::replaceMacros(Renderer::getMarkupTemplate('manage.tpl'), [ - '$title' => L10n::t('Manage Identities and/or Pages'), - '$desc' => L10n::t('Toggle between different identities or community/group pages which share your account details or which you have been granted "manage" permissions'), - '$choose' => L10n::t('Select an identity to manage: '), - '$identities' => $identities, - '$submit' => L10n::t('Submit'), - ]); - - return $o; - -} diff --git a/src/Content/Nav.php b/src/Content/Nav.php index e81214cee..ff1680ab3 100644 --- a/src/Content/Nav.php +++ b/src/Content/Nav.php @@ -29,7 +29,7 @@ class Nav 'directory' => null, 'settings' => null, 'contacts' => null, - 'manage' => null, + 'delegation'=> null, 'events' => null, 'register' => null ]; @@ -257,11 +257,9 @@ class Nav $nav['messages']['new'] = ['message/new', L10n::t('New Message'), '', L10n::t('New Message')]; if (is_array($a->identities) && count($a->identities) > 1) { - $nav['manage'] = ['manage', L10n::t('Manage'), '', L10n::t('Manage other pages')]; + $nav['delegation'] = ['delegation', L10n::t('Delegation'), '', L10n::t('Manage other pages')]; } - $nav['delegations'] = ['settings/delegation', L10n::t('Delegations'), '', L10n::t('Delegate Page Management')]; - $nav['settings'] = ['settings', L10n::t('Settings'), '', L10n::t('Account settings')]; if (Feature::isEnabled(local_user(), 'multi_profiles')) { diff --git a/src/Module/Delegation.php b/src/Module/Delegation.php new file mode 100644 index 000000000..77baefeaa --- /dev/null +++ b/src/Module/Delegation.php @@ -0,0 +1,136 @@ +user; + + if (Session::get('submanage')) { + $user = User::getById(Session::get('submanage')); + if (DBA::isResult($user)) { + $uid = intval($user['uid']); + $orig_record = $user; + } + } + + $identity = intval($_POST['identity'] ?? 0); + if (!$identity) { + return; + } + + $limited_id = 0; + $original_id = $uid; + + $manages = DBA::selectToArray('manage', ['mid'], ['uid' => $uid]); + foreach ($manages as $manage) { + if ($identity == $manage['mid']) { + $limited_id = $manage['mid']; + break; + } + } + + if ($limited_id) { + $user = User::getById($limited_id); + } else { + // Check if the target user is one of our children + $user = DBA::selectFirst('user', [], ['uid' => $identity, 'parent-uid' => $orig_record['uid']]); + + // Check if the target user is one of our siblings + if (!DBA::isResult($user) && ($orig_record['parent-uid'] != 0)) { + $user = DBA::selectFirst('user', [], ['uid' => $identity, 'parent-uid' => $orig_record['parent-uid']]); + } + + // Check if it's our parent or our own user + if (!DBA::isResult($user) + && ( + $orig_record['parent-uid'] != 0 && $orig_record['parent-uid'] == $identity + || + $orig_record['uid'] != 0 && $orig_record['uid'] == $identity + ) + ) { + $user = User::getById($identity); + } + } + + if (!DBA::isResult($user)) { + return; + } + + Session::clear(); + + Session::setAuthenticatedForUser(self::getApp(), $user, true, true); + + if ($limited_id) { + Session::set('submanage', $original_id); + } + + $ret = []; + Hook::callAll('home_init', $ret); + + self::getApp()->internalRedirect('profile/' . self::getApp()->user['nickname']); + // NOTREACHED + } + + public static function content() + { + if (!local_user()) { + throw new ForbiddenException(L10n::t('Permission denied.')); + } + + $identities = self::getApp()->identities; + + //getting additinal information for each identity + foreach ($identities as $key => $identity) { + $thumb = Contact::selectFirst(['thumb'], ['uid' => $identity['uid'], 'self' => true]); + if (!DBA::isResult($thumb)) { + continue; + } + + $identities[$key]['thumb'] = $thumb['thumb']; + + $identities[$key]['selected'] = ($identity['nickname'] === self::getApp()->user['nickname']); + + $condition = ["`uid` = ? AND `msg` != '' AND NOT (`type` IN (?, ?)) AND NOT `seen`", $identity['uid'], NOTIFY_INTRO, NOTIFY_MAIL]; + $params = ['distinct' => true, 'expression' => 'parent']; + $notifications = DBA::count('notify', $condition, $params); + + $params = ['distinct' => true, 'expression' => 'convid']; + $notifications += DBA::count('mail', ['uid' => $identity['uid'], 'seen' => false], $params); + + $notifications += DBA::count('intro', ['blocked' => false, 'ignore' => false, 'uid' => $identity['uid']]); + + $identities[$key]['notifications'] = $notifications; + } + + $o = Renderer::replaceMacros(Renderer::getMarkupTemplate('delegation.tpl'), [ + '$title' => L10n::t('Manage Identities and/or Pages'), + '$desc' => L10n::t('Toggle between different identities or community/group pages which share your account details or which you have been granted "manage" permissions'), + '$choose' => L10n::t('Select an identity to manage: '), + '$identities' => $identities, + '$submit' => L10n::t('Submit'), + ]); + + return $o; + } +} diff --git a/static/routes.config.php b/static/routes.config.php index 841fd68f9..ef65c4685 100644 --- a/static/routes.config.php +++ b/static/routes.config.php @@ -92,6 +92,7 @@ return [ '/ignored' => [Module\Contact::class, [R::GET]], ], '/credits' => [Module\Credits::class, [R::GET]], + '/delegation'=> [Module\Delegation::class, [R::GET, R::POST]], '/dirfind' => [Module\Search\Directory::class, [R::GET]], '/directory' => [Module\Directory::class, [R::GET]], diff --git a/view/templates/delegation.tpl b/view/templates/delegation.tpl new file mode 100644 index 000000000..0e8e406d0 --- /dev/null +++ b/view/templates/delegation.tpl @@ -0,0 +1,37 @@ + +

{{$title}}

+
{{$desc nofilter}}
+
{{$choose}}
+ + diff --git a/view/templates/manage.tpl b/view/templates/manage.tpl deleted file mode 100644 index d5ea0dc05..000000000 --- a/view/templates/manage.tpl +++ /dev/null @@ -1,33 +0,0 @@ - -

{{$title}}

-
{{$desc nofilter}}
-
{{$choose}}
- - diff --git a/view/templates/nav.tpl b/view/templates/nav.tpl index 17a60113c..b9c2cf1f1 100644 --- a/view/templates/nav.tpl +++ b/view/templates/nav.tpl @@ -44,7 +44,7 @@ - {{if $nav.manage}}{{$nav.manage.1}}{{/if}} + {{if $nav.delegation}}{{$nav.delegation.1}}{{/if}} {{if $nav.notifications}} diff --git a/view/theme/duepuntozero/style.css b/view/theme/duepuntozero/style.css index 412899fc7..9bad9d348 100644 --- a/view/theme/duepuntozero/style.css +++ b/view/theme/duepuntozero/style.css @@ -2724,12 +2724,12 @@ aside input[type='text'] { margin: 10px; } -#identity-manage-desc { +#identity-delegation-desc { margin-top:15px; margin-bottom: 15px; } -#identity-manage-choose { +#identity-delegation-choose { margin-bottom: 15px; } @@ -3382,7 +3382,7 @@ div.jGrowl div.info { } /* notifications popup menu */ -.manage-notify { +.delegation-notify { font-size: 10px; padding: 1px 3px; top: 0px; diff --git a/view/theme/duepuntozero/templates/nav.tpl b/view/theme/duepuntozero/templates/nav.tpl index aac7aaeb2..3a0db1264 100644 --- a/view/theme/duepuntozero/templates/nav.tpl +++ b/view/theme/duepuntozero/templates/nav.tpl @@ -62,7 +62,7 @@ {{if $nav.contacts}}{{$nav.contacts.1}}{{/if}} - {{if $nav.manage}}{{$nav.manage.1}}{{/if}} + {{if $nav.delegation}}{{$nav.delegation.1}}{{/if}} diff --git a/view/theme/frio/css/style.css b/view/theme/frio/css/style.css index 2cfc63d36..1d47d862b 100644 --- a/view/theme/frio/css/style.css +++ b/view/theme/frio/css/style.css @@ -2339,7 +2339,7 @@ ul.dropdown-menu li:hover { .generic-page-wrapper, .profile_photo-content-wrapper, .videos-content-wrapper, .suggest-content-wrapper, .common-content-wrapper, .help-content-wrapper, .allfriends-content-wrapper, .match-content-wrapper, .dirfind-content-wrapper, -.manage-content-wrapper, .notes-content-wrapper, +.delegation-content-wrapper, .notes-content-wrapper, .message-content-wrapper, .apps-content-wrapper, #adminpage, .delegate-content-wrapper, .uexport-content-wrapper, .dfrn_request-content-wrapper, @@ -3574,7 +3574,7 @@ section .profile-match-wrapper { right: 10px; } - .generic-page-wrapper, .profile_photo-content-wrapper, .videos-content-wrapper, .suggest-content-wrapper, .common-content-wrapper, .help-content-wrapper, .allfriends-content-wrapper, .match-content-wrapper, .dirfind-content-wrapper, .directory-content-wrapper, .manage-content-wrapper, .notes-content-wrapper, .message-content-wrapper, .apps-content-wrapper, #adminpage, .delegate-content-wrapper, .uexport-content-wrapper, .dfrn_request-content-wrapper, .friendica-content-wrapper, .credits-content-wrapper, .nogroup-content-wrapper, .profperm-content-wrapper, .invite-content-wrapper, .tos-content-wrapper, .fsuggest-content-wrapper { + .generic-page-wrapper, .profile_photo-content-wrapper, .videos-content-wrapper, .suggest-content-wrapper, .common-content-wrapper, .help-content-wrapper, .allfriends-content-wrapper, .match-content-wrapper, .dirfind-content-wrapper, .directory-content-wrapper, .delegation-content-wrapper, .notes-content-wrapper, .message-content-wrapper, .apps-content-wrapper, #adminpage, .delegate-content-wrapper, .uexport-content-wrapper, .dfrn_request-content-wrapper, .friendica-content-wrapper, .credits-content-wrapper, .nogroup-content-wrapper, .profperm-content-wrapper, .invite-content-wrapper, .tos-content-wrapper, .fsuggest-content-wrapper { border-radius: 0; padding: 10px; } diff --git a/view/theme/frio/templates/nav.tpl b/view/theme/frio/templates/nav.tpl index 4698fb657..7df6dd04f 100644 --- a/view/theme/frio/templates/nav.tpl +++ b/view/theme/frio/templates/nav.tpl @@ -149,13 +149,13 @@ {{if $nav.contacts}}
  • {{$nav.contacts.1}}
  • {{/if}} - {{if $nav.manage}} -
  • {{$nav.manage.1}}
  • + {{if $nav.delegation}} +
  • {{$nav.delegation.1}}
  • {{/if}}
  • {{$nav.directory.1}}
  • {{if $nav.apps}} -
  • {{$nav.apps.1}} +
  • {{$nav.apps.1}}
  • {{/if}} {{if $nav.help}} @@ -207,8 +207,8 @@ {{if $nav.messages}} {{/if}} - {{if $nav.manage}} - + {{if $nav.delegation}} + {{/if}} {{if $nav.settings}} diff --git a/view/theme/quattro/dark/style.css b/view/theme/quattro/dark/style.css index bfb078e56..6b4d2b880 100644 --- a/view/theme/quattro/dark/style.css +++ b/view/theme/quattro/dark/style.css @@ -2136,7 +2136,7 @@ ul.tabs li .active { .identity-match-photo { position: relative; } -.identity-match-photo .manage-notify { +.identity-match-photo .delegation-notify { background-color: #19AEFF; border-radius: 5px; font-size: 10px; diff --git a/view/theme/quattro/green/style.css b/view/theme/quattro/green/style.css index 1dce844ac..326a2fbfd 100644 --- a/view/theme/quattro/green/style.css +++ b/view/theme/quattro/green/style.css @@ -2136,7 +2136,7 @@ ul.tabs li .active { .identity-match-photo { position: relative; } -.identity-match-photo .manage-notify { +.identity-match-photo .delegation-notify { background-color: #19AEFF; border-radius: 5px; font-size: 10px; diff --git a/view/theme/quattro/lilac/style.css b/view/theme/quattro/lilac/style.css index 870fe6ce2..064b60ba6 100644 --- a/view/theme/quattro/lilac/style.css +++ b/view/theme/quattro/lilac/style.css @@ -2136,7 +2136,7 @@ ul.tabs li .active { .identity-match-photo { position: relative; } -.identity-match-photo .manage-notify { +.identity-match-photo .delegation-notify { background-color: #19AEFF; border-radius: 5px; font-size: 10px; diff --git a/view/theme/quattro/quattro.less b/view/theme/quattro/quattro.less index 415eda83c..0c1c21a7b 100644 --- a/view/theme/quattro/quattro.less +++ b/view/theme/quattro/quattro.less @@ -1419,7 +1419,7 @@ ul.tabs { /* manage page */ .identity-match-photo { position: relative; - .manage-notify { + .delegation-notify { background-color: #19AEFF; border-radius: 5px; font-size: 10px; diff --git a/view/theme/quattro/templates/nav.tpl b/view/theme/quattro/templates/nav.tpl index cb5412c16..c42e570f5 100644 --- a/view/theme/quattro/templates/nav.tpl +++ b/view/theme/quattro/templates/nav.tpl @@ -71,7 +71,7 @@