diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b7886d1e..e583db4e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,7 +9,7 @@ jobs: strategy: matrix: operating-system: ['ubuntu-latest'] - php-versions: ['5.5', '5.6', '7.0', '7.1', '7.2', '7.3', '7.4', '8.0'] + php-versions: ['7.2', '7.3', '7.4', '8.0', '8.1'] phpunit-versions: ['latest'] steps: - name: Checkout diff --git a/.gitignore b/.gitignore index 8fc16d75..498d6c99 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ composer.lock phpunit.xml .phpunit +.phpunit.* vendor .php_cs.cache .php_cs diff --git a/Command/MongoDBMigrateMetadataCommand.php b/Command/MongoDBMigrateMetadataCommand.php index 3bd6689d..d5e399cf 100644 --- a/Command/MongoDBMigrateMetadataCommand.php +++ b/Command/MongoDBMigrateMetadataCommand.php @@ -66,7 +66,7 @@ protected function configure() fields to a new schema optimized for MongoDB queries. This command requires the participant class to be provided as its first and only parameter: - php app/console fos:message:mongodb:migrate:metadata "Acme\Document\User" + php bin/console fos:message:mongodb:migrate:metadata "Acme\Document\User" The following hash fields will become obsolete after migration: @@ -104,15 +104,15 @@ protected function initialize(InputInterface $input, OutputInterface $output) $this->threadCollection = $this->getMongoCollectionForClass($registry, $this->getContainer()->getParameter('fos_message.thread_class')); $this->participantCollection = $this->getMongoCollectionForClass($registry, $input->getArgument('participantClass')); - $this->updateOptions = array( + $this->updateOptions = [ 'multiple' => false, 'safe' => $input->getOption('safe'), - 'fsync' => $input->getOption('fsync'), - ); + 'fsync' => $input->getOption('fsync') + ]; $this->printStatusCallback = function () { }; - register_tick_function(array($this, 'printStatus')); + register_tick_function([$this, 'printStatus']); } /** @@ -124,7 +124,7 @@ protected function execute(InputInterface $input, OutputInterface $output) $this->migrateThreads($output); $size = memory_get_peak_usage(true); - $unit = array('b', 'k', 'm', 'g', 't', 'p'); + $unit = ['b', 'k', 'm', 'g', 't', 'p']; $output->writeln(sprintf('Peak Memory Usage: %s', round($size / pow(1024, $i = floor(log($size, 1024))), 2).$unit[$i])); } @@ -134,11 +134,8 @@ protected function execute(InputInterface $input, OutputInterface $output) private function migrateMessages(OutputInterface $output) { $cursor = $this->messageCollection->find( - array('metadata' => array('$exists' => false)), - array( - 'isReadByParticipant' => 1, - 'isSpam' => 1, - ) + ['metadata' => ['$exists' => false]], + ['isReadByParticipant' => 1, 'isSpam' => 1] ); $cursor->snapshot(); @@ -160,11 +157,11 @@ private function migrateMessages(OutputInterface $output) $this->createMessageUnreadForParticipants($message); $this->messageCollection->update( - array('_id' => $message['_id']), - array('$set' => array( + ['_id' => $message['_id']], + ['$set' => [ 'metadata' => $message['metadata'], - 'unreadForParticipants' => $message['unreadForParticipants'], - )), + 'unreadForParticipants' => $message['unreadForParticipants'] + ]], $this->updateOptions ); ++$numProcessed; @@ -181,15 +178,15 @@ private function migrateMessages(OutputInterface $output) private function migrateThreads(OutputInterface $output) { $cursor = $this->threadCollection->find( - array('metadata' => array('$exists' => false)), - array( + ['metadata' => ['$exists' => false]], + [ 'datesOfLastMessageWrittenByOtherParticipant' => 1, 'datesOfLastMessageWrittenByParticipant' => 1, 'isDeletedByParticipant' => 1, 'isSpam' => 1, 'messages' => 1, - 'participants' => 1, - ) + 'participants' => 1 + ] ); $numProcessed = 0; @@ -211,14 +208,14 @@ private function migrateThreads(OutputInterface $output) $this->createThreadActiveParticipantArrays($thread); $this->threadCollection->update( - array('_id' => $thread['_id']), - array('$set' => array( + ['_id' => $thread['_id']], + ['$set' => [ 'activeParticipants' => $thread['activeParticipants'], 'activeRecipients' => $thread['activeRecipients'], 'activeSenders' => $thread['activeSenders'], 'lastMessageDate' => $thread['lastMessageDate'], - 'metadata' => $thread['metadata'], - )), + 'metadata' => $thread['metadata'] + ]], $this->updateOptions ); ++$numProcessed; @@ -237,13 +234,13 @@ private function migrateThreads(OutputInterface $output) */ private function createMessageMetadata(array &$message) { - $metadata = array(); + $metadata = []; foreach ($message['isReadByParticipant'] as $participantId => $isRead) { - $metadata[] = array( + $metadata[] = [ 'isRead' => $isRead, - 'participant' => $this->participantCollection->createDBRef(array('_id' => new \MongoId($participantId))) + array('$db' => (string) $this->participantCollection->db), - ); + 'participant' => $this->participantCollection->createDBRef(['_id' => new \MongoId($participantId)]) + ['$db' => (string) $this->participantCollection->db] + ]; } $message['metadata'] = $metadata; @@ -258,7 +255,7 @@ private function createMessageMetadata(array &$message) */ private function createMessageUnreadForParticipants(array &$message) { - $unreadForParticipants = array(); + $unreadForParticipants = []; if (!$message['isSpam']) { foreach ($message['metadata'] as $metadata) { @@ -281,15 +278,12 @@ private function createMessageUnreadForParticipants(array &$message) */ private function createThreadMetadata(array &$thread) { - $metadata = array(); + $metadata = []; $participantIds = array_keys($thread['datesOfLastMessageWrittenByOtherParticipant'] + $thread['datesOfLastMessageWrittenByParticipant'] + $thread['isDeletedByParticipant']); foreach ($participantIds as $participantId) { - $meta = array( - 'isDeleted' => false, - 'participant' => $this->participantCollection->createDBRef(array('_id' => new \MongoId($participantId))) + array('$db' => (string) $this->participantCollection->db), - ); + $meta = ['isDeleted' => false, 'participant' => $this->participantCollection->createDBRef(['_id' => new \MongoId($participantId)]) + ['$db' => (string) $this->participantCollection->db]]; if (isset($thread['isDeletedByParticipant'][$participantId])) { $meta['isDeleted'] = $thread['isDeletedByParticipant'][$participantId]; @@ -320,8 +314,8 @@ private function createThreadLastMessageDate(array &$thread) if (false !== $lastMessageRef) { $lastMessage = $this->messageCollection->findOne( - array('_id' => $lastMessageRef['$id']), - array('createdAt' => 1) + ['_id' => $lastMessageRef['$id']], + ['createdAt' => 1] ); } @@ -337,9 +331,9 @@ private function createThreadLastMessageDate(array &$thread) */ private function createThreadActiveParticipantArrays(array &$thread) { - $activeParticipants = array(); - $activeRecipients = array(); - $activeSenders = array(); + $activeParticipants = []; + $activeRecipients = []; + $activeSenders = []; foreach ($thread['participants'] as $participantRef) { foreach ($thread['metadata'] as $metadata) { diff --git a/Controller/MessageController.php b/Controller/MessageController.php index 9fdcfbbc..ac582334 100644 --- a/Controller/MessageController.php +++ b/Controller/MessageController.php @@ -2,23 +2,85 @@ namespace FOS\MessageBundle\Controller; +use FOS\MessageBundle\Deleter\DeleterInterface; +use FOS\MessageBundle\FormFactory\FactoryInterface; +use FOS\MessageBundle\FormHandler\FormHandlerInterface; +use FOS\MessageBundle\ModelManager\ThreadManagerInterface; use FOS\MessageBundle\Provider\ProviderInterface; +use FOS\MessageBundle\Search\FinderInterface; +use FOS\MessageBundle\Search\QueryFactoryInterface; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\DependencyInjection\ContainerInterface; class MessageController extends AbstractController { - public function __construct(ContainerInterface $container) - { - $this->setContainer($container); - } + /** + * @var ProviderInterface + */ + protected $provider; /** - * @var ContainerInterface + * @var FactoryInterface */ - protected $container; + protected $replyFormfactory; + + /** + * @var FormHandlerInterface + */ + protected $replyFormHandler; + + /** + * @var FactoryInterface + */ + protected $newThreadFormFactory; + + /** + * @var FormHandlerInterface + */ + protected $newThreadFormHandler; + + /** + * @var DeleterInterface + */ + protected $deleter; + + /** + * @var ThreadManagerInterface + */ + protected $threadManager; + + /** + * @var QueryFactoryInterface + */ + protected $queryFactory; + + /** + * @var FinderInterface + */ + protected $finder; + + public function __construct( + ProviderInterface $provider, + FactoryInterface $replyFormfactory, + FormHandlerInterface $replyFormHandler, + FactoryInterface $newThreadFormFactory, + FormHandlerInterface $newThreadFormHandler, + DeleterInterface $deleter, + ThreadManagerInterface $threadManager, + QueryFactoryInterface $queryFactory, + FinderInterface $finder + ) { + $this->provider = $provider; + $this->replyFormfactory = $replyFormfactory; + $this->replyFormHandler = $replyFormHandler; + $this->newThreadFormFactory = $newThreadFormFactory; + $this->newThreadFormHandler = $newThreadFormHandler; + $this->deleter = $deleter; + $this->threadManager = $threadManager; + $this->queryFactory = $queryFactory; + $this->finder = $finder; + } /** * Displays the authenticated participant inbox. @@ -27,11 +89,9 @@ public function __construct(ContainerInterface $container) */ public function inboxAction() { - $threads = $this->getProvider()->getInboxThreads(); + $threads = $this->provider->getInboxThreads(); - return $this->render('@FOSMessage/Message/inbox.html.twig', array( - 'threads' => $threads, - )); + return $this->render('@FOSMessage/Message/inbox.html.twig', ['threads' => $threads]); } /** @@ -41,11 +101,9 @@ public function inboxAction() */ public function sentAction() { - $threads = $this->getProvider()->getSentThreads(); + $threads = $this->provider->getSentThreads(); - return $this->render('@FOSMessage/Message/sent.html.twig', array( - 'threads' => $threads, - )); + return $this->render('@FOSMessage/Message/sent.html.twig', ['threads' => $threads]); } /** @@ -55,11 +113,9 @@ public function sentAction() */ public function deletedAction() { - $threads = $this->getProvider()->getDeletedThreads(); + $threads = $this->provider->getDeletedThreads(); - return $this->render('@FOSMessage/Message/deleted.html.twig', array( - 'threads' => $threads, - )); + return $this->render('@FOSMessage/Message/deleted.html.twig', ['threads' => $threads]); } /** @@ -71,20 +127,17 @@ public function deletedAction() */ public function threadAction($threadId) { - $thread = $this->getProvider()->getThread($threadId); - $form = $this->container->get('fos_message.reply_form.factory')->create($thread); - $formHandler = $this->container->get('fos_message.reply_form.handler'); - - if ($message = $formHandler->process($form)) { - return new RedirectResponse($this->container->get('router')->generate('fos_message_thread_view', array( - 'threadId' => $message->getThread()->getId(), - ))); + $thread = $this->provider->getThread($threadId); + $form = $this->replyFormfactory->create($thread); + + if ($message = $this->replyFormHandler->process($form)) { + return $this->redirectToRoute('fos_message_thread_view', ['threadId' => $message->getThread()->getId()]); } - return $this->render('@FOSMessage/Message/thread.html.twig', array( + return $this->render('@FOSMessage/Message/thread.html.twig', [ 'form' => $form->createView(), - 'thread' => $thread, - )); + 'thread' => $thread + ]); } /** @@ -94,19 +147,16 @@ public function threadAction($threadId) */ public function newThreadAction() { - $form = $this->container->get('fos_message.new_thread_form.factory')->create(); - $formHandler = $this->container->get('fos_message.new_thread_form.handler'); + $form = $this->newThreadFormFactory->create(); - if ($message = $formHandler->process($form)) { - return new RedirectResponse($this->container->get('router')->generate('fos_message_thread_view', array( - 'threadId' => $message->getThread()->getId(), - ))); + if ($message = $this->newThreadFormHandler->process($form)) { + return $this->redirectToRoute('fos_message_thread_view', ['threadId' => $message->getThread()->getId()]); } - return $this->render('@FOSMessage/Message/newThread.html.twig', array( + return $this->render('@FOSMessage/Message/newThread.html.twig', [ 'form' => $form->createView(), - 'data' => $form->getData(), - )); + 'data' => $form->getData() + ]); } /** @@ -118,11 +168,11 @@ public function newThreadAction() */ public function deleteAction($threadId) { - $thread = $this->getProvider()->getThread($threadId); - $this->container->get('fos_message.deleter')->markAsDeleted($thread); - $this->container->get('fos_message.thread_manager')->saveThread($thread); + $thread = $this->provider->getThread($threadId); + $this->deleter->markAsDeleted($thread); + $this->threadManager->saveThread($thread); - return new RedirectResponse($this->container->get('router')->generate('fos_message_inbox')); + return $this->redirectToRoute('fos_message_inbox'); } /** @@ -132,13 +182,13 @@ public function deleteAction($threadId) * * @return RedirectResponse */ - public function undeleteAction($threadId) + public function undeleteAction($threadId, DeleterInterface $deleter, ThreadManagerInterface $threadManager) { - $thread = $this->getProvider()->getThread($threadId); - $this->container->get('fos_message.deleter')->markAsUndeleted($thread); - $this->container->get('fos_message.thread_manager')->saveThread($thread); + $thread = $this->provider->getThread($threadId); + $deleter->markAsUndeleted($thread); + $threadManager->saveThread($thread); - return new RedirectResponse($this->container->get('router')->generate('fos_message_inbox')); + return $this->redirectToRoute('fos_message_inbox'); } /** @@ -148,22 +198,9 @@ public function undeleteAction($threadId) */ public function searchAction() { - $query = $this->container->get('fos_message.search_query_factory')->createFromRequest(); - $threads = $this->container->get('fos_message.search_finder')->find($query); - - return $this->render('@FOSMessage/Message/search.html.twig', array( - 'query' => $query, - 'threads' => $threads, - )); - } + $query = $this->queryFactory->createFromRequest(); + $threads = $this->finder->find($query); - /** - * Gets the provider service. - * - * @return ProviderInterface - */ - protected function getProvider() - { - return $this->container->get('fos_message.provider'); + return $this->render('@FOSMessage/Message/search.html.twig', ['query' => $query, 'threads' => $threads]); } } diff --git a/DataTransformer/RecipientsDataTransformer.php b/DataTransformer/RecipientsDataTransformer.php index 02c7809d..a0242c56 100644 --- a/DataTransformer/RecipientsDataTransformer.php +++ b/DataTransformer/RecipientsDataTransformer.php @@ -33,13 +33,13 @@ public function __construct(DataTransformerInterface $userToUsernameTransformer) * * @return string */ - public function transform($recipients) + public function transform($recipients): mixed { if (null === $recipients || 0 === $recipients->count()) { return ''; } - $usernames = array(); + $usernames = []; foreach ($recipients as $recipient) { $usernames[] = $this->userToUsernameTransformer->transform($recipient); diff --git a/Deleter/Deleter.php b/Deleter/Deleter.php index b9685337..d0e8fade 100644 --- a/Deleter/Deleter.php +++ b/Deleter/Deleter.php @@ -56,7 +56,7 @@ public function markAsDeleted(ThreadInterface $thread) } $thread->setIsDeletedByParticipant($this->getAuthenticatedParticipant(), true); - $this->dispatcher->dispatch(FOSMessageEvents::POST_DELETE, new ThreadEvent($thread)); + $this->dispatcher->dispatch(new ThreadEvent($thread), FOSMessageEvents::POST_DELETE); } /** @@ -69,7 +69,7 @@ public function markAsUndeleted(ThreadInterface $thread) } $thread->setIsDeletedByParticipant($this->getAuthenticatedParticipant(), false); - $this->dispatcher->dispatch(FOSMessageEvents::POST_UNDELETE, new ThreadEvent($thread)); + $this->dispatcher->dispatch(new ThreadEvent($thread), FOSMessageEvents::POST_UNDELETE); } /** diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index bc39b192..bae5c758 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -26,7 +26,7 @@ public function getConfigTreeBuilder() $rootNode = $treeBuilder->root(self::ROOT_NAME); } - $rootNode + $treeBuilder->getRootNode() ->children() ->scalarNode('db_driver')->cannotBeOverwritten()->isRequired()->cannotBeEmpty()->end() ->scalarNode('thread_class')->isRequired()->cannotBeEmpty()->end() @@ -47,8 +47,8 @@ public function getConfigTreeBuilder() ->arrayNode('search') ->addDefaultsIfNotSet() ->children() - ->scalarNode('query_factory')->defaultValue('fos_message.search_query_factory.default')->cannotBeEmpty()->end() - ->scalarNode('finder')->defaultValue('fos_message.search_finder.default')->cannotBeEmpty()->end() + ->scalarNode('query_factory')->defaultValue('fos_message.search.query_factory.default')->cannotBeEmpty()->end() + ->scalarNode('finder')->defaultValue('fos_message.search.finder.default')->cannotBeEmpty()->end() ->scalarNode('query_parameter')->defaultValue('q')->cannotBeEmpty()->end() ->end() ->end() diff --git a/DependencyInjection/FOSMessageExtension.php b/DependencyInjection/FOSMessageExtension.php index 169f3b82..e895a85b 100644 --- a/DependencyInjection/FOSMessageExtension.php +++ b/DependencyInjection/FOSMessageExtension.php @@ -21,7 +21,7 @@ public function load(array $configs, ContainerBuilder $container) $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); - if (!in_array(strtolower($config['db_driver']), array('orm', 'mongodb'))) { + if (!in_array(strtolower($config['db_driver']), ['orm', 'mongodb'])) { throw new \InvalidArgumentException(sprintf('Invalid db driver "%s".', $config['db_driver'])); } @@ -84,9 +84,9 @@ public function load(array $configs, ContainerBuilder $container) $container->setAlias('fos_message.reply_form.factory', new Alias($config['reply_form']['factory'], true)); $container->setAlias('fos_message.reply_form.handler', new Alias($config['reply_form']['handler'], true)); - $container->setAlias('fos_message.search_query_factory', new Alias($config['search']['query_factory'], true)); - $container->setAlias('fos_message.search_finder', new Alias($config['search']['finder'], true)); - $container->getDefinition('fos_message.search_query_factory.default') + $container->setAlias('fos_message.search.query_factory', new Alias($config['search']['query_factory'], true)); + $container->setAlias('fos_message.search.finder', new Alias($config['search']['finder'], true)); + $container->getDefinition('fos_message.search.query_factory.default') ->replaceArgument(1, $config['search']['query_parameter']); $container->getDefinition('fos_message.recipients_data_transformer') diff --git a/Document/Message.php b/Document/Message.php index c92760ff..443d2d44 100644 --- a/Document/Message.php +++ b/Document/Message.php @@ -20,7 +20,7 @@ abstract class Message extends BaseMessage * * @var array of participant ID's */ - protected $unreadForParticipants = array(); + protected $unreadForParticipants = []; /** * @param bool $isSpam @@ -58,7 +58,7 @@ protected function doSenderIsRead() */ protected function doEnsureUnreadForParticipantsArray() { - $this->unreadForParticipants = array(); + $this->unreadForParticipants = []; if ($this->isSpam) { return; diff --git a/Document/Thread.php b/Document/Thread.php index 237a072d..a70d5c4c 100644 --- a/Document/Thread.php +++ b/Document/Thread.php @@ -31,7 +31,7 @@ abstract class Thread extends AbstractThread * * @var array of participant ID's */ - protected $activeParticipants = array(); + protected $activeParticipants = []; /** * The activeRecipients array will contain a participant's ID if the thread @@ -40,7 +40,7 @@ abstract class Thread extends AbstractThread * * @var array of participant ID's */ - protected $activeRecipients = array(); + protected $activeRecipients = []; /** * The activeSenders array will contain a participant's ID if the thread is @@ -49,7 +49,7 @@ abstract class Thread extends AbstractThread * * @var array of participant ID's */ - protected $activeSenders = array(); + protected $activeSenders = []; /** * Gets the users participating in this conversation. @@ -186,9 +186,9 @@ protected function doMetadataLastMessageDates() */ protected function doEnsureActiveParticipantArrays() { - $this->activeParticipants = array(); - $this->activeRecipients = array(); - $this->activeSenders = array(); + $this->activeParticipants = []; + $this->activeRecipients = []; + $this->activeSenders = []; foreach ($this->getParticipants() as $participant) { if ($this->isDeletedByParticipant($participant)) { diff --git a/DocumentManager/MessageManager.php b/DocumentManager/MessageManager.php index 0b2c9c59..21bac32c 100644 --- a/DocumentManager/MessageManager.php +++ b/DocumentManager/MessageManager.php @@ -133,7 +133,7 @@ protected function markIsReadByCondition(ParticipantInterface $participant, $isR $queryBuilder ->field('metadata.$.isRead')->set((bool) $isRead) - ->getQuery(array('multiple' => true)) + ->getQuery(['multiple' => true]) ->execute(); /* If marking the message as unread for a participant, add their ID to @@ -147,7 +147,7 @@ protected function markIsReadByCondition(ParticipantInterface $participant, $isR ->field('metadata.participant.$id')->equals(new \MongoId($participant->getId())) ->field('isSpam')->equals(false) ->field('unreadForParticipants')->addToSet($participant->getId()) - ->getQuery(array('multiple' => true)) + ->getQuery(['multiple' => true]) ->execute(); } } diff --git a/Event/ReadableEvent.php b/Event/ReadableEvent.php index 3f9e18c6..3cc17083 100644 --- a/Event/ReadableEvent.php +++ b/Event/ReadableEvent.php @@ -3,7 +3,7 @@ namespace FOS\MessageBundle\Event; use FOS\MessageBundle\Model\ReadableInterface; -use Symfony\Component\EventDispatcher\Event; +use Symfony\Contracts\EventDispatcher\Event; class ReadableEvent extends Event { diff --git a/Event/ThreadEvent.php b/Event/ThreadEvent.php index b7176180..0ae3fa7c 100644 --- a/Event/ThreadEvent.php +++ b/Event/ThreadEvent.php @@ -3,7 +3,7 @@ namespace FOS\MessageBundle\Event; use FOS\MessageBundle\Model\ThreadInterface; -use Symfony\Component\EventDispatcher\Event; +use Symfony\Contracts\EventDispatcher\Event; class ThreadEvent extends Event { diff --git a/FormFactory/AbstractMessageFormFactory.php b/FormFactory/AbstractMessageFormFactory.php index fe6ace22..e0ae3801 100644 --- a/FormFactory/AbstractMessageFormFactory.php +++ b/FormFactory/AbstractMessageFormFactory.php @@ -11,7 +11,7 @@ * * @author Thibault Duplessis */ -abstract class AbstractMessageFormFactory +abstract class AbstractMessageFormFactory implements FactoryInterface { /** * The Symfony form factory. diff --git a/FormFactory/FactoryInterface.php b/FormFactory/FactoryInterface.php new file mode 100644 index 00000000..309d0af1 --- /dev/null +++ b/FormFactory/FactoryInterface.php @@ -0,0 +1,14 @@ +formFactory->createNamed($this->formName, $this->formType, $this->createModelInstance()); } diff --git a/FormFactory/ReplyMessageFormFactory.php b/FormFactory/ReplyMessageFormFactory.php index 27cc599a..89632899 100644 --- a/FormFactory/ReplyMessageFormFactory.php +++ b/FormFactory/ReplyMessageFormFactory.php @@ -19,7 +19,7 @@ class ReplyMessageFormFactory extends AbstractMessageFormFactory * * @return FormInterface */ - public function create(ThreadInterface $thread) + public function create(?ThreadInterface $thread = null) { $message = $this->createModelInstance(); $message->setThread($thread); diff --git a/FormHandler/AbstractMessageFormHandler.php b/FormHandler/AbstractMessageFormHandler.php index 08e3aa75..32a9c79c 100644 --- a/FormHandler/AbstractMessageFormHandler.php +++ b/FormHandler/AbstractMessageFormHandler.php @@ -17,7 +17,7 @@ * * @author Thibault Duplessis */ -abstract class AbstractMessageFormHandler +abstract class AbstractMessageFormHandler implements FormHandlerInterface { protected $request; protected $composer; diff --git a/FormHandler/FormHandlerInterface.php b/FormHandler/FormHandlerInterface.php new file mode 100644 index 00000000..b6545516 --- /dev/null +++ b/FormHandler/FormHandlerInterface.php @@ -0,0 +1,27 @@ +add('recipient', LegacyFormHelper::getType('FOS\UserBundle\Form\Type\UsernameFormType'), array( + ->add('recipient', LegacyFormHelper::getType('FOS\UserBundle\Form\Type\UsernameFormType'), [ 'label' => 'recipient', - 'translation_domain' => 'FOSMessageBundle', - )) - ->add('subject', LegacyFormHelper::getType('Symfony\Component\Form\Extension\Core\Type\TextType'), array( + 'translation_domain' => 'FOSMessageBundle' + ]) + ->add('subject', LegacyFormHelper::getType('Symfony\Component\Form\Extension\Core\Type\TextType'), [ 'label' => 'subject', - 'translation_domain' => 'FOSMessageBundle', - )) - ->add('body', LegacyFormHelper::getType('Symfony\Component\Form\Extension\Core\Type\TextareaType'), array( + 'translation_domain' => 'FOSMessageBundle' + ]) + ->add('body', LegacyFormHelper::getType('Symfony\Component\Form\Extension\Core\Type\TextareaType'), [ 'label' => 'body', - 'translation_domain' => 'FOSMessageBundle', - )); + 'translation_domain' => 'FOSMessageBundle' + ]); } public function configureOptions(OptionsResolver $resolver) { - $resolver->setDefaults(array( - 'intention' => 'message', - )); + $resolver->setDefaults(['intention' => 'message']); } /** * {@inheritdoc} */ - public function getBlockPrefix() + public function getBlockPrefix(): string { return 'fos_message_new_thread'; } diff --git a/FormType/NewThreadMultipleMessageFormType.php b/FormType/NewThreadMultipleMessageFormType.php index 51a1bcbe..19582fe8 100644 --- a/FormType/NewThreadMultipleMessageFormType.php +++ b/FormType/NewThreadMultipleMessageFormType.php @@ -16,24 +16,24 @@ class NewThreadMultipleMessageFormType extends AbstractType public function buildForm(FormBuilderInterface $builder, array $options) { $builder - ->add('recipients', LegacyFormHelper::getType('FOS\MessageBundle\FormType\RecipientsType'), array( + ->add('recipients', LegacyFormHelper::getType('FOS\MessageBundle\FormType\RecipientsType'), [ 'label' => 'recipients', - 'translation_domain' => 'FOSMessageBundle', - )) - ->add('subject', LegacyFormHelper::getType('Symfony\Component\Form\Extension\Core\Type\TextType'), array( + 'translation_domain' => 'FOSMessageBundle' + ]) + ->add('subject', LegacyFormHelper::getType('Symfony\Component\Form\Extension\Core\Type\TextType'), [ 'label' => 'subject', - 'translation_domain' => 'FOSMessageBundle', - )) - ->add('body', LegacyFormHelper::getType('Symfony\Component\Form\Extension\Core\Type\TextareaType'), array( + 'translation_domain' => 'FOSMessageBundle' + ]) + ->add('body', LegacyFormHelper::getType('Symfony\Component\Form\Extension\Core\Type\TextareaType'), [ 'label' => 'body', - 'translation_domain' => 'FOSMessageBundle', - )); + 'translation_domain' => 'FOSMessageBundle' + ]); } /** * {@inheritdoc} */ - public function getBlockPrefix() + public function getBlockPrefix(): string { return 'fos_message_new_multiperson_thread'; } diff --git a/FormType/RecipientsType.php b/FormType/RecipientsType.php index 6a1fe369..43cd8ad6 100644 --- a/FormType/RecipientsType.php +++ b/FormType/RecipientsType.php @@ -42,9 +42,7 @@ public function buildForm(FormBuilderInterface $builder, array $options) */ public function configureOptions(OptionsResolver $resolver) { - $resolver->setDefaults(array( - 'invalid_message' => 'The selected recipient does not exist', - )); + $resolver->setDefaults(['invalid_message' => 'The selected recipient does not exist']); } public function setDefaultOptions(OptionsResolverInterface $resolver) @@ -55,7 +53,7 @@ public function setDefaultOptions(OptionsResolverInterface $resolver) /** * {@inheritdoc} */ - public function getBlockPrefix() + public function getBlockPrefix(): string { return 'recipients_selector'; } @@ -63,7 +61,7 @@ public function getBlockPrefix() /** * {@inheritdoc} */ - public function getParent() + public function getParent(): ?string { return LegacyFormHelper::getType('Symfony\Component\Form\Extension\Core\Type\TextType'); } diff --git a/FormType/ReplyMessageFormType.php b/FormType/ReplyMessageFormType.php index 3d1592e5..83a42709 100644 --- a/FormType/ReplyMessageFormType.php +++ b/FormType/ReplyMessageFormType.php @@ -18,23 +18,22 @@ class ReplyMessageFormType extends AbstractType public function buildForm(FormBuilderInterface $builder, array $options) { $builder - ->add('body', LegacyFormHelper::getType('Symfony\Component\Form\Extension\Core\Type\TextareaType'), array( + ->add('body', LegacyFormHelper::getType('Symfony\Component\Form\Extension\Core\Type\TextareaType'), [ 'label' => 'body', - 'translation_domain' => 'FOSMessageBundle', - )); + 'translation_domain' => 'FOSMessageBundle' + ] + ); } public function configureOptions(OptionsResolver $resolver) { - $resolver->setDefaults(array( - 'intention' => 'reply', - )); + $resolver->setDefaults(['intention' => 'reply']); } /** * {@inheritdoc} */ - public function getBlockPrefix() + public function getBlockPrefix(): string { return 'fos_message_reply_message'; } diff --git a/Model/ParticipantInterface.php b/Model/ParticipantInterface.php index 6849dec9..b8d10011 100644 --- a/Model/ParticipantInterface.php +++ b/Model/ParticipantInterface.php @@ -9,7 +9,7 @@ * * @author Thibault Duplessis */ -interface ParticipantInterface +interface ParticipantInterface extends \Stringable { /** * Gets the unique identifier of the participant. diff --git a/Reader/Reader.php b/Reader/Reader.php index f0a25812..a45052a8 100644 --- a/Reader/Reader.php +++ b/Reader/Reader.php @@ -56,7 +56,7 @@ public function markAsRead(ReadableInterface $readable) } $this->readableManager->markAsReadByParticipant($readable, $participant); - $this->dispatcher->dispatch(FOSMessageEvents::POST_READ, new ReadableEvent($readable)); + $this->dispatcher->dispatch(new ReadableEvent($readable), FOSMessageEvents::POST_READ); } /** @@ -70,7 +70,7 @@ public function markAsUnread(ReadableInterface $readable) } $this->readableManager->markAsUnreadByParticipant($readable, $participant); - $this->dispatcher->dispatch(FOSMessageEvents::POST_UNREAD, new ReadableEvent($readable)); + $this->dispatcher->dispatch(new ReadableEvent($readable), FOSMessageEvents::POST_UNREAD); } /** diff --git a/Resources/config/config.xml b/Resources/config/config.xml index 7acf5474..fbcb30a6 100644 --- a/Resources/config/config.xml +++ b/Resources/config/config.xml @@ -5,12 +5,20 @@ xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> - - + + + + + + + + + + + + + @@ -58,19 +66,19 @@ - + - + - + diff --git a/Resources/doc/01-installation.md b/Resources/doc/01-installation.md index 28ff3b11..e8a5b010 100644 --- a/Resources/doc/01-installation.md +++ b/Resources/doc/01-installation.md @@ -32,7 +32,7 @@ Your user class may look something like the following: ```php ['all' => true], + // ... +]; ``` ### Step 5 - Import the bundle routing @@ -80,7 +77,7 @@ public function registerBundles() Add FOSMessageBundle's routing to your application with an optional routing prefix. ```yaml -# app/config/routing.yml +# config/routing.yaml fos_message: resource: "@FOSMessageBundle/Resources/config/routing.xml" @@ -89,13 +86,7 @@ fos_message: ### Step 6 - Check templating -Make sure to add this to `framwork.yaml` (and check twig is installed) if you run into the non-existant service `templating` issue: - -```yaml -templating: - engines: - twig -``` +Make sure to have twig installed and ready to be used ## Installation Finished diff --git a/Resources/doc/01a-orm-models.md b/Resources/doc/01a-orm-models.md index 4b3e2246..ba7d6189 100644 --- a/Resources/doc/01a-orm-models.md +++ b/Resources/doc/01a-orm-models.md @@ -7,15 +7,15 @@ ORM. Given the examples below with their namespaces and class names, you need to configure FOSMessageBundle to tell them about these classes. -Add the following to your `app/config/config.yml` file. +Create and add the following config to your `config/fos_message.yaml` file. ```yaml -# app/config/config.yml +# config/fos_message.yaml fos_message: db_driver: orm - thread_class: AppBundle\Entity\Thread - message_class: AppBundle\Entity\Message + thread_class: App\Entity\Thread + message_class: App\Entity\Message ``` [Continue with the installation][] @@ -25,49 +25,38 @@ Message class ```php repository = $doctrine->getManager()->getRepository('AppBundle:User'); + $this->em = $em; } /** - * Transforms a User instance into a username string. + * Transforms a UserInterface instance into a username string. * - * @param User|null $value User instance + * @param UserInterface|null $value UserInterface instance * * @return string|null Username * - * @throws UnexpectedTypeException if the given value is not a User instance + * @throws UnexpectedTypeException if the given value is not a UserInterface instance */ - public function transform($value) + public function transform($value): ?string { if (null === $value) { return null; } - if (! $value instanceof User) { - throw new UnexpectedTypeException($value, 'AppBundle\Entity\User'); + if (!$value instanceof UserInterface) { + throw new UnexpectedTypeException($value, 'Symfony\Component\Security\Core\User\UserInterface'); } - return $value->getUsername(); + return $value->getUserIdentifier(); } /** - * Transforms a username string into a User instance. + * Transforms a username string into a UserInterface instance. * * @param string $value Username * - * @return User the corresponding User instance + * @return UserInterface|null the corresponding UserInterface instance * * @throws UnexpectedTypeException if the given value is not a string */ - public function reverseTransform($value) + public function reverseTransform($value): ?UserInterface { if (null === $value || '' === $value) { return null; } - if (! is_string($value)) { + if (!is_string($value)) { throw new UnexpectedTypeException($value, 'string'); } - return $this->repository->findOneByUsername($value); + return $this->em->getRepository(User::class)->findOneByIdentifier($value); } } ``` @@ -93,15 +92,142 @@ For the moment, there is no configuration key to do it so we will emulate the FOSUserBundle transformer by using its name as an alias of our own service: ``` xml - + - - + ``` +Or + +``` yaml +# config/services.yaml +services: + ... + app.user_to_username_transformer: + class: App\Form\DataTransformer\UserToUsernameTransformer + + fos_user.user_to_username_transformer: + alias: app.user_to_username_transformer +``` + +As `NewThreadMessageFormType` used `FOS\UserBundle\Form\Type\UsernameFormType` for recipied field, you need to create +a new form type to replace it + +```php +add('recipient', UsernameFormType::class, [ + 'label' => 'recipient', + 'translation_domain' => 'FOSMessageBundle', + ]) + ->add('subject', TextType::class, [ + 'label' => 'subject', + 'translation_domain' => 'FOSMessageBundle', + ]) + ->add('body', TextareaType::class, [ + 'label' => 'body', + 'translation_domain' => 'FOSMessageBundle', + ]); + } + + public function configureOptions(OptionsResolver $resolver) + { + $resolver->setDefaults([ + 'intention' => 'message', + ]); + } + + /** + * {@inheritdoc} + */ + public function getBlockPrefix() + { + return 'new_thread_message'; + } +} +``` + +And create a new form type linked to `UserToUsernameTransformer` + +```php +usernameTransformer = $usernameTransformer; + } + + /** + * {@inheritdoc} + */ + public function buildForm(FormBuilderInterface $builder, array $options) + { + $builder->addModelTransformer($this->usernameTransformer); + } + + /** + * {@inheritdoc} + */ + public function getParent() + { + return TextType::class; + } + + /** + * {@inheritdoc} + */ + public function getBlockPrefix() + { + return 'app_username_type'; + } +} + +``` + ### Problems you may encounter #### User identifier field is not `id` @@ -113,32 +239,31 @@ made by the bundle. You can copy the default ones (in `FOS\MessageBundle\EntityManager` if you use the Doctrine ORM) into your bundle, change their queries and register them as services: -``` xml - - - - - %fos_message.message_class% - %fos_message.message_meta_class% - - - - - %fos_message.thread_class% - %fos_message.thread_meta_class% - - +``` yaml +# config/services.yaml + +services: + ... + App\Manager\MessageManager: + bind: + $class: '%fos_message.message_class%' + $metaClass: '%fos_message.message_meta_class%' + + App\Manager\ThreadManager: + bind: + $class: '%fos_message.thread_class%' + $metaClass: '%fos_message.thread_meta_class%' ``` Once done, tell FOSMessageBundle to use them in the configuration: ``` yaml -# app/config/config.yml +# config/fos_message.yaml fos_message: # ... - thread_manager: app.thread_manager - message_manager: app.message_manager + thread_manager: App\Manager\ThreadManager + message_manager: App\Manager\MessageManager ``` #### The default form does not work with my User entity @@ -150,11 +275,11 @@ You have to redefine two things : You can copy and paste the bundle versions into your application and define them as services: ``` xml - + - + %fos_message.new_thread_form.name% @@ -167,7 +292,7 @@ You can copy and paste the bundle versions into your application and define them And configure the bundle to use your services: ``` yaml -# app/config/config.yml +# config/fos_message.yaml fos_message: # ... diff --git a/Sender/Sender.php b/Sender/Sender.php index 471d44f2..7201fd43 100644 --- a/Sender/Sender.php +++ b/Sender/Sender.php @@ -31,8 +31,11 @@ class Sender implements SenderInterface */ protected $dispatcher; - public function __construct(MessageManagerInterface $messageManager, ThreadManagerInterface $threadManager, EventDispatcherInterface $dispatcher) - { + public function __construct( + MessageManagerInterface $messageManager, + ThreadManagerInterface $threadManager, + EventDispatcherInterface $dispatcher + ) { $this->messageManager = $messageManager; $this->threadManager = $threadManager; $this->dispatcher = $dispatcher; @@ -54,6 +57,6 @@ public function send(MessageInterface $message) $message->getThread()->setIsDeleted(false); $this->messageManager->saveMessage($message); - $this->dispatcher->dispatch(FOSMessageEvents::POST_SEND, new MessageEvent($message)); + $this->dispatcher->dispatch(new MessageEvent($message), FOSMessageEvents::POST_SEND); } } diff --git a/SpamDetection/AkismetSpamDetector.php b/SpamDetection/AkismetSpamDetector.php index 070d8160..3ef54208 100644 --- a/SpamDetection/AkismetSpamDetector.php +++ b/SpamDetection/AkismetSpamDetector.php @@ -29,9 +29,9 @@ public function __construct(AkismetInterface $akismet, ParticipantProviderInterf */ public function isSpam(NewThreadMessage $message) { - return $this->akismet->isSpam(array( + return $this->akismet->isSpam([ 'comment_author' => (string) $this->participantProvider->getAuthenticatedParticipant(), - 'comment_content' => $message->getBody(), - )); + 'comment_content' => $message->getBody() + ]); } } diff --git a/Tests/Document/ThreadDenormalizerTest.php b/Tests/Document/ThreadDenormalizerTest.php index 0196b206..81902f5d 100644 --- a/Tests/Document/ThreadDenormalizerTest.php +++ b/Tests/Document/ThreadDenormalizerTest.php @@ -20,12 +20,12 @@ protected function setUpBeforeTest() { $this->markTestIncomplete('Broken, needs to be fixed'); - $this->dates = array( + $this->dates = [ new DateTime('- 3 days'), new DateTime('- 2 days'), new DateTime('- 1 days'), - new DateTime('- 1 hour'), - ); + new DateTime('- 1 hour') + ]; } public function testDenormalize() @@ -44,9 +44,9 @@ public function testDenormalize() $thread->addParticipant($user2); $thread->addMessage($message); - $this->assertSame(array($user1, $user2), $thread->getParticipants()); - $this->assertSame(array('u2' => $this->dates[0]->getTimestamp()), $thread->getDatesOfLastMessageWrittenByOtherParticipant()); - $this->assertSame(array('u1' => $this->dates[0]->getTimestamp()), $thread->getDatesOfLastMessageWrittenByParticipant()); + $this->assertSame([$user1, $user2], $thread->getParticipants()); + $this->assertSame(['u2' => $this->dates[0]->getTimestamp()], $thread->getDatesOfLastMessageWrittenByOtherParticipant()); + $this->assertSame(['u1' => $this->dates[0]->getTimestamp()], $thread->getDatesOfLastMessageWrittenByParticipant()); /* * Second message @@ -54,9 +54,9 @@ public function testDenormalize() $message = $this->createMessageMock($user2, $user1, $this->dates[1]); $thread->addMessage($message); - $this->assertSame(array($user1, $user2), $thread->getParticipants()); - $this->assertSame(array('u1' => $this->dates[1]->getTimestamp(), 'u2' => $this->dates[0]->getTimestamp()), $thread->getDatesOfLastMessageWrittenByOtherParticipant()); - $this->assertSame(array('u1' => $this->dates[0]->getTimestamp(), 'u2' => $this->dates[1]->getTimestamp()), $thread->getDatesOfLastMessageWrittenByParticipant()); + $this->assertSame([$user1, $user2], $thread->getParticipants()); + $this->assertSame(['u1' => $this->dates[1]->getTimestamp(), 'u2' => $this->dates[0]->getTimestamp()], $thread->getDatesOfLastMessageWrittenByOtherParticipant()); + $this->assertSame(['u1' => $this->dates[0]->getTimestamp(), 'u2' => $this->dates[1]->getTimestamp()], $thread->getDatesOfLastMessageWrittenByParticipant()); /* * Third message @@ -64,9 +64,9 @@ public function testDenormalize() $message = $this->createMessageMock($user2, $user1, $this->dates[2]); $thread->addMessage($message); - $this->assertSame(array($user1, $user2), $thread->getParticipants()); - $this->assertSame(array('u1' => $this->dates[2]->getTimestamp(), 'u2' => $this->dates[0]->getTimestamp()), $thread->getDatesOfLastMessageWrittenByOtherParticipant()); - $this->assertSame(array('u1' => $this->dates[0]->getTimestamp(), 'u2' => $this->dates[2]->getTimestamp()), $thread->getDatesOfLastMessageWrittenByParticipant()); + $this->assertSame([$user1, $user2], $thread->getParticipants()); + $this->assertSame(['u1' => $this->dates[2]->getTimestamp(), 'u2' => $this->dates[0]->getTimestamp()], $thread->getDatesOfLastMessageWrittenByOtherParticipant()); + $this->assertSame(['u1' => $this->dates[0]->getTimestamp(), 'u2' => $this->dates[2]->getTimestamp()], $thread->getDatesOfLastMessageWrittenByParticipant()); /* * Fourth message @@ -74,12 +74,12 @@ public function testDenormalize() $message = $this->createMessageMock($user1, $user2, $this->dates[3]); $thread->addMessage($message); - $this->assertSame(array($user1, $user2), $thread->getParticipants()); - $this->assertSame(array('u1' => $this->dates[2]->getTimestamp(), 'u2' => $this->dates[3]->getTimestamp()), $thread->getDatesOfLastMessageWrittenByOtherParticipant()); - $this->assertSame(array('u1' => $this->dates[3]->getTimestamp(), 'u2' => $this->dates[2]->getTimestamp()), $thread->getDatesOfLastMessageWrittenByParticipant()); + $this->assertSame([$user1, $user2], $thread->getParticipants()); + $this->assertSame(['u1' => $this->dates[2]->getTimestamp(), 'u2' => $this->dates[3]->getTimestamp()], $thread->getDatesOfLastMessageWrittenByOtherParticipant()); + $this->assertSame(['u1' => $this->dates[3]->getTimestamp(), 'u2' => $this->dates[2]->getTimestamp()], $thread->getDatesOfLastMessageWrittenByParticipant()); $this->assertEquals('test thread subject hi dude', $thread->getKeywords()); - $this->assertSame(array('u1' => false, 'u2' => false), $thread->getIsDeletedByParticipant()); + $this->assertSame(['u1' => false, 'u2' => false], $thread->getIsDeletedByParticipant()); } protected function createMessageMock($sender, $recipient, DateTime $date) diff --git a/Tests/Functional/Entity/Message.php b/Tests/Functional/Entity/Message.php index de629e15..9e9c97d4 100644 --- a/Tests/Functional/Entity/Message.php +++ b/Tests/Functional/Entity/Message.php @@ -4,6 +4,40 @@ use FOS\MessageBundle\Entity\Message as BaseMessage; +/** + * @ORM\Entity + */ class Message extends BaseMessage { + /** + * @ORM\Id + * @ORM\Column(type="integer") + * @ORM\GeneratedValue(strategy="AUTO") + */ + protected $id; + + /** + * @ORM\ManyToOne( + * targetEntity="App\Entity\Thread", + * inversedBy="messages" + * ) + * @var \FOS\MessageBundle\Model\ThreadInterface + */ + protected $thread; + + /** + * @ORM\ManyToOne(targetEntity="App\Entity\User") + * @var \FOS\MessageBundle\Model\ParticipantInterface + */ + protected $sender; + + /** + * @ORM\OneToMany( + * targetEntity="App\Entity\MessageMetadata", + * mappedBy="message", + * cascade={"all"} + * ) + * @var MessageMetadata[]|Collection + */ + protected $metadata; } diff --git a/Tests/Functional/Entity/User.php b/Tests/Functional/Entity/User.php index 5ebbe971..135b7974 100644 --- a/Tests/Functional/Entity/User.php +++ b/Tests/Functional/Entity/User.php @@ -3,16 +3,17 @@ namespace FOS\MessageBundle\Tests\Functional\Entity; use FOS\MessageBundle\Model\ParticipantInterface; +use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface; use Symfony\Component\Security\Core\User\UserInterface; -class User implements ParticipantInterface, UserInterface +class User implements ParticipantInterface, UserInterface, PasswordAuthenticatedUserInterface { - public function getUsername() + public function getUserIdentifier(): string { return 'guilhem'; } - public function getPassword() + public function getPassword(): ?string { return 'pass'; } @@ -21,9 +22,9 @@ public function getSalt() { } - public function getRoles() + public function getRoles(): array { - return array(); + return []; } public function eraseCredentials() @@ -34,4 +35,14 @@ public function getId() { return 1; } + + public function getUserName(): string + { + return $this->getUserIdentifier(); + } + + public function __toString(): string + { + return $this->getUserIdentifier(); + } } diff --git a/Tests/Functional/Entity/UserProvider.php b/Tests/Functional/Entity/UserProvider.php index 704995d7..1b3658e4 100644 --- a/Tests/Functional/Entity/UserProvider.php +++ b/Tests/Functional/Entity/UserProvider.php @@ -7,17 +7,17 @@ class UserProvider implements UserProviderInterface { - public function loadUserByUsername($username) + public function loadUserByIdentifier($username): UserInterface { return new User(); } - public function refreshUser(UserInterface $user) + public function refreshUser(UserInterface $user): UserInterface { return $user; } - public function supportsClass($class) + public function supportsClass($class): bool { return User::class === $class; } @@ -26,4 +26,9 @@ private function fetchUser($username) { return new User(); } + + public function loadUserByUsername($username): UserInterface + { + return $this->loadUserByIdentifier($username); + } } diff --git a/Tests/Functional/EntityManager/ThreadManager.php b/Tests/Functional/EntityManager/ThreadManager.php index fa03ef74..aed6f0b2 100644 --- a/Tests/Functional/EntityManager/ThreadManager.php +++ b/Tests/Functional/EntityManager/ThreadManager.php @@ -21,7 +21,7 @@ public function getParticipantInboxThreadsQueryBuilder(ParticipantInterface $par public function findParticipantInboxThreads(ParticipantInterface $participant) { - return array(new Thread()); + return [new Thread()]; } public function getParticipantSentThreadsQueryBuilder(ParticipantInterface $participant) @@ -30,7 +30,7 @@ public function getParticipantSentThreadsQueryBuilder(ParticipantInterface $part public function findParticipantSentThreads(ParticipantInterface $participant) { - return array(); + return []; } public function getParticipantDeletedThreadsQueryBuilder(ParticipantInterface $participant) @@ -39,7 +39,7 @@ public function getParticipantDeletedThreadsQueryBuilder(ParticipantInterface $p public function findParticipantDeletedThreads(ParticipantInterface $participant) { - return array(); + return []; } public function getParticipantThreadsBySearchQueryBuilder(ParticipantInterface $participant, $search) @@ -48,12 +48,12 @@ public function getParticipantThreadsBySearchQueryBuilder(ParticipantInterface $ public function findParticipantThreadsBySearch(ParticipantInterface $participant, $search) { - return array(); + return []; } public function findThreadsCreatedBy(ParticipantInterface $participant) { - return array(); + return []; } public function markAsReadByParticipant(ReadableInterface $readable, ParticipantInterface $participant) diff --git a/Tests/Functional/Form/UserToUsernameTransformer.php b/Tests/Functional/Form/UserToUsernameTransformer.php index 915ab171..4e123863 100644 --- a/Tests/Functional/Form/UserToUsernameTransformer.php +++ b/Tests/Functional/Form/UserToUsernameTransformer.php @@ -8,17 +8,17 @@ class UserToUsernameTransformer implements DataTransformerInterface { - public function transform($value) + public function transform($value): ?string { if (null === $value) { - return; + return null; } if (!$value instanceof User) { throw new \RuntimeException(); } - return $value->getUsername(); + return $value->getUserIdentifier(); } /** diff --git a/Tests/Functional/FunctionalTest.php b/Tests/Functional/FunctionalTest.php index bd0dffcc..c4b3e4eb 100644 --- a/Tests/Functional/FunctionalTest.php +++ b/Tests/Functional/FunctionalTest.php @@ -6,10 +6,7 @@ class FunctionalTest extends WebTestCase { public function testController() { - $client = self::createClient(array(), array( - 'PHP_AUTH_USER' => 'guilhem', - 'PHP_AUTH_PW' => 'pass', - )); + $client = self::createClient([], ['PHP_AUTH_USER' => 'guilhem', 'PHP_AUTH_PW' => 'pass']); $crawler = $client->request('GET', '/sent'); $response = $client->getResponse(); diff --git a/Tests/Functional/TestKernel.php b/Tests/Functional/TestKernel.php index 22f04dc9..8ca97425 100644 --- a/Tests/Functional/TestKernel.php +++ b/Tests/Functional/TestKernel.php @@ -17,7 +17,7 @@ use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\HttpKernel\Kernel; -use Symfony\Component\Routing\RouteCollectionBuilder; +use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator; /** * @author Guilhem N. @@ -29,14 +29,14 @@ class TestKernel extends Kernel /** * {@inheritdoc} */ - public function registerBundles() + public function registerBundles(): iterable { - $bundles = array( + $bundles = [ new FrameworkBundle(), new SecurityBundle(), new TwigBundle(), new FOSMessageBundle(), - ); + ]; return $bundles; } @@ -44,7 +44,7 @@ public function registerBundles() /** * {@inheritdoc} */ - protected function configureRoutes(RouteCollectionBuilder $routes) + protected function configureRoutes(RoutingConfigurator $routes) { $routes->import('@FOSMessageBundle/Resources/config/routing.xml'); } @@ -54,30 +54,28 @@ protected function configureRoutes(RouteCollectionBuilder $routes) */ protected function configureContainer(ContainerBuilder $c, LoaderInterface $loader) { - $c->loadFromExtension('framework', array( + $c->loadFromExtension('framework', [ 'secret' => 'MySecretKey', 'test' => null, 'form' => null, - 'templating' => array( - 'engines' => array('twig'), - ), - )); + 'http_method_override' => false + ]); - $c->loadFromExtension('security', array( - 'providers' => array('permissive' => array('id' => 'app.user_provider')), - 'encoders' => array('FOS\MessageBundle\Tests\Functional\Entity\User' => 'plaintext'), - 'firewalls' => array('main' => array('http_basic' => true)), - )); + $c->loadFromExtension('security', [ + 'providers' => ['permissive' => ['id' => 'app.user_provider']], + 'password_hashers' => ['FOS\MessageBundle\Tests\Functional\Entity\User' => 'plaintext'], + 'firewalls' => ['main' => ['http_basic' => true]], + ]); - $c->loadFromExtension('twig', array( + $c->loadFromExtension('twig', [ 'strict_variables' => '%kernel.debug%', - )); + ]); - $c->loadFromExtension('fos_message', array( + $c->loadFromExtension('fos_message', [ 'db_driver' => 'orm', 'thread_class' => Thread::class, 'message_class' => Message::class, - )); + ]); $c->register('fos_user.user_to_username_transformer', UserToUsernameTransformer::class); $c->register('app.user_provider', UserProvider::class); diff --git a/Tests/Functional/WebTestCase.php b/Tests/Functional/WebTestCase.php index e853eed5..8364df2c 100644 --- a/Tests/Functional/WebTestCase.php +++ b/Tests/Functional/WebTestCase.php @@ -6,7 +6,7 @@ class WebTestCase extends BaseWebTestCase { - protected static function getKernelClass() + protected static function getKernelClass(): string { return 'FOS\MessageBundle\Tests\Functional\TestKernel'; } diff --git a/Tests/Model/ThreadTest.php b/Tests/Model/ThreadTest.php index d1eb8d01..b006c5d7 100644 --- a/Tests/Model/ThreadTest.php +++ b/Tests/Model/ThreadTest.php @@ -16,7 +16,7 @@ public function testGetOtherParticipants() $thread = $this->getMockForAbstractClass('FOS\MessageBundle\Model\Thread'); $thread->expects($this->atLeastOnce()) ->method('getParticipants') - ->will($this->returnValue(array($u1, $u2, $u3))); + ->will($this->returnValue([$u1, $u2, $u3])); $toIds = function (array $participants) { return array_map(function (ParticipantInterface $participant) { @@ -24,9 +24,9 @@ public function testGetOtherParticipants() }, $participants); }; - $this->assertSame($toIds(array($u2, $u3)), $toIds($thread->getOtherParticipants($u1))); - $this->assertSame($toIds(array($u1, $u3)), $toIds($thread->getOtherParticipants($u2))); - $this->assertSame($toIds(array($u1, $u2)), $toIds($thread->getOtherParticipants($u3))); + $this->assertSame($toIds([$u2, $u3]), $toIds($thread->getOtherParticipants($u1))); + $this->assertSame($toIds([$u1, $u3]), $toIds($thread->getOtherParticipants($u2))); + $this->assertSame($toIds([$u1, $u2]), $toIds($thread->getOtherParticipants($u3))); } protected function createParticipantMock($id) diff --git a/Tests/Twig/Extension/MessageExtensionTest.php b/Tests/Twig/Extension/MessageExtensionTest.php index 85597bc8..2f8ab94d 100644 --- a/Tests/Twig/Extension/MessageExtensionTest.php +++ b/Tests/Twig/Extension/MessageExtensionTest.php @@ -2,7 +2,7 @@ namespace FOS\MessageBundle\Tests\Twig\Extension; -use FOS\MessageBundle\Twig\Extension\MessageExtension; +use FOS\MessageBundle\Twig\MessageExtension; use PHPUnit\Framework\TestCase; /** diff --git a/Twig/Extension/MessageExtension.php b/Twig/MessageExtension.php similarity index 81% rename from Twig/Extension/MessageExtension.php rename to Twig/MessageExtension.php index dba25a4c..08ae9cca 100644 --- a/Twig/Extension/MessageExtension.php +++ b/Twig/MessageExtension.php @@ -1,6 +1,6 @@ participantProvider = $participantProvider; $this->provider = $provider; $this->authorizer = $authorizer; @@ -29,14 +32,14 @@ public function __construct(ParticipantProviderInterface $participantProvider, P /** * {@inheritdoc} */ - public function getFunctions() + public function getFunctions(): array { - return array( - new TwigFunction('fos_message_is_read', array($this, 'isRead')), - new TwigFunction('fos_message_nb_unread', array($this, 'getNbUnread')), - new TwigFunction('fos_message_can_delete_thread', array($this, 'canDeleteThread')), - new TwigFunction('fos_message_deleted_by_participant', array($this, 'isThreadDeletedByParticipant')), - ); + return [ + new TwigFunction('fos_message_is_read', [$this, 'isRead']), + new TwigFunction('fos_message_nb_unread', [$this, 'getNbUnread']), + new TwigFunction('fos_message_can_delete_thread', [$this, 'canDeleteThread']), + new TwigFunction('fos_message_deleted_by_participant', [$this, 'isThreadDeletedByParticipant']) + ]; } /** diff --git a/UPGRADING.md b/UPGRADING.md index 74a9257a..4751a69d 100644 --- a/UPGRADING.md +++ b/UPGRADING.md @@ -30,7 +30,7 @@ The 1.3 version added the support for Symfony 3.0+. Several changes were made fo # ... new_thread_form: - type: AppBundle\Form\Type\NewThreadFormType + type: App\Form\Type\NewThreadFormType reply_form: - type: AppBundle\Form\Type\ReplyFormType + type: App\Form\Type\ReplyFormType ``` diff --git a/Util/LegacyFormHelper.php b/Util/LegacyFormHelper.php index 54cc5bf5..171aaa92 100644 --- a/Util/LegacyFormHelper.php +++ b/Util/LegacyFormHelper.php @@ -11,15 +11,15 @@ */ final class LegacyFormHelper { - private static $map = array( + private static $map = [ 'FOS\UserBundle\Form\Type\UsernameFormType' => 'fos_user_username', 'FOS\MessageBundle\FormType\RecipientsType' => 'recipients_selector', 'Symfony\Component\Form\Extension\Core\Type\EmailType' => 'email', 'Symfony\Component\Form\Extension\Core\Type\PasswordType' => 'password', 'Symfony\Component\Form\Extension\Core\Type\RepeatedType' => 'repeated', 'Symfony\Component\Form\Extension\Core\Type\TextType' => 'text', - 'Symfony\Component\Form\Extension\Core\Type\TextareaType' => 'textarea', - ); + 'Symfony\Component\Form\Extension\Core\Type\TextareaType' => 'textarea' + ]; public static function getType($class) { diff --git a/composer.json b/composer.json index 493bd5f7..b9fe3136 100644 --- a/composer.json +++ b/composer.json @@ -17,21 +17,22 @@ } ], "require": { - "php": ">=5.5.9", + "php": ">=7.2", "doctrine/collections": "^1.3", - "symfony/form": "^3.4|^4.0", - "symfony/framework-bundle": "^3.4|^4.0", - "symfony/security": "^3.4|^4.0", - "symfony/twig-bundle": "^3.4|^4.0" + "symfony/event-dispatcher": "^5.0 || ^6.0", + "symfony/event-dispatcher-contracts": "^2.0 || ^3.0", + "symfony/form": "^5.0|^6.0", + "symfony/framework-bundle": "^5.0|^6.0", + "symfony/security-bundle": "^5.0|^6.0", + "symfony/twig-bundle": "^5.0|^6.0" }, "require-dev": { - "symfony/validator": "^3.4|^4.0", - "symfony/translation": "^3.4|^4.0", - "symfony/yaml": "^3.4|^4.0", - "symfony/security-bundle": "^3.4|^4.0", - "symfony/templating": "^3.4|^4.0", - "symfony/browser-kit": "^3.4|^4.0", - "symfony/phpunit-bridge": "^4.2.8", + "symfony/validator": "^5.0|^6.0", + "symfony/translation": "^5.0|^6.0", + "symfony/yaml": "^5.0|^6.0", + "symfony/security-bundle": "^5.0|^6.0", + "symfony/browser-kit": "^5.0|^6.0", + "symfony/phpunit-bridge": "^6.1", "doctrine/orm": "^2.0" }, "suggest": {