Artisan Développeur

Qualité, amélioration continue, agilité.

Add default ROLE to user when registering, with FOS User bundle

Add default when registering a new user with FOS user bundle.

I want to add a default ROLE to all my users when they use registration on my web app, but I had some difficulties.

This is my working files : Listener default ROLE user fos user bundle

You have to add a listener to the REGISTRATION_SUCCESS event dispatch by FOS user bundle. You need to create a class, and make it implements « EventSubscriberInterface » .

When you have your class, you have to register it as a service in service.yaml (or xml).

But, before I succeed, I try to add ROLE_USER by default, and no matter what I code, test, write, try, implements, spell, cast… No way to have this default ROLE to my user, database field was empty.

After some search, I found why in FOS User Bundle code :

yourProjectRoot/vendor/friendsofsymfony/user-bundle/Model/UserInterface.php :

interface UserInterface extends AdvancedUserInterface, \Serializable
{
    const ROLE_DEFAULT = 'ROLE_USER';
    const ROLE_SUPER_ADMIN = 'ROLE_SUPER_ADMIN';
Fos user bundle default static role

In :

yourProjectRoot/vendor/friendsofsymfony/user-bundle/Model/User.php

 

public function addRole($role)
    {
        $role = strtoupper($role);
        if ($role === static::ROLE_DEFAULT) {
            return $this;
        }

        if (!in_array($role, $this->roles, true)) {
            $this->roles[] = $role;
        }

        return $this;
    }

(line of code from FOS userBundle repo on github)

If you try to add ROLE_USER, as ROLE_USER is ROLE_DEFAULT, you role is not added to $this->roles[] and not persisted, it is why even with a good working listener, ROLE_USER is never write into user account details in database.

Resources :

 

Twig filter to generate alt attribute of an img tag from filename

Today I want share a little Twig filter.

To add a Twig filter, you need to :

  • Create an extension class
  • Register as a service
  • ???
  • Enjoy

I worked on a project on which I never had the possibility to manage medias.
I had to take images filenames and render them through twig.
For some reasons, like SEO, I want to add the alt attribute of img tag, but no way to manage some text attached to images.
It was like a frontend to big property management system, I can’t alter content, just get and render.

I write this little twig filter, to take keyword from filename.

I PR this filter to twig extension [GITHUB for twig filter PR for alt image], and Fabpot say :

As the alt attribute is nowadays mostly used by screen readers, using a generated text seems like a bad idea. I’m :-1: on adding this.

I really think he make a point, and it is not the best way to do it, but, I can not do otherwise than have auto generated keyword as alt image.

If you want to use it :

So, even if it’s not such good practice, if you need this, and if it’s useful, use it 🙂

 

Jenkins et symfony2

L’intégration continue est une des bonnes bases à mettre en place au début d’un projet.

(Ce post me sert principalement de mémo, n’hésitez pas à commenter ou me contacter si besoin)
(Note : j’ai installé les outils en phar dans le répertoire de jenkins, il serait bien de voir si il y a moyen de tous les gérer avec composer)

Je choisis Jenkins que je vais installer sur mon serveur de dev, de cette manière, lorsque je ferais un push sur github, Jenkins lancera un build, puis déploiera mon application en préproduction.

Le développement et l’avancement du projet seront complètement transparents, ce qui est une bonne chose, pour (la future) équipe, et les associés.

Pour l’installation basique sous debian :

Tuto install site jenkins

Pour la suite, il faut bien penser à installer git et curl :

apt-get install curl git

1-admin

Sécurité Globale, pour définir un mode d’authentification :

2-admin-securite-globale

Je choisis de gérer les users Jenkins à part, il y en aura peu au début.
Ensuite, je choisis de donner le contrôle de Jenkins aux users, c’est surtout pour protéger le serveur des accès extérieurs non autorisés.

 

Après avoir valider je vais créer mon user :

0-admin-menu

Dans la « Gestion des utilisateurs » -> « Créer un utilisateur »

4-admin-user-add

Une fois inscrit, je préfère supprimer la possibilité de s’inscrire, retour dans le sécurité globale, pour décocher la case « 

Prochaine étape installer et configurer les plugins nécessaires et les configurer.

Pour faire mon setup j’ai utilisé les infos de plusieurs sources :

Pour avoir un mot de passe pour l’utilisateur Jenkins et pouvoir faire certaines manips :

http://stackoverflow.com/questions/6234016/jenkins-user-on-apt-get-install-installation

Sous debian 8, je suis logué en root, j’ai donc fait :

passwd jenkins

Maintenant que je peux faire un su jenkins, et me loguer.

J’ai choisis d’utiliser Github pour mon projet,

j’ai configuré jenkins pour lancer un build quand je push.

Reste à faire :

  • code check, duplicator, php mess detector
  • configurer mage.php pour déployer ma preprod à la fin si le build est ok

Pour cela il y a ce tuto : http://blog.lazycloud.net/utiliser-jenkins-pour-un-projet-symfony2/

Cependant je vais installer les outils en .phar dans le répertoire de jenkins (puisque j’ai commencé comme ça) :

Pdepend : (site officiel)

wget http://static.pdepend.org/php/latest/pdepend.phar
chmod +x pdepend.phar

Dans Jenkins : « Administrer jenkins » -> « gestion des plugins » -> onglet « Disponibles » -> Jdepend

5-plugins-jdepend

J’ajoute dans le script shell du build :

#pdepend - Calculate software metrics using PHP_Depend
php ~/pdepend.phar --jdepend-xml=build/logs/jdepend.xml --jdepend-chart=build/pdepend/dependencies.svg --overview-pyramid=build/pdepend/overview-pyramid.svg ./src || status=$((status+$?))

(Voir le lien vers le tuto les-tilleuls.coop plus faut pour le script shell)

Ensuite, il faut configurer après le build :

6-plugins-jdepend-config

7-plugins-jdepend-config

Php mess detector : (site officiel download)

wget -c http://static.phpmd.org/php/latest/phpmd.phar
chmod +x phpmd.phar
Ensuite il faut :
  •  ajouter une ligne au script shell
  • ajouter une action après le build pour montrer le résultat
php ~/phpmd.phar ./src xml --reportfile build/pmd/phpmd.xml cleancode, codesize, design, naming, unusedcode || status=$((status+$?))

8-plugins-phpMD-config

Php Code sniffer : (le github)

curl -OL https://squizlabs.github.io/PHP_CodeSniffer/phpcs.phar
php phpcs.phar -h

curl -OL https://squizlabs.github.io/PHP_CodeSniffer/phpcbf.phar
php phpcbf.phar -h

chmod +x phpcs.phar phpcbf.phar

#installation des standards symfony
#je le met dans le répertoire de jenkins
mkdir -p CodeSniffer/Standards

#J'ai utilisé ce repo, n'hésitez pas à commenter si vous en avez d'autres, mieux...
git clone git://github.com/escapestudios/Symfony2-coding-standard.git Symfony2

#config phpcs pour l'ajout du standard symfony
./phpcs.phar --config-set installed_paths CodeSniffer/Standards

Dans le script shell :

#phpcs-ci Find coding standard violations using PHP_CodeSniffer creating a log file for the continuous integration server
php ~/phpcs.phar --report=checkstyle --report-file=build/logs/checkstyle.xml --standard=Symfony2 ./src || status=$((status+$?))

Ensuite dans les plugins jenkins, il faut ajouter : « Checkstyle plugin »

Pour finir la config de l’affichage avec le plugin après le build:

9-plugins-checkstyle-config

(un tuto spécifique a code sniffer : http://www.theodo.fr/blog/2014/06/easily-comply-with-symfony2-coding-style-using-codesniffer-and-phpstorm-code-inspection/ )

Pour le déploiement automatique de la preprod, juste un cp ou un rsync à la fin du script shell peut faire l’affaire, il faut penser à ajouter l’utilisateur « jenkins » au groupe « www-data » pour pouvoir écrire dans le répertoire web. Un symlink ou bien un vhost configuré sur le répertoire workspace de Jenkins aurait fonctionné, mais Jenkins utilise l’env de test le symfony2 pour lancer les tests unitaires, et je préfère que ma preprod soit indépendante le Jenkins.

De plus, à termes, je prévois d’utiliser un outil comme Magallanes (pour l’instant il ne gère pas le deploy local)