Merge pull request #7727 from MrPetovan/task/4090-move-manage-to-src

Move mod/manage to src/Module/Delegation
This commit is contained in:
Philipp 2019-10-13 18:20:47 +02:00 committed by GitHub
commit fed486bfc5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
31 changed files with 370 additions and 254 deletions

View File

@ -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);

View File

@ -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);

View File

@ -1,137 +0,0 @@
<?php
/**
* @file mod/manage.php
*/
use Friendica\App;
use Friendica\Core\Hook;
use Friendica\Core\L10n;
use Friendica\Core\Renderer;
use Friendica\Core\Session;
use Friendica\Database\DBA;
function manage_post(App $a) {
if (!local_user()) {
return;
}
$uid = local_user();
$orig_record = $a->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;
}

View File

@ -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);
}

View File

@ -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;

View File

@ -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')) {

136
src/Module/Delegation.php Normal file
View File

@ -0,0 +1,136 @@
<?php
namespace Friendica\Module;
use Friendica\BaseModule;
use Friendica\Core\Hook;
use Friendica\Core\L10n;
use Friendica\Core\Renderer;
use Friendica\Core\Session;
use Friendica\Database\DBA;
use Friendica\Model\Contact;
use Friendica\Model\User;
use Friendica\Network\HTTPException\ForbiddenException;
/**
* Switches current user between delegates/parent user
*/
class Delegation extends BaseModule
{
public static function post()
{
if (!local_user()) {
return;
}
$uid = local_user();
$orig_record = self::getApp()->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;
}
}

View File

@ -0,0 +1,15 @@
<?php
namespace Friendica\Module\HTTPException;
use Friendica\BaseModule;
use Friendica\Core\L10n;
use Friendica\Network\HTTPException;
class MethodNotAllowed extends BaseModule
{
public static function content()
{
throw new HTTPException\MethodNotAllowedException(L10n::t('Method Not Allowed.'));
}
}

View File

@ -1,6 +1,6 @@
<?php
namespace Friendica\Module;
namespace Friendica\Module\HTTPException;
use Friendica\BaseModule;
use Friendica\Core\L10n;

View File

@ -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]],

View File

@ -5,7 +5,7 @@ namespace Friendica\Test\src\App;
use Friendica\App;
use Friendica\Core\Config\Configuration;
use Friendica\LegacyModule;
use Friendica\Module\PageNotFound;
use Friendica\Module\HTTPException\PageNotFound;
use Friendica\Module\WellKnown\HostMeta;
use Friendica\Test\DatabaseTest;
@ -166,7 +166,7 @@ class ModuleTest extends DatabaseTest
{
$module = new App\Module();
$moduleNew = $module->determineModule(new App\Arguments(), []);
$moduleNew = $module->determineModule(new App\Arguments());
$this->assertNotSame($moduleNew, $module);
}

View File

@ -4,41 +4,127 @@ 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' => Router::GET]);
$routeCollector = $router->getRouteCollector();
$routeCollector->addRoute(['GET'], '/', 'IndexModuleClassName');
$routeCollector->addRoute(['GET'], '/test', 'TestModuleClassName');
$routeCollector->addRoute(['GET'], '/test/sub', 'TestSubModuleClassName');
$routeCollector->addRoute(['GET'], '/optional[/option]', 'OptionalModuleClassName');
$routeCollector->addRoute(['GET'], '/variable/{var}', 'VariableModuleClassName');
$routeCollector->addRoute(['GET'], '/optionalvariable[/{option}]', 'OptionalVariableModuleClassName');
$routeCollector->addRoute(['POST', 'PUT', 'PATCH', 'DELETE', 'HEAD'], '/unsupported', 'UnsupportedMethodModuleClassName');
$routeCollector->addRoute([Router::GET], '/', 'IndexModuleClassName');
$routeCollector->addRoute([Router::GET], '/test', 'TestModuleClassName');
$routeCollector->addRoute([Router::GET, Router::POST], '/testgetpost', 'TestGetPostModuleClassName');
$routeCollector->addRoute([Router::GET], '/test/sub', 'TestSubModuleClassName');
$routeCollector->addRoute([Router::GET], '/optional[/option]', 'OptionalModuleClassName');
$routeCollector->addRoute([Router::GET], '/variable/{var}', 'VariableModuleClassName');
$routeCollector->addRoute([Router::GET], '/optionalvariable[/{option}]', 'OptionalVariableModuleClassName');
$this->assertEquals('IndexModuleClassName', $router->getModuleClass('/'));
$this->assertEquals('TestModuleClassName', $router->getModuleClass('/test'));
$this->assertNull($router->getModuleClass('/tes'));
$this->assertEquals('TestGetPostModuleClassName', $router->getModuleClass('/testgetpost'));
$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 testPostModuleClass()
{
$router = new Router(['REQUEST_METHOD' => Router::POST]);
$routeCollector = $router->getRouteCollector();
$routeCollector->addRoute([Router::POST], '/', 'IndexModuleClassName');
$routeCollector->addRoute([Router::POST], '/test', 'TestModuleClassName');
$routeCollector->addRoute([Router::GET, Router::POST], '/testgetpost', 'TestGetPostModuleClassName');
$routeCollector->addRoute([Router::POST], '/test/sub', 'TestSubModuleClassName');
$routeCollector->addRoute([Router::POST], '/optional[/option]', 'OptionalModuleClassName');
$routeCollector->addRoute([Router::POST], '/variable/{var}', 'VariableModuleClassName');
$routeCollector->addRoute([Router::POST], '/optionalvariable[/{option}]', 'OptionalVariableModuleClassName');
$this->assertEquals('IndexModuleClassName', $router->getModuleClass('/'));
$this->assertEquals('TestModuleClassName', $router->getModuleClass('/test'));
$this->assertEquals('TestGetPostModuleClassName', $router->getModuleClass('/testgetpost'));
$this->assertEquals('TestSubModuleClassName', $router->getModuleClass('/test/sub'));
$this->assertEquals('OptionalModuleClassName', $router->getModuleClass('/optional'));
$this->assertEquals('OptionalModuleClassName', $router->getModuleClass('/optional/option'));
$this->assertEquals('VariableModuleClassName', $router->getModuleClass('/variable/123abc'));
$this->assertEquals('OptionalVariableModuleClassName', $router->getModuleClass('/optionalvariable'));
$this->assertEquals('OptionalVariableModuleClassName', $router->getModuleClass('/optionalvariable/123abc'));
}
public function testGetModuleClassNotFound()
{
$this->expectException(NotFoundException::class);
$router = new Router(['REQUEST_METHOD' => Router::GET]);
$router->getModuleClass('/unsupported');
}
public function testGetModuleClassNotFoundTypo()
{
$this->expectException(NotFoundException::class);
$router = new Router(['REQUEST_METHOD' => Router::GET]);
$routeCollector = $router->getRouteCollector();
$routeCollector->addRoute([Router::GET], '/test', 'TestModuleClassName');
$router->getModuleClass('/tes');
}
public function testGetModuleClassNotFoundOptional()
{
$this->expectException(NotFoundException::class);
$router = new Router(['REQUEST_METHOD' => Router::GET]);
$routeCollector = $router->getRouteCollector();
$routeCollector->addRoute([Router::GET], '/optional[/option]', 'OptionalModuleClassName');
$router->getModuleClass('/optional/opt');
}
public function testGetModuleClassNotFoundVariable()
{
$this->expectException(NotFoundException::class);
$router = new Router(['REQUEST_METHOD' => Router::GET]);
$routeCollector = $router->getRouteCollector();
$routeCollector->addRoute([Router::GET], '/variable/{var}', 'VariableModuleClassName');
$router->getModuleClass('/variable');
}
public function testGetModuleClassMethodNotAllowed()
{
$this->expectException(MethodNotAllowedException::class);
$router = new Router(['REQUEST_METHOD' => Router::POST]);
$routeCollector = $router->getRouteCollector();
$routeCollector->addRoute([Router::GET], '/test', 'TestModuleClassName');
$router->getModuleClass('/test');
}
public function testPostModuleClassMethodNotAllowed()
{
$this->expectException(MethodNotAllowedException::class);
$router = new Router(['REQUEST_METHOD' => Router::GET]);
$routeCollector = $router->getRouteCollector();
$routeCollector->addRoute([Router::POST], '/test', 'TestModuleClassName');
$router->getModuleClass('/test');
}
public function dataRoutes()
@ -78,7 +164,6 @@ class RouterTest extends TestCase
$this->assertEquals(Module\Home::class, $router->getModuleClass('/'));
$this->assertEquals(Module\Friendica::class, $router->getModuleClass('/group/route'));
$this->assertEquals(Module\Xrd::class, $router->getModuleClass('/group2/group3/route'));
$this->assertNull($router->getModuleClass('/post/it'));
$this->assertEquals(Module\Profile::class, $router->getModuleClass('/double'));
}
@ -92,9 +177,6 @@ class RouterTest extends TestCase
]))->addRoutes($routes);
// Don't find GET
$this->assertNull($router->getModuleClass('/'));
$this->assertNull($router->getModuleClass('/group/route'));
$this->assertNull($router->getModuleClass('/group2/group3/route'));
$this->assertEquals(Module\NodeInfo::class, $router->getModuleClass('/post/it'));
$this->assertEquals(Module\Profile::class, $router->getModuleClass('/double'));
}

View File

@ -0,0 +1,37 @@
<h3>{{$title}}</h3>
<div id="identity-delegation-desc">{{$desc nofilter}}</div>
<div id="identity-delegation-choose">{{$choose}}</div>
<div id="identity-selector-wrapper" role="menu">
<form action="delegation" method="post">
{{foreach $identities as $identity}}
<div class="itentity-match-wrapper {{if $identity.selected}}selected-identity{{/if}}" id="identity-match-{{$identity.uid}}">
<div class="identity-match-photo" id="identity-match-photo-{{$identity.uid}}">
<button type="submit" name="identity" value="{{$identity.uid}}" title="{{$identity.username}}">
<img src="{{$identity.thumb}}" alt="{{$identity.username}}" />
{{if $identity.notifications}}<span class="delegation-notify badge">{{$identity.notifications}}</span>{{/if}}
</button>
</div>
<div class="identity-match-break"></div>
<div class="identity-match-desc">
<div class="identity-match-name" id="identity-match-name-{{$identity.uid}}">
{{if $identity.selected}}
{{$identity.username}}
{{else}}
<button type="submit" name="identity" class="btn-link" value="{{$identity.uid}}">{{$identity.username}}</button>
{{/if}}
</div>
<div class="identity-match-details" id="identity-match-nick-{{$identity.uid}}">({{$identity.nickname}})</div>
</div>
<div class="identity-match-end"></div>
</div>
{{/foreach}}
<div class="identity-match-break"></div>
</form>
</div>

View File

@ -1,33 +0,0 @@
<h3>{{$title}}</h3>
<div id="identity-manage-desc">{{$desc nofilter}}</div>
<div id="identity-manage-choose">{{$choose}}</div>
<div id="identity-selector-wrapper" role="menu">
<form action="manage" method="post" >
{{foreach $identities as $id}}
<div class="itentity-match-wrapper {{if $id.selected}}selected-identity{{/if}}" id="identity-match-{{$id.uid}}">
<div class="identity-match-photo" id="identity-match-photo-{{$id.uid}}">
<button name="identity" value="{{$id.uid}}" onclick="this.form.submit();" title="{{$id.username}}">
<img src="{{$id.thumb}}" alt="{{$id.username}}" />
{{if $id.notifications}}<span class="manage-notify badge">{{$id.notifications}}</span>{{/if}}
</button>
</div>
<div class="identity-match-break"></div>
<div class="identity-match-desc">
<div class="identity-match-name" id="identity-match-name-{{$id.uid}}">
{{if $id.selected}}{{$id.username}}{{else}}<a role="menuitem" href="manage?identity={{$id.uid}}">{{$id.username}}</a>{{/if}}
</div>
<div class="identity-match-details" id="identity-match-nick-{{$id.uid}}">({{$id.nickname}})</div>
</div>
<div class="identity-match-end"></div>
</div>
{{/foreach}}
<div class="identity-match-break"></div>
</form>
</div>

View File

@ -44,7 +44,7 @@
{{if $nav.manage}}<a id="nav-manage-link" class="nav-commlink {{$nav.manage.2}} {{$sel.manage}}" href="{{$nav.manage.0}}" title="{{$nav.manage.3}}">{{$nav.manage.1}}</a>{{/if}}
{{if $nav.delegation}}<a id="nav-delegation-link" class="nav-commlink {{$nav.delegation.2}} {{$sel.delegation}}" href="{{$nav.delegation.0}}" title="{{$nav.delegation.3}}">{{$nav.delegation.1}}</a>{{/if}}
{{if $nav.notifications}}

View File

@ -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;

View File

@ -62,7 +62,7 @@
{{if $nav.contacts}}<a id="nav-contacts-link" class="nav-link {{$nav.contacts.2}}" href="{{$nav.contacts.0}}" title="{{$nav.contacts.3}}" >{{$nav.contacts.1}}</a>{{/if}}
{{if $nav.manage}}<a id="nav-manage-link" class="nav-link {{$nav.manage.2}} {{$sel.manage}}" href="{{$nav.manage.0}}" title="{{$nav.manage.3}}">{{$nav.manage.1}}</a>{{/if}}
{{if $nav.delegation}}<a id="nav-delegation-link" class="nav-link {{$nav.delegation.2}} {{$sel.delegation}}" href="{{$nav.delegation.0}}" title="{{$nav.delegation.3}}">{{$nav.delegation.1}}</a>{{/if}}
</span>
<span id="nav-end"></span>
<span id="banner">{{$banner nofilter}}</span>

View File

@ -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;
}

View File

@ -149,13 +149,13 @@
{{if $nav.contacts}}
<li role="presentation"><a role="menuitem" id="nav-menu-contacts-link" class="nav-link {{$nav.contacts.2}}" href="{{$nav.contacts.0}}" title="{{$nav.contacts.3}}"><i class="fa fa-users fa-fw" aria-hidden="true"></i> {{$nav.contacts.1}}</a><span id="intro-update-li" class="nav-intro-badge badge nav-notify"></span></li>
{{/if}}
{{if $nav.manage}}
<li role="presentation"><a role="menuitem" id="nav-manage-link" class="nav-commlink {{$nav.manage.2}} {{$sel.manage}}" href="{{$nav.manage.0}}" title="{{$nav.manage.3}}"><i class="fa fa-flag fa-fw" aria-hidden="true"></i> {{$nav.manage.1}}</a></li>
{{if $nav.delegation}}
<li role="presentation"><a role="menuitem" id="nav-delegation-link" class="nav-commlink {{$nav.delegation.2}} {{$sel.delegation}}" href="{{$nav.delegation.0}}" title="{{$nav.delegation.3}}"><i class="fa fa-flag fa-fw" aria-hidden="true"></i> {{$nav.delegation.1}}</a></li>
{{/if}}
<li role="presentation"><a role="menuitem" id="nav-directory-link" class="nav-link {{$nav.directory.2}}" href="{{$nav.directory.0}}" title="{{$nav.directory.3}}"><i class="fa fa-sitemap fa-fw" aria-hidden="true"></i>{{$nav.directory.1}}</a></li>
<li role="presentation" class="divider"></li>
{{if $nav.apps}}
<li role="presentation"><a role="menuitem" id="nav-apps-link" class="nav-link {{$nav.apps.2}} {{$sel.manage}}" href="{{$nav.apps.0}}" title="{{$nav.apps.3}}" ><i class="fa fa-puzzle-piece fa-fw" aria-hidden="true"></i> {{$nav.apps.1}}</a>
<li role="presentation"><a role="menuitem" id="nav-apps-link" class="nav-link {{$nav.apps.2}}" href="{{$nav.apps.0}}" title="{{$nav.apps.3}}" ><i class="fa fa-puzzle-piece fa-fw" aria-hidden="true"></i> {{$nav.apps.1}}</a>
<li role="presentation" class="divider"></li>
{{/if}}
{{if $nav.help}}
@ -207,8 +207,8 @@
{{if $nav.messages}}
<li role="presentation" class="list-group-item"><a role="menuitem" class="nav-link {{$nav.messages.2}} {{$sel.messages}}" href="{{$nav.messages.0}}" title="{{$nav.messages.3}}" ><i class="fa fa-envelope fa-fw" aria-hidden="true"></i> {{$nav.messages.1}}</a></li>
{{/if}}
{{if $nav.manage}}
<li role="presentation" class="list-group-item"><a role="menuitem" class="nav-commlink {{$nav.manage.2}} {{$sel.manage}}" href="{{$nav.manage.0}}" title="{{$nav.manage.3}}"><i class="fa fa-flag fa-fw" aria-hidden="true"></i> {{$nav.manage.1}}</a></li>
{{if $nav.delegation}}
<li role="presentation" class="list-group-item"><a role="menuitem" class="nav-commlink {{$nav.delegation.2}} {{$sel.delegation}}" href="{{$nav.delegation.0}}" title="{{$nav.delegation.3}}"><i class="fa fa-flag fa-fw" aria-hidden="true"></i> {{$nav.delegation.1}}</a></li>
{{/if}}
{{if $nav.settings}}
<li role="presentation" class="list-group-item"><a role="menuitem" class="nav-link {{$nav.settings.2}}" href="{{$nav.settings.0}}" title="{{$nav.settings.3}}"><i class="fa fa-cog fa-fw" aria-hidden="true"></i> {{$nav.settings.1}}</a></li>

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -71,7 +71,7 @@
<li id="nav-site-linkmenu" class="nav-menu-icon"><a href="#" rel="#nav-site-menu"><span class="icon s22 gear">Site</span></a>
<ul id="nav-site-menu" class="menu-popup">
{{if $nav.manage}}<li><a class="{{$nav.manage.2}}" href="{{$nav.manage.0}}" title="{{$nav.manage.3}}">{{$nav.manage.1}}</a></li>{{/if}}
{{if $nav.delegation}}<li><a class="{{$nav.delegation.2}}" href="{{$nav.delegation.0}}" title="{{$nav.delegation.3}}">{{$nav.delegation.1}}</a></li>{{/if}}
{{if $nav.settings}}<li><a class="{{$nav.settings.2}}" href="{{$nav.settings.0}}" title="{{$nav.settings.3}}">{{$nav.settings.1}}</a></li>{{/if}}
{{if $nav.admin}}<li><a accesskey="a" class="{{$nav.admin.2}}" href="{{$nav.admin.0}}" title="{{$nav.admin.3}}" >{{$nav.admin.1}}</a></li>{{/if}}

View File

@ -4287,7 +4287,7 @@ a.active {
}
/* notifications popup menu */
.manage-notify {
.delegation-notify {
font-size: 10px;
padding: 1px 3px;
top: 0px;

View File

@ -45,7 +45,7 @@
{{if $nav.profiles}}<li><a id="nav-profiles-link" class="nav-commlink nav-sep {{$nav.profiles.2}}" href="{{$nav.profiles.0}}">{{$nav.profiles.1}}</a></li>{{/if}}
{{if $nav.settings}}<li><a id="nav-settings-link" class="nav-commlink {{$nav.settings.2}}" href="{{$nav.settings.0}}">{{$nav.settings.1}}</a></li>{{/if}}
{{if $nav.manage}}<li><a id="nav-manage-link" class="nav-commlink {{$nav.manage.2}}" href="{{$nav.manage.0}}">{{$nav.manage.1}}</a></li>{{/if}}
{{if $nav.delegation}}<li><a id="nav-delegation-link" class="nav-commlink {{$nav.delegation.2}}" href="{{$nav.delegation.0}}">{{$nav.delegation.1}}</a></li>{{/if}}
{{if $nav.admin}}<li><a id="nav-admin-link" class="nav-commlink {{$nav.admin.2}}" href="{{$nav.admin.0}}">{{$nav.admin.1}}</a></li>{{/if}}

View File

@ -17,7 +17,7 @@ nav a:hover,
color: #000;
}
.manage-notify {
.delegation-notify {
background-color: #CB4437;
border-radius: 10px;
font: bold 11px/16px Arial;

View File

@ -54,7 +54,7 @@ nav a:hover,
color: #000;
}
.manage-notify {
.delegation-notify {
background-color: #CB4437;
border-radius: 10px;
font: bold 11px/16px Arial;

View File

@ -725,7 +725,7 @@ nav .nav-menu:hover {
text-decoration: none;
}
.manage-notify {
.delegation-notify {
background-color: #F80;
-moz-border-radius: 5px 5px 5px 5px;
-webkit-border-radius: 5px 5px 5px 5px;
@ -2923,12 +2923,12 @@ a.mail-list-link {
margin: 0px;
}
#identity-manage-desc {
#identity-delegation-desc {
margin-top:15px;
margin-bottom: 15px;
}
#identity-manage-choose {
#identity-delegation-choose {
margin-bottom: 15px;
}

View File

@ -84,7 +84,7 @@
{{if $nav.introductions}}<li role="menuitem"><a class="{{$nav.introductions.2}}" href="{{$nav.introductions.0}}" title="{{$nav.introductions.3}}" >{{$nav.introductions.1}}</a><span id="intro-update-li" class="nav-notify"></span></li>{{/if}}
{{if $nav.contacts}}<li role="menuitem"><a class="{{$nav.contacts.2}}" href="{{$nav.contacts.0}}" title="{{$nav.contacts.3}}" >{{$nav.contacts.1}}</a></li>{{/if}}
{{if $nav.messages}}<li role="menuitem"><a class="{{$nav.messages.2}}" href="{{$nav.messages.0}}" title="{{$nav.messages.3}}" >{{$nav.messages.1}} <span id="mail-update-li" class="nav-notify"></span></a></li>{{/if}}
{{if $nav.manage}}<li role="menuitem"><a class="{{$nav.manage.2}}" href="{{$nav.manage.0}}" title="{{$nav.manage.3}}">{{$nav.manage.1}}</a></li>{{/if}}
{{if $nav.delegation}}<li role="menuitem"><a class="{{$nav.delegation.2}}" href="{{$nav.delegation.0}}" title="{{$nav.delegation.3}}">{{$nav.delegation.1}}</a></li>{{/if}}
{{if $nav.usermenu.1}}<li role="menuitem"><a class="{{$nav.usermenu.1.2}}" href="{{$nav.usermenu.1.0}}" title="{{$nav.usermenu.1.3}}">{{$nav.usermenu.1.1}}</a></li>{{/if}}
{{if $nav.settings}}<li role="menuitem"><a class="{{$nav.settings.2}}" href="{{$nav.settings.0}}" title="{{$nav.settings.3}}">{{$nav.settings.1}}</a></li>{{/if}}
{{if $nav.admin}}

View File

@ -104,7 +104,7 @@ EOT;
// Hide the left menu bar
/// @TODO maybe move this static array out where it should belong?
if (empty($a->page['aside']) && in_array($a->argv[0], ["community", "events", "help", "manage", "notifications",
if (empty($a->page['aside']) && in_array($a->argv[0], ["community", "events", "help", "delegation", "notifications",
"probe", "webfinger", "login", "invite", "credits"])) {
$a->page['htmlhead'] .= "<link rel='stylesheet' href='view/theme/vier/hide.css' />";
}