summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--apps/files/appinfo/app.php14
-rw-r--r--apps/files/appinfo/info.xml7
-rw-r--r--apps/files/img/app.svg6
-rw-r--r--lib/private/NavigationManager.php107
-rw-r--r--lib/private/Server.php8
-rw-r--r--tests/lib/NavigationManagerTest.php66
6 files changed, 188 insertions, 20 deletions
diff --git a/apps/files/appinfo/app.php b/apps/files/appinfo/app.php
index a194bb5e795..63acda3a706 100644
--- a/apps/files/appinfo/app.php
+++ b/apps/files/appinfo/app.php
@@ -26,20 +26,10 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
+// required for translation purpose
+// t('Files')
$l = \OC::$server->getL10N('files');
-\OC::$server->getNavigationManager()->add(function () {
- $urlGenerator = \OC::$server->getURLGenerator();
- $l = \OC::$server->getL10N('files');
- return [
- 'id' => 'files_index',
- 'order' => 0,
- 'href' => $urlGenerator->linkToRoute('files.view.index'),
- 'icon' => $urlGenerator->imagePath('core', 'places/files.svg'),
- 'name' => $l->t('Files'),
- ];
-});
-
\OC::$server->getSearch()->registerProvider('OC\Search\Provider\File', array('apps' => array('files')));
$templateManager = \OC_Helper::getFileTemplateManager();
diff --git a/apps/files/appinfo/info.xml b/apps/files/appinfo/info.xml
index a25c043f332..2bb4d98c158 100644
--- a/apps/files/appinfo/info.xml
+++ b/apps/files/appinfo/info.xml
@@ -53,4 +53,11 @@
<command>OCA\Files\Command\DeleteOrphanedFiles</command>
<command>OCA\Files\Command\TransferOwnership</command>
</commands>
+
+ <navigation>
+ <name>Files</name>
+ <route>files.view.index</route>
+ <order>0</order>
+ </navigation>
+
</info>
diff --git a/apps/files/img/app.svg b/apps/files/img/app.svg
new file mode 100644
index 00000000000..130f59eab23
--- /dev/null
+++ b/apps/files/img/app.svg
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg xmlns="http://www.w3.org/2000/svg" height="32" width="32" version="1.1" viewBox="0 0 32 32">
+ <g fill-rule="evenodd" transform="matrix(1.7333 0 0 1.7333 -344.09 -1727.8)" fill="#fff">
+ <path d="m200.2 999.72c-0.28913 0-0.53125 0.2421-0.53125 0.5312v12.784c0 0.2985 0.23264 0.5312 0.53125 0.5312h15.091c0.2986 0 0.53124-0.2327 0.53124-0.5312l0.0004-10.474c0-0.2889-0.24211-0.5338-0.53124-0.5338l-7.5457 0.0005-2.3076-2.3078z" fill-rule="evenodd" fill="#fff"/>
+ </g>
+</svg>
diff --git a/lib/private/NavigationManager.php b/lib/private/NavigationManager.php
index 3e9ddfc6466..f7bc02943a3 100644
--- a/lib/private/NavigationManager.php
+++ b/lib/private/NavigationManager.php
@@ -1,6 +1,6 @@
<?php
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @copyright Copyright (c) 2016, ownCloud GmbH
*
* @author Bart Visscher <bartv@thisnet.nl>
* @author Joas Schilling <coding@schilljs.com>
@@ -26,13 +26,46 @@
namespace OC;
+use OC\App\AppManager;
+use OCP\App\IAppManager;
+use OCP\IGroupManager;
+use OCP\INavigationManager;
+use OCP\IURLGenerator;
+use OCP\IUserSession;
+use OCP\L10N\IFactory;
+
/**
* Manages the ownCloud navigation
*/
-class NavigationManager implements \OCP\INavigationManager {
- protected $entries = array();
- protected $closureEntries = array();
+
+class NavigationManager implements INavigationManager {
+ protected $entries = [];
+ protected $closureEntries = [];
protected $activeEntry;
+ /** @var bool */
+ protected $init = false;
+ /** @var IAppManager|AppManager */
+ protected $appManager;
+ /** @var IURLGenerator */
+ private $urlGenerator;
+ /** @var IFactory */
+ private $l10nFac;
+ /** @var IUserSession */
+ private $userSession;
+ /** @var IGroupManager */
+ private $groupManager;
+
+ public function __construct(IAppManager $appManager = null,
+ IURLGenerator $urlGenerator = null,
+ IFactory $l10nFac = null,
+ IUserSession $userSession = null,
+ IGroupManager$groupManager = null) {
+ $this->appManager = $appManager;
+ $this->urlGenerator = $urlGenerator;
+ $this->l10nFac = $l10nFac;
+ $this->userSession = $userSession;
+ $this->groupManager = $groupManager;
+ }
/**
* Creates a new navigation entry
@@ -60,6 +93,7 @@ class NavigationManager implements \OCP\INavigationManager {
* @return array an array of the added entries
*/
public function getAll() {
+ $this->init();
foreach ($this->closureEntries as $c) {
$this->add($c());
}
@@ -71,8 +105,9 @@ class NavigationManager implements \OCP\INavigationManager {
* removes all the entries
*/
public function clear() {
- $this->entries = array();
- $this->closureEntries = array();
+ $this->entries = [];
+ $this->closureEntries = [];
+ $this->init = false;
}
/**
@@ -93,4 +128,64 @@ class NavigationManager implements \OCP\INavigationManager {
public function getActiveEntry() {
return $this->activeEntry;
}
+
+ private function init() {
+ if ($this->init) {
+ return;
+ }
+ $this->init = true;
+ if (is_null($this->appManager)) {
+ return;
+ }
+ foreach ($this->appManager->getInstalledApps() as $app) {
+ // load plugins and collections from info.xml
+ $info = $this->appManager->getAppInfo($app);
+ if (!isset($info['navigation'])) {
+ continue;
+ }
+ $nav = $info['navigation'];
+ if (!isset($nav['name'])) {
+ continue;
+ }
+ if (!isset($nav['route'])) {
+ continue;
+ }
+ $role = isset($nav['@attributes']['role']) ? $nav['@attributes']['role'] : 'all';
+ if ($role === 'admin' && !$this->isAdmin()) {
+ continue;
+ }
+ $l = $this->l10nFac->get($app);
+ $order = isset($nav['order']) ? $nav['order'] : 100;
+ $route = $this->urlGenerator->linkToRoute($nav['route']);
+ $icon = isset($nav['icon']) ? $nav['icon'] : 'app.svg';
+ foreach ([$icon, "$app.svg"] as $i) {
+ try {
+ $icon = $this->urlGenerator->imagePath($app, $i);
+ break;
+ } catch (\RuntimeException $ex) {
+ // no icon? - ignore it then
+ }
+ }
+ if (is_null($icon)) {
+ $icon = $this->urlGenerator->imagePath('core', 'default-app-icon');
+ }
+
+ $this->add([
+ 'id' => $app,
+ 'order' => $order,
+ 'href' => $route,
+ 'icon' => $icon,
+ 'name' => $l->t($nav['name']),
+ ]);
+ }
+ }
+
+ private function isAdmin() {
+ $user = $this->userSession->getUser();
+ if ($user !== null) {
+ return $this->groupManager->isAdmin($user->getUID());
+ }
+ return false;
+ }
+
}
diff --git a/lib/private/Server.php b/lib/private/Server.php
index a514534049d..bd8818e9460 100644
--- a/lib/private/Server.php
+++ b/lib/private/Server.php
@@ -316,8 +316,12 @@ class Server extends ServerContainer implements IServerContainer {
return new \OC\Authentication\TwoFactorAuth\Manager($c->getAppManager(), $c->getSession(), $c->getConfig(), $c->getActivityManager(), $c->getLogger());
});
- $this->registerService('NavigationManager', function ($c) {
- return new \OC\NavigationManager();
+ $this->registerService('NavigationManager', function (Server $c) {
+ return new \OC\NavigationManager($c->getAppManager(),
+ $c->getURLGenerator(),
+ $c->getL10NFactory(),
+ $c->getUserSession(),
+ $c->getGroupManager());
});
$this->registerService('AllConfig', function (Server $c) {
return new \OC\AllConfig(
diff --git a/tests/lib/NavigationManagerTest.php b/tests/lib/NavigationManagerTest.php
index 96708786e39..64fec802eca 100644
--- a/tests/lib/NavigationManagerTest.php
+++ b/tests/lib/NavigationManagerTest.php
@@ -12,7 +12,15 @@
namespace Test;
+use OC\App\AppManager;
use OC\NavigationManager;
+use OCP\App\IAppManager;
+use OCP\IGroupManager;
+use OCP\IL10N;
+use OCP\IURLGenerator;
+use OCP\IUser;
+use OCP\IUserSession;
+use OCP\L10N\IFactory;
class NavigationManagerTest extends TestCase {
/** @var \OC\NavigationManager */
@@ -157,4 +165,62 @@ class NavigationManagerTest extends TestCase {
$this->assertEmpty($this->navigationManager->getAll(), 'Expected no navigation entry exists after clear()');
$this->assertEquals(0, $testAddClosureNumberOfCalls, 'Expected that the closure is not called by getAll()');
}
+
+ /**
+ * @dataProvider providesNavigationConfig
+ */
+ public function testWithAppManager($expected, $config, $isAdmin = false) {
+
+ $appManager = $this->createMock(AppManager::class);
+ $urlGenerator = $this->createMock(IURLGenerator::class);
+ $l10nFac = $this->createMock(IFactory::class);
+ $userSession = $this->createMock(IUserSession::class);
+ $groupManager = $this->createMock(IGroupManager::class);
+ $l = $this->createMock(IL10N::class);
+ $l->expects($this->any())->method('t')->willReturnCallback(function($text, $parameters = []) {
+ return vsprintf($text, $parameters);
+ });
+
+ $appManager->expects($this->once())->method('getInstalledApps')->willReturn(['test']);
+ $appManager->expects($this->once())->method('getAppInfo')->with('test')->willReturn($config);
+ $l10nFac->expects($this->exactly(count($expected)))->method('get')->with('test')->willReturn($l);
+ $urlGenerator->expects($this->any())->method('imagePath')->willReturnCallback(function($appName, $file) {
+ return "/apps/$appName/img/$file";
+ });
+ $urlGenerator->expects($this->exactly(count($expected)))->method('linkToRoute')->willReturnCallback(function($route) {
+ return "/apps/test/";
+ });
+ $user = $this->createMock(IUser::class);
+ $user->expects($this->any())->method('getUID')->willReturn('user001');
+ $userSession->expects($this->any())->method('getUser')->willReturn($user);
+ $groupManager->expects($this->any())->method('isAdmin')->willReturn($isAdmin);
+
+ $navigationManager = new NavigationManager($appManager, $urlGenerator, $l10nFac, $userSession, $groupManager);
+
+ $entries = $navigationManager->getAll();
+ $this->assertEquals($expected, $entries);
+ }
+
+ public function providesNavigationConfig() {
+ return [
+ 'minimalistic' => [[[
+ 'id' => 'test',
+ 'order' => 100,
+ 'href' => '/apps/test/',
+ 'icon' => '/apps/test/img/app.svg',
+ 'name' => 'Test',
+ 'active' => false
+ ]], ['navigation' => ['route' => 'test.page.index', 'name' => 'Test']]],
+ 'no admin' => [[[
+ 'id' => 'test',
+ 'order' => 100,
+ 'href' => '/apps/test/',
+ 'icon' => '/apps/test/img/app.svg',
+ 'name' => 'Test',
+ 'active' => false
+ ]], ['navigation' => ['@attributes' => ['role' => 'admin'], 'route' => 'test.page.index', 'name' => 'Test']], true],
+ 'no name' => [[], ['navigation' => ['@attributes' => ['role' => 'admin'], 'route' => 'test.page.index']], true],
+ 'admin' => [[], ['navigation' => ['@attributes' => ['role' => 'admin'], 'route' => 'test.page.index', 'name' => 'Test']]]
+ ];
+ }
}