dynamic branding options (#1205)
This commit is contained in:
@@ -26,9 +26,6 @@ trait StringAccessibleConfigTrait
|
|||||||
*/
|
*/
|
||||||
protected $initialized = false;
|
protected $initialized = false;
|
||||||
|
|
||||||
/**
|
|
||||||
* @param array $settings
|
|
||||||
*/
|
|
||||||
public function __construct(ConfigLoaderInterface $repository, array $settings)
|
public function __construct(ConfigLoaderInterface $repository, array $settings)
|
||||||
{
|
{
|
||||||
$this->repository = $repository;
|
$this->repository = $repository;
|
||||||
@@ -120,4 +117,45 @@ trait StringAccessibleConfigTrait
|
|||||||
|
|
||||||
return $config[$search];
|
return $config[$search];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function offsetExists($offset)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$this->find($offset);
|
||||||
|
} catch (\Exception $ex) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function offsetGet($offset)
|
||||||
|
{
|
||||||
|
return $this->find($offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param mixed $offset
|
||||||
|
* @param mixed $value
|
||||||
|
* @throws \BadMethodCallException
|
||||||
|
*/
|
||||||
|
public function offsetSet($offset, $value)
|
||||||
|
{
|
||||||
|
throw new \BadMethodCallException('SystemBundleConfiguration does not support offsetSet()');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param mixed $offset
|
||||||
|
* @throws \BadMethodCallException
|
||||||
|
*/
|
||||||
|
public function offsetUnset($offset)
|
||||||
|
{
|
||||||
|
throw new \BadMethodCallException('SystemBundleConfiguration does not support offsetUnset()');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
namespace App\Configuration;
|
namespace App\Configuration;
|
||||||
|
|
||||||
class ThemeConfiguration implements SystemBundleConfiguration
|
class ThemeConfiguration implements SystemBundleConfiguration, \ArrayAccess
|
||||||
{
|
{
|
||||||
use StringAccessibleConfigTrait;
|
use StringAccessibleConfigTrait;
|
||||||
|
|
||||||
|
|||||||
@@ -312,6 +312,30 @@ class SystemConfigurationController extends AbstractController
|
|||||||
->setType(TextType::class)
|
->setType(TextType::class)
|
||||||
->setConstraints([new DateTime(['format' => 'H:i']), new NotNull()]),
|
->setConstraints([new DateTime(['format' => 'H:i']), new NotNull()]),
|
||||||
]),
|
]),
|
||||||
|
(new SystemConfigurationModel())
|
||||||
|
->setSection(SystemConfigurationModel::SECTION_BRANDING)
|
||||||
|
->setConfiguration([
|
||||||
|
(new Configuration())
|
||||||
|
->setName('theme.branding.logo')
|
||||||
|
->setTranslationDomain('system-configuration')
|
||||||
|
->setRequired(false)
|
||||||
|
->setType(TextType::class),
|
||||||
|
(new Configuration())
|
||||||
|
->setName('theme.branding.company')
|
||||||
|
->setTranslationDomain('system-configuration')
|
||||||
|
->setRequired(false)
|
||||||
|
->setType(TextType::class),
|
||||||
|
(new Configuration())
|
||||||
|
->setName('theme.branding.mini')
|
||||||
|
->setTranslationDomain('system-configuration')
|
||||||
|
->setRequired(false)
|
||||||
|
->setType(TextType::class),
|
||||||
|
(new Configuration())
|
||||||
|
->setName('theme.branding.title')
|
||||||
|
->setTranslationDomain('system-configuration')
|
||||||
|
->setRequired(false)
|
||||||
|
->setType(TextType::class),
|
||||||
|
]),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
namespace App\DependencyInjection\Compiler;
|
namespace App\DependencyInjection\Compiler;
|
||||||
|
|
||||||
|
use App\Configuration\ThemeConfiguration;
|
||||||
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
|
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
|
||||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||||
|
|
||||||
@@ -24,8 +25,8 @@ class TwigContextCompilerPass implements CompilerPassInterface
|
|||||||
public function process(ContainerBuilder $container)
|
public function process(ContainerBuilder $container)
|
||||||
{
|
{
|
||||||
$twig = $container->getDefinition('twig');
|
$twig = $container->getDefinition('twig');
|
||||||
$theme = $container->getParameter('kimai.theme');
|
|
||||||
|
|
||||||
|
$theme = $container->getDefinition(ThemeConfiguration::class);
|
||||||
$twig->addMethodCall('addGlobal', ['kimai_context', $theme]);
|
$twig->addMethodCall('addGlobal', ['kimai_context', $theme]);
|
||||||
|
|
||||||
if ($container->hasDefinition('twig.loader.native_filesystem')) {
|
if ($container->hasDefinition('twig.loader.native_filesystem')) {
|
||||||
|
|||||||
@@ -33,6 +33,10 @@ final class Configuration
|
|||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
private $type;
|
private $type;
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
private $options = [];
|
||||||
/**
|
/**
|
||||||
* @var bool
|
* @var bool
|
||||||
*/
|
*/
|
||||||
@@ -155,4 +159,16 @@ final class Configuration
|
|||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getOptions(): array
|
||||||
|
{
|
||||||
|
return $this->options;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setOptions(array $options): Configuration
|
||||||
|
{
|
||||||
|
$this->options = $options;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ class SystemConfiguration
|
|||||||
public const SECTION_FORM_USER = 'form_user';
|
public const SECTION_FORM_USER = 'form_user';
|
||||||
public const SECTION_THEME = 'theme';
|
public const SECTION_THEME = 'theme';
|
||||||
public const SECTION_CALENDAR = 'calendar';
|
public const SECTION_CALENDAR = 'calendar';
|
||||||
|
public const SECTION_BRANDING = 'branding';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var string
|
* @var string
|
||||||
|
|||||||
@@ -54,13 +54,15 @@ class SystemConfigurationType extends AbstractType
|
|||||||
$type = HiddenType::class;
|
$type = HiddenType::class;
|
||||||
}
|
}
|
||||||
|
|
||||||
$event->getForm()->add('value', $type, [
|
$options = [
|
||||||
'label' => 'label.' . ($preference->getLabel() ?? $preference->getName()),
|
'label' => 'label.' . ($preference->getLabel() ?? $preference->getName()),
|
||||||
'constraints' => $preference->getConstraints(),
|
'constraints' => $preference->getConstraints(),
|
||||||
'required' => $required,
|
'required' => $required,
|
||||||
'disabled' => !$preference->isEnabled(),
|
'disabled' => !$preference->isEnabled(),
|
||||||
'translation_domain' => $preference->getTranslationDomain(),
|
'translation_domain' => $preference->getTranslationDomain(),
|
||||||
]);
|
];
|
||||||
|
|
||||||
|
$event->getForm()->add('value', $type, array_merge($options, $preference->getOptions()));
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
$builder->add('name', HiddenType::class);
|
$builder->add('name', HiddenType::class);
|
||||||
|
|||||||
@@ -47,6 +47,11 @@ class ConfigurationRepository extends EntityRepository implements ConfigLoaderIn
|
|||||||
$entity = $this->findOneBy(['name' => $configuration->getName()]);
|
$entity = $this->findOneBy(['name' => $configuration->getName()]);
|
||||||
$value = $configuration->getValue();
|
$value = $configuration->getValue();
|
||||||
|
|
||||||
|
if (null === $value && null !== $entity) {
|
||||||
|
$em->remove($entity);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (null === $entity) {
|
if (null === $entity) {
|
||||||
$entity = new Configuration();
|
$entity = new Configuration();
|
||||||
$entity->setName($configuration->getName());
|
$entity->setName($configuration->getName());
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ class SystemConfigurationControllerTest extends ControllerBaseTest
|
|||||||
['form[name=system_configuration_form_form_user]', $this->createUrl('/admin/system-config/update/form_user')],
|
['form[name=system_configuration_form_form_user]', $this->createUrl('/admin/system-config/update/form_user')],
|
||||||
['form[name=system_configuration_form_theme]', $this->createUrl('/admin/system-config/update/theme')],
|
['form[name=system_configuration_form_theme]', $this->createUrl('/admin/system-config/update/theme')],
|
||||||
['form[name=system_configuration_form_calendar]', $this->createUrl('/admin/system-config/update/calendar')],
|
['form[name=system_configuration_form_calendar]', $this->createUrl('/admin/system-config/update/calendar')],
|
||||||
|
['form[name=system_configuration_form_branding]', $this->createUrl('/admin/system-config/update/branding')],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -98,6 +98,26 @@
|
|||||||
<source>label.calendar.visibleHours.end</source>
|
<source>label.calendar.visibleHours.end</source>
|
||||||
<target>Ende des sichtbaren Zeitbereichs</target>
|
<target>Ende des sichtbaren Zeitbereichs</target>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
|
<trans-unit id="branding">
|
||||||
|
<source>branding</source>
|
||||||
|
<target>Markendarstellung</target>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="label.theme.branding.logo">
|
||||||
|
<source>label.theme.branding.logo</source>
|
||||||
|
<target>Logo (Bild URL, ersetzt das Unternehmen im Anmeldebildschirm)</target>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="label.theme.branding.company">
|
||||||
|
<source>label.theme.branding.company</source>
|
||||||
|
<target>Unternehmen</target>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="label.theme.branding.mini">
|
||||||
|
<source>label.theme.branding.mini</source>
|
||||||
|
<target>Mini Logo (zugeklappte Seitenleiste)</target>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="label.theme.branding.title">
|
||||||
|
<source>label.theme.branding.title</source>
|
||||||
|
<target>Browser Titel</target>
|
||||||
|
</trans-unit>
|
||||||
</body>
|
</body>
|
||||||
</file>
|
</file>
|
||||||
</xliff>
|
</xliff>
|
||||||
|
|||||||
@@ -98,6 +98,26 @@
|
|||||||
<source>label.calendar.visibleHours.end</source>
|
<source>label.calendar.visibleHours.end</source>
|
||||||
<target>End of visible time range</target>
|
<target>End of visible time range</target>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
|
<trans-unit id="branding">
|
||||||
|
<source>branding</source>
|
||||||
|
<target>Branding</target>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="label.theme.branding.logo">
|
||||||
|
<source>label.theme.branding.logo</source>
|
||||||
|
<target>Logo (Image URL, replaces the company in login screen)</target>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="label.theme.branding.company">
|
||||||
|
<source>label.theme.branding.company</source>
|
||||||
|
<target>Company</target>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="label.theme.branding.mini">
|
||||||
|
<source>label.theme.branding.mini</source>
|
||||||
|
<target>Mini Logo (collapsed sidebar)</target>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="label.theme.branding.title">
|
||||||
|
<source>label.theme.branding.title</source>
|
||||||
|
<target>Browser Title</target>
|
||||||
|
</trans-unit>
|
||||||
</body>
|
</body>
|
||||||
</file>
|
</file>
|
||||||
</xliff>
|
</xliff>
|
||||||
|
|||||||
Reference in New Issue
Block a user