curl
Curl hints / aide
curl -v -H "Host:www.djangoproject.com" https://www.olivierpons.fr/
curl -v -H "Host:www.djangoproject.com" https://www.olivierpons.fr/
Django a une manière de gérer la date et l’heure de façon très pratique… encore faut-il la comprendre !
Il y a la date et l’heure qui prend en compte le fuseau horaire.
Imaginez qu’un type en Chine envoie une date et une heure avec le fuseau horaire de Chine sur votre serveur, via un formulaire Web.
Le plus pratique est donc d’enregistrer au format UTC = 0 décalage horaire en se souvenant que l’heure est basée sur le fuseau de Chine.
Comme ça, si un Français demande cette heure, hop, il voit que c’est pour un fuseau +1 (ou +2 selon la saison) et fait le calcul tout seul.
Génial non ?
Seule chose à laquelle il faut faire attention : Python a son package datetime
, et il y a une fonction now()
qui n’est pas la même que la fonction now()
de Django !
Donc si vous voulez enregistrer une date « style Django », il faut faire cet import :
from django.utils.timezone import now
Ensuite, vous pourrez, par exemple, faire des différences de secondes qui fonctionneront :
def is_expired(self, nb_seconds):
return (now()-self.date_last_update).total_seconds() > nb_seconds
(Attention au code précédent : deux choses : le now()
qui doit être importé comme je l’ai dit, et total_seconds()
auquel il faut faire attention, car il y a une propriété seconds
qui ne fait pas du tout la même chose….)
et surtout ne pas faire from datetime import datetime
Si vous faites comme moi et faites le mauvais import, l’heure ne sera pas « recentrée » à fuseau + 0 afin que tout le monde puisse la lire !
Voici une petite compilation de sites que j’ai apprécié, il y a plus ou moins longtemps :
Voici ce qu’on peut faire quand on commence à maitriser WordPress :
http://www.studio-output.com/
Utiliser à la main uglifyjs :
http://marijnhaverbeke.nl/uglifyjs
Terminer l’appel à la déconnexion en AJAX
$(document).ready(function () { $('div[role="navigation"]') .find('form') .submit(function () { $(this).fadeOut(function() { $.ajax({ url: $(this).attr('action'), method: $(this).attr('method'), params: $(this).serialize() }) .done(function (data) { if (data.success) { /* montrer le bouton de déconnexion */ } else { /* montrer un message d'erreur (PAS alert) et * remontrer la form de connexion */ } }) .error(function () { alert('Erreur'); }); }); return false; }); });
Après bon nombre de commentaires, voire d’insultes (si si), je résume l’article qui suit :
Vous allez toujours entendre le même discours pour ceux qui commencent avec Symfony et qui n’ont jamais vraiment développé d’autres choses, qui est quelque part logique : Symfony c’est génial, c’est super, c’est la réponse à la vie, l’univers, et au reste, il aurait dû s’appeler « Php – 42 » ou quelque chose comme ça (et si vous ne comprenez pas l’allusion c’est qu’on n’a ni le même background, ni le même humour). C’est, de plus, très souvent le genre de personnes qui n’admettent pas qu’ils n’ont pas d’expérience et cela finit à l’insulte ou au pugilat.
S’ils avaient vraiment pratiqué d’autres choses, il verraient qu’il y a plein d’autres trucs ailleurs, et ils verraient qu’à d’autres endroits il y a des choses mieux.
Ceux qui n’ont pas d’expérience mais l’esprit ouvert me demandent ce qu’il y a comme autres choses à tester, et je leur réponds avec plaisir ! Ceux qui n’ont pas d’expérience et ont besoin de justifier leur existence diront « c’est un gros con il est dépassé il n’y comprend rien ». Je ne donne des cours que pour les premiers. Les autres je les laisse faire alt-tab en permanence entre Facebook et Symfony (et si vous saviez tout ce que je pense quand je parle ainsi…).
Après avoir développé deux applications relativement basiques, voici les inconvénients que j’ai relevé de Symfony :
$_SERVER
pour suivre quelques infos.… bref, refaire des milliers de choses d’une inutilité absolument affligeante, tout ça pour faire un simple resize. Après avoir passé plusieurs heures à installer le LiipImagineBundle : et m’être aperçu que pour faire un resize, il fallait déclarer vouloir utiliser un service dans ‘app/config/config.yml’, je vois qu’il y a un exemple qui est censé fonctionner sur stackoverflow ici. Et puis là le code qui fonctionne utilise getRequest()
. Et le container. Moi j’en avais besoin dans l’entité, car c’est ici qu’on écrit les informations en base de données. Pour pouvoir accéder à un container dans une entité, il faut faire un méga hack, ou pire (lire les deux réponses ici). La seule réponse viable c’et de.. créer un service ! Non mais allô quoi ! Juste pour un crop ! Vraiment on est en plein délire. Hop, top chrono : google =» php imageresize, copier coller, et en moins de 5 minutes, tout fonctionnait. Symfony clame haut et fort qu’il vous fait gagner des heures de boulot ? C’est une blague, une grosse blague ! Posez les pieds sur terre, voici la réalité concrète du terrain : Symfony essaie de pousser encore et encore l’abstraction à son maximum mais on arrive à des non-sens comme celui-là : une entité qui appelle deux services différents, surchargés à mort, des centaines de lignes de code totalement inutiles, juste pour faire un resize. C’est tellement grossier comme problème qu’on en arriverait presque à croire que c’est faux… mais c’est vrai, et les liens que j’ai mis sont bien là pour le prouver.
"SELECT COS(5) as distance;"
. Non non ça n’est pas une blague, c’est du sérieux. Voir tout mon article détaillé ici.Je n’ai pas le temps de lister toutes les autres choses qui m’ont fait perdre un temps fou. J’ai vendu un site que je comptais faire en maximum dix jours, et je l’ai fait en un mois. Symfony était tout bonnement un mauvais choix.
Pour la petite note, les personnes qui m’ont sous traité le projet – qui tourne bien actuellement – ont été déçues parce que je n’ai pas tenu mes délais, et que mes premières livraisons n’étaient pas de bonne qualité – alors que je « semblais » compétent. Je ne jette pas tout sur Symfony, mais bon sang quelle grossière erreur de ma part ! Pour vous donner une idée de comparaison : j’ai terminé en 3 jours un site qui devrait être mis en ligne incessamment sous peu : un site spécialisé la constatation fiable de sites Web. Il contient :
CSRF
protection, re-Captcha
etc) ;Webkit
(très gros boulot) ;Smarty
pour modifier l’habillage rapidement ;PhpDocumentor
;SQL
pur. Ouf, je respire, des heures entières de gagnées.PHPMailer
, un outil simple, ultra facile d’utilisation, et utilisé dans ma classe, finit par un code ainsi :
$mail = new ObjetMail( EMAIL_DEFAUT_FROM, EMAIL_DEFAUT_FROM_NAME, EMAIL_DEFAUT_REPLYTO, EMAIL_DEFAUT_REPLYTO_NAME, $email, 'Capture bien prise', /*... Texte HTML ...*/, /*... Texte alternatif ...*/ ); try { $mail->send(); array_push( $this->_TabResult, $this->trad->get( 'mail_envoye_en_attente_confirmation' ) ); } catch (Exception $e) { $this->addTabErr( $this->trad->get('err_envoi_email') ); $ok = false; }
Faire la même chose avec Symfony ? Je vous laisse estimer le temps de faire les estimations, le cahier des charges, le devis, le développement, mais attention, grâce à Symfony vous allez gagner énormément de temps : Symfony peut générer le CRUD pour l’administration en ligne de commande, regardez ici. Oulah que de temps gagné ! Sachant que je génère un custom getter-setter en 3 touches avec vim, même s’il y a plusieurs centaines de champs, et plusieurs dizaines de tables, je ferais ça « à la main » au maximum en une journée… enfin bon en comparant avec Symfony je peux dire sans éxagérer : sans Symfony, une journée de perdue, mais dix d’économisées ! Mais pourquoi je continue à essayer de prouver que Symfony ne fait jamais gagner de temps, moi ? Même ces personnes expertes Symfony ont décidé de le laisser tomber et de n’utiliser que Silex pour tous leur nouveaux projets à moins qu’ils n’aient vraiment besoin de choses spécifiques à Symfony… et personnellement je n’arrive pas à voir ce que Symfony a de si spécifique dont on ne peut pas se passer 🙂 … A l’inverse, je vois vraiment toutes les raisons pour lesquelles on peut se passer de Symfony.
Pour les Anglais uniquement, vous serez sûrement intéressées :
Le livre Mastering ExtJS.
Mastering Ext JS montre aux lecteurs comment utiliser le potentiel de Ext JS au complet et créer une application au complet en partant de rien, mais explique aussi comment créer un thème WordPress avec ExtJS. Cette dernière section est assez surprenante, mais semble efficace.
Au final, ce livre comporte beaucoup de choses intéressantes, et (à mon sens), même si vous êtes développeur avancé ExtJS, les trois derniers chapitres sont super intéressants et rien que pour ces trois derniers, même si vous trouvez qu’acheter un livre c’est trop cher (ce que je comprends ;)), les quelques 17 € que vous coûteront la version en ligne seront rapidement rentabilisés.
D’ailleurs en parlant de version en ligne, ils ont complètement refait leur reader en ligne, et ce dernier est très bien fait : moi qui suis très critique, je n’ai rien trouvé à redire !
Comment utiliser createQueryBuilder()
?
La documentation n’est pas très claire sur le sujet. Enfin, disons que si vous êtes comme moi, il va vous manquer des exemples pour mieux comprendre. Je vais essayer de vous faire gagner du temps.
Voilà le problème : j’ai crée un repository pour mes partenaires, que j’ai appelé PartenaireRepository.php
.
Dans la plupart des exemples, ils utilisent createQueryBuilder('p')
, qui semble pratique (puisqu’il référence immédiatement la table et en fait un alias (dans mon exemple c’est p
)
J’ai donc voulu utiliser createQueryBuilder()
mais j’ai eu besoin deux jointures d’affilée : les partenaires avaient une ou plusieurs adresses, et ces adresses étaient réliées à des villes. La solution est en fait simple, à partir du moment où on a compris le principe :
class PartenaireRepository extends EntityRepository { /** * Récupération de tous les partenaires donnés pour un * code postal donné. */ public function findAllActiveByCp($cp) { return $this->createQueryBuilder('p') ->leftJoin('p.adresses', 'a') ->leftJoin('a.ville', 'v') ->where('v.cp=:cp') ->setParameter('cp', $cp); ... blabla } }
Ici, le leftJoin('p.adresses', 'a')
signifie : dans la classe Partenaire
que j’ai déclarée dans le fichier Entity\Partenaire.php
, il y a la propriété adresses
et tu vas faire une jointure dessus, et cette jointure, tu vas l’aliaser "a
". On aura donc, à partir de cette jointure, une référence à une table adresse
qu’on pourra utiliser via le "a
".
Il est possible de refaire une jointure avec cet alias !
La preuve : la jointure juste après : ->leftJoin('a.ville', 'v')
qui signifie, exactement sur le même principe : dans le fichier Entity\Adresse.php
, il y a la propriété "ville
" et tu vas faire une jointure dessus, et cette jointure, tu vas l’aliaser "v
".
Enfin, je termine sur le "where
" classique :
->where('v.cp=:cp')
.
D’après ce que j’ai compris, on ne peut faire des jointures que sur des propriétés qui sont elles même déclarées en tant que jointures. Donc, sur mon fichier « entité » Partenaire
, ma jointure est déclarée ainsi :
/** * @ORM\ManyToMany(targetEntity="Adresse") * @ORM\JoinTable(name="partenaire_adresse", * joinColumns={@ORM\JoinColumn(name="id_partenaire", referencedColumnName="id")}, * inverseJoinColumns={@ORM\JoinColumn(name="id_adresse", referencedColumnName="id")} * ) */ private $adresses;
Et de la même façon, sur mon fichier « entité » Ville
, ma jointure est déclarée ainsi :
/** * @var string * * @ORM\ManyToOne(targetEntity="Ville") * @ORM\JoinColumn(name="id_ville", referencedColumnName="id") */ private $ville;
J’espère vous avoir fait gagner du temps, parce que pour moi, la syntaxe n’était pas évidente à trouver.
Drupal : comment s’adapter à une migration si le site n’est plus à la racine ?
Dans les modules, activation du module « Php filter », afin que le code Php soit exécuté.
Et dans le texte qu’il y a dans un bloc « menu », par exemple, vous pourriez vous inspirer d’un code comme celui-ci (sachant qu’il vous faut absolument revoir l’indentation, qui n’est pas acceptable pour un code digne de ce nom) 🙂 :
<?php /* Ce code sert à générer les URLs * de manière dynamique, afin que si l'installation * Drupal est dans un sous-répertoire, les liens * soient "automatiquement" adaptés, via * le code "'absolute' => TRUE", */ ?> <ol> <li> <?php echo l(t('Menu1'), 'lien1', array( 'absolute' => TRUE, 'query' => array() )); ?> </li> <li> <?php echo l(t('Menu2'), 'lien2', array( 'absolute' => TRUE, 'query' => array() )); ?> </li> <li> <?php echo l(t('Menu3'), 'lien3', array( 'absolute' => TRUE, 'query' => array() )); ?> </li> <li> <?php echo l(t('Menu4'), 'lien4', array( 'absolute' => TRUE, 'query' => array() )); ?> </li> </ol>
Après avoir fait ma présentation, cela fait toujours plaisir de savoir qu’on est suffisamment intéressé pour demander ma présentation !
Cliquez sur le lien pour la récupérer, et n’hésitez pas à laisser une appréciation sur ce qui était bien et ce qui manquait éventuellement, sachant que j’ai fait ce que je pouvais dans un laps de temps aussi court 😉
Cliquez ici.