Release 2.35 (#5470)

* open up API for plugins by removing internal
* use constants in entity column definition
* simplified entity management API
* bump packages
* allow installing assets and run database migrations independently
* bump to apidoc-bundle 5
* do not duplicate http method in API operationId
* new security entries in Open API definition
* changed API UI provider for Swagger to Stoplight, improved endpoint titles, hide internal endpoints
* deactivate swagger json endpoint
This commit is contained in:
Kevin Papst
2025-05-24 14:28:39 +02:00
committed by GitHub
parent 6e26a37c4d
commit 1e0fbf0b73
63 changed files with 518 additions and 529 deletions

View File

@@ -14,6 +14,7 @@ use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Exception\LogicException;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\Filesystem\Exception\FileNotFoundException;
@@ -25,8 +26,6 @@ abstract class AbstractBundleInstallerCommand extends Command
{
/**
* Returns the base directory to the Kimai installation.
*
* @return string
*/
protected function getRootDirectory(): string
{
@@ -39,18 +38,26 @@ abstract class AbstractBundleInstallerCommand extends Command
/**
* If your bundle ships assets, that need to be available in the public/ directory,
* then overwrite this method and return: <true>.
*
* @return bool
*/
protected function hasAssets(): bool
{
return false;
}
private function hasMigrations(SymfonyStyle $io): bool
{
$config = $this->getMigrationConfigFilename();
if ($config === null) {
return false;
}
return true;
}
/**
* Returns an absolute filename to your doctrine migrations configuration, if you want to install database tables.
*
* @return string|null
* Returns an absolute filename to your doctrine migrations configuration
* if you want to run database migrations.
*/
protected function getMigrationConfigFilename(): ?string
{
@@ -59,16 +66,12 @@ abstract class AbstractBundleInstallerCommand extends Command
/**
* Returns the bundle short name for the installer command.
*
* @return string
*/
abstract protected function getBundleCommandNamePart(): string;
/**
* Returns the full name fo this command.
* Please stick to the standard and overwrite getBundleCommandNamePart() only.
*
* @return string
*/
protected function getInstallerCommandName(): string
{
@@ -77,8 +80,6 @@ abstract class AbstractBundleInstallerCommand extends Command
/**
* Returns the bundles real name (same as your namespace).
*
* @return string
*/
protected function getBundleName(): string
{
@@ -100,6 +101,8 @@ abstract class AbstractBundleInstallerCommand extends Command
->setName($this->getInstallerCommandName())
->setDescription('Install the bundle: ' . $this->getBundleName())
->setHelp('This command will perform the basic installation steps to get the bundle up and running.')
->addOption('database', null, InputOption::VALUE_NONE, 'Only run the database installation')
->addOption('assets', null, InputOption::VALUE_NONE, 'Only run the asset installation')
;
}
@@ -107,6 +110,15 @@ abstract class AbstractBundleInstallerCommand extends Command
{
$io = new SymfonyStyle($input, $output);
$noAssets = $input->getOption('database');
$onlyAssets = $input->getOption('assets');
if ($noAssets && $onlyAssets) {
$io->error('Options --assets and --database are mutually exclusive');
return Command::FAILURE;
}
// many users execute the bin/console command from arbitrary locations
// this will make sure that relative paths (like doctrine migrations) work as expected
$path = getcwd();
@@ -117,17 +129,19 @@ abstract class AbstractBundleInstallerCommand extends Command
\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())
);
if (!$onlyAssets && $this->hasMigrations($io)) {
try {
$this->importMigrations($io, $output);
} catch (\Exception $ex) {
$io->error(
\sprintf('Failed to install database for bundle %s. %s', $bundleName, $ex->getMessage())
);
return Command::FAILURE;
return Command::FAILURE;
}
}
if ($this->hasAssets()) {
if (!$noAssets && $this->hasAssets()) {
try {
$this->installAssets($io, $output);
} catch (\Exception $ex) {
@@ -148,7 +162,7 @@ abstract class AbstractBundleInstallerCommand extends Command
return Command::SUCCESS;
}
protected function installAssets(SymfonyStyle $io, OutputInterface $output): void
private function installAssets(SymfonyStyle $io, OutputInterface $output): void
{
$command = $this->getApplication()->find('assets:install');
$cmdInput = new ArrayInput([]);
@@ -160,11 +174,11 @@ abstract class AbstractBundleInstallerCommand extends Command
$io->writeln('');
}
protected function importMigrations(SymfonyStyle $io, OutputInterface $output): void
private function importMigrations(SymfonyStyle $io, OutputInterface $output): void
{
$config = $this->getMigrationConfigFilename();
if (null === $config) {
if ($config === null) {
return;
}

View File

@@ -25,7 +25,7 @@ use Symfony\Component\Console\Style\SymfonyStyle;
*
* @codeCoverageIgnore
*/
#[AsCommand(name: 'kimai:install', description: 'Kimai installation command', aliases: ['kimai:update'])]
#[AsCommand(name: 'kimai:install', description: 'Install and update Kimai', aliases: ['kimai:update'])]
final class InstallCommand extends Command
{
public function __construct(private readonly Connection $connection)

View File

@@ -22,10 +22,13 @@ use Symfony\Component\Console\Style\SymfonyStyle;
*
* @codeCoverageIgnore
*/
#[AsCommand(name: 'kimai:reload')]
#[AsCommand(name: 'kimai:reload', description: 'Reload Kimai caches')]
final class ReloadCommand extends Command
{
public function __construct(private string $projectDirectory, private string $kernelEnvironment)
public function __construct(
private readonly string $projectDirectory,
private readonly string $kernelEnvironment
)
{
parent::__construct();
}
@@ -42,10 +45,7 @@ final class ReloadCommand extends Command
protected function configure(): void
{
$this
->setDescription('Reload Kimai caches')
->setHelp('This command will validate the configurations and translations and then clear and rebuild the application cache.')
;
$this->setHelp('This will validate configurations and translations and then clear and rebuild the application cache.');
}
protected function execute(InputInterface $input, OutputInterface $output): int