Mots-clé : web

Ingesup – Y-nov à terminer après les vacances

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;
        });
});

Mots clés de tentatives de hack

Voici tous les mots clés les plus essayés afin de trouver des failles sur mes sites Web 

123flashchat.php 99billdo.php abf_js.php aboutinfo.php
about.php account.php acc.php add.cgi.php
add_link.php addpost_newpoll.php addressbook.php add_rss.php
addsite.php addvip.php ad_main.php adminhead.php
admin.loudmouth.php admin.php agenda2.php3 agenda.php3
ains_main.php ajouter.php akocomments.php annonce.php
announcements.php anzagien.php api.php archive.php
artlist.php athena.php auth.cookie.inc.php authenticate.php
auth.header.inc.php auth.sessions.inc.php auto_check_renewals.php autoindex.php
b2verifauth.php bb_admin.php BE_config.php bild.php
bingoserver.php3 block.php bp_ncom.php bp_news.php
buddy.php builddb.php calcul-page.php calendar.php
cal.func.php cart_content.php cart.php catalogshop.php
challenge.php change_preferences2.php chat.php checkout.php
CheckUpload.php ch_readalso.php circ.php classified.php
classified_right.php class.mysql.php clearinfo.php clear.php
click.php client.php cls_fast_template.php cn_config.php
comments.php common.inc.php common.php config.inc.php
config.inc.php3 config.php configuration.php configuration.php.bak
configuration.php.old confirmUnsubscription.php conf.php connect.php
connexion.php contacts.php content.php convert-date.php
corpo.php CoupleDB.php cp2.php crea.php
create_file.php creat_news_all.php cron.php cross.php
custom_vars.php datei.php debugger.php defaults_setup.php
defines.php depouilg.php3 development.php dfcode.php
dialog.php digg.php direct.php displayCategory.php
display.php dix.php3 dosearch.php download.php
dp_logs.php editor.php edit.php editprofile.php
editsite.php email_subscribe.php environment.php errors.php
es_custom_menu.php es_desp.php eshow.php es_offer.php
eventcal2.php.php event.php eventscroller.php examplefile.php
example.php ezusermanager_pwd_forgott.php faq.php fcring.php
feed.php Flickrclient.php fonctions_racine.php footer.inc.php
footer.php form.php forum.php frame.php
ftp.php function.inc.php function.php functions_mod_user.php
functions.php fusebox5.php galerie.php games.php
genepi.php generate.php gen_m3u.php getpage.php
get_session_vars.php global.php graph.php gruppen.php
header.inc.php header.php head.php hello_sir.php
helperfunction.php help.php help_text_vars.php hioxBannerRotate.php
hioxRandomAd.php hioxstats.php hioxupdate.php home1.php
home2.php home.php hsList.php iframe.php
i_head.php image.php importinfo.php import.php
i_nav.php inc_group.php include.php inc_manager.php
inc_newgroup.php.php inc_smb_conf.php inc_user.php index1.php
index2.php indexinfo.php indexk.php index.php
index.php3 info.php inhalt.php initialize.php
initiate.php init.php in.php install.php
ip.inc.php joinus.php jscript.php latestposts.php
latex.php lib.editor.inc.php libsecure.php license.php
linkadmin.php link_main.php list.php ListRecords.php
loader.php load_lang.php load_phplib.php login.php
login.php3 log.php maguz.php main.inc.php
mainpage.php main.php main_prepend.php mamboleto.php
manage_songs.php master.php mcf.php member.php
members_help.php menu.php menu.php3 middle.php
migrateNE2toNE3.php minica_down.php mini-pub.php mitglieder.php
MOD_forum_fields_parse.php modules.php movie_cls.php msDb.php
mysave.php naboard_pnr.php network_module_selector.php newsadmin.php
newsarchive.php news.php newticket.php noticias.php
nukebrowser.php online.php owimg.php3 page.php
param_editor.php photo_comment.php php121db.php php4you.php
phpCards.header.php phphtml.php php-include-robotsservices.php phpMyChat.php3
phpunity-postcard.php ping.php playlist.php plus.php
p-news.php pollvote.php pop.php popup_window.php
portfolio.php port.php prepare.php prepend.php
preview.php principal.php print.php process.php
profil.php protection.php qte_web.php quickie.php
quick_reply.php random2.php rdf.php reactivate.php
readmore.php read.php recent.php rechnung.php
reconfig.php redirect.php register.php releasenote.php
rempass.php report.php reset.php robotstats.inc.php
rpc.php rss2.php rss.php run.php
s01.php s02.php s03.php s04.php
save.php saveserver.php searchbot.php search.php
search_wA.php self_adherent.php services.php settings.php
settings_sql.php shopping_cart.php shoutbox.php show_archives.php
show.php signin.php sinagb.php sinapis.php
sitemap.xml.php slogin_lib.inc.php smarty.php smilies.php
social_game_play.php song.php source.php spellcheckwindowframeset.php
start.php stats.php stphpapplication.php stphpbtnimage.php
stphpform.php strload.php str.php styles.php
submit_abuse.php submit_comment.php subscp.php tags.php
taxonservice.php template_csv.php template.php themes.php
thumbnail.php timedifference.php toolbar.loudmouth.php toplist.php
top.php track.php ubbt.inc.php unavailable.php
unsubs.php upload_local.php upload_multi.php upload.php
up.php user_language.php user_new_2.php user.php
validate.php viewforum.php view_func.php view.php
viewtopic.php visible_count_inc.php visitor.php volume.php
votebox.php vote.php warn.php war.php
watermark.php window.php worldpay_notify.php wp-cache-phase1.php
wp-config.bak.php wp-config.php wp-config.php.bak wp-config.php.old
wp-login.php wptable-tinymce.php xarg_corner_bottom.php xarg_corner.php
xarg_corner_top.php xmlrpc.php xt_counter.php zipndownload.php

Symfony 2 : avantages et inconvénients

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 :

  • Twig : c’est la seule chose qui semble vraiment pratique, utile et optimisée dans Symfony. A tel point que Zend l’utilisera comme moteur de templates, et Drupal 8 aussi. Un bon point pour Symfony, et le seul. Voici la suite.
  • Symfony prône les bonnes pratiques – ce qui est louable – pourtant j’ai dû faire trois fois du copier coller pour que ça fonctionne… Exemple le plus frappant : la bonne pratique (louable) est de séparer totalement la vue du modèle, et du contrôleur. Mieux : ils ont fait un endroit où on écrit toutes les requêtes complexes, afin de les séparer du modèle : ce sont les Repositories. Problème concret : quand on a un type fichier dans un formulaire qui est envoyé, le type « file » est posté. Si on veut écrire le fichier envoyé, ça passe par un contrôleur, et c’est lui qui est censé l’écrire en base de données ? Non ! Donc c’est côté de la base de données, côté modèle donc. Mais… les entités ne peuvent pas accéder à leur propre repository ! Si vous vous retrouvez dans ce cadre (hypra courant) alors vous allez devoir bidouiller, et créer une fonction statique qui renvoie le manager d’entités et demander à ce dernier de récupérer le repository de la classe en cours. Véridique. Bidouillage, bidouillage, bidouillage. Pourtant, j’insiste : Symfony prône les bonnes pratiques et essaie de faire au mieux, mais il échoue assez… attendez je cherche le qualificatif exact… j’ai trouvé : il échoue lamentablement.
  • Je pensais gagner du temps avec le bundle FOSUser. Faux ! En théorie il est censé simplifier la vie à mort et faire gagner énormément de temps. En pratique, c’est comme Symfony, il va vous falloir entrer dans son coeur, comprendre comment il a été écrit afin de pouvoir vous en servir. Exemple concret là aussi : il n’est fait que pour un seul type d’utilisateurs. Si on en veut plusieurs, il va vous falloir installer un bundle supplémentaire : le PUGXMultiUserBundle. Quelques heures plus tard après l’installation et la configuration, on m’a demandé de créer un rôle modérateur, qui doit pouvoir valider les fiches d’inscription, c’est à dire pouvoir afficher n’importe quelle fiche. Je ne peux même pas vous expliquer comment faire, car j’ai demandé aux experts Symfony – ce sont des personnes qui m’ont sous-traité le second travail que j’ai fait sur Symfony, de le faire eux même parce que je n’en pouvais plus de perdre autant de temps inutilement. J’ai beau chercher, mais un bon développeur Php va perdre beaucoup plus de temps à rechercher tout ça, installer, comprendre le fonctionnement, copier coller puis modifier le code, plutôt que de le faire direct à la main, avec des variables dans $_SERVER pour suivre quelques infos.
  • Symfony et le redimensionnement d’images. Je voulais juste, une fois qu’une image est arrivée en base de données, créer une vignette de cette dernière, afin de pouvoir l’afficher plus rapidement. J’ai donc cherché et voici le résultat – vous noterez bien qu’il est affligeant si on veut simplement redimensionner une image : en théorie  :
    • il faudrait mettre en place un service,
    • à partir de ce service, aller chercher des informations,
    • mettre en place toute une configuration, avec un système de hook (les « écouteurs »)

    … 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.

  • Doctrine est quelque chose… que je ne comprends pas. Il a été crée pour « optimiser » les requêtes. Déjà, rien que d’écrire ça, c’est inévitablement un non sens : on n’optimise pas les requêtes via du Php… À moins que je ne me trompe, on n’a jamais besoin d’optimiser les requêtes à ce niveau ! L’optimisation et la mise en cache doit se faire au niveau du moteur de bases de données. Pourtant, là, on doit écrire du SQL, mais pas vraiment. Olivier arrête de dire n’importe quoi me direz vous. Pourtant ça n’est pas une blague, lisez tout ça ici. Tout y est expliqué : ils ont « surchargé » l’écriture de requêtes, afin de… pouvoir optimiser les requête et mieux faire du cache. Si si. Et ils ont même inventé un concept super novateur, que personne ne connaissait avant (grincement de dents cynique), j’ai nommé : l’hydratation (ou en anglais : « hydration »). Non non, j’insiste, arrêtez de rigoler, c’est pas une blague, ils prennent ça très au sérieux là bas, regardez sur la documentation officielle et cherchez « hydration ». Par contre pour bosser il faut absolument savoir ce que ce mot d’une débilité profonde – au sens informatique – signifie : j’ai mené un entretien d’embauche avec une personne (qui se disait expert), et comme je n’ai pas parlé d’hydratation des données, ça ne lui a pas plu. Bon quand je dis « expert », il faut dire qu’il s’était fait dégager à grands coups de pieds au derrière par sa précédente boîte… j’arrête là je vais être méchant 😉
  • Avec Doctrine, on se prend tout le temps la tête sur les requêtes, ce qui fait qu’au final, comme jamais rien ne fonctionne comme on voudrait avec Doctrine, on se retrouve à vouloir connaitre quelle est la vraie requête faite en base. Voir ici. Réponse officielle : on ne peut pas. On ne peut pas voir les requêtes qui sont envoyées au moteur de base de données. Mais si continuez de lire, arrêtez de pleurer de rire ! Allez vous chercher un mouchoir, essuyez-vous les yeux et revenez.
  • Doctrine est censé simplifier la vie en proposant un modèle d’héritage. Exemple de ce que j’ai réalisé : une personne est la classe de base, et de là descendent les professeurs et les étudiants. Pourtant il est lourd. Très lourd. Très (très³²) lourd. Tellement lourd, que même sur la documentation officielle ils reconnaissent que Doctrine est lourd. La preuve sur la documentation officielle. En fait il est censé simplifier la vie du développeur, mais avec Doctrine il faut une machine énorme pour pouvoir faire tourner la moindre requête un tant soit peu complexe.
  • Pire. Encore bien pire (si c’est possible !). Si, comme moi, vous voulez utiliser des requêtes comprenant des calculs de distance, il vous faudra utiliser des fonctions mathématiques et là, de base, Doctrine ne connait rien, et il vous faudra passer quelques heures à installer un bundle dans votre installation, en modifiant pas mal de fichiers un peu partout. Si, là aussi, essuyez vos larmes de rire et lisez bien ce qui suit, car c’est vrai : il est impossible de faire immédiatement cette requête sous Symfony : "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.
  • Symfony est tellement complexe qu’il faut absolument avoir un débogueur intégré tel que xdebug et pouvoir faire du pas à pas dans un environnement tel que PhpStorm qui donne la possibilité de suivre tout, avec la pile d’appel. Rendez vous compte : pour développer un site Web simple, des frameworks comme symfony sont tellement complexes qu’il faut obligatoirement pouvoir faire du pas à pas. Ce sont des experts Symfony qui me l’ont expliqué. Sur le coup j’ai sincèrement (honnêtement, ce n’est pas ironique, c’est véridique) cru que c’était une blague. Php est tellement simple et fluide quand il est bien développé que je n’ai jamais eu à utiliser de débogueur pas à pas en plus de dix ans ! Et ma dernière prestation était en tant qu’expert Web chez Business & Décision, prestation pour la banque, et on n’a jamais eu besoin de faire du pas à pas ! D’ailleurs pourquoi je me justifie ? N’importe quel béotien doit se douter de ça…

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.

En conclusion :

Symfony est censé faire gagner du temps mais en pratique, on est obligé d’apprendre la globalité de tout le framework et au final on ne gagne absolument pas de temps, et bien pire : si le projet est petit, il faut à tout prix éviter des usines à gaz telles que Symfony.

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 :

  • Un formulaire d’inscription contenant tout ce qu’il faut (CSRF protection, re-Captcha etc) ;
  • Un CSS full responsive ;
  • Un blog WordPress (évidemment full responsive) ;
  • Un outil complet de capture d’écran basé sur du Webkit (très gros boulot) ;
  • Du code pour gérer un multi-partenariat en marque blanche ;
  • Du templating Smarty pour modifier l’habillage rapidement ;
  • Une documentation entièrement compatible PhpDocumentor ;
  • Une classe (assez longue) pour le traitement des images (archivage, signature chiffrée etc) ;
  • Un ORM qui :
    • ne fait des requêtes que quand c’est nécessaire,
    • fait des requêtes en SQL pur. Ouf, je respire, des heures entières de gagnées.
    • délègue au maximum à la base de données, ce qui est absolument vital pour avoir une application stable, rapide et pérenne sur le temps.
  • Une classe simple d’envoi de mail, avec la possibilité d’envoyer le texte alternatif (= si jamais le client ne peut pas lire du HTML, on peut préciser le texte). Merci 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;
    }
  • Tout est tracé et archivé, aussi bien en base que dans les captures d’écran, et tout est prévu pour une grosse évolution : un compte, ce compte pourra avoir plusieurs emails, plusieurs captures, toutes les connexions – réussies ou échouées – sont déjà tracées, ils pourront avoir une ou plusieurs adresses etc.

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.

PhpStorm, Windows / WAMP et xdebug : howto – la solution

Si jamais vous êtes comme moi, et que vous n’avez pas réussi à faire fonctionner PhpStorm avec xdebug sous Windows avec WAMP, vous avez peut-être le même problème que moi à savoir : le serveur Apache semble mal configuré – ou configurable, et incapable d’utiliser Php correctement avec xdebug.

Je passe toutes les étapes de configuration « classiques », parce qu’elles sont simples et bien documentées – y compris dans PhpStorm. Malgré tout ça, il se peut que cela ne fonctionne pas.

La solution :

Solution PhpStorm RunDebug Configurations pour Windows - WAMP

En fait il faut configurer PhpStorm pour qu’il ne passe pas par Apache, mais qu’il lance le serveur Php intégré (si, Php a un serveur HTTP, cherchez dans la documentation).

Et ainsi, le déboguage en ligne fonctionnera.

C’est grâce à cette vidéo que j’ai eu l’idée d’essayer :

http://www.youtube.com/watch?v=LUTolQw8K9A

Bien sûr, si vous essayez xdebug sous Linux, vous aurez nettement moins de difficultés :).

Symfony 2 Notice: Undefined offset: 0 in vendor/…/Hydration/SimpleObjectHydrator.php line 103

Voici un petit problème que j’ai résolu.

Supposons que vous ayez plusieurs entités qui descendent d’une seule.
Dans l’entité mère, vous précisez ce qui va différencier les autres via la propriété DiscriminatorColumn :

/**
 * @ORM\Entity
 * @ORM\Table(name="table_de_base")
 * @ORM\InheritanceType("JOINED")
 * @ORM\Entity(
 *   repositoryClass="SOCIETE\Bundle\MegaSuperBundle\Repository\PersonRepository"
 * )
 * @ORM\DiscriminatorColumn(name="person_type", type="integer")
 * @ORM\DiscriminatorMap({"1" = "PersonneBoss", "2" = "PersonneLarbin"})
 */
abstract class Personne extends BaseUser
{
...
}

Cela signifie en clair : l’entité «PersonneBoss», descendante de «Personne», aura aura la valeur «1» dans le champ person_type, et l’entité descendante «PersonneLarbin», de «Personne», aura la valeur «2» dans le champ person_type. C’est, comme son nom l’indique, un «discriminateur».

Si jamais vous vous retrouvez avec une erreur de ce type : Notice: Undefined offset: 0 in vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/SimpleObjectHydrator.php line 103, alors il se peut, comme c’était le cas pour moi, que les valeurs pour le «discriminateur» n’aient pas été correctement renseignées : dans mon cas, les valeurs étaient soit null, soit 0 et en fait cette valeur sert apparemment d’indice dans une table afin de pouvoir faire la jointure avec les descendants : donc il essayait de chercher une table avec l’indice 0, alors que je n’ai précisé que 1PersonneBoss») ou 2PersonneLarbin»)… donc pour la valeur 0, forcément, Symfony sort un Notice: Undefined offset: 0.

Bref, si vous avez une erreur comme celle-là, vérifiez que les valeurs en base de données sont cohérentes avec vos déclarations !

Packtlib : Mastering ExtJS : impressions à chaud

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.

  • Chapter 1. Getting Started
    Les bases pour installer ExtJS (LAMP, ou pour les newbies WAMP etc)
  • Chapter 2. The Login Page
    La plupart des applications ont une page d’identification. L’auteur explique comment faire l’identification « classique » avec ExtJS.
  • Chapter 3. Logout and Multilingual
    La plupart des applications ont une page de déconnexion, et en 2013, il faut savoir rapidement implémenter une autre langue. L’auteur explique comment faire cela : déconnexion et gestion du multilangue.
  • Chapter 4. Advanced Dynamic Menu
    Comment créer des menus dynamiques, qui sont constitués en fonction des droits de la personne connectée (cf chapitres 2 et 3).
  • Chapter 5. User Identification and Security
    Création d’une page de gestion complètes des identifications : comment donner les permissions à des utilisateurs (lister tous les utilisateurs, créer, éditer et supprimer des utilisateurs et aperçu d’une image d’un utilisateur qui va être envoyée).
  • Chapter 6. MySQL Table Management
    Création d’un système modulaire appelé « données statiques ». Liste de toutes les informations d’une table MySQL. Créer de nouveaux enregistrements dans la table. Live search sur les tables. Mettre en place des filtres. Éditer et supprimer des enregistrements. Créer un composant abstrait réutilisable pour toutes les tables.
  • Chapter 7. Content Management
    Gestion de contenu complexe avec ExtJS : comment gérer les associations many-to-many. Comment gérer et faire des formes avec les associations. Explication pour faire des composants réutilisables.
  • Chapter 8. Adding Extra Capabilities
    Possibilités supplémentaires. Comment imprimer des champs d’un panneau de type grille (GridPanel). Comment exporter des champs d’un panneau de type grille (GridPanel) en PDF ou au format Excel. Comment créer des graphiques /courbes. Comment utiliser des composants tiers ou des plugins.
  • Chapter 9. The E-mail Client Module
    Cette partie explique comment développer un client Web mail avec ExtJS. Comment dessiner le client email. Comment lister les emails. Comment créer la boîte de réception (gestion d’un TreePanel). Comment gérer le drag’n’drop entre deux composants (grid et tree). Améliorer le GridPanel de manière impressionnante (customisation).
  • Chapter 10. Preparing for Production
    Comment créer un thème personnaliser. Comment préparer (packager) l’application pour qu’elle soit prête pour la production. Comment utiliser le packager. Il peut sembler y avoir peu de choses dans ce chapitre, mais les explications sont longues et détaillées et j’ai appris énormément de choses.
  • Chapter 11. Building a WordPress Theme
    Je pensais que l’idée était de faire à la main un thème WordPress, mais non : l’idée est d’utiliser tout l’habillage au complet ExtJS, ainsi que le code JavaScript qui va avec, afin de l’intégrer dans une application WordPress. Comment fonctionne WordPress. Comment créer un thème, un header, un footer, une page principale, une Sidebar, une page d’articles et enfin une page de type « Page » (par opposition aux pages de type « Article »)
  • Chapter 12. Debugging and Testing
    C’est un des chapitres les plus pratiques pour la vie quotidienne : la plupart des outils avancés et peu connus y sont, pourtant il sont très utiles : comment déboguer une application ExtJS. Comment tester les applications ExtJS. Les outils utiles (JSLint, YSlow, Sas, Less, YUI Compressor…). Comment passer de ExtJS à une version mobile. Composants tiers et plugins utiles pour développer rapidement. Résumé

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 !

De la nourriture pour le cerveau !

Pris ici, et traduit en français par moi même.

C’est mon site favori.

Je le visite presque tous les jours.

Il n’est pas « responsive ». Il n’est pas optimisé pour iPhone.
Il a l’air flou sur un affichage de type Retina.
Il n’utilise pas le tout dernier framework HTML5/CSS3.
Il n’a pas un « rythme vertical réfléchi pour être agréable ».
Les fontes n’ont rien d’original. Ni Le skeuomorphique ni plat.
Il n’a pas son propre favicon.
Il n’a aucune application native Twitter ou Instagram.
Il n’utilise ni d’AJAX ni de SCRUM ou de node.js ou de Sinatra.
Il n’a pas sa propre API ou son suivi RSS, et pas de VC funding.
Il n’a jamais été numéro un sur un blog technique connu et n’a jamais gagné un seul concours.

Il me dit comment faire la soupe du jour.

Une information donnée gratuitement, qui est pratique pour la personne qui le lit.

C’est ça, le web design.

Symfony 2 : mon site de démonstration est sorti : livrepizzas

Mon site de démonstration pour l’utilisation du framework Symfony 2 est sorti.

http://www.livrepizzas.fr

Ce n’est qu’un site de démonstration, il est loin d’être parfait !

  • Bien sûr il est optimisé pour google et pour les mobiles et tablettes.
  • Bien sûr il est compatible w3c.
  • Bien sûr il est moderne et utilise du HTML5.
  • Bien sûr il est en responsive design.
  • Bien sûr c’est facile à faire. 🙂

Si vous avez des commentaires ou suggestions à faire, n’hésitez pas !

Drupal : code pour les liens avec des URLs dynamiques

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>

Cours optimisation Internet – Ecole d’ingénieurs des Mines

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.