allow to disable user preferences by permission (#895)
This commit is contained in:
@@ -22,4 +22,14 @@ class ThemeConfiguration implements SystemBundleConfiguration
|
||||
{
|
||||
return (string) $this->find('select_type');
|
||||
}
|
||||
|
||||
public function getTitle(): ?string
|
||||
{
|
||||
$title = $this->find('branding.title');
|
||||
if (null === $title) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (string) $title;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -335,6 +335,9 @@ class Configuration implements ConfigurationInterface
|
||||
->scalarNode('company')
|
||||
->defaultNull()
|
||||
->end()
|
||||
->scalarNode('title')
|
||||
->defaultNull()
|
||||
->end()
|
||||
->end()
|
||||
->end()
|
||||
->end()
|
||||
|
||||
@@ -64,12 +64,13 @@ class ThemeOptionsSubscriber implements EventSubscriberInterface
|
||||
/** @var User $user */
|
||||
$user = $this->storage->getToken()->getUser();
|
||||
|
||||
$skin = '';
|
||||
foreach ($user->getPreferences() as $ref) {
|
||||
$name = $ref->getName();
|
||||
switch ($name) {
|
||||
case UserPreference::SKIN:
|
||||
$skin = 'skin-' . $ref->getValue();
|
||||
if (!empty($ref->getValue())) {
|
||||
$this->helper->setOption('skin', 'skin-' . $ref->getValue());
|
||||
}
|
||||
break;
|
||||
|
||||
case 'theme.collapsed_sidebar':
|
||||
@@ -77,12 +78,6 @@ class ThemeOptionsSubscriber implements EventSubscriberInterface
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($skin)) {
|
||||
$skin = 'skin-green';
|
||||
}
|
||||
|
||||
$this->helper->setOption('skin', $skin);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -97,7 +97,6 @@ class UserPreferenceSubscriber implements EventSubscriberInterface
|
||||
|
||||
(new UserPreference())
|
||||
->setName(UserPreference::SKIN)
|
||||
->setValue('green')
|
||||
->setType(SkinType::class),
|
||||
|
||||
(new UserPreference())
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
namespace App\Twig;
|
||||
|
||||
use App\Configuration\ThemeConfiguration;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
use Twig\Extension\AbstractExtension;
|
||||
use Twig\TwigFunction;
|
||||
@@ -19,13 +20,18 @@ class TitleExtension extends AbstractExtension
|
||||
* @var TranslatorInterface
|
||||
*/
|
||||
protected $translator;
|
||||
/**
|
||||
* @var ThemeConfiguration
|
||||
*/
|
||||
protected $configuration;
|
||||
|
||||
/**
|
||||
* @param TranslatorInterface $translator
|
||||
*/
|
||||
public function __construct(TranslatorInterface $translator)
|
||||
public function __construct(TranslatorInterface $translator, ThemeConfiguration $configuration)
|
||||
{
|
||||
$this->translator = $translator;
|
||||
$this->configuration = $configuration;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -38,13 +44,10 @@ class TitleExtension extends AbstractExtension
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param null|string $prefix
|
||||
* @param string $delimiter
|
||||
* @return string
|
||||
*/
|
||||
public function generateTitle(?string $prefix = null, string $delimiter = ' – ')
|
||||
public function generateTitle(?string $prefix = null, string $delimiter = ' – '): string
|
||||
{
|
||||
return ($prefix ?? '') . 'Kimai' . $delimiter . $this->translator->trans('time_tracking', [], 'messages');
|
||||
$title = $this->configuration->getTitle() ?? 'Kimai';
|
||||
|
||||
return ($prefix ?? '') . ($title) . $delimiter . $this->translator->trans('time_tracking', [], 'messages');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,13 +83,13 @@ class UserVoter extends AbstractVoter
|
||||
// used in templates and ProfileController
|
||||
case self::VIEW:
|
||||
case self::EDIT:
|
||||
case self::PREFERENCES:
|
||||
// always allow the user to edit these own settings
|
||||
if ($subject->getId() === $user->getId()) {
|
||||
return true;
|
||||
}
|
||||
// no break on purpose
|
||||
|
||||
case self::PREFERENCES:
|
||||
case self::PASSWORD:
|
||||
case self::API_TOKEN:
|
||||
case self::ROLES:
|
||||
|
||||
@@ -121,6 +121,7 @@
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
{% if app.user is not null %}
|
||||
{% if is_granted('view', app.user) %}
|
||||
<li>
|
||||
<a href="{{ path('user_profile', {'username' : app.user.username}) }}">
|
||||
<h4 class="control-sidebar-subheading">
|
||||
@@ -129,6 +130,8 @@
|
||||
</h4>
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if is_granted('edit', app.user) %}
|
||||
<li>
|
||||
<a href="{{ path('user_profile_edit', {'username' : app.user.username}) }}">
|
||||
<h4 class="control-sidebar-subheading">
|
||||
@@ -137,6 +140,8 @@
|
||||
</h4>
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if is_granted('preferences', app.user) %}
|
||||
<li>
|
||||
<a href="{{ path('user_profile_preferences', {'username' : app.user.username}) }}">
|
||||
<h4 class="control-sidebar-subheading">
|
||||
@@ -145,6 +150,7 @@
|
||||
</h4>
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
<li>
|
||||
<a href="{{ path('fos_user_security_logout') }}">
|
||||
<h4 class="control-sidebar-subheading">
|
||||
|
||||
@@ -340,7 +340,7 @@ class ProfileControllerTest extends ControllerBaseTest
|
||||
$user = $this->getUserByName($em, $username);
|
||||
|
||||
$this->assertEquals($hourlyRateOriginal, $user->getPreferenceValue(UserPreference::HOURLY_RATE));
|
||||
$this->assertEquals('green', $user->getPreferenceValue(UserPreference::SKIN));
|
||||
$this->assertNull($user->getPreferenceValue(UserPreference::SKIN));
|
||||
$this->assertEquals(false, $user->getPreferenceValue('theme.collapsed_sidebar'));
|
||||
$this->assertEquals('month', $user->getPreferenceValue('calendar.initial_view'));
|
||||
|
||||
|
||||
@@ -107,6 +107,7 @@ class AppExtensionTest extends TestCase
|
||||
'logo' => null,
|
||||
'mini' => null,
|
||||
'company' => null,
|
||||
'title' => null,
|
||||
],
|
||||
],
|
||||
'kimai.theme.select_type' => null,
|
||||
|
||||
@@ -9,6 +9,9 @@
|
||||
|
||||
namespace App\Tests\Twig;
|
||||
|
||||
use App\Configuration\ThemeConfiguration;
|
||||
use App\Entity\Configuration;
|
||||
use App\Tests\Configuration\TestConfigLoader;
|
||||
use App\Twig\TitleExtension;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
@@ -19,12 +22,20 @@ use Twig\TwigFunction;
|
||||
*/
|
||||
class TitleExtensionTest extends TestCase
|
||||
{
|
||||
protected function getSut(): TitleExtension
|
||||
protected function getSut(string $title = null): TitleExtension
|
||||
{
|
||||
$translator = $this->getMockBuilder(TranslatorInterface::class)->getMock();
|
||||
$translator->method('trans')->willReturn('foo');
|
||||
|
||||
return new TitleExtension($translator);
|
||||
$configs = [
|
||||
(new Configuration())->setName('theme.branding.title')->setValue($title)
|
||||
];
|
||||
|
||||
$loader = new TestConfigLoader($configs);
|
||||
|
||||
$configuration = new ThemeConfiguration($loader, ['branding' => ['title' => null]]);
|
||||
|
||||
return new TitleExtension($translator, $configuration);
|
||||
}
|
||||
|
||||
public function testGetFunctions()
|
||||
@@ -49,4 +60,13 @@ class TitleExtensionTest extends TestCase
|
||||
$this->assertEquals('<b>Kimai</b> ... foo', $sut->generateTitle('<b>', '</b> ... '));
|
||||
$this->assertEquals('Kimai | foo', $sut->generateTitle(null, ' | '));
|
||||
}
|
||||
|
||||
public function testGetBrandedTitle()
|
||||
{
|
||||
$sut = $this->getSut('MyCompany');
|
||||
$this->assertEquals('MyCompany – foo', $sut->generateTitle());
|
||||
$this->assertEquals('sdfsdf | MyCompany – foo', $sut->generateTitle('sdfsdf | '));
|
||||
$this->assertEquals('<b>MyCompany</b> ... foo', $sut->generateTitle('<b>', '</b> ... '));
|
||||
$this->assertEquals('MyCompany | foo', $sut->generateTitle(null, ' | '));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user