Release 2.20.0 (#4987)
This commit is contained in:
@@ -72,7 +72,7 @@ abstract class AbstractBundleInstallerCommand extends Command
|
||||
*/
|
||||
protected function getInstallerCommandName(): string
|
||||
{
|
||||
return sprintf('kimai:bundle:%s:install', $this->getBundleCommandNamePart());
|
||||
return \sprintf('kimai:bundle:%s:install', $this->getBundleCommandNamePart());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -87,7 +87,7 @@ abstract class AbstractBundleInstallerCommand extends Command
|
||||
|
||||
if ($parts[0] !== 'KimaiPlugin') {
|
||||
throw new LogicException(
|
||||
sprintf('Unsupported namespace given, expected "KimaiPlugin" but received "%s". Please overwrite getBundleName() and return the correct bundle name.', $parts[0])
|
||||
\sprintf('Unsupported namespace given, expected "KimaiPlugin" but received "%s". Please overwrite getBundleName() and return the correct bundle name.', $parts[0])
|
||||
);
|
||||
}
|
||||
|
||||
@@ -114,14 +114,14 @@ abstract class AbstractBundleInstallerCommand extends Command
|
||||
|
||||
$bundleName = $this->getBundleName();
|
||||
$io->title(
|
||||
sprintf('Starting installation of plugin: %s ...', $bundleName)
|
||||
\sprintf('Starting installation of plugin: %s ...', $bundleName)
|
||||
);
|
||||
|
||||
try {
|
||||
$this->importMigrations($io, $output);
|
||||
} catch (\Exception $ex) {
|
||||
$io->error(
|
||||
sprintf('Failed to install database for bundle %s. %s', $bundleName, $ex->getMessage())
|
||||
\sprintf('Failed to install database for bundle %s. %s', $bundleName, $ex->getMessage())
|
||||
);
|
||||
|
||||
return Command::FAILURE;
|
||||
@@ -132,7 +132,7 @@ abstract class AbstractBundleInstallerCommand extends Command
|
||||
$this->installAssets($io, $output);
|
||||
} catch (\Exception $ex) {
|
||||
$io->error(
|
||||
sprintf('Failed to install assets for bundle %s. %s', $bundleName, $ex->getMessage())
|
||||
\sprintf('Failed to install assets for bundle %s. %s', $bundleName, $ex->getMessage())
|
||||
);
|
||||
|
||||
return Command::FAILURE;
|
||||
@@ -142,7 +142,7 @@ abstract class AbstractBundleInstallerCommand extends Command
|
||||
chdir($path);
|
||||
|
||||
$io->success(
|
||||
sprintf('Congratulations! Plugin was successful installed: %s', $bundleName)
|
||||
\sprintf('Congratulations! Plugin was successful installed: %s', $bundleName)
|
||||
);
|
||||
|
||||
return Command::SUCCESS;
|
||||
|
||||
@@ -51,9 +51,9 @@ final class ActivateUserCommand extends Command
|
||||
if (!$user->isEnabled()) {
|
||||
$user->setEnabled(true);
|
||||
$this->userService->saveUser($user);
|
||||
$io->success(sprintf('User "%s" has been activated.', $username));
|
||||
$io->success(\sprintf('User "%s" has been activated.', $username));
|
||||
} else {
|
||||
$io->warning(sprintf('User "%s" is already active.', $username));
|
||||
$io->warning(\sprintf('User "%s" is already active.', $username));
|
||||
}
|
||||
|
||||
return Command::SUCCESS;
|
||||
|
||||
@@ -67,7 +67,7 @@ final class ChangePasswordCommand extends AbstractUserCommand
|
||||
try {
|
||||
$user->setPlainPassword($password);
|
||||
$this->userService->updateUser($user, ['PasswordUpdate']);
|
||||
$io->success(sprintf('Changed password for user "%s".', $username));
|
||||
$io->success(\sprintf('Changed password for user "%s".', $username));
|
||||
} catch (ValidationFailedException $ex) {
|
||||
$this->validationError($ex, $io);
|
||||
|
||||
|
||||
@@ -77,7 +77,7 @@ final class CreateUserCommand extends AbstractUserCommand
|
||||
|
||||
try {
|
||||
$this->userService->saveUser($user);
|
||||
$io->success(sprintf('Success! Created user: %s', $username));
|
||||
$io->success(\sprintf('Success! Created user: %s', $username));
|
||||
} catch (ValidationFailedException $ex) {
|
||||
$this->validationError($ex, $io);
|
||||
|
||||
|
||||
@@ -51,9 +51,9 @@ final class DeactivateUserCommand extends Command
|
||||
if ($user->isEnabled()) {
|
||||
$user->setEnabled(false);
|
||||
$this->userService->saveUser($user);
|
||||
$io->success(sprintf('User "%s" has been deactivated.', $username));
|
||||
$io->success(\sprintf('User "%s" has been deactivated.', $username));
|
||||
} else {
|
||||
$io->warning(sprintf('User "%s" is already deactivated.', $username));
|
||||
$io->warning(\sprintf('User "%s" is already deactivated.', $username));
|
||||
}
|
||||
|
||||
return Command::SUCCESS;
|
||||
|
||||
@@ -40,17 +40,17 @@ final class DemoteUserCommand extends AbstractRoleCommand
|
||||
if ($user->isSuperAdmin()) {
|
||||
$user->setSuperAdmin(false);
|
||||
$userService->saveUser($user);
|
||||
$output->success(sprintf('Super administrator role has been removed from the user "%s".', $username));
|
||||
$output->success(\sprintf('Super administrator role has been removed from the user "%s".', $username));
|
||||
} else {
|
||||
$output->warning(sprintf('User "%s" doesn\'t have the super administrator role.', $username));
|
||||
$output->warning(\sprintf('User "%s" doesn\'t have the super administrator role.', $username));
|
||||
}
|
||||
} else {
|
||||
if ($user->hasRole($role)) {
|
||||
$user->removeRole($role);
|
||||
$userService->saveUser($user);
|
||||
$output->success(sprintf('Role "%s" has been removed from user "%s".', $role, $username));
|
||||
$output->success(\sprintf('Role "%s" has been removed from user "%s".', $role, $username));
|
||||
} else {
|
||||
$output->warning(sprintf('User "%s" didn\'t have "%s" role.', $username, $role));
|
||||
$output->warning(\sprintf('User "%s" didn\'t have "%s" role.', $username, $role));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,13 +35,13 @@ use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
final class ExportCreateCommand extends Command
|
||||
{
|
||||
public function __construct(
|
||||
private ServiceExport $serviceExport,
|
||||
private CustomerRepository $customerRepository,
|
||||
private ProjectRepository $projectRepository,
|
||||
private TeamRepository $teamRepository,
|
||||
private UserRepository $userRepository,
|
||||
private TranslatorInterface $translator,
|
||||
private MailerInterface $mailer
|
||||
private readonly ServiceExport $serviceExport,
|
||||
private readonly CustomerRepository $customerRepository,
|
||||
private readonly ProjectRepository $projectRepository,
|
||||
private readonly TeamRepository $teamRepository,
|
||||
private readonly UserRepository $userRepository,
|
||||
private readonly TranslatorInterface $translator,
|
||||
private readonly MailerInterface $mailer
|
||||
) {
|
||||
parent::__construct();
|
||||
}
|
||||
@@ -197,17 +197,19 @@ final class ExportCreateCommand extends Command
|
||||
$subject = 'Export data available';
|
||||
$body = 'Your exported data is available, please find it attached to this email.';
|
||||
|
||||
/** @var array<string> $emails */
|
||||
$emails = [];
|
||||
/** @var array<string> $tmp */
|
||||
$tmp = $input->getOption('email');
|
||||
if (\count($tmp) > 0) {
|
||||
foreach ($tmp as $email) {
|
||||
$result = filter_var($email, FILTER_VALIDATE_EMAIL);
|
||||
if ($result === false) {
|
||||
$io->error('Invalid "email" given: ' . $email);
|
||||
$io->error('Invalid "email" given');
|
||||
|
||||
return Command::FAILURE;
|
||||
}
|
||||
$emails[] = $email;
|
||||
$emails[] = (string) $email;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -227,7 +229,7 @@ final class ExportCreateCommand extends Command
|
||||
$user = $this->userRepository->loadUserByIdentifier($username);
|
||||
} catch(\Exception) {
|
||||
$io->error(
|
||||
sprintf('The given username "%s" could not be resolved', $username)
|
||||
\sprintf('The given username "%s" could not be resolved', $username)
|
||||
);
|
||||
|
||||
return Command::FAILURE;
|
||||
|
||||
@@ -73,7 +73,7 @@ final class InstallCommand extends Command
|
||||
}
|
||||
|
||||
$io->success(
|
||||
sprintf('Congratulations! Successfully installed %s version %s', Constants::SOFTWARE, Constants::VERSION)
|
||||
\sprintf('Congratulations! Successfully installed %s version %s', Constants::SOFTWARE, Constants::VERSION)
|
||||
);
|
||||
|
||||
return Command::SUCCESS;
|
||||
@@ -118,12 +118,12 @@ final class InstallCommand extends Command
|
||||
{
|
||||
try {
|
||||
if ($this->connection->isConnected()) {
|
||||
$io->note(sprintf('Database is existing and connection could be established'));
|
||||
$io->note(\sprintf('Database is existing and connection could be established'));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!$this->askConfirmation($input, $output, sprintf('Create the database "%s" (yes) or skip (no)?', $this->connection->getDatabase()), true)) {
|
||||
if (!$this->askConfirmation($input, $output, \sprintf('Create the database "%s" (yes) or skip (no)?', $this->connection->getDatabase()), true)) {
|
||||
throw new \Exception('Skipped database creation, aborting installation');
|
||||
}
|
||||
} catch (\Exception $exception) {
|
||||
@@ -152,7 +152,7 @@ final class InstallCommand extends Command
|
||||
{
|
||||
/** @var QuestionHelper $questionHelper */
|
||||
$questionHelper = $this->getHelperSet()->get('question');
|
||||
$text = sprintf('<info>%s (yes/no)</info> [<comment>%s</comment>]:', $question, $default ? 'yes' : 'no');
|
||||
$text = \sprintf('<info>%s (yes/no)</info> [<comment>%s</comment>]:', $question, $default ? 'yes' : 'no');
|
||||
$question = new ConfirmationQuestion(' ' . $text . ' ', $default, '/^y|yes/i');
|
||||
|
||||
return $questionHelper->ask($input, $output, $question);
|
||||
|
||||
@@ -90,7 +90,7 @@ final class InvoiceCreateCommand extends Command
|
||||
$user = $this->userRepository->loadUserByIdentifier($username);
|
||||
} catch (\Exception $exception) {
|
||||
$io->error(
|
||||
sprintf('The given username "%s" could not be resolved', $username)
|
||||
\sprintf('The given username "%s" could not be resolved', $username)
|
||||
);
|
||||
|
||||
return Command::FAILURE;
|
||||
@@ -281,7 +281,7 @@ final class InvoiceCreateCommand extends Command
|
||||
|
||||
$tpl = $this->getTemplateForCustomer($input, $customer);
|
||||
if (null === $tpl) {
|
||||
$io->warning(sprintf('Could not find invoice template for project "%s", skipping!', $project->getName()));
|
||||
$io->warning(\sprintf('Could not find invoice template for project "%s", skipping!', $project->getName()));
|
||||
continue;
|
||||
}
|
||||
$query->setTemplate($tpl);
|
||||
@@ -293,7 +293,7 @@ final class InvoiceCreateCommand extends Command
|
||||
$invoices[] = $this->serviceInvoice->createInvoice($this->serviceInvoice->createModel($query), $this->eventDispatcher);
|
||||
}
|
||||
} catch (\Exception $ex) {
|
||||
$io->error(sprintf('Failed to create invoice for project "%s" with: %s', $project->getName(), $ex->getMessage()));
|
||||
$io->error(\sprintf('Failed to create invoice for project "%s" with: %s', $project->getName(), $ex->getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -352,7 +352,7 @@ final class InvoiceCreateCommand extends Command
|
||||
|
||||
$tpl = $this->getTemplateForCustomer($input, $customer);
|
||||
if (null === $tpl) {
|
||||
$io->warning(sprintf('Could not find invoice template for customer "%s", skipping!', $customer->getName()));
|
||||
$io->warning(\sprintf('Could not find invoice template for customer "%s", skipping!', $customer->getName()));
|
||||
continue;
|
||||
}
|
||||
$query->setTemplate($tpl);
|
||||
@@ -364,7 +364,7 @@ final class InvoiceCreateCommand extends Command
|
||||
$invoices[] = $this->serviceInvoice->createInvoice($this->serviceInvoice->createModel($query), $this->eventDispatcher);
|
||||
}
|
||||
} catch (\Exception $ex) {
|
||||
$io->error(sprintf('Failed to create invoice for customer "%s" with: %s', $customer->getName(), $ex->getMessage()));
|
||||
$io->error(\sprintf('Failed to create invoice for customer "%s" with: %s', $customer->getName(), $ex->getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -391,7 +391,7 @@ final class InvoiceCreateCommand extends Command
|
||||
$columns = ['Filename'];
|
||||
|
||||
$table = new Table($output);
|
||||
$table->setHeaderTitle(sprintf('Created %s invoice(s)', \count($invoices)));
|
||||
$table->setHeaderTitle(\sprintf('Created %s invoice(s)', \count($invoices)));
|
||||
$table->setHeaders($columns);
|
||||
|
||||
foreach ($invoices as $invoiceFile) {
|
||||
@@ -406,14 +406,14 @@ final class InvoiceCreateCommand extends Command
|
||||
$columns = ['ID', 'Customer', 'Total', 'Filename'];
|
||||
|
||||
$table = new Table($output);
|
||||
$table->setHeaderTitle(sprintf('Created %s invoice(s)', \count($invoices)));
|
||||
$table->setHeaderTitle(\sprintf('Created %s invoice(s)', \count($invoices)));
|
||||
$table->setHeaders($columns);
|
||||
|
||||
foreach ($invoices as $invoice) {
|
||||
$file = $this->serviceInvoice->getInvoiceFile($invoice);
|
||||
if (null === $file) {
|
||||
$io->warning(
|
||||
sprintf('Created invoice with ID %s, but file was not found %s', $invoice->getId(), $invoice->getInvoiceFilename())
|
||||
\sprintf('Created invoice with ID %s, but file was not found %s', $invoice->getId(), $invoice->getInvoiceFilename())
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -40,17 +40,17 @@ final class PromoteUserCommand extends AbstractRoleCommand
|
||||
if (!$user->isSuperAdmin()) {
|
||||
$user->setSuperAdmin(true);
|
||||
$userService->saveUser($user);
|
||||
$output->success(sprintf('User "%s" has been promoted as a super administrator.', $username));
|
||||
$output->success(\sprintf('User "%s" has been promoted as a super administrator.', $username));
|
||||
} else {
|
||||
$output->warning(sprintf('User "%s" does already have the super administrator role.', $username));
|
||||
$output->warning(\sprintf('User "%s" does already have the super administrator role.', $username));
|
||||
}
|
||||
} else {
|
||||
if (!$user->hasRole($role)) {
|
||||
$user->addRole($role);
|
||||
$userService->saveUser($user);
|
||||
$output->success(sprintf('Role "%s" has been added to user "%s".', $role, $username));
|
||||
$output->success(\sprintf('Role "%s" has been added to user "%s".', $role, $username));
|
||||
} else {
|
||||
$output->warning(sprintf('User "%s" did already have "%s" role.', $username, $role));
|
||||
$output->warning(\sprintf('User "%s" did already have "%s" role.', $username, $role));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ final class RegenerateLocalesCommand extends Command
|
||||
*/
|
||||
private array $noRegionCode = ['ar', 'id', 'pa', 'sl'];
|
||||
/**
|
||||
* A list of locales that will be activated, not matter if translation files exist for them.
|
||||
* A list of locales that will be activated, no matter if translation files exist for them.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
|
||||
@@ -110,7 +110,7 @@ final class ReloadCommand extends Command
|
||||
}
|
||||
|
||||
$io->success(
|
||||
sprintf('Kimai config was reloaded')
|
||||
\sprintf('Kimai config was reloaded')
|
||||
);
|
||||
|
||||
return Command::SUCCESS;
|
||||
|
||||
@@ -38,7 +38,7 @@ final class TimesheetStopAllCommand extends Command
|
||||
|
||||
if (!$output->isQuiet()) {
|
||||
$io = new SymfonyStyle($input, $output);
|
||||
$io->success(sprintf('Stopped %s timesheet records.', $amount));
|
||||
$io->success(\sprintf('Stopped %s timesheet records.', $amount));
|
||||
}
|
||||
|
||||
return Command::SUCCESS;
|
||||
|
||||
@@ -28,7 +28,11 @@ use Symfony\Component\HttpClient\HttpClient;
|
||||
#[AsCommand(name: 'kimai:translations')]
|
||||
final class TranslationCommand extends Command
|
||||
{
|
||||
public function __construct(private string $projectDirectory, private string $kernelEnvironment, private LocaleService $localeService)
|
||||
public function __construct(
|
||||
private readonly string $projectDirectory,
|
||||
private readonly string $kernelEnvironment,
|
||||
private readonly LocaleService $localeService
|
||||
)
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
@@ -70,6 +74,7 @@ final class TranslationCommand extends Command
|
||||
|
||||
$sources = [];
|
||||
if ($input->getOption('source') !== null) {
|
||||
/** @var string $tmp */
|
||||
$tmp = $input->getOption('source');
|
||||
foreach ($bases as $directory) {
|
||||
$files = glob($directory);
|
||||
@@ -95,6 +100,7 @@ final class TranslationCommand extends Command
|
||||
|
||||
$targets = [];
|
||||
if ($input->getOption('target') !== null) {
|
||||
/** @var string $tmp */
|
||||
$tmp = $input->getOption('target');
|
||||
foreach ($bases as $directory) {
|
||||
$files = glob($directory);
|
||||
@@ -402,7 +408,7 @@ final class TranslationCommand extends Command
|
||||
|
||||
$xmlContent = '';
|
||||
foreach ($translations as $id => $values) {
|
||||
$xmlContent .= sprintf(
|
||||
$xmlContent .= \sprintf(
|
||||
'<trans-unit id="%s" resname="%s"><source>%s</source><target>%s</target></trans-unit>',
|
||||
$id,
|
||||
$values['resname'],
|
||||
@@ -463,7 +469,7 @@ final class TranslationCommand extends Command
|
||||
|
||||
if (!\array_key_exists($key, $translations)) {
|
||||
throw new \Exception(
|
||||
sprintf('Missing english translation for key: %s in file %s', $key, $file)
|
||||
\sprintf('Missing english translation for key: %s in file %s', $key, $file)
|
||||
);
|
||||
}
|
||||
$unit->target[0] = $translations[$key];
|
||||
|
||||
@@ -91,7 +91,7 @@ final class UpdateCommand extends Command
|
||||
if ($cacheResult !== Command::SUCCESS) {
|
||||
$io->warning(
|
||||
[
|
||||
sprintf('Updated %s to version %s but the cache could not be rebuilt.', Constants::SOFTWARE, Constants::VERSION),
|
||||
\sprintf('Updated %s to version %s but the cache could not be rebuilt.', Constants::SOFTWARE, Constants::VERSION),
|
||||
'Please run the cache commands manually:',
|
||||
'bin/console cache:clear --env=' . $environment . PHP_EOL .
|
||||
'bin/console cache:warmup --env=' . $environment
|
||||
@@ -99,7 +99,7 @@ final class UpdateCommand extends Command
|
||||
);
|
||||
} else {
|
||||
$io->success(
|
||||
sprintf('Congratulations! Successfully updated %s to version %s', Constants::SOFTWARE, Constants::VERSION)
|
||||
\sprintf('Congratulations! Successfully updated %s to version %s', Constants::SOFTWARE, Constants::VERSION)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ final class VersionCommand extends Command
|
||||
return Command::SUCCESS;
|
||||
}
|
||||
|
||||
$io->writeln(sprintf('%s <info>%s</info> by Kevin Papst.', Constants::SOFTWARE, Constants::VERSION));
|
||||
$io->writeln(\sprintf('%s <info>%s</info> by Kevin Papst.', Constants::SOFTWARE, Constants::VERSION));
|
||||
|
||||
return Command::SUCCESS;
|
||||
}
|
||||
|
||||
@@ -140,11 +140,11 @@ final class LocaleService
|
||||
private function getConfig(string $key, string $locale): string|bool
|
||||
{
|
||||
if (!isset($this->languageSettings[$locale])) {
|
||||
throw new \InvalidArgumentException(sprintf('Unknown locale given: %s', $locale));
|
||||
throw new \InvalidArgumentException(\sprintf('Unknown locale given: %s', $locale));
|
||||
}
|
||||
|
||||
if (!isset($this->languageSettings[$locale][$key])) {
|
||||
throw new \InvalidArgumentException(sprintf('Unknown setting for locale %s: %s', $locale, $key));
|
||||
throw new \InvalidArgumentException(\sprintf('Unknown setting for locale %s: %s', $locale, $key));
|
||||
}
|
||||
|
||||
return $this->languageSettings[$locale][$key];
|
||||
|
||||
@@ -33,6 +33,6 @@ final class ConsoleApplication extends Application
|
||||
*/
|
||||
public function getLongVersion(): string
|
||||
{
|
||||
return sprintf('%s <info>%s</info> (env: <comment>%s</>, debug: <comment>%s</>)', $this->getName(), $this->getVersion(), $this->getKernel()->getEnvironment(), $this->getKernel()->isDebug() ? 'true' : 'false');
|
||||
return \sprintf('%s <info>%s</info> (env: <comment>%s</>, debug: <comment>%s</>)', $this->getName(), $this->getVersion(), $this->getKernel()->getEnvironment(), $this->getKernel()->isDebug() ? 'true' : 'false');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,11 +17,11 @@ class Constants
|
||||
/**
|
||||
* The current release version
|
||||
*/
|
||||
public const VERSION = '2.19.1';
|
||||
public const VERSION = '2.20.0';
|
||||
/**
|
||||
* The current release: major * 10000 + minor * 100 + patch
|
||||
*/
|
||||
public const VERSION_ID = 21901;
|
||||
public const VERSION_ID = 22000;
|
||||
/**
|
||||
* The software name
|
||||
*/
|
||||
|
||||
@@ -88,7 +88,7 @@ final class BookmarkController extends AbstractController
|
||||
}
|
||||
|
||||
if (\count($enabled) > 50) {
|
||||
throw new RuntimeException(sprintf('Too many columns provided, expected maximum 50, received %s.', \count($enabled)));
|
||||
throw new RuntimeException(\sprintf('Too many columns provided, expected maximum 50, received %s.', \count($enabled)));
|
||||
}
|
||||
|
||||
$user = $this->getUser();
|
||||
|
||||
@@ -304,12 +304,12 @@ final class DoctorController extends AbstractController
|
||||
)) {
|
||||
foreach ($matches as $match) {
|
||||
$fn = $plainText;
|
||||
if (isset($match[3])) {
|
||||
if (isset($match[2]) && isset($match[3])) {
|
||||
$keys1 = array_keys($phpinfo);
|
||||
$phpinfo[end($keys1)][$fn($match[2])] = isset($match[4]) ? [$fn($match[3]), $fn($match[4])] : $fn($match[3]);
|
||||
} else {
|
||||
$keys1 = array_keys($phpinfo);
|
||||
$phpinfo[end($keys1)][] = $fn($match[2]);
|
||||
$phpinfo[end($keys1)][] = $fn($match[2]); // @phpstan-ignore-line
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -319,7 +319,7 @@ final class InvoiceController extends AbstractController
|
||||
|
||||
if (null === $file) {
|
||||
throw $this->createNotFoundException(
|
||||
sprintf('Invoice file "%s" could not be found for invoice ID "%s"', $invoice->getInvoiceFilename(), $invoice->getId())
|
||||
\sprintf('Invoice file "%s" could not be found for invoice ID "%s"', $invoice->getInvoiceFilename(), $invoice->getId())
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -243,7 +243,7 @@ final class PermissionController extends AbstractController
|
||||
}
|
||||
|
||||
if (false === $value && $role->getName() === User::ROLE_SUPER_ADMIN && \array_key_exists($name, RolePermissionManager::SUPER_ADMIN_PERMISSIONS)) {
|
||||
throw new BadRequestHttpException(sprintf('Permission "%s" cannot be deactivated for role "%s"', $name, $role->getName()));
|
||||
throw new BadRequestHttpException(\sprintf('Permission "%s" cannot be deactivated for role "%s"', $name, $role->getName()));
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
@@ -118,7 +118,7 @@ final class QuickEntryController extends AbstractController
|
||||
$startFrom = null;
|
||||
if ($takeOverWeeks !== null && \intval($takeOverWeeks) > 0) {
|
||||
$startFrom = clone $startWeek;
|
||||
$startFrom->modify(sprintf('-%s weeks', $takeOverWeeks));
|
||||
$startFrom->modify(\sprintf('-%s weeks', $takeOverWeeks));
|
||||
}
|
||||
|
||||
$favorites = $this->favoriteRecordService->favoriteEntries($user, $amount);
|
||||
|
||||
@@ -71,7 +71,7 @@ final class PasswordResetController extends AbstractController
|
||||
if (!$user->isPasswordRequestNonExpired($this->configuration->getPasswordResetRetryLifetime())) {
|
||||
if (!$user->isInternalUser()) {
|
||||
throw $this->createAccessDeniedException(
|
||||
sprintf('The user "%s" tried to reset the password, but it is registered as "%s" auth-type.', $user->getUserIdentifier(), $user->getAuth())
|
||||
\sprintf('The user "%s" tried to reset the password, but it is registered as "%s" auth-type.', $user->getUserIdentifier(), $user->getAuth())
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -164,7 +164,7 @@ final class SelfRegistrationController extends AbstractController
|
||||
return null;
|
||||
}
|
||||
|
||||
$key = sprintf('_security.%s.target_path', $token->getProviderKey());
|
||||
$key = \sprintf('_security.%s.target_path', $token->getProviderKey());
|
||||
|
||||
if ($session->has($key)) {
|
||||
return $session->get($key);
|
||||
|
||||
@@ -97,7 +97,7 @@ final class TeamController extends AbstractController
|
||||
|
||||
$i = 1;
|
||||
do {
|
||||
$newName = sprintf('%s (%s)', $team->getName(), $i++);
|
||||
$newName = \sprintf('%s (%s)', $team->getName(), $i++);
|
||||
} while ($this->repository->count(['name' => $newName]) > 0 && $i < 10);
|
||||
$newTeam->setName($newName);
|
||||
|
||||
|
||||
@@ -321,7 +321,7 @@ abstract class TimesheetAbstractController extends AbstractController
|
||||
}
|
||||
|
||||
if ($disallowed > 0) {
|
||||
$this->flashWarning(sprintf('You are missing the permission to edit %s timesheets', $disallowed));
|
||||
$this->flashWarning(\sprintf('You are missing the permission to edit %s timesheets', $disallowed));
|
||||
}
|
||||
|
||||
$dto->setEntities($timesheets);
|
||||
@@ -411,7 +411,7 @@ abstract class TimesheetAbstractController extends AbstractController
|
||||
$this->flashUpdateException($ex);
|
||||
}
|
||||
} else {
|
||||
$this->flashSuccess(sprintf('No changes for %s entries detected.', \count($timesheets)));
|
||||
$this->flashSuccess(\sprintf('No changes for %s entries detected.', \count($timesheets)));
|
||||
|
||||
return $this->redirectToRoute($this->getTimesheetRoute());
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ final class AppExtension extends Extension
|
||||
}
|
||||
foreach ($bundleConfig as $key => $value) {
|
||||
if (\array_key_exists($key, $config)) {
|
||||
throw new \Exception(sprintf('Invalid bundle configuration "%s" found, skipping', $key));
|
||||
throw new \Exception(\sprintf('Invalid bundle configuration "%s" found, skipping', $key));
|
||||
}
|
||||
$config[$key] = $value;
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ class ActivityMeta implements MetaTableTypeInterface
|
||||
{
|
||||
if (!($entity instanceof Activity)) {
|
||||
throw new \InvalidArgumentException(
|
||||
sprintf('Expected instanceof Activity, received "%s"', \get_class($entity))
|
||||
\sprintf('Expected instanceof Activity, received "%s"', \get_class($entity))
|
||||
);
|
||||
}
|
||||
$this->activity = $entity;
|
||||
|
||||
@@ -31,7 +31,7 @@ class CustomerMeta implements MetaTableTypeInterface
|
||||
{
|
||||
if (!($entity instanceof Customer)) {
|
||||
throw new \InvalidArgumentException(
|
||||
sprintf('Expected instanceof Customer, received "%s"', \get_class($entity))
|
||||
\sprintf('Expected instanceof Customer, received "%s"', \get_class($entity))
|
||||
);
|
||||
}
|
||||
$this->customer = $entity;
|
||||
|
||||
@@ -31,7 +31,7 @@ class InvoiceMeta implements MetaTableTypeInterface
|
||||
{
|
||||
if (!($entity instanceof Invoice)) {
|
||||
throw new \InvalidArgumentException(
|
||||
sprintf('Expected instanceof Invoice, received "%s"', \get_class($entity))
|
||||
\sprintf('Expected instanceof Invoice, received "%s"', \get_class($entity))
|
||||
);
|
||||
}
|
||||
$this->invoice = $entity;
|
||||
|
||||
@@ -31,7 +31,7 @@ class ProjectMeta implements MetaTableTypeInterface
|
||||
{
|
||||
if (!($entity instanceof Project)) {
|
||||
throw new \InvalidArgumentException(
|
||||
sprintf('Expected instanceof Project, received "%s"', \get_class($entity))
|
||||
\sprintf('Expected instanceof Project, received "%s"', \get_class($entity))
|
||||
);
|
||||
}
|
||||
$this->project = $entity;
|
||||
|
||||
@@ -491,7 +491,7 @@ class Timesheet implements EntityWithMetaFields, ExportableItem, ModifiedAt
|
||||
$allowed = [self::WORK, self::HOLIDAY, self::SICKNESS, self::PARENTAL, self::OVERTIME];
|
||||
|
||||
if (!\in_array($category, $allowed)) {
|
||||
throw new \InvalidArgumentException(sprintf('Invalid timesheet category "%s" given, expected one of: %s', $category, implode(', ', $allowed)));
|
||||
throw new \InvalidArgumentException(\sprintf('Invalid timesheet category "%s" given, expected one of: %s', $category, implode(', ', $allowed)));
|
||||
}
|
||||
|
||||
$this->category = $category;
|
||||
|
||||
@@ -31,7 +31,7 @@ class TimesheetMeta implements MetaTableTypeInterface
|
||||
{
|
||||
if (!($entity instanceof Timesheet)) {
|
||||
throw new \InvalidArgumentException(
|
||||
sprintf('Expected instanceof Timesheet, received "%s"', \get_class($entity))
|
||||
\sprintf('Expected instanceof Timesheet, received "%s"', \get_class($entity))
|
||||
);
|
||||
}
|
||||
$this->timesheet = $entity;
|
||||
|
||||
@@ -17,7 +17,7 @@ final class Expose
|
||||
public function __construct(public ?string $name = null, public ?string $label = null, string $type = 'string', public ?string $exp = null, public ?string $translationDomain = null)
|
||||
{
|
||||
if (!\in_array($type, ['string', 'datetime', 'date', 'time', 'integer', 'float', 'duration', 'boolean', 'array'])) {
|
||||
throw new \InvalidArgumentException(sprintf('Unknown type "%s" on annotation "%s".', $type, self::class));
|
||||
throw new \InvalidArgumentException(\sprintf('Unknown type "%s" on annotation "%s".', $type, self::class));
|
||||
}
|
||||
$this->type = $type;
|
||||
}
|
||||
|
||||
@@ -194,7 +194,7 @@ abstract class AbstractSpreadsheetRenderer
|
||||
|
||||
protected function setDurationTotal(Worksheet $sheet, int $column, int $row, string $startCoordinate, string $endCoordinate): void
|
||||
{
|
||||
$sheet->setCellValue(CellAddress::fromColumnAndRow($column, $row), sprintf('=SUBTOTAL(9,%s:%s)', $startCoordinate, $endCoordinate));
|
||||
$sheet->setCellValue(CellAddress::fromColumnAndRow($column, $row), \sprintf('=SUBTOTAL(9,%s:%s)', $startCoordinate, $endCoordinate));
|
||||
$style = $sheet->getStyle(CellAddress::fromColumnAndRow($column, $row));
|
||||
$style->getNumberFormat()->setFormatCode($this->durationFormat);
|
||||
}
|
||||
@@ -204,19 +204,19 @@ abstract class AbstractSpreadsheetRenderer
|
||||
if (null === $duration) {
|
||||
$duration = 0;
|
||||
}
|
||||
$sheet->setCellValue(CellAddress::fromColumnAndRow($column, $row), sprintf('=%s/%s', $duration, $this->durationBase));
|
||||
$sheet->setCellValue(CellAddress::fromColumnAndRow($column, $row), \sprintf('=%s/%s', $duration, $this->durationBase));
|
||||
$sheet->getStyle(CellAddress::fromColumnAndRow($column, $row))->getNumberFormat()->setFormatCode($this->durationFormat);
|
||||
}
|
||||
|
||||
protected function setRateTotal(Worksheet $sheet, int $column, int $row, string $startCoordinate, string $endCoordinate): void
|
||||
{
|
||||
$sheet->setCellValue(CellAddress::fromColumnAndRow($column, $row), sprintf('=SUBTOTAL(9,%s:%s)', $startCoordinate, $endCoordinate));
|
||||
$sheet->setCellValue(CellAddress::fromColumnAndRow($column, $row), \sprintf('=SUBTOTAL(9,%s:%s)', $startCoordinate, $endCoordinate));
|
||||
}
|
||||
|
||||
protected function setRateStyle(Worksheet $sheet, int $column, int $row, ?string $currency): void
|
||||
{
|
||||
$sheet->getStyle(CellAddress::fromColumnAndRow($column, $row))->getNumberFormat()->setFormatCode(
|
||||
sprintf($this->rateFormat, $currency ?? '')
|
||||
\sprintf($this->rateFormat, $currency ?? '')
|
||||
);
|
||||
}
|
||||
|
||||
@@ -710,7 +710,7 @@ abstract class AbstractSpreadsheetRenderer
|
||||
}
|
||||
|
||||
if (!\array_key_exists('render', $settings) || !\is_callable($settings['render'])) {
|
||||
throw new \RuntimeException(sprintf('Missing or invalid renderer for export column %s', $label));
|
||||
throw new \RuntimeException(\sprintf('Missing or invalid renderer for export column %s', $label));
|
||||
}
|
||||
|
||||
$amount = $settings['render']($sheet, $entryHeaderRow, $entryHeaderColumn, $exportItem);
|
||||
|
||||
@@ -57,7 +57,7 @@ class CsvRenderer extends AbstractSpreadsheetRenderer
|
||||
|
||||
protected function setDuration(Worksheet $sheet, int $column, int $row, ?int $duration): void
|
||||
{
|
||||
$sheet->setCellValue(CellAddress::fromColumnAndRow($column, $row), sprintf('=%s', $duration ?? 0));
|
||||
$sheet->setCellValue(CellAddress::fromColumnAndRow($column, $row), \sprintf('=%s', $duration ?? 0));
|
||||
}
|
||||
|
||||
protected function setRate(Worksheet $sheet, int $column, int $row, ?float $rate, ?string $currency): void
|
||||
|
||||
@@ -161,7 +161,7 @@ final class ServiceExport
|
||||
$items = array_merge($items, $repository->getExportItemsForQuery($query));
|
||||
if ($max !== null && \count($items) > $max) {
|
||||
throw new TooManyItemsExportException(
|
||||
sprintf('Limit reached! Expected max. %s items but got %s', $max, \count($items))
|
||||
\sprintf('Limit reached! Expected max. %s items but got %s', $max, \count($items))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ final class DurationFormatter implements CellFormatterInterface
|
||||
throw new \InvalidArgumentException('Unsupported value given, only int is supported');
|
||||
}
|
||||
|
||||
$sheet->setCellValue(CellAddress::fromColumnAndRow($column, $row), sprintf('=%s/86400', $value));
|
||||
$sheet->setCellValue(CellAddress::fromColumnAndRow($column, $row), \sprintf('=%s/86400', $value));
|
||||
$sheet->getStyle(CellAddress::fromColumnAndRow($column, $row))->getNumberFormat()->setFormatCode(self::DURATION_FORMAT);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,13 +56,13 @@ final class AnnotationExtractor implements ExtractorInterface
|
||||
foreach ($definitions as $definition) {
|
||||
$arguments = $definition->getArguments();
|
||||
if (!\array_key_exists('name', $arguments) || $arguments['name'] === null) {
|
||||
throw new ExtractorException(sprintf('@Expose needs the "name" attribute on class level hierarchy, check %s::class', $value));
|
||||
throw new ExtractorException(\sprintf('@Expose needs the "name" attribute on class level hierarchy, check %s::class', $value));
|
||||
}
|
||||
if (!\array_key_exists('exp', $arguments) || $arguments['exp'] === null) {
|
||||
throw new ExtractorException(sprintf('@Expose needs the "exp" attribute on class level hierarchy, check %s::class', $value));
|
||||
throw new ExtractorException(\sprintf('@Expose needs the "exp" attribute on class level hierarchy, check %s::class', $value));
|
||||
}
|
||||
if (!\array_key_exists('label', $arguments) || $arguments['label'] === null) {
|
||||
throw new ExtractorException(sprintf('@Expose needs the "label" attribute on class level hierarchy, check %s::class', $value));
|
||||
throw new ExtractorException(\sprintf('@Expose needs the "label" attribute on class level hierarchy, check %s::class', $value));
|
||||
}
|
||||
|
||||
$parsed = $this->expressionLanguage->parse($arguments['exp'], ['object']);
|
||||
@@ -87,10 +87,10 @@ final class AnnotationExtractor implements ExtractorInterface
|
||||
foreach ($definitions as $definition) {
|
||||
$arguments = $definition->getArguments();
|
||||
if (\array_key_exists('exp', $arguments) && $arguments['exp'] !== null) {
|
||||
throw new ExtractorException(sprintf('@Expose only supports the "exp" attribute on class level hierarchy, check %s::$%s', $value, $property->getName()));
|
||||
throw new ExtractorException(\sprintf('@Expose only supports the "exp" attribute on class level hierarchy, check %s::$%s', $value, $property->getName()));
|
||||
}
|
||||
if (!\array_key_exists('label', $arguments) || $arguments['label'] === null) {
|
||||
throw new ExtractorException(sprintf('@Expose needs the "label" attribute on property level hierarchy, check %s::$%s', $value, $property->getName()));
|
||||
throw new ExtractorException(\sprintf('@Expose needs the "label" attribute on property level hierarchy, check %s::$%s', $value, $property->getName()));
|
||||
}
|
||||
|
||||
$name = $property->getName();
|
||||
@@ -120,15 +120,15 @@ final class AnnotationExtractor implements ExtractorInterface
|
||||
$definitions = $method->getAttributes(Expose::class);
|
||||
foreach ($definitions as $definition) {
|
||||
if (\count($method->getParameters()) > 0) {
|
||||
throw new ExtractorException(sprintf('@Expose does not support method %s::%s(...) as it has required parameters.', $value, $method->getName()));
|
||||
throw new ExtractorException(\sprintf('@Expose does not support method %s::%s(...) as it has required parameters.', $value, $method->getName()));
|
||||
}
|
||||
|
||||
$arguments = $definition->getArguments();
|
||||
if (\array_key_exists('exp', $arguments) && $arguments['exp'] !== null) {
|
||||
throw new ExtractorException(sprintf('@Expose only supports the "exp" attribute on method level hierarchy, check %s::%s()', $value, $method->getName()));
|
||||
throw new ExtractorException(\sprintf('@Expose only supports the "exp" attribute on method level hierarchy, check %s::%s()', $value, $method->getName()));
|
||||
}
|
||||
if (!\array_key_exists('label', $arguments) || $arguments['label'] === null) {
|
||||
throw new ExtractorException(sprintf('@Expose needs the "label" attribute on method level hierarchy, check %s::%s()', $value, $method->getName()));
|
||||
throw new ExtractorException(\sprintf('@Expose needs the "label" attribute on method level hierarchy, check %s::%s()', $value, $method->getName()));
|
||||
}
|
||||
|
||||
$name = $method->getName();
|
||||
|
||||
@@ -30,7 +30,7 @@ final class ColorPickerType extends AbstractType implements DataTransformerInter
|
||||
$resolver->setDefaults([
|
||||
'documentation' => [
|
||||
'type' => 'string',
|
||||
'description' => sprintf('The hexadecimal color code (default: %s)', self::DEFAULT_COLOR),
|
||||
'description' => \sprintf('The hexadecimal color code (default: %s)', self::DEFAULT_COLOR),
|
||||
],
|
||||
'label' => 'color',
|
||||
'empty_data' => null,
|
||||
|
||||
@@ -49,7 +49,8 @@ final class DateRangeType extends AbstractType
|
||||
'max_day' => null,
|
||||
'locale' => \Locale::getDefault(),
|
||||
]);
|
||||
$resolver->addAllowedTypes('timezone', ['string']);
|
||||
$resolver->setAllowedTypes('separator', 'string');
|
||||
$resolver->addAllowedTypes('timezone', 'string');
|
||||
$resolver->addAllowedTypes('min_day', ['null', 'string', \DateTimeInterface::class]);
|
||||
$resolver->addAllowedTypes('max_day', ['null', 'string', \DateTimeInterface::class]);
|
||||
|
||||
@@ -59,6 +60,7 @@ final class DateRangeType extends AbstractType
|
||||
|
||||
return $converter->convert($format);
|
||||
});
|
||||
$resolver->setAllowedTypes('format', ['string']);
|
||||
|
||||
$resolver->setDefault('attr', function (Options $options): array {
|
||||
$format = $this->localeService->getDateFormat($options['locale']);
|
||||
@@ -115,7 +117,10 @@ final class DateRangeType extends AbstractType
|
||||
}
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder, array $options): void
|
||||
/**
|
||||
* @param array{'format': non-empty-string, 'separator': non-empty-string, 'allow_empty': true, 'timezone': non-empty-string} $options
|
||||
*/
|
||||
public function buildForm(FormBuilderInterface $builder, array $options): void // @phpstan-ignore-line
|
||||
{
|
||||
$formatDate = $options['format'];
|
||||
$separator = $options['separator'];
|
||||
|
||||
@@ -34,6 +34,7 @@ final class DurationType extends AbstractType
|
||||
'max_hours' => 24,
|
||||
'icon' => 'clock',
|
||||
]);
|
||||
$resolver->setAllowedTypes('max_hours', 'int');
|
||||
}
|
||||
|
||||
public function buildView(FormView $view, FormInterface $form, array $options): void
|
||||
@@ -54,7 +55,7 @@ final class DurationType extends AbstractType
|
||||
}
|
||||
|
||||
// we track times for humans and no entry should ever be that long
|
||||
if ($maxHours > $options['max_hours']) {
|
||||
if (\is_int($options['max_hours']) && $maxHours > $options['max_hours']) {
|
||||
$maxHours = $options['max_hours'];
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ final class UserLocaleType extends AbstractType
|
||||
$resolver->setDefaults([
|
||||
'label' => 'locale',
|
||||
'help_html' => true,
|
||||
'help' => sprintf('<a href="%1$s" target="help_locales">%2$s</a>', $route, $moreLink)
|
||||
'help' => \sprintf('<a href="%1$s" target="help_locales">%2$s</a>', $route, $moreLink)
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@@ -212,11 +212,11 @@ final class ServiceInvoice
|
||||
}
|
||||
|
||||
if (mb_strlen($filename) >= 150) {
|
||||
throw new \Exception(sprintf('Invoice filename "%s" is too long, max. 150 characters allowed', $filename));
|
||||
throw new \Exception(\sprintf('Invoice filename "%s" is too long, max. 150 characters allowed', $filename));
|
||||
}
|
||||
|
||||
if (is_file($invoiceDirectory . $filename)) {
|
||||
throw new \Exception(sprintf('Invoice "%s" already exists', $filename));
|
||||
throw new \Exception(\sprintf('Invoice "%s" already exists', $filename));
|
||||
}
|
||||
|
||||
if ($response instanceof BinaryFileResponse) {
|
||||
@@ -303,7 +303,7 @@ final class ServiceInvoice
|
||||
}
|
||||
|
||||
throw new \Exception(
|
||||
sprintf('Cannot render invoice: %s (%s)', $model->getTemplate()->getRenderer(), $document->getName())
|
||||
\sprintf('Cannot render invoice: %s (%s)', $model->getTemplate()->getRenderer(), $document->getName())
|
||||
);
|
||||
}
|
||||
|
||||
@@ -354,7 +354,7 @@ final class ServiceInvoice
|
||||
}
|
||||
|
||||
throw new \Exception(
|
||||
sprintf('Cannot render invoice: %s (%s)', $model->getTemplate()->getRenderer(), $document->getName())
|
||||
\sprintf('Cannot render invoice: %s (%s)', $model->getTemplate()->getRenderer(), $document->getName())
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -106,13 +106,13 @@ class Kernel extends BaseKernel
|
||||
|
||||
$plugin = new $pluginClass();
|
||||
if (!$plugin instanceof PluginInterface) {
|
||||
throw new \Exception(sprintf('Bundle "%s" does not implement %s, which is not supported since 2.0.', $bundleName, PluginInterface::class));
|
||||
throw new \Exception(\sprintf('Bundle "%s" does not implement %s, which is not supported since 2.0.', $bundleName, PluginInterface::class));
|
||||
}
|
||||
|
||||
$meta = new PluginMetadata($fullPath);
|
||||
|
||||
if ($meta->getKimaiVersion() > Constants::VERSION_ID) {
|
||||
throw new \Exception(sprintf('Bundle "%s" requires minimum Kimai version %s, but yours is lower: %s (%s). Please update Kimai or use a lower Plugin version.', $bundleName, $meta->getKimaiVersion(), Constants::VERSION, Constants::VERSION_ID));
|
||||
throw new \Exception(\sprintf('Bundle "%s" requires minimum Kimai version %s, but yours is lower: %s (%s). Please update Kimai or use a lower Plugin version.', $bundleName, $meta->getKimaiVersion(), Constants::VERSION, Constants::VERSION_ID));
|
||||
}
|
||||
|
||||
$plugins[] = $plugin;
|
||||
|
||||
@@ -77,7 +77,7 @@ final class LdapAuthenticator implements AuthenticationEntryPointInterface, Inte
|
||||
public function start(Request $request, AuthenticationException $authException = null): Response
|
||||
{
|
||||
if (!$this->authenticator instanceof AuthenticationEntryPointInterface) {
|
||||
throw new NotAnEntryPointException(sprintf('Decorated authenticator "%s" does not implement interface "%s".', get_debug_type($this->authenticator), AuthenticationEntryPointInterface::class));
|
||||
throw new NotAnEntryPointException(\sprintf('Decorated authenticator "%s" does not implement interface "%s".', get_debug_type($this->authenticator), AuthenticationEntryPointInterface::class));
|
||||
}
|
||||
|
||||
return $this->authenticator->start($request, $authException);
|
||||
|
||||
@@ -41,7 +41,7 @@ final class LdapCredentialsSubscriber implements EventSubscriberInterface
|
||||
}
|
||||
|
||||
if (!$passport instanceof Passport || !$passport->hasBadge(PasswordCredentials::class)) {
|
||||
throw new \LogicException(sprintf('LDAP authentication requires a passport containing a user and password credentials, authenticator "%s" does not fulfill these requirements.', \get_class($event->getAuthenticator())));
|
||||
throw new \LogicException(\sprintf('LDAP authentication requires a passport containing a user and password credentials, authenticator "%s" does not fulfill these requirements.', \get_class($event->getAuthenticator())));
|
||||
}
|
||||
|
||||
/** @var PasswordCredentials $passwordCredentials */
|
||||
|
||||
@@ -60,10 +60,10 @@ class LdapManager
|
||||
$filters[] = $params['filter'];
|
||||
foreach ($criteria as $key => $value) {
|
||||
$value = ldap_escape($value, '', LDAP_ESCAPE_FILTER);
|
||||
$filters[] = sprintf('(%s=%s)', $key, $value);
|
||||
$filters[] = \sprintf('(%s=%s)', $key, $value);
|
||||
}
|
||||
|
||||
return sprintf('(%s%s)', $condition, implode($filters));
|
||||
return \sprintf('(%s%s)', $condition, implode($filters));
|
||||
}
|
||||
|
||||
public function bind(string $dn, string $password): bool
|
||||
@@ -84,7 +84,7 @@ class LdapManager
|
||||
// always look up the users current DN first, as the current user might be upgraded from local to LDAP
|
||||
$userFresh = $this->findUserByUsername($user->getUserIdentifier());
|
||||
if (null === $userFresh || null === ($baseDn = $userFresh->getPreferenceValue('ldap_dn'))) {
|
||||
throw new LdapDriverException(sprintf('Failed fetching user DN for %s', $user->getUserIdentifier()));
|
||||
throw new LdapDriverException(\sprintf('Failed fetching user DN for %s', $user->getUserIdentifier()));
|
||||
}
|
||||
$user->setPreferenceValue('ldap_dn', $baseDn);
|
||||
|
||||
@@ -128,7 +128,7 @@ class LdapManager
|
||||
|
||||
return $this->driver->search(
|
||||
$roleParameter['baseDn'],
|
||||
sprintf('(&%s(%s=%s))', $filter, $roleParameter['userDnAttribute'], ldap_escape($dn, '', LDAP_ESCAPE_FILTER)),
|
||||
\sprintf('(&%s(%s=%s))', $filter, $roleParameter['userDnAttribute'], ldap_escape($dn, '', LDAP_ESCAPE_FILTER)),
|
||||
[$roleParameter['nameAttribute']]
|
||||
);
|
||||
}
|
||||
@@ -200,7 +200,7 @@ class LdapManager
|
||||
}
|
||||
|
||||
if (!$mapped) {
|
||||
$roleName = sprintf('ROLE_%s', self::slugify($roleName));
|
||||
$roleName = \sprintf('ROLE_%s', self::slugify($roleName));
|
||||
}
|
||||
|
||||
if (!\in_array($roleName, $allowedRoles, true)) {
|
||||
|
||||
@@ -35,7 +35,7 @@ final class LdapUserProvider implements UserProviderInterface
|
||||
'username' => $identifier,
|
||||
'result' => 'not found',
|
||||
]);
|
||||
$ex = new UserNotFoundException(sprintf('User "%s" not found', $identifier));
|
||||
$ex = new UserNotFoundException(\sprintf('User "%s" not found', $identifier));
|
||||
$ex->setUserIdentifier($identifier);
|
||||
|
||||
throw $ex;
|
||||
@@ -53,17 +53,17 @@ final class LdapUserProvider implements UserProviderInterface
|
||||
public function refreshUser(UserInterface $user): UserInterface
|
||||
{
|
||||
if (!($user instanceof User)) {
|
||||
throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.', \get_class($user)));
|
||||
throw new UnsupportedUserException(\sprintf('Instances of "%s" are not supported.', \get_class($user)));
|
||||
}
|
||||
|
||||
if (!$user->isLdapUser()) {
|
||||
throw new UnsupportedUserException(sprintf('Account "%s" is not a registered LDAP user.', $user->getUserIdentifier()));
|
||||
throw new UnsupportedUserException(\sprintf('Account "%s" is not a registered LDAP user.', $user->getUserIdentifier()));
|
||||
}
|
||||
|
||||
try {
|
||||
$this->ldapManager->updateUser($user);
|
||||
} catch (LdapDriverException $ex) {
|
||||
throw new UnsupportedUserException(sprintf('Failed to refresh user "%s", probably DN is expired.', $user->getUserIdentifier()));
|
||||
throw new UnsupportedUserException(\sprintf('Failed to refresh user "%s", probably DN is expired.', $user->getUserIdentifier()));
|
||||
}
|
||||
|
||||
return $user;
|
||||
|
||||
@@ -25,7 +25,7 @@ final class Month extends Timesheet
|
||||
$monthNumber = (int) $month;
|
||||
if ($monthNumber < 1 || $monthNumber > 12) {
|
||||
throw new InvalidArgumentException(
|
||||
sprintf('Invalid month given. Expected 1-12, received "%s".', $monthNumber)
|
||||
\sprintf('Invalid month given. Expected 1-12, received "%s".', $monthNumber)
|
||||
);
|
||||
}
|
||||
$this->month = str_pad($month, 2, '0', STR_PAD_LEFT);
|
||||
|
||||
@@ -25,36 +25,36 @@ class PluginMetadata
|
||||
public function __construct(string $path)
|
||||
{
|
||||
if (!is_dir($path) || !is_readable($path)) {
|
||||
throw new \Exception(sprintf('Bundle directory "%s" cannot be accessed.', $path));
|
||||
throw new \Exception(\sprintf('Bundle directory "%s" cannot be accessed.', $path));
|
||||
}
|
||||
|
||||
$pluginName = basename($path);
|
||||
$composer = $path . '/composer.json';
|
||||
|
||||
if (!file_exists($composer) || !is_readable($composer)) {
|
||||
throw new \Exception(sprintf('Bundle "%s" does not ship composer.json, which is required since 2.0.', $pluginName));
|
||||
throw new \Exception(\sprintf('Bundle "%s" does not ship composer.json, which is required since 2.0.', $pluginName));
|
||||
}
|
||||
|
||||
$json = json_decode(file_get_contents($composer), true);
|
||||
|
||||
if (!\array_key_exists('extra', $json)) {
|
||||
throw new \Exception(sprintf('Bundle "%s" does not define an "extra" node in composer.json, which is required since 2.0.', $pluginName));
|
||||
throw new \Exception(\sprintf('Bundle "%s" does not define an "extra" node in composer.json, which is required since 2.0.', $pluginName));
|
||||
}
|
||||
|
||||
if (!\array_key_exists('kimai', $json['extra'])) {
|
||||
throw new \Exception(sprintf('Bundle "%s" does not define the "extra.kimai" node in composer.json, which is required since 2.0.', $pluginName));
|
||||
throw new \Exception(\sprintf('Bundle "%s" does not define the "extra.kimai" node in composer.json, which is required since 2.0.', $pluginName));
|
||||
}
|
||||
|
||||
if (!\array_key_exists('require', $json['extra']['kimai'])) {
|
||||
throw new \Exception(sprintf('Bundle "%s" does not define the minimum Kimai version in "extra.kimai.required" in composer.json, which is required since 2.0.', $pluginName));
|
||||
throw new \Exception(\sprintf('Bundle "%s" does not define the minimum Kimai version in "extra.kimai.required" in composer.json, which is required since 2.0.', $pluginName));
|
||||
}
|
||||
|
||||
if (!\array_key_exists('name', $json['extra']['kimai'])) {
|
||||
throw new \Exception(sprintf('Bundle "%s" does not define its name in "extra.kimai.name" in composer.json, which is required since 2.0.', $pluginName));
|
||||
throw new \Exception(\sprintf('Bundle "%s" does not define its name in "extra.kimai.name" in composer.json, which is required since 2.0.', $pluginName));
|
||||
}
|
||||
|
||||
if (!\is_int($json['extra']['kimai']['require'])) {
|
||||
throw new \Exception(sprintf('Bundle "%s" defines an invalid Kimai minimum version in extra.kimai.require. Please provide an integer as in Constants::VERSION_ID.', $pluginName));
|
||||
throw new \Exception(\sprintf('Bundle "%s" defines an invalid Kimai minimum version in extra.kimai.require. Please provide an integer as in Constants::VERSION_ID.', $pluginName));
|
||||
}
|
||||
|
||||
$this->description = $json['description'] ?? '';
|
||||
|
||||
@@ -76,7 +76,7 @@ trait RepositorySearchTrait
|
||||
$and->add($qb->expr()->isNotNull($alias . '.value'));
|
||||
} elseif ($metaValue === '~') {
|
||||
$and->add(
|
||||
sprintf('NOT EXISTS(SELECT metaNotExists FROM %s metaNotExists WHERE metaNotExists.%s = %s.id)', $this->getMetaFieldClass(), $this->getMetaFieldName(), $rootAlias)
|
||||
\sprintf('NOT EXISTS(SELECT metaNotExists FROM %s metaNotExists WHERE metaNotExists.%s = %s.id)', $this->getMetaFieldClass(), $this->getMetaFieldName(), $rootAlias)
|
||||
);
|
||||
} elseif ($metaValue === '' || $metaValue === null) {
|
||||
$qb->leftJoin($rootAlias . '.meta', $alias);
|
||||
@@ -86,7 +86,7 @@ trait RepositorySearchTrait
|
||||
$qb->expr()->eq($alias . '.name', ':' . $paramName),
|
||||
$qb->expr()->isNull($alias . '.value')
|
||||
),
|
||||
sprintf('NOT EXISTS(SELECT metaNotExists FROM %s metaNotExists WHERE metaNotExists.%s = %s.id)', $this->getMetaFieldClass(), $this->getMetaFieldName(), $rootAlias)
|
||||
\sprintf('NOT EXISTS(SELECT metaNotExists FROM %s metaNotExists WHERE metaNotExists.%s = %s.id)', $this->getMetaFieldClass(), $this->getMetaFieldName(), $rootAlias)
|
||||
)
|
||||
);
|
||||
$qb->setParameter($paramName, $metaName);
|
||||
|
||||
@@ -98,7 +98,7 @@ class SamlAuthenticator extends AbstractAuthenticator
|
||||
|
||||
if (isset($this->options['username_attribute'])) {
|
||||
if (!\array_key_exists($this->options['username_attribute'], $attributes)) {
|
||||
throw new \Exception(sprintf("Attribute '%s' not found in SAML data", $this->options['username_attribute']));
|
||||
throw new \Exception(\sprintf("Attribute '%s' not found in SAML data", $this->options['username_attribute']));
|
||||
}
|
||||
|
||||
$username = $attributes[$this->options['username_attribute']][0];
|
||||
|
||||
@@ -32,7 +32,7 @@ final class SamlLoginAttributes
|
||||
public function getAttribute(string $name): mixed
|
||||
{
|
||||
if (!\array_key_exists($name, $this->attributes)) {
|
||||
throw new \InvalidArgumentException(sprintf('This SAML login has no "%s" attribute.', $name));
|
||||
throw new \InvalidArgumentException(\sprintf('This SAML login has no "%s" attribute.', $name));
|
||||
}
|
||||
|
||||
return $this->attributes[$name];
|
||||
|
||||
@@ -54,7 +54,7 @@ final class SamlProvider
|
||||
} catch (\Exception $ex) {
|
||||
$this->logger->error($ex->getMessage());
|
||||
throw new AuthenticationException(
|
||||
sprintf('Failed creating or hydrating user "%s": %s', $token->getUserIdentifier(), $ex->getMessage())
|
||||
\sprintf('Failed creating or hydrating user "%s": %s', $token->getUserIdentifier(), $ex->getMessage())
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -173,7 +173,7 @@ final class LocaleFormatExtensions extends AbstractExtension implements LocaleAw
|
||||
}
|
||||
$months = [];
|
||||
for ($i = 1; $i < 13; $i++) {
|
||||
$months[] = $this->getFormatter()->monthName(new DateTime(sprintf('%s-%s-10', $year, ($i < 10 ? '0' . $i : (string) $i))), $withYear);
|
||||
$months[] = $this->getFormatter()->monthName(new DateTime(\sprintf('%s-%s-10', $year, ($i < 10 ? '0' . $i : (string) $i))), $withYear);
|
||||
}
|
||||
|
||||
return $months;
|
||||
|
||||
@@ -37,7 +37,7 @@ final class WidgetExtension implements RuntimeExtensionInterface
|
||||
|
||||
if (\is_string($widget)) {
|
||||
if (!$this->service->hasWidget($widget)) {
|
||||
throw new \InvalidArgumentException(sprintf('Unknown widget "%s" requested', $widget));
|
||||
throw new \InvalidArgumentException(\sprintf('Unknown widget "%s" requested', $widget));
|
||||
}
|
||||
|
||||
$widget = $this->service->getWidget($widget);
|
||||
|
||||
@@ -51,19 +51,19 @@ final class ForbiddenPolicy implements SecurityPolicyInterface
|
||||
{
|
||||
foreach ($tags as $tag) {
|
||||
if (\in_array($tag, $this->forbiddenTags)) {
|
||||
throw new SecurityNotAllowedTagError(sprintf('Tag "%s" is not allowed.', $tag), $tag);
|
||||
throw new SecurityNotAllowedTagError(\sprintf('Tag "%s" is not allowed.', $tag), $tag);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($filters as $filter) {
|
||||
if (\in_array($filter, $this->forbiddenFilters)) {
|
||||
throw new SecurityNotAllowedFilterError(sprintf('Filter "%s" is not allowed.', $filter), $filter);
|
||||
throw new SecurityNotAllowedFilterError(\sprintf('Filter "%s" is not allowed.', $filter), $filter);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($functions as $function) {
|
||||
if (\in_array($function, $this->forbiddenFunctions)) {
|
||||
throw new SecurityNotAllowedFunctionError(sprintf('Function "%s" is not allowed.', $function), $function);
|
||||
throw new SecurityNotAllowedFunctionError(\sprintf('Function "%s" is not allowed.', $function), $function);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -86,7 +86,7 @@ final class ForbiddenPolicy implements SecurityPolicyInterface
|
||||
|
||||
if ($forbidden) {
|
||||
$class = \get_class($obj);
|
||||
throw new SecurityNotAllowedMethodError(sprintf('Calling "%s" method on a "%s" object is not allowed.', $method, $class), $class, $method);
|
||||
throw new SecurityNotAllowedMethodError(\sprintf('Calling "%s" method on a "%s" object is not allowed.', $method, $class), $class, $method);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@ final class ForbiddenPolicy implements SecurityPolicyInterface
|
||||
|
||||
if ($forbidden) {
|
||||
$class = \get_class($obj);
|
||||
throw new SecurityNotAllowedPropertyError(sprintf('Calling "%s" property on a "%s" object is not allowed.', $property, $class), $class, $property);
|
||||
throw new SecurityNotAllowedPropertyError(\sprintf('Calling "%s" property on a "%s" object is not allowed.', $property, $class), $class, $property);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,7 +136,7 @@ class UserService
|
||||
$user = $this->findUserByName($username);
|
||||
|
||||
if ($user === null) {
|
||||
throw new \InvalidArgumentException(sprintf('User identified by "%s" username does not exist.', $username));
|
||||
throw new \InvalidArgumentException(\sprintf('User identified by "%s" username does not exist.', $username));
|
||||
}
|
||||
|
||||
return $user;
|
||||
|
||||
@@ -96,7 +96,7 @@ final class Color
|
||||
|
||||
public function getRandomColor(): string
|
||||
{
|
||||
return sprintf('#%06x', rand(0, 16777215));
|
||||
return \sprintf('#%06x', rand(0, 16777215));
|
||||
}
|
||||
|
||||
public function getRandomFromPalette(string $input): string
|
||||
|
||||
@@ -85,7 +85,7 @@ final class Duration
|
||||
self::FORMAT_COLON => $this->parseColonFormat($duration),
|
||||
self::FORMAT_NATURAL => $this->parseNaturalFormat($duration),
|
||||
self::FORMAT_DECIMAL => $this->parseDecimalFormat($duration),
|
||||
default => throw new \InvalidArgumentException(sprintf('Unsupported duration format "%s"', $mode)),
|
||||
default => throw new \InvalidArgumentException(\sprintf('Unsupported duration format "%s"', $mode)),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -116,7 +116,7 @@ final class Duration
|
||||
$parts = explode(':', $duration);
|
||||
if (\count($parts) < 2 || \count($parts) > 3) {
|
||||
throw new \InvalidArgumentException(
|
||||
sprintf('Invalid colon format given in "%s"', $duration)
|
||||
\sprintf('Invalid colon format given in "%s"', $duration)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -124,13 +124,13 @@ final class Duration
|
||||
foreach ($parts as $part) {
|
||||
if (\strlen($part) === 0) {
|
||||
throw new \InvalidArgumentException(
|
||||
sprintf('Colon format cannot parse "%s"', $duration)
|
||||
\sprintf('Colon format cannot parse "%s"', $duration)
|
||||
);
|
||||
}
|
||||
// the entire time could be negative
|
||||
if ($i++ > 0 && ((int) $part) < 0) {
|
||||
throw new \InvalidArgumentException(
|
||||
sprintf('Negative input is not allowed in "%s"', $duration)
|
||||
\sprintf('Negative input is not allowed in "%s"', $duration)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,11 +40,11 @@ final class FileHelper
|
||||
$this->makeDir($directory);
|
||||
|
||||
if (!is_dir($directory)) {
|
||||
throw new \Exception(sprintf('Directory "%s" does not exist', $directory));
|
||||
throw new \Exception(\sprintf('Directory "%s" does not exist', $directory));
|
||||
}
|
||||
|
||||
if (!is_writable($directory)) {
|
||||
throw new \Exception(sprintf('Directory "%s" is not writable', $directory));
|
||||
throw new \Exception(\sprintf('Directory "%s" is not writable', $directory));
|
||||
}
|
||||
|
||||
return $directory;
|
||||
|
||||
@@ -39,9 +39,9 @@ final class PaginationTemplate extends TwitterBootstrap5Template
|
||||
protected function linkLi(string $class, string $href, $text, ?string $rel = null): string
|
||||
{
|
||||
$liClass = implode(' ', array_filter(['page-item', $class]));
|
||||
$rel = $rel ? sprintf(' rel="%s"', $rel) : '';
|
||||
$rel = $rel ? \sprintf(' rel="%s"', $rel) : '';
|
||||
|
||||
return sprintf('<li class="%s"><a class="page-link pagination-link" href="%s"%s>%s</a></li>', $liClass, $href, $rel, $text);
|
||||
return \sprintf('<li class="%s"><a class="page-link pagination-link" href="%s"%s>%s</a></li>', $liClass, $href, $rel, $text);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -53,7 +53,7 @@ final class PaginationTemplate extends TwitterBootstrap5Template
|
||||
{
|
||||
$liClass = implode(' ', array_filter(['page-item', $class]));
|
||||
|
||||
return sprintf('<li class="%s"><span class="page-link pagination-link">%s</span></li>', $liClass, $text);
|
||||
return \sprintf('<li class="%s"><span class="page-link pagination-link">%s</span></li>', $liClass, $text);
|
||||
}
|
||||
|
||||
public function current(int $page): string
|
||||
|
||||
@@ -130,6 +130,6 @@ abstract class AbstractWidget implements WidgetInterface
|
||||
{
|
||||
$name = (new \ReflectionClass($this))->getShortName();
|
||||
|
||||
return sprintf('widget/widget-%s.html.twig', strtolower($name));
|
||||
return \sprintf('widget/widget-%s.html.twig', strtolower($name));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,8 +128,8 @@ final class PaginatedWorkingTimeChart extends AbstractWidget
|
||||
$monthBegin = (clone $weekBegin)->setDate((int) $weekBegin->format('Y'), (int) $weekBegin->format('n'), 1)->setTime(0, 0, 0);
|
||||
$monthEnd = (clone $weekBegin)->setDate((int) $weekBegin->format('Y'), (int) $weekBegin->format('n'), (int) $weekBegin->format('t'))->setTime(23, 59, 59);
|
||||
|
||||
$yearBegin = $dateTimeFactory->createDateTime(sprintf('01 january %s 00:00:00', $year));
|
||||
$yearEnd = $dateTimeFactory->createDateTime(sprintf('31 december %s 23:59:59', $year));
|
||||
$yearBegin = $dateTimeFactory->createDateTime(\sprintf('01 january %s 00:00:00', $year));
|
||||
$yearEnd = $dateTimeFactory->createDateTime(\sprintf('31 december %s 23:59:59', $year));
|
||||
$yearData = $this->repository->getDurationForTimeRange($yearBegin, $yearEnd, $user);
|
||||
|
||||
$financialYearData = null;
|
||||
|
||||
@@ -41,7 +41,7 @@ class WidgetService
|
||||
public function getWidget(string $id): WidgetInterface
|
||||
{
|
||||
if (!$this->hasWidget($id)) {
|
||||
throw new \InvalidArgumentException(sprintf('Cannot find widget: %s', $id));
|
||||
throw new \InvalidArgumentException(\sprintf('Cannot find widget: %s', $id));
|
||||
}
|
||||
|
||||
return $this->widgets[$id];
|
||||
|
||||
Reference in New Issue
Block a user