bump symfony to 5.4.21

adapt to the new EventDispatcher API
  - Symfony\Component\EventDispatcher => Symfony\Contracts\EventDispatcher
  - dispatch() arguments swap
  - execute() must return int
This commit is contained in:
Joe Nahmias 2023-06-01 23:06:38 -04:00 committed by Frédéric Guillot
parent bb4b547ffe
commit bd7f3d219d
42 changed files with 513 additions and 95 deletions

View File

@ -7,6 +7,7 @@ use JsonRPC\Exception\AuthenticationFailureException;
use JsonRPC\MiddlewareInterface; use JsonRPC\MiddlewareInterface;
use Kanboard\Auth\ApiAccessTokenAuth; use Kanboard\Auth\ApiAccessTokenAuth;
use Kanboard\Core\Base; use Kanboard\Core\Base;
use Symfony\Contracts\EventDispatcher\Event;
/** /**
* Class AuthenticationApiMiddleware * Class AuthenticationApiMiddleware
@ -28,7 +29,7 @@ class AuthenticationMiddleware extends Base implements MiddlewareInterface
*/ */
public function execute($username, $password, $procedureName) public function execute($username, $password, $procedureName)
{ {
$this->dispatcher->dispatch('app.bootstrap'); $this->dispatcher->dispatch(new Event, 'app.bootstrap');
session_set('scope', 'API'); session_set('scope', 'API');
if ($this->isUserAuthenticated($username, $password)) { if ($this->isUserAuthenticated($username, $password)) {

View File

@ -22,11 +22,12 @@ class CronjobCommand extends BaseCommand
->setDescription('Execute daily cronjob'); ->setDescription('Execute daily cronjob');
} }
protected function execute(InputInterface $input, OutputInterface $output) protected function execute(InputInterface $input, OutputInterface $output): int
{ {
foreach ($this->commands as $command) { foreach ($this->commands as $command) {
$job = $this->getApplication()->find($command); $job = $this->getApplication()->find($command);
$job->run(new ArrayInput(array('command' => $command)), new NullOutput()); $job->run(new ArrayInput(array('command' => $command)), new NullOutput());
} }
return 0;
} }
} }

View File

@ -102,7 +102,7 @@ class CssCommand extends BaseCommand
; ;
} }
protected function execute(InputInterface $input, OutputInterface $output) protected function execute(InputInterface $input, OutputInterface $output): int
{ {
$this->minifyFiles(self::CSS_SRC_PATH, array_merge(['themes'.DIRECTORY_SEPARATOR.'light.css'], $this->appFiles), 'light.min.css'); $this->minifyFiles(self::CSS_SRC_PATH, array_merge(['themes'.DIRECTORY_SEPARATOR.'light.css'], $this->appFiles), 'light.min.css');
$this->minifyFiles(self::CSS_SRC_PATH, array_merge(['themes'.DIRECTORY_SEPARATOR.'dark.css'], $this->appFiles), 'dark.min.css'); $this->minifyFiles(self::CSS_SRC_PATH, array_merge(['themes'.DIRECTORY_SEPARATOR.'dark.css'], $this->appFiles), 'dark.min.css');
@ -111,6 +111,7 @@ class CssCommand extends BaseCommand
$vendorBundle = concat_files($this->vendorFiles); $vendorBundle = concat_files($this->vendorFiles);
file_put_contents('assets/css/vendor.min.css', $vendorBundle); file_put_contents('assets/css/vendor.min.css', $vendorBundle);
return 0;
} }
private function minifyFiles($folder, array $files, $destination) private function minifyFiles($folder, array $files, $destination)

View File

@ -15,9 +15,10 @@ class DatabaseMigrationCommand extends DatabaseVersionCommand
->setDescription('Execute SQL migrations'); ->setDescription('Execute SQL migrations');
} }
protected function execute(InputInterface $input, OutputInterface $output) protected function execute(InputInterface $input, OutputInterface $output): int
{ {
parent::execute($input, $output); parent::execute($input, $output);
DatabaseProvider::runMigrations($this->container['db']); DatabaseProvider::runMigrations($this->container['db']);
return 0;
} }
} }

View File

@ -15,9 +15,10 @@ class DatabaseVersionCommand extends BaseCommand
->setDescription('Show database schema version'); ->setDescription('Show database schema version');
} }
protected function execute(InputInterface $input, OutputInterface $output) protected function execute(InputInterface $input, OutputInterface $output): int
{ {
$output->writeln('<info>Current version: '.DatabaseProvider::getSchemaVersion($this->container['db']).'</info>'); $output->writeln('<info>Current version: '.DatabaseProvider::getSchemaVersion($this->container['db']).'</info>');
$output->writeln('<info>Last version: '.\Schema\VERSION.'</info>'); $output->writeln('<info>Last version: '.\Schema\VERSION.'</info>');
return 0;
} }
} }

View File

@ -23,7 +23,7 @@ class JobCommand extends BaseCommand
; ;
} }
protected function execute(InputInterface $input, OutputInterface $output) protected function execute(InputInterface $input, OutputInterface $output): int
{ {
$payload = fgets(STDIN); $payload = fgets(STDIN);
@ -31,5 +31,6 @@ class JobCommand extends BaseCommand
$job->unserialize($payload); $job->unserialize($payload);
JobHandler::getInstance($this->container)->executeJob($job); JobHandler::getInstance($this->container)->executeJob($job);
return 0;
} }
} }

View File

@ -77,7 +77,7 @@ class JsCommand extends BaseCommand
; ;
} }
protected function execute(InputInterface $input, OutputInterface $output) protected function execute(InputInterface $input, OutputInterface $output): int
{ {
$appBundle = concat_files($this->appFiles); $appBundle = concat_files($this->appFiles);
$vendorBundle = concat_files($this->vendorFiles); $vendorBundle = concat_files($this->vendorFiles);
@ -86,5 +86,6 @@ class JsCommand extends BaseCommand
file_put_contents('assets/js/app.min.js', $minifier->minify()); file_put_contents('assets/js/app.min.js', $minifier->minify());
file_put_contents('assets/js/vendor.min.js', $vendorBundle); file_put_contents('assets/js/vendor.min.js', $vendorBundle);
return 0;
} }
} }

View File

@ -18,7 +18,7 @@ class LocaleComparatorCommand extends BaseCommand
->setDescription('Compare application translations with the '.self::REF_LOCALE.' locale'); ->setDescription('Compare application translations with the '.self::REF_LOCALE.' locale');
} }
protected function execute(InputInterface $input, OutputInterface $output) protected function execute(InputInterface $input, OutputInterface $output): int
{ {
$strings = array(); $strings = array();
$it = new RecursiveIteratorIterator(new RecursiveDirectoryIterator(APP_DIR)); $it = new RecursiveIteratorIterator(new RecursiveDirectoryIterator(APP_DIR));
@ -33,6 +33,7 @@ class LocaleComparatorCommand extends BaseCommand
} }
$this->compare(array_unique($strings)); $this->compare(array_unique($strings));
return 0;
} }
public function show(array $strings) public function show(array $strings)

View File

@ -17,7 +17,7 @@ class LocaleSyncCommand extends BaseCommand
->setDescription('Synchronize all translations based on the '.self::REF_LOCALE.' locale'); ->setDescription('Synchronize all translations based on the '.self::REF_LOCALE.' locale');
} }
protected function execute(InputInterface $input, OutputInterface $output) protected function execute(InputInterface $input, OutputInterface $output): int
{ {
$reference_file = APP_DIR.DIRECTORY_SEPARATOR.'Locale'.DIRECTORY_SEPARATOR.self::REF_LOCALE.DIRECTORY_SEPARATOR.'translations.php'; $reference_file = APP_DIR.DIRECTORY_SEPARATOR.'Locale'.DIRECTORY_SEPARATOR.self::REF_LOCALE.DIRECTORY_SEPARATOR.'translations.php';
$reference = include $reference_file; $reference = include $reference_file;
@ -30,6 +30,7 @@ class LocaleSyncCommand extends BaseCommand
file_put_contents($filename, $this->updateFile($reference, $filename)); file_put_contents($filename, $this->updateFile($reference, $filename));
} }
} }
return 0;
} }
public function updateFile(array $reference, $outdated_file) public function updateFile(array $reference, $outdated_file)

View File

@ -19,7 +19,7 @@ class PluginInstallCommand extends BaseCommand
->addArgument('url', InputArgument::REQUIRED, 'Archive URL'); ->addArgument('url', InputArgument::REQUIRED, 'Archive URL');
} }
protected function execute(InputInterface $input, OutputInterface $output) protected function execute(InputInterface $input, OutputInterface $output): int
{ {
if (!Installer::isConfigured()) { if (!Installer::isConfigured()) {
throw new LogicException('Kanboard is not configured to install plugins itself'); throw new LogicException('Kanboard is not configured to install plugins itself');
@ -29,8 +29,10 @@ class PluginInstallCommand extends BaseCommand
$installer = new Installer($this->container); $installer = new Installer($this->container);
$installer->install($input->getArgument('url')); $installer->install($input->getArgument('url'));
$output->writeln('<info>Plugin installed successfully</info>'); $output->writeln('<info>Plugin installed successfully</info>');
return 0;
} catch (PluginInstallerException $e) { } catch (PluginInstallerException $e) {
$output->writeln('<error>'.$e->getMessage().'</error>'); $output->writeln('<error>'.$e->getMessage().'</error>');
return 1;
} }
} }
} }

View File

@ -19,7 +19,7 @@ class PluginUninstallCommand extends BaseCommand
->addArgument('pluginId', InputArgument::REQUIRED, 'Plugin directory name'); ->addArgument('pluginId', InputArgument::REQUIRED, 'Plugin directory name');
} }
protected function execute(InputInterface $input, OutputInterface $output) protected function execute(InputInterface $input, OutputInterface $output): int
{ {
if (!Installer::isConfigured()) { if (!Installer::isConfigured()) {
throw new LogicException('Kanboard is not configured to install plugins itself'); throw new LogicException('Kanboard is not configured to install plugins itself');
@ -29,8 +29,10 @@ class PluginUninstallCommand extends BaseCommand
$installer = new Installer($this->container); $installer = new Installer($this->container);
$installer->uninstall($input->getArgument('pluginId')); $installer->uninstall($input->getArgument('pluginId'));
$output->writeln('<info>Plugin removed successfully</info>'); $output->writeln('<info>Plugin removed successfully</info>');
return 0;
} catch (PluginInstallerException $e) { } catch (PluginInstallerException $e) {
$output->writeln('<error>'.$e->getMessage().'</error>'); $output->writeln('<error>'.$e->getMessage().'</error>');
return 1;
} }
} }
} }

View File

@ -19,7 +19,7 @@ class PluginUpgradeCommand extends BaseCommand
; ;
} }
protected function execute(InputInterface $input, OutputInterface $output) protected function execute(InputInterface $input, OutputInterface $output): int
{ {
if (!Installer::isConfigured()) { if (!Installer::isConfigured()) {
throw new LogicException('Kanboard is not configured to install plugins itself'); throw new LogicException('Kanboard is not configured to install plugins itself');
@ -40,6 +40,7 @@ class PluginUpgradeCommand extends BaseCommand
$output->writeln('<info>* Plugin up to date: '.$installedPlugin->getPluginName().'</info>'); $output->writeln('<info>* Plugin up to date: '.$installedPlugin->getPluginName().'</info>');
} }
} }
return 0;
} }
protected function getPluginDetails(array $availablePlugins, BasePlugin $installedPlugin) protected function getPluginDetails(array $availablePlugins, BasePlugin $installedPlugin)

View File

@ -14,8 +14,9 @@ class ProjectActivityArchiveCommand extends BaseCommand
->setDescription('Remove project activities after one year'); ->setDescription('Remove project activities after one year');
} }
protected function execute(InputInterface $input, OutputInterface $output) protected function execute(InputInterface $input, OutputInterface $output): int
{ {
$this->projectActivityModel->cleanup(strtotime('-1 year')); $this->projectActivityModel->cleanup(strtotime('-1 year'));
return 0;
} }
} }

View File

@ -15,7 +15,7 @@ class ProjectArchiveCommand extends BaseCommand
->setDescription('Disable projects not touched during one year'); ->setDescription('Disable projects not touched during one year');
} }
protected function execute(InputInterface $input, OutputInterface $output) protected function execute(InputInterface $input, OutputInterface $output): int
{ {
$projects = $this->db->table(ProjectModel::TABLE) $projects = $this->db->table(ProjectModel::TABLE)
->eq('is_active', 1) ->eq('is_active', 1)
@ -26,5 +26,6 @@ class ProjectArchiveCommand extends BaseCommand
$output->writeln('Deactivating project: #'.$project['id'].' - '.$project['name']); $output->writeln('Deactivating project: #'.$project['id'].' - '.$project['name']);
$this->projectModel->disable($project['id']); $this->projectModel->disable($project['id']);
} }
return 0;
} }
} }

View File

@ -19,7 +19,7 @@ class ProjectDailyColumnStatsExportCommand extends BaseCommand
->addArgument('end_date', InputArgument::REQUIRED, 'End date (YYYY-MM-DD)'); ->addArgument('end_date', InputArgument::REQUIRED, 'End date (YYYY-MM-DD)');
} }
protected function execute(InputInterface $input, OutputInterface $output) protected function execute(InputInterface $input, OutputInterface $output): int
{ {
$data = $this->projectDailyColumnStatsModel->getAggregatedMetrics( $data = $this->projectDailyColumnStatsModel->getAggregatedMetrics(
$input->getArgument('project_id'), $input->getArgument('project_id'),
@ -30,5 +30,6 @@ class ProjectDailyColumnStatsExportCommand extends BaseCommand
if (is_array($data)) { if (is_array($data)) {
Csv::output($data); Csv::output($data);
} }
return 0;
} }
} }

View File

@ -15,7 +15,7 @@ class ProjectDailyStatsCalculationCommand extends BaseCommand
->setDescription('Calculate daily statistics for all projects'); ->setDescription('Calculate daily statistics for all projects');
} }
protected function execute(InputInterface $input, OutputInterface $output) protected function execute(InputInterface $input, OutputInterface $output): int
{ {
$projects = $this->projectModel->getAllByStatus(ProjectModel::ACTIVE); $projects = $this->projectModel->getAllByStatus(ProjectModel::ACTIVE);
@ -24,5 +24,6 @@ class ProjectDailyStatsCalculationCommand extends BaseCommand
$this->projectDailyColumnStatsModel->updateTotals($project['id'], date('Y-m-d')); $this->projectDailyColumnStatsModel->updateTotals($project['id'], date('Y-m-d'));
$this->projectDailyStatsModel->updateTotals($project['id'], date('Y-m-d')); $this->projectDailyStatsModel->updateTotals($project['id'], date('Y-m-d'));
} }
return 0;
} }
} }

View File

@ -18,7 +18,7 @@ class ResetPasswordCommand extends BaseCommand
; ;
} }
protected function execute(InputInterface $input, OutputInterface $output) protected function execute(InputInterface $input, OutputInterface $output): int
{ {
$helper = $this->getHelper('question'); $helper = $this->getHelper('question');
$username = $input->getArgument('username'); $username = $input->getArgument('username');
@ -38,6 +38,7 @@ class ResetPasswordCommand extends BaseCommand
if ($this->validatePassword($output, $password, $confirmation)) { if ($this->validatePassword($output, $password, $confirmation)) {
$this->resetPassword($output, $username, $password); $this->resetPassword($output, $username, $password);
} }
return 0;
} }
private function validatePassword(OutputInterface $output, $password, $confirmation) private function validatePassword(OutputInterface $output, $password, $confirmation)

View File

@ -16,7 +16,7 @@ class ResetTwoFactorCommand extends BaseCommand
->addArgument('username', InputArgument::REQUIRED, 'Username'); ->addArgument('username', InputArgument::REQUIRED, 'Username');
} }
protected function execute(InputInterface $input, OutputInterface $output) protected function execute(InputInterface $input, OutputInterface $output): int
{ {
$username = $input->getArgument('username'); $username = $input->getArgument('username');
$userId = $this->userModel->getIdByUsername($username); $userId = $this->userModel->getIdByUsername($username);
@ -32,5 +32,6 @@ class ResetTwoFactorCommand extends BaseCommand
} }
$output->writeln('<info>Two-factor authentication disabled</info>'); $output->writeln('<info>Two-factor authentication disabled</info>');
return 0;
} }
} }

View File

@ -19,7 +19,7 @@ class SubtaskExportCommand extends BaseCommand
->addArgument('end_date', InputArgument::REQUIRED, 'End date (YYYY-MM-DD)'); ->addArgument('end_date', InputArgument::REQUIRED, 'End date (YYYY-MM-DD)');
} }
protected function execute(InputInterface $input, OutputInterface $output) protected function execute(InputInterface $input, OutputInterface $output): int
{ {
$data = $this->subtaskExport->export( $data = $this->subtaskExport->export(
$input->getArgument('project_id'), $input->getArgument('project_id'),
@ -30,5 +30,6 @@ class SubtaskExportCommand extends BaseCommand
if (is_array($data)) { if (is_array($data)) {
Csv::output($data); Csv::output($data);
} }
return 0;
} }
} }

View File

@ -19,7 +19,7 @@ class TaskExportCommand extends BaseCommand
->addArgument('end_date', InputArgument::REQUIRED, 'End date (YYYY-MM-DD)'); ->addArgument('end_date', InputArgument::REQUIRED, 'End date (YYYY-MM-DD)');
} }
protected function execute(InputInterface $input, OutputInterface $output) protected function execute(InputInterface $input, OutputInterface $output): int
{ {
$data = $this->taskExport->export( $data = $this->taskExport->export(
$input->getArgument('project_id'), $input->getArgument('project_id'),
@ -30,5 +30,6 @@ class TaskExportCommand extends BaseCommand
if (is_array($data)) { if (is_array($data)) {
Csv::output($data); Csv::output($data);
} }
return 0;
} }
} }

View File

@ -24,7 +24,7 @@ class TaskOverdueNotificationCommand extends BaseCommand
; ;
} }
protected function execute(InputInterface $input, OutputInterface $output) protected function execute(InputInterface $input, OutputInterface $output): int
{ {
if ($input->getOption('project')) { if ($input->getOption('project')) {
$tasks = $this->taskFinderModel->getOverdueTasksQuery() $tasks = $this->taskFinderModel->getOverdueTasksQuery()
@ -48,6 +48,7 @@ class TaskOverdueNotificationCommand extends BaseCommand
if ($input->getOption('show')) { if ($input->getOption('show')) {
$this->showTable($output, $tasks); $this->showTable($output, $tasks);
} }
return 0;
} }
public function showTable(OutputInterface $output, array $tasks) public function showTable(OutputInterface $output, array $tasks)

View File

@ -16,7 +16,7 @@ class TaskTriggerCommand extends BaseCommand
->setDescription('Trigger scheduler event for all tasks'); ->setDescription('Trigger scheduler event for all tasks');
} }
protected function execute(InputInterface $input, OutputInterface $output) protected function execute(InputInterface $input, OutputInterface $output): int
{ {
foreach ($this->getProjectIds() as $project_id) { foreach ($this->getProjectIds() as $project_id) {
$tasks = $this->taskFinderModel->getAll($project_id); $tasks = $this->taskFinderModel->getAll($project_id);
@ -27,6 +27,7 @@ class TaskTriggerCommand extends BaseCommand
$this->sendEvent($tasks, $project_id); $this->sendEvent($tasks, $project_id);
} }
} }
return 0;
} }
private function getProjectIds() private function getProjectIds()

View File

@ -19,7 +19,7 @@ class TransitionExportCommand extends BaseCommand
->addArgument('end_date', InputArgument::REQUIRED, 'End date (YYYY-MM-DD)'); ->addArgument('end_date', InputArgument::REQUIRED, 'End date (YYYY-MM-DD)');
} }
protected function execute(InputInterface $input, OutputInterface $output) protected function execute(InputInterface $input, OutputInterface $output): int
{ {
$data = $this->transitionExport->export( $data = $this->transitionExport->export(
$input->getArgument('project_id'), $input->getArgument('project_id'),
@ -30,5 +30,6 @@ class TransitionExportCommand extends BaseCommand
if (is_array($data)) { if (is_array($data)) {
Csv::output($data); Csv::output($data);
} }
return 0;
} }
} }

View File

@ -21,8 +21,9 @@ class VersionCommand extends BaseCommand
; ;
} }
protected function execute(InputInterface $input, OutputInterface $output) protected function execute(InputInterface $input, OutputInterface $output): int
{ {
$output->writeln(APP_VERSION); $output->writeln(APP_VERSION);
return 0;
} }
} }

View File

@ -21,8 +21,9 @@ class WorkerCommand extends BaseCommand
; ;
} }
protected function execute(InputInterface $input, OutputInterface $output) protected function execute(InputInterface $input, OutputInterface $output): int
{ {
$this->queueManager->listen(); $this->queueManager->listen();
return 0;
} }
} }

View File

@ -97,7 +97,7 @@ class AuthenticationManager extends Base
{ {
foreach ($this->filterProviders('PreAuthenticationProviderInterface') as $provider) { foreach ($this->filterProviders('PreAuthenticationProviderInterface') as $provider) {
if ($provider->authenticate() && $this->userProfile->initialize($provider->getUser())) { if ($provider->authenticate() && $this->userProfile->initialize($provider->getUser())) {
$this->dispatcher->dispatch(self::EVENT_SUCCESS, new AuthSuccessEvent($provider->getName())); $this->dispatcher->dispatch(new AuthSuccessEvent($provider->getName()), self::EVENT_SUCCESS);
return true; return true;
} }
} }
@ -122,7 +122,7 @@ class AuthenticationManager extends Base
if ($provider->authenticate() && $this->userProfile->initialize($provider->getUser())) { if ($provider->authenticate() && $this->userProfile->initialize($provider->getUser())) {
if ($fireEvent) { if ($fireEvent) {
$this->dispatcher->dispatch(self::EVENT_SUCCESS, new AuthSuccessEvent($provider->getName())); $this->dispatcher->dispatch(new AuthSuccessEvent($provider->getName()), self::EVENT_SUCCESS);
} }
return true; return true;
@ -130,7 +130,7 @@ class AuthenticationManager extends Base
} }
if ($fireEvent) { if ($fireEvent) {
$this->dispatcher->dispatch(self::EVENT_FAILURE, new AuthFailureEvent($username)); $this->dispatcher->dispatch(new AuthFailureEvent($username), self::EVENT_FAILURE);
} }
return false; return false;
@ -148,11 +148,11 @@ class AuthenticationManager extends Base
$provider = $this->getProvider($name); $provider = $this->getProvider($name);
if ($provider->authenticate() && $this->userProfile->initialize($provider->getUser())) { if ($provider->authenticate() && $this->userProfile->initialize($provider->getUser())) {
$this->dispatcher->dispatch(self::EVENT_SUCCESS, new AuthSuccessEvent($provider->getName())); $this->dispatcher->dispatch(new AuthSuccessEvent($provider->getName()), self::EVENT_SUCCESS);
return true; return true;
} }
$this->dispatcher->dispatch(self::EVENT_FAILURE, new AuthFailureEvent); $this->dispatcher->dispatch(new AuthFailureEvent, self::EVENT_FAILURE);
return false; return false;
} }

View File

@ -59,7 +59,7 @@ class UserProfile extends Base
if (! empty($profile) && $profile['is_active'] == 1) { if (! empty($profile) && $profile['is_active'] == 1) {
$this->userSession->initialize($profile); $this->userSession->initialize($profile);
$this->dispatcher->dispatch(self::EVENT_USER_PROFILE_AFTER_SYNC, new UserProfileSyncEvent($profile, $user)); $this->dispatcher->dispatch(new UserProfileSyncEvent($profile, $user), self::EVENT_USER_PROFILE_AFTER_SYNC);
return true; return true;
} }

View File

@ -2,7 +2,7 @@
namespace Kanboard\Event; namespace Kanboard\Event;
use Symfony\Component\EventDispatcher\Event as BaseEvent; use Symfony\Contracts\EventDispatcher\Event as BaseEvent;
/** /**
* Authentication Failure Event * Authentication Failure Event

View File

@ -2,7 +2,7 @@
namespace Kanboard\Event; namespace Kanboard\Event;
use Symfony\Component\EventDispatcher\Event as BaseEvent; use Symfony\Contracts\EventDispatcher\Event as BaseEvent;
/** /**
* Authentication Success Event * Authentication Success Event

View File

@ -3,7 +3,7 @@
namespace Kanboard\Event; namespace Kanboard\Event;
use ArrayAccess; use ArrayAccess;
use Symfony\Component\EventDispatcher\Event as BaseEvent; use Symfony\Contracts\EventDispatcher\Event as BaseEvent;
class GenericEvent extends BaseEvent implements ArrayAccess class GenericEvent extends BaseEvent implements ArrayAccess
{ {

View File

@ -4,7 +4,7 @@ namespace Kanboard\Event;
use Kanboard\Core\User\UserProviderInterface; use Kanboard\Core\User\UserProviderInterface;
use Kanboard\User\LdapUserProvider; use Kanboard\User\LdapUserProvider;
use Symfony\Component\EventDispatcher\Event; use Symfony\Contracts\EventDispatcher\Event;
/** /**
* Class UserProfileSyncEvent * Class UserProfileSyncEvent

View File

@ -39,7 +39,7 @@ class CommentEventJob extends BaseJob
->buildEvent(); ->buildEvent();
if ($event !== null) { if ($event !== null) {
$this->dispatcher->dispatch($eventName, $event); $this->dispatcher->dispatch($event, $eventName);
if ($eventName === CommentModel::EVENT_CREATE) { if ($eventName === CommentModel::EVENT_CREATE) {
$userMentionJob = $this->userMentionJob->withParams($event['comment']['comment'], CommentModel::EVENT_USER_MENTION, $event); $userMentionJob = $this->userMentionJob->withParams($event['comment']['comment'], CommentModel::EVENT_USER_MENTION, $event);

View File

@ -38,7 +38,7 @@ class ProjectFileEventJob extends BaseJob
->buildEvent(); ->buildEvent();
if ($event !== null) { if ($event !== null) {
$this->dispatcher->dispatch($eventName, $event); $this->dispatcher->dispatch($event, $eventName);
} }
} }
} }

View File

@ -42,7 +42,7 @@ class SubtaskEventJob extends BaseJob
if ($event !== null) { if ($event !== null) {
foreach ($eventNames as $eventName) { foreach ($eventNames as $eventName) {
$this->dispatcher->dispatch($eventName, $event); $this->dispatcher->dispatch($event, $eventName);
} }
} }
} }

View File

@ -65,7 +65,7 @@ class TaskEventJob extends BaseJob
protected function fireEvent($eventName, TaskEvent $event) protected function fireEvent($eventName, TaskEvent $event)
{ {
$this->logger->debug(__METHOD__.' Event fired: '.$eventName); $this->logger->debug(__METHOD__.' Event fired: '.$eventName);
$this->dispatcher->dispatch($eventName, $event); $this->dispatcher->dispatch($event, $eventName);
if ($eventName === TaskModel::EVENT_CREATE) { if ($eventName === TaskModel::EVENT_CREATE) {
$userMentionJob = $this->userMentionJob->withParams($event['task']['description'], TaskModel::EVENT_USER_MENTION, $event); $userMentionJob = $this->userMentionJob->withParams($event['task']['description'], TaskModel::EVENT_USER_MENTION, $event);

View File

@ -38,7 +38,7 @@ class TaskFileEventJob extends BaseJob
->buildEvent(); ->buildEvent();
if ($event !== null) { if ($event !== null) {
$this->dispatcher->dispatch($eventName, $event); $this->dispatcher->dispatch($event, $eventName);
} }
} }
} }

View File

@ -38,7 +38,7 @@ class TaskLinkEventJob extends BaseJob
->buildEvent(); ->buildEvent();
if ($event !== null) { if ($event !== null) {
$this->dispatcher->dispatch($eventName, $event); $this->dispatcher->dispatch($event, $eventName);
} }
} }
} }

View File

@ -42,7 +42,7 @@ class UserMentionJob extends BaseJob
foreach ($users as $user) { foreach ($users as $user) {
if ($this->projectPermissionModel->isMember($event->getProjectId(), $user['id'])) { if ($this->projectPermissionModel->isMember($event->getProjectId(), $user['id'])) {
$event['mention'] = $user; $event['mention'] = $user;
$this->dispatcher->dispatch($eventName, $event); $this->dispatcher->dispatch($event, $eventName);
} }
} }
} }

View File

@ -3,6 +3,7 @@
namespace Kanboard\Middleware; namespace Kanboard\Middleware;
use Kanboard\Core\Controller\BaseMiddleware; use Kanboard\Core\Controller\BaseMiddleware;
use Symfony\Contracts\EventDispatcher\Event;
/** /**
* Class BootstrapMiddleware * Class BootstrapMiddleware
@ -18,7 +19,7 @@ class BootstrapMiddleware extends BaseMiddleware
public function execute() public function execute()
{ {
$this->sessionManager->open(); $this->sessionManager->open();
$this->dispatcher->dispatch('app.bootstrap'); $this->dispatcher->dispatch(new Event, 'app.bootstrap');
$this->sendHeaders(); $this->sendHeaders();
$this->next(); $this->next();
} }

4
cli
View File

@ -2,7 +2,7 @@
<?php <?php
use Symfony\Component\Console\Input\ArgvInput; use Symfony\Component\Console\Input\ArgvInput;
use Symfony\Component\EventDispatcher\Event; use Symfony\Contracts\EventDispatcher\Event;
if (php_sapi_name() !== 'cli') { if (php_sapi_name() !== 'cli') {
echo 'This script run only from the command line'.PHP_EOL; echo 'This script run only from the command line'.PHP_EOL;
@ -15,7 +15,7 @@ try {
$input = new ArgvInput(); $input = new ArgvInput();
if (! in_array($input->getFirstArgument(), ['db:migrate', 'db:version'])) { if (! in_array($input->getFirstArgument(), ['db:migrate', 'db:version'])) {
$container['dispatcher']->dispatch('app.bootstrap', new Event); $container['dispatcher']->dispatch(new Event, 'app.bootstrap');
} }
$container['cli']->run($input); $container['cli']->run($input);

View File

@ -30,8 +30,8 @@
"erusev/parsedown": "1.7.4", "erusev/parsedown": "1.7.4",
"pimple/pimple": "3.5.0", "pimple/pimple": "3.5.0",
"psr/log": "1.1.4", "psr/log": "1.1.4",
"symfony/console": "4.4.37", "symfony/console": "5.4.21",
"symfony/event-dispatcher": "4.4.37", "symfony/event-dispatcher": "5.4.21",
"symfony/finder": "5.4.21", "symfony/finder": "5.4.21",
"symfony/service-contracts": "2.5.2", "symfony/service-contracts": "2.5.2",
"symfony/deprecation-contracts": "2.5.2" "symfony/deprecation-contracts": "2.5.2"

486
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "eafa043aaba47ff79aa1646b8398bb65", "content-hash": "760929e9c58804e49b4aa92d3cce7b82",
"packages": [ "packages": [
{ {
"name": "christian-riesen/base32", "name": "christian-riesen/base32",
@ -271,6 +271,56 @@
}, },
"time": "2021-11-05T16:50:12+00:00" "time": "2021-11-05T16:50:12+00:00"
}, },
{
"name": "psr/event-dispatcher",
"version": "1.0.0",
"source": {
"type": "git",
"url": "https://github.com/php-fig/event-dispatcher.git",
"reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0",
"reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0",
"shasum": ""
},
"require": {
"php": ">=7.2.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\EventDispatcher\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "http://www.php-fig.org/"
}
],
"description": "Standard interfaces for event handling.",
"keywords": [
"events",
"psr",
"psr-14"
],
"support": {
"issues": "https://github.com/php-fig/event-dispatcher/issues",
"source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0"
},
"time": "2019-01-08T18:20:26+00:00"
},
{ {
"name": "psr/log", "name": "psr/log",
"version": "1.1.4", "version": "1.1.4",
@ -323,43 +373,46 @@
}, },
{ {
"name": "symfony/console", "name": "symfony/console",
"version": "v4.4.37", "version": "v5.4.21",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/console.git", "url": "https://github.com/symfony/console.git",
"reference": "0259f01dbf9d77badddbbf4c2abb681f24c9cac6" "reference": "c77433ddc6cdc689caf48065d9ea22ca0853fbd9"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/console/zipball/0259f01dbf9d77badddbbf4c2abb681f24c9cac6", "url": "https://api.github.com/repos/symfony/console/zipball/c77433ddc6cdc689caf48065d9ea22ca0853fbd9",
"reference": "0259f01dbf9d77badddbbf4c2abb681f24c9cac6", "reference": "c77433ddc6cdc689caf48065d9ea22ca0853fbd9",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": ">=7.1.3", "php": ">=7.2.5",
"symfony/deprecation-contracts": "^2.1|^3",
"symfony/polyfill-mbstring": "~1.0", "symfony/polyfill-mbstring": "~1.0",
"symfony/polyfill-php73": "^1.8", "symfony/polyfill-php73": "^1.9",
"symfony/polyfill-php80": "^1.16", "symfony/polyfill-php80": "^1.16",
"symfony/service-contracts": "^1.1|^2" "symfony/service-contracts": "^1.1|^2|^3",
"symfony/string": "^5.1|^6.0"
}, },
"conflict": { "conflict": {
"psr/log": ">=3", "psr/log": ">=3",
"symfony/dependency-injection": "<3.4", "symfony/dependency-injection": "<4.4",
"symfony/event-dispatcher": "<4.3|>=5", "symfony/dotenv": "<5.1",
"symfony/event-dispatcher": "<4.4",
"symfony/lock": "<4.4", "symfony/lock": "<4.4",
"symfony/process": "<3.3" "symfony/process": "<4.4"
}, },
"provide": { "provide": {
"psr/log-implementation": "1.0|2.0" "psr/log-implementation": "1.0|2.0"
}, },
"require-dev": { "require-dev": {
"psr/log": "^1|^2", "psr/log": "^1|^2",
"symfony/config": "^3.4|^4.0|^5.0", "symfony/config": "^4.4|^5.0|^6.0",
"symfony/dependency-injection": "^3.4|^4.0|^5.0", "symfony/dependency-injection": "^4.4|^5.0|^6.0",
"symfony/event-dispatcher": "^4.3", "symfony/event-dispatcher": "^4.4|^5.0|^6.0",
"symfony/lock": "^4.4|^5.0", "symfony/lock": "^4.4|^5.0|^6.0",
"symfony/process": "^3.4|^4.0|^5.0", "symfony/process": "^4.4|^5.0|^6.0",
"symfony/var-dumper": "^4.3|^5.0" "symfony/var-dumper": "^4.4|^5.0|^6.0"
}, },
"suggest": { "suggest": {
"psr/log": "For using the console logger", "psr/log": "For using the console logger",
@ -392,8 +445,14 @@
], ],
"description": "Eases the creation of beautiful and testable command line interfaces", "description": "Eases the creation of beautiful and testable command line interfaces",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"keywords": [
"cli",
"command line",
"console",
"terminal"
],
"support": { "support": {
"source": "https://github.com/symfony/console/tree/v4.4.37" "source": "https://github.com/symfony/console/tree/v5.4.21"
}, },
"funding": [ "funding": [
{ {
@ -409,7 +468,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2022-01-26T16:15:26+00:00" "time": "2023-02-25T16:59:41+00:00"
}, },
{ {
"name": "symfony/deprecation-contracts", "name": "symfony/deprecation-contracts",
@ -480,39 +539,40 @@
}, },
{ {
"name": "symfony/event-dispatcher", "name": "symfony/event-dispatcher",
"version": "v4.4.37", "version": "v5.4.21",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/event-dispatcher.git", "url": "https://github.com/symfony/event-dispatcher.git",
"reference": "3ccfcfb96ecce1217d7b0875a0736976bc6e63dc" "reference": "f0ae1383a8285dfc6752b8d8602790953118ff5a"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/3ccfcfb96ecce1217d7b0875a0736976bc6e63dc", "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/f0ae1383a8285dfc6752b8d8602790953118ff5a",
"reference": "3ccfcfb96ecce1217d7b0875a0736976bc6e63dc", "reference": "f0ae1383a8285dfc6752b8d8602790953118ff5a",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": ">=7.1.3", "php": ">=7.2.5",
"symfony/event-dispatcher-contracts": "^1.1", "symfony/deprecation-contracts": "^2.1|^3",
"symfony/event-dispatcher-contracts": "^2|^3",
"symfony/polyfill-php80": "^1.16" "symfony/polyfill-php80": "^1.16"
}, },
"conflict": { "conflict": {
"symfony/dependency-injection": "<3.4" "symfony/dependency-injection": "<4.4"
}, },
"provide": { "provide": {
"psr/event-dispatcher-implementation": "1.0", "psr/event-dispatcher-implementation": "1.0",
"symfony/event-dispatcher-implementation": "1.1" "symfony/event-dispatcher-implementation": "2.0"
}, },
"require-dev": { "require-dev": {
"psr/log": "^1|^2|^3", "psr/log": "^1|^2|^3",
"symfony/config": "^3.4|^4.0|^5.0", "symfony/config": "^4.4|^5.0|^6.0",
"symfony/dependency-injection": "^3.4|^4.0|^5.0", "symfony/dependency-injection": "^4.4|^5.0|^6.0",
"symfony/error-handler": "~3.4|~4.4", "symfony/error-handler": "^4.4|^5.0|^6.0",
"symfony/expression-language": "^3.4|^4.0|^5.0", "symfony/expression-language": "^4.4|^5.0|^6.0",
"symfony/http-foundation": "^3.4|^4.0|^5.0", "symfony/http-foundation": "^4.4|^5.0|^6.0",
"symfony/service-contracts": "^1.1|^2", "symfony/service-contracts": "^1.1|^2|^3",
"symfony/stopwatch": "^3.4|^4.0|^5.0" "symfony/stopwatch": "^4.4|^5.0|^6.0"
}, },
"suggest": { "suggest": {
"symfony/dependency-injection": "", "symfony/dependency-injection": "",
@ -544,7 +604,7 @@
"description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"support": { "support": {
"source": "https://github.com/symfony/event-dispatcher/tree/v4.4.37" "source": "https://github.com/symfony/event-dispatcher/tree/v5.4.21"
}, },
"funding": [ "funding": [
{ {
@ -560,33 +620,30 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2022-01-02T09:41:36+00:00" "time": "2023-02-14T08:03:56+00:00"
}, },
{ {
"name": "symfony/event-dispatcher-contracts", "name": "symfony/event-dispatcher-contracts",
"version": "v1.1.13", "version": "v3.3.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/event-dispatcher-contracts.git", "url": "https://github.com/symfony/event-dispatcher-contracts.git",
"reference": "1d5cd762abaa6b2a4169d3e77610193a7157129e" "reference": "a76aed96a42d2b521153fb382d418e30d18b59df"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/1d5cd762abaa6b2a4169d3e77610193a7157129e", "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/a76aed96a42d2b521153fb382d418e30d18b59df",
"reference": "1d5cd762abaa6b2a4169d3e77610193a7157129e", "reference": "a76aed96a42d2b521153fb382d418e30d18b59df",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": ">=7.1.3" "php": ">=8.1",
}, "psr/event-dispatcher": "^1"
"suggest": {
"psr/event-dispatcher": "",
"symfony/event-dispatcher-implementation": ""
}, },
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-main": "1.1-dev" "dev-main": "3.4-dev"
}, },
"thanks": { "thanks": {
"name": "symfony/contracts", "name": "symfony/contracts",
@ -623,7 +680,7 @@
"standards" "standards"
], ],
"support": { "support": {
"source": "https://github.com/symfony/event-dispatcher-contracts/tree/v1.1.13" "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.3.0"
}, },
"funding": [ "funding": [
{ {
@ -639,7 +696,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2022-01-02T09:41:36+00:00" "time": "2023-05-23T14:45:45+00:00"
}, },
{ {
"name": "symfony/finder", "name": "symfony/finder",
@ -704,6 +761,253 @@
], ],
"time": "2023-02-16T09:33:00+00:00" "time": "2023-02-16T09:33:00+00:00"
}, },
{
"name": "symfony/polyfill-ctype",
"version": "v1.27.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-ctype.git",
"reference": "5bbc823adecdae860bb64756d639ecfec17b050a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/5bbc823adecdae860bb64756d639ecfec17b050a",
"reference": "5bbc823adecdae860bb64756d639ecfec17b050a",
"shasum": ""
},
"require": {
"php": ">=7.1"
},
"provide": {
"ext-ctype": "*"
},
"suggest": {
"ext-ctype": "For best performance"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.27-dev"
},
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
}
},
"autoload": {
"files": [
"bootstrap.php"
],
"psr-4": {
"Symfony\\Polyfill\\Ctype\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Gert de Pagter",
"email": "BackEndTea@gmail.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill for ctype functions",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"ctype",
"polyfill",
"portable"
],
"support": {
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.27.0"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2022-11-03T14:55:06+00:00"
},
{
"name": "symfony/polyfill-intl-grapheme",
"version": "v1.27.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-grapheme.git",
"reference": "511a08c03c1960e08a883f4cffcacd219b758354"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/511a08c03c1960e08a883f4cffcacd219b758354",
"reference": "511a08c03c1960e08a883f4cffcacd219b758354",
"shasum": ""
},
"require": {
"php": ">=7.1"
},
"suggest": {
"ext-intl": "For best performance"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.27-dev"
},
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
}
},
"autoload": {
"files": [
"bootstrap.php"
],
"psr-4": {
"Symfony\\Polyfill\\Intl\\Grapheme\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill for intl's grapheme_* functions",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"grapheme",
"intl",
"polyfill",
"portable",
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.27.0"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2022-11-03T14:55:06+00:00"
},
{
"name": "symfony/polyfill-intl-normalizer",
"version": "v1.27.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-normalizer.git",
"reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/19bd1e4fcd5b91116f14d8533c57831ed00571b6",
"reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6",
"shasum": ""
},
"require": {
"php": ">=7.1"
},
"suggest": {
"ext-intl": "For best performance"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.27-dev"
},
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
}
},
"autoload": {
"files": [
"bootstrap.php"
],
"psr-4": {
"Symfony\\Polyfill\\Intl\\Normalizer\\": ""
},
"classmap": [
"Resources/stubs"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill for intl's Normalizer class and related functions",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"intl",
"normalizer",
"polyfill",
"portable",
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.27.0"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2022-11-03T14:55:06+00:00"
},
{ {
"name": "symfony/polyfill-mbstring", "name": "symfony/polyfill-mbstring",
"version": "v1.27.0", "version": "v1.27.0",
@ -1031,6 +1335,92 @@
} }
], ],
"time": "2022-05-30T19:17:29+00:00" "time": "2022-05-30T19:17:29+00:00"
},
{
"name": "symfony/string",
"version": "v6.3.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/string.git",
"reference": "f2e190ee75ff0f5eced645ec0be5c66fac81f51f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/string/zipball/f2e190ee75ff0f5eced645ec0be5c66fac81f51f",
"reference": "f2e190ee75ff0f5eced645ec0be5c66fac81f51f",
"shasum": ""
},
"require": {
"php": ">=8.1",
"symfony/polyfill-ctype": "~1.8",
"symfony/polyfill-intl-grapheme": "~1.0",
"symfony/polyfill-intl-normalizer": "~1.0",
"symfony/polyfill-mbstring": "~1.0"
},
"conflict": {
"symfony/translation-contracts": "<2.5"
},
"require-dev": {
"symfony/error-handler": "^5.4|^6.0",
"symfony/http-client": "^5.4|^6.0",
"symfony/intl": "^6.2",
"symfony/translation-contracts": "^2.5|^3.0",
"symfony/var-exporter": "^5.4|^6.0"
},
"type": "library",
"autoload": {
"files": [
"Resources/functions.php"
],
"psr-4": {
"Symfony\\Component\\String\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way",
"homepage": "https://symfony.com",
"keywords": [
"grapheme",
"i18n",
"string",
"unicode",
"utf-8",
"utf8"
],
"support": {
"source": "https://github.com/symfony/string/tree/v6.3.0"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2023-03-21T21:06:29+00:00"
} }
], ],
"packages-dev": [ "packages-dev": [