mercredi 5 juillet 2017

Issue #23406 : Doctrine bigint casté en string depuis la 3.2.10

Une PR, validée pour Symfony 3.2.10 mais pas les autres versions (2.7, 2.8 et 3.3, à voir si la PR n'était pas déjà présente sur ces branches) casse tous les typages PHP pour le type Doctrine bigint.

Ils ont décidé de caster les bigint Doctrine en string PHP, au lieu de int PHP (comme avant).
Tous les typages PHP7 sont cassés, et toutes les comparaisons typés avec === également.

En espérant qu'ils corrigent ça vite, le type bigint est sûrement utilisé par beaucoup de gens pour les identifiants de table !

Issue #23406

mardi 27 juin 2017

Doctrine issue #6509 : PersistentCollection et orphanRemoval

Remontée de bug pour Doctrine 2.5.x (et probalement les versions précédentes) : si on appelle PersistentCollection::clear() ou PersistentCollection::removeElement(), et que la liaison a orphanRemoval, alors les éléments supprimés seront enregistrés dans l'UnitOfWork comme étant à supprimer en base de données.

Jusque là, tout va bien. Mais si on veut de nouveau ajouter un élément dans la PersistentCollection, et que cet élément a été indiqué comme étant à supprimer avant, alors PersistentCollection n'annule pas la demande de suppression.

Résultat : l'élément supprimé, puis re-ajouté, est supprimé en base, alors qu'on voulait le conserver.

Issue #6509

mercredi 21 juin 2017

Symfony Issue #23248 : DataCollectorTranslator::getFallbackLocales() retourne un tableau vide

En environnement de développement, si on appelle $container->get('translator')->getFallbackLocales(), on a un tableau vide.

La surcharge DataCollectorTranslator, qu'on n'a qu'en environnement de développement (pour le profiler), gère correctement les fallbacks si le service translator est une instance de Translator.
Pour les autres implémentations, fournies par Symfony (LogginTranslator par exemple), DataCollectorTranslator retourne un tableau vide.

DataCollectorTranslator.php#100
Issue #23248

vendredi 2 juin 2017

[symfony/validator] Issue #23032 Valider un tableau valide les valeurs récursivement

Si on valide un tableau, qui contient un objet parmi ses valeurs, alors cet objet sera validé, avec le groupe de validation utilisé pour le tableau.

C'est différent pour les objets, qui ont besoin du validateur Valid pour avoir le même comportement.

#23032

mardi 23 mai 2017

Connexion d'un User dans Symfony via un Listener

On peut avoir besoin de connecter un utilisateur via du code, par exemple pour des tests d'url via steevanb/php-url-test.
La documentation de Symfony est une base pour comprendre le mécanisme, il manque cependant quelques détails.

Vous trouverez ci-dessous un exemple complet, qui créé LoginListener, pour connecter votre utilisateur avant que le firewall n'essaye de le récupérer.
Notez que pour des raisons de sécurité, je met ce code dans app/AppTestKernel.php. Ce fichier sera supprimé de l'environnement de prod.

Création du listener dans AppTestKernel.php :
protected function getContainerBuilder(): ContainerBuilder { $container = parent::getContainerBuilder(); $container->setDefinition( 'foo.login_event_listener', new Definition( LoginEventListener::class, [ new Reference('security.token_storage'), new Reference('foo.user_provider'), new Reference('event_dispatcher'), new Reference('session'), new Reference('request_stack') ] ) ); return $container; }
Ajout du listener sur kernel.request, dans AppTestKernel.php :
public function boot(): void { parent::boot(); $this ->getContainer() ->get('event_dispatcher') // priorité 9 parceque le firewall qui redirige sur la page de login a une priorité de 8 ->addListenerService('kernel.request', ['foo.login_event_listener', 'login'], 9); }
Listener qui log le user admin :
<?php declare(strict_types=1); namespace Foo; use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\HttpKernel\Event\GetResponseEvent; use Symfony\Component\HttpFoundation\{ RequestStack, Session\SessionInterface }; use Symfony\Component\Security\{ Core\Authentication\Token\Storage\TokenStorageInterface, Core\Authentication\Token\UsernamePasswordToken, Core\User\UserProviderInterface, Http\Event\InteractiveLoginEvent }; class LoginEventListener { /** @var TokenStorageInterface */ protected $tokenStorage; /** @var UserProviderInterface */ protected $userProvider; /** @var EventDispatcherInterface */ protected $eventDispatcher; /** @var SessionInterface */ protected $session; /** @var RequestStack */ protected $requestStack; public function __construct( TokenStorageInterface $tokenStorage, UserProviderInterface $userProvider, EventDispatcherInterface $eventDispatcher, SessionInterface $session, RequestStack $requestStack ) { $this->tokenStorage = $tokenStorage; $this->userProvider = $userProvider; $this->eventDispatcher = $eventDispatcher; $this->session = $session; $this->requestStack = $requestStack; } public function login(GetResponseEvent $event): void { // récupération de l'utilisateur et connexion $user = $this->userProvider->loadUserByUsername('admin'); $token = new UsernamePasswordToken( $user, $user->getPassword(), 'main', $user->getRoles() ); $this->tokenStorage->setToken($token); // l'événement security.interactive_login n'est pas lancé automatiquement $event = new InteractiveLoginEvent($event->getRequest(), $token); $this->eventDispatcher->dispatch('security.interactive_login', $event); // http://symfony.com/doc/current/testing/http_authentication.html // sauvegarde du token dans la session, pour que le firewall le retrouve $this->session->set('_security_main', serialize($token)); $this->session->save(); // création du cookie // si on ne le fait pas, le firewall redirige sur la page de connexion $this->requestStack->getCurrentRequest()->cookies->set( $this->session->getName(), $this->session->getId() ); } }
Documentation Symfony

vendredi 5 mai 2017

Feature request : [symfony/console] pouvoir supprimer une commande

Le composant symfony/console permet d'exécuter des commandes PHP facilement.
Intégré dans Symfony, il permet à des bundles externes d'ajouter leurs commandes, par exemple doctrine:schema:update.
Cependant, certaines commandes ne devraient pas être accessibles en fonction de l'environnement, ou du projet.

Pour reprendre doctrine:schema:update, elle est très utile en dev, mais ne devrait pas pouvoir être lancée en prod.
Autre exemple : l'application sur laquelle je travaille est découpée en plusieurs projets, dont un qui contient toutes les fixtures, migrations, création de triggers, vues, etc.
Toute la gestion de la base de données est centralisée dans ce projet.
Donc, les commandes doctrine:* n'ont pas lieu d'être dans les autres projets, et surtout, ne profitent pas d'une éventuelle surcharge effectuée par le projet database.

Feature request #22645

mardi 14 mars 2017

Git log coloré et plus facile à lire

Merci à Sebastien Huot pour cet alias à git log, avec des couleurs, et plus lisible :
alias gitlog="git log --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --reverse --max-count=50"