jeudi 20 juin 2013

Redimensionnement des fenêtres sous Linux

Utilisatrice de Xubuntu depuis un certain, rien ne m'énerve plus que devoir attraper le bord de ma fenêtre pour la redimensionner. Je ne suis pourtant pas une handicapée de la souris !

Heureusement pour mes nerfs j'ai trouvé une solution qui ne nécessite aucune configuration ni installation complémentaire :

alt + clic droit n'importe où vers un bord et c'est parti ! Je me sens beaucoup mieux depuis...

mardi 11 juin 2013

Afficher les fichiers .gitignore dans les arborescences de Netbeans

Par défaut Netbeans (pour ma part Netbeans 7.3) affiche certains types de fichiers dans l'explorateur. Le fichier .gitignore n'en fait pas partie, ce qui n'est pas très pratique.

Heureusement, les fichiers affichés sont défini par un pattern, qui peut être configuré dans les préférences de Netbeans :

Allez dans Outils > Options > Divers, puis dans "Fichiers ignorés par l'IDE" modifier le pattern pour l'adapter à vos besoins :

^(CVS|SCCS|vssver.?\.scc|#.*#|%.*%|_svn)$|~$|^\.(?!(htaccess|gitignore)$).*$

lundi 10 juin 2013

Utilisation de this dans un appel AJAX en jQuery

J'ai voulu déclencher une action en AJAX au clic sur un bouton, et je me suis rendu compte que le code exécuté dans "success" avec "this" ne fonctionnait pas :

$('a.comment-remove').live("click", function(e) {
    e.preventDefault();
    $.ajax({
        type: "POST",    

        url: "note_comment_remove.php",
        data: { comment_id: $(this).attr('data-id') },
        success: function(data) {
            $(this).parent().parent().remove();
        }
    });

});

C'est tout simplement parce que le "this" à cet endroit s'applique au contexte AJAX et non au contexte de la fonction appelée sur le onclick. Il faut donc setter le context :

$('a.comment-remove').live("click", function(e) {
    e.preventDefault();
    $.ajax({
        type: "POST",    

        url: "note_comment_remove.php",
        data: { comment_id: $(this).attr('data-id') },

        context: this,
        success: function(data) {
            $(this).parent().parent().remove();
        }
    });

});

Et ça marche !

vendredi 7 juin 2013

Setter manuellement la pk d'une entité Doctrine 2

Parfois, pour une une bonne raison, il peut être utile de forcer l'identifiant d'un objet Doctrine2. Celà ne fonctionne pas naturellement, il y a une petite astuce que voici :

jeudi 6 juin 2013

Envoi d'email avec des accents dans le sujet

Un problème d'accent dans le sujet d'un email envoyé en PHP ?

Le sujet arrive dans votre boîte mail avec un problème d'encodage sur le "à".

Pour règler ce problème vous devez spécifier que l'encodage de l'email est UTF8 :

Ainsi cette fois votre email arrive bien avec le "à" visible dans le sujet et un contenu bien affiché !

mercredi 5 juin 2013

Comment avoir sa branche GIT dans le prompt et définir des alias

Utilisateur de GIT sous Linux, vous avez envie de vous simplifier la vie en ayant la branche courante GIT de votre projet dans le prompt, ainsi qu'une astérisque si des sources ont été modifiée, voici la marche à suivre :

Ouvrez le fichier :

/home/[votre nom d'utilisateur]/.bashrc

Ajoutez à la fin du fichier :

Voici ce que vous devriez voir : 
~/Workspace/project[master]$   

ou encore :
~/Workspace/project[master*]$   

Voilà une chose dont vous ne pourrez désormais plus vous passer !

Et pour la route une autre petite astuce, toujours pour vous simplifier la vie, pour ajouter des alias GIT en ligne de commande. Cela permet par exemple de taper juste  git s pour avoir le status au lieu de git status. Vous allez me dire que je chipote, mais mine de rien, c'est une économie de temps dont on arrive plus à se passer après.
Ouvrez le fichier :

/home/[votre nom d'utilisateur]/.gitconfig

Ajoutez par exemple :

[alias]
    s = status -s
    a = add .
    c = commit -m


Et n'hésitez pas à ajoutez les vôtres !

lundi 3 juin 2013

Importer un dump MySQL en ligne de commande

Lorsqu'un fichier *.sql est trop volumineux, il est impossible de l'importer depuis PHPMyAdmin ; il faut donc l'importer en ligne de commande.

mysql -h host -u user -ppass base_de_donnees < fichier

-> par exemple :
mysql -h localhost -u root -padmin videotheque < videos.sql

Et inversement pour exporter une base de données :
mysql -h host -u user -ppass base_de_donnees > fichier.sql

Savoir si un paquet est déjà installé sous Linux

Pour savoir si un paquet est déjà installé sur Linux, voici ce que vous pouvez taper dans le terminal :
aptitude show paquet
-> par exemple :
aptitude show libjargs-java

Si en bon informaticien vous trouvez que 3 secondes c'est trop, vous pouvez toujours essayer :
apt-cache policy libjargs-java | grep Installé

C'est presque instantané. Si rien n'est retourné, c'est que le paquet n'est pas installé. Si la version du paquet s'affiche, c'est que celui-ci est installé.

Problème de validation du numéro de téléphone AdSense

Il y a peu de temps, j'ai été confrontée à un problème sur AdSense : je devais valider mon numéro de téléphone pour débloquer mes gains, mais mon numéro de vérification n'était pas le bon.

Quand j'allais dans mon compte, le numéro de téléphone indiqué dans la section "Informations personnelles" était le bon, mais une fois sur la page de validation du numéro, c'était mon ancien numéro.

J'ai essayé de le changer en effaçant le numéro et en le remettant, rien n'y faisait, c'était toujours l'ancien numéro dans le processus de validation.

Puis par hasard en cliquant sur "Modifier" dans la section "Adresse", je me suis rendue compte qu'il y avait un autre numéro de téléphone ici, qui correspondait à mon ancien numéro. Après avoir changé celui-ci j'ai enfin pu valider mon numéro de téléphone.

Ca peut paraître bête, mais le support AdSense n'a jamais pu me renseigner, et les gens concernés sur les forums n'ont jamais pu apporter de solution. Tout ça pour un champ bien caché !

Mise en place de Varnish avec Symfony2

Après une mise en place un peu laborieuse, voici un petit récapitulatif de ce que j'ai fait pour faire fonctionner Varnish avec Symfony 2.

La configuration utilisée : Ubuntu 11.10, Varnish 3.0.0-4, Symfony 2.0

Installation


Ouvrir le terminal et taper :
sudo apt-get install varnish

Configuration de Varnish


Ouvrir et modifier le fichier de configuration de Varnish, par exemple :
sudo vi /etc/varnish/default.vcl

Surcharger les méthodes vcl_recv (réception des données), vcl_hash (construction de la clé unique qui correspondra à une entrée de cache donnée) et vcl_fetch :
sub vcl_recv {
    set req.http.Surrogate-Capability = "abc=ESI/1.0";

    if (req.restarts == 0) {
        if (req.http.x-forwarded-for) {
            set req.http.X-Forwarded-For =
            req.http.X-Forwarded-For + ", " + client.ip;
        } else {
            set req.http.X-Forwarded-For = client.ip;
        }
    }

    if (req.request != "GET" &&
        req.request != "HEAD" &&
        req.request != "PUT" &&
        req.request != "POST" &&
        req.request != "TRACE" &&
        req.request != "OPTIONS" &&
        req.request != "DELETE") {
            /* Non-RFC2616 or CONNECT which is weird. */
            return (pipe);
        }

    if (req.request != "GET" && req.request != "HEAD") {
        /* We only deal with GET and HEAD by default */
        return (pass);
    }

    if (req.http.Authorization || req.http.Cookie) {
        /* Not cacheable by default */
        #return (pass);
    }

    return (lookup);
}
set req.http.Surrogate-Capability = "abc=ESI/1.0"; permet de dire à Varnish de prendre en charge le langage ESI, qui est un langage de balisage qui s'insère dans le code HTML, et déclenche des traitement de construction de la page.

sub vcl_hash {
    ### these 2 entries are the default ones used for vcl. Below we add our own.
    hash_data(req.url);
    hash_data(req.http.host);

    if( req.http.Cookie ~ "locale" ) {
        hash_data(regsub( req.http.Cookie, "^.*?locale=([^;]*);*.*$", "\1" ));
    }


    return (hash);
}
if( req.http.Cookie ~ "locale" ) {
        hash_data(regsub( req.http.Cookie, "^.*?locale=([^;]*);*.*$", "\1" ));
}

permet de gérer un cache par langue, dans le cas où la langue n'est pas spécifiée dans l'URL. Par défaut, Varnish prend pour hash l'URL de la page, donc si votre langue est en session, vous obtiendrez le même contenu pour toutes vos langues. Mettre la locale en cookie, puis ici ajouter sa valeur au hash règle ce problème.

Nous verrons plus bas comment mettre votre locale en cookie.

sub vcl_fetch {
    if (beresp.http.surrogate-control ~ "ESI/1.0") {
        unset beresp.http.surrogate-control;
        set beresp.do_esi = true;
    }

    if (beresp.ttl <= 0s ||
        beresp.http.Set-Cookie ||
        beresp.http.Vary == "*") {
        /*
        * Mark as "Hit-For-Pass" for the next 2 minutes
        */
        set beresp.ttl = 120 s;
        return (hit_for_pass);
    }

    return (deliver);
}


Après avoir modifié ce fichier, redémarrez Varnish :
sudo service varnish restart


Configuration de Symfony2


app/config/config.yml

framework:
  templating: { engines: ['twig'] }
  session:
    default_locale: fr
    auto_start: false # Pour ne pas générer le PHPSESSID à chaque page (cache multi user)
  esi: true # Pour utiliser les tags ESI dans les templates Twig

app/config/routing.yml

_internal:
  resource: "@FrameworkBundle/Resources/config/routing/internal.xml"
  prefix: /_internal
-> pour la prise en charge des routes internes de Symfony2 dans les tags ESI

web/app.php

//$kernel = new AppCache($kernel);
-> On commente cette ligne pour passer par Varnish et non plus par le système de cache de Symfony2. (voir s’il y a une possibilité de gérer ça autrement car ce n'est pas très propre !)

Mise en place des blocs et pages cachées dans Symfony2


Pour cacher un bloc, il faut que celui-ci soit rendu par une action :
{% render "NomDeBundle:Test:monAction" with {'locale': app.session.locale}, {'standalone': true} %}

La locale sert à gérer le cache par langue, du fait que ce paramètre se retrouve dans l’url interne et donc dans le hash utilisé par Varnish. Si la langue n’est pas encore dans le cookie, le le hash ne contiendra pas la locale ni fr, ni en, mais sera vide. Il est donc mieux de faire :
{% if app.session.locale %}
    {% render "NomDeBundle:Test:monAction" with {'locale': app.session.locale}, {'standalone': true} %}
{% else %}
    {% render "NomDeBundle:Test:monAction" with {'locale': app.session.defaultLocale}, {'standalone': true} %}
{% endif %}

L’option 'standalone': true va faire que ce bloc deviendra un tag ESI.

Le tag ESI ressemblera à :
<esi:include src="http://example.com/1.html" onerror="continue"/>

Dans l’action qui rend le bloc :
/**
 * Renders the user cart block on the top right of the page
 * ESI block
 *
 * @Extra\Template("NomDeBundle:Test:esi_header_top.html.twig")
 */
public function cartBlockAction() {
    $response = new Response();

    $response->setContent($this->renderView('NomDeBundle:Test:esi_header_top.html.twig', array()));
    $response->setSharedMaxAge(600); # en secondes, donc environ 10 minutes
    $response->setPublic();


    return $response;
}
-> On ajoute les bons headers à la réponse, où setSharedMaxAge est le temps en secondes de la durée de vie du cache.
-> Même fonctionnement pour les pages complètes.

Pour ne pas mettre en cache les blocs utilisant par exemple la session, mettre les headers adéquats dans la réponse :
$response->setMaxAge(0);
$response->setPrivate();

Cookie de langue


Comme on l'a vu plus haut, si votre locale est dans votre session et non dans l'URL, il faut créer un cookie contenant la locale, au moment où vous changez votre locale ; dans une action changeLocaleAction par exemple.

Lorsque vous vous apprêtez à retourner l'objet Response :
$response->headers->setCookie(
    new Cookie(
        'locale',
        $votreLocale,
        time() + 600));

Pour faire vos tests


Créer un fichier de test qui fait un CURL sur une URL passée en paramètre GET avec le header “Surrogate-Capability:abc=ESI/1.0”
-> celà permet de voir les balises ESI dans le code source (par exemple en inspectant avec Firebug).

Par exemple web/testvarnish.php
<?php

$url = $_GET["url"];
$ret = curl_init($url);
curl_setopt($ret, CURLOPT_HTTPHEADER, array(
'Surrogate-Capability:abc=ESI/1.0'
));
echo curl_exec($ret);

?>

Enfin, vous pouvez tester les performances avec un outil tel que JMeter.