Catégorie : développement Internet

IUT informatique : script Shell pour injecter la base de données WordPress

Dumper la base de données

mysqldump -u root -pmysql wordpresslocal > 2013.12.19.wordpresslocal.sql

Réinjecter la base de données

mysql -u root -pmysql -e "DROP DATABASE IF EXISTS wordpresslocal;"
mysql -u root -pmysql -e "CREATE DATABASE wordpresslocal DEFAULT CHARACTER SET utf8;"
mysql -u root -pmysql -e "USE wordpresslocal ; GRANT ALL PRIVILEGES ON wordpresslocal   TO 'v69a6YK614454xA'@'localhost' IDENTIFIED BY 'nQ1e7NfDRXG2q6H';"
mysql -u root -pmysql -e "USE wordpresslocal ; GRANT ALL PRIVILEGES ON wordpresslocal.* TO 'v69a6YK614454xA'@'localhost' IDENTIFIED BY 'nQ1e7NfDRXG2q6H';"
mysql -u root -pmysql wordpresslocal < 2013.12.19.wordpresslocal.sql

IUT : comment faire fonctionner WordPress en local

Solution trouvée ici

Créer un fichier .htaccess à la racine de ce que vous avez décompressé. Ce fichier doit contenir :

DirectoryIndex index.php index.html
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress

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 !

symfony 2 : isset et null avec Twig

Une des questions qu’on cherche le plus souvent avec Twig, c’est comment vérifier si une variable existe ou pas ?

La réponse se fait en trois étapes :

  1. Vérifier si une variable existe (= si elle a été initialisée) :
    En php, c’est isset().
    En Twig, c’est defined.
    Exemple de code Twig :

    {% if app.user is defined %}
    Code html
    {% endif %}
  2. Vérifier si une variable n’est pas null (= elle est définie, mais contient la valeur null) :
    En php, c’est !is_null().
    En Twig, c’est is not null.
    Exemple de code Twig :

    {% if app.user is not null%}
    Code html
    {% endif %}
  3. Vérifier si une variable existe et qu’elle n’est pas null (= elle est définie, et contient autre chose que la valeur null) :
    En php, c’est isset() && (!is_null()).
    En Twig, c’est is defined and is not null.
    Exemple de code Twig :

    {% if app.user is defined and app.user is not null%}
    Code html
    {% endif %}

En espérant que cela aide du monde !

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 !

PHPExcel : comment générer des cellules avec des styles différents

PHPExcel est un outil pour génerer des fichier Excel en Php.

Il y a beaucoup d’exemples, et tout est bien censé fonctionner. Comme les méthodes sont très parlantes et que c’est bien écrit, j’ai voulu faire un code qui crée plusieurs cellules avec des styles différents.

Ce qui n’est pas expliqué dans la documentation c’est ce qui suit : les « pages » Excel (« tabsheets ») ont des groupes de styles, et chaque cellule référence un de ces styles (sachant qu’il y a un style par défaut). Donc ce que j’ai fait était faux : j’ai essayé d’appliquer directement un style à une cellule, puis un autre style à une autre cellule. Le code exécuté ne correspondait pas du tout à ce que je pensais. Le code faisait ceci : je recherche le style à appliquer parmi tous les styles qui sont recensés dans le « tabsheet » courant. Comme le style n’existait pas, alors il remplaçait le style par défaut du « tabsheet » courant par celui que je demandais à appliquer. Donc comme toutes les cellules référençaient le même style, elles avaient toutes les mêmes propriétés, et évidemment, la dernière « application de style » modifiait en conséquence toutes les cellules. La solution est simple, mais elle n’est pas documentée, et de plus, la fonction à appeler (« duplicateStyle() ») n’est pas très parlante, contrairement à la totalité de l’outil PhpExcel (ce qui est d’autant plus déroutant).

Voici mon code, et je vous explique après pourquoi ça ne fonctionnait pas, et ce qu’il faut faire pour que cela fonctionne.

(1) Je crée deux tableaux différents, de styles différents :

$styleParDefaut = array(
    'font' => array(
        'name'   => 'Bernard MT Condensed',
        'size'   => 10,
        'italic' => false,
        'bold'   => false,
    ),
    'alignment' => array(
        'horizontal' => PHPExcel_Style_Alignment::HORIZONTAL_LEFT,
        'wraptext' => false
    )
);
$styleDonneesTelechargeesLe = array(
    'font' => array(
        'name'   => 'Arial',
        'size'   => 10,
        'italic' => true,
        'bold'   => false,
    ),
    'alignment' => array(
        'horizontal' => PHPExcel_Style_Alignment::HORIZONTAL_LEFT,
        'wraptext' => false
    )
);

(2) Puis je tente de les assigner, un par cellule, comme ça je pensais obtenir deux cellules avec deux styles différents :

function setText($sheet, $colonne, $ligne, $style, $text)
{
    $cell->setValue($text);
    $cell = $sheet->getCellByColumnAndRow($colonne, $ligne);
    $cell->getStyle()->applyFromArray($style);
    $cell->setValue($text);
}

Et le code par cellule :

setText(
    $sheet,
    $colonne, $ligne + 3,
    $styleParDefaut,
    'Texte 1'
);
setText(
    $sheet,
    $colonne, $ligne + 5,
    $styleDonneesTelechargeesLe,
    'Texte 2'
);

Eh bien ça ne fonctionne pas du tout comme cela. En lisant le code, il faut générer dynamiquement les style, et les passer via duplicateStyle().

Donc :

(1) Créer les styles :

$styleParDefaut = new PHPExcel_Style();
$styleParDefaut->applyFromArray(array(.. même chose que précedemment ..));
$styleDonneesTelechargeesLe = new PHPExcel_Style();
$styleDonneesTelechargeesLe->applyFromArray(array(.. même chose que précedemment ..));

(2) Les réutiliser via duplicateStyle()

$cell = $sheet->getCellByColumnAndRow($colonne, $ligne);
$sheet->duplicateStyle($style, $cell->getCoordinate());
$cell->setValue($text);

Symfony: The form’s view data is expected to be of type scalar, array or an instance of \ArrayAccess, but is…

J’ai eu l’erreur qui est le titre de mon post.

Pourtant, j’avais tout fait correctement. J’avais mis en place une collection ManyToMany simple : un partenaire peut être relié à une ou plusieurs personnes et une personne peut être reliée à un ou plusieurs partenaires.

Sur symfony 2.1, tout fonctionnait correctement, et j’ai fait la mise à jour sur symfony 2.3 (pour rester à la pointe 😉 ) mais là une erreur apparaissait :

« The form’s view data is expected to be of type scalar, array or an instance of \ArrayAccess, but is an instance of class HQF\Bundle\PizzasBundle\Entity\Personne. You can avoid this error by setting the « data_class » option to « HQF\Bundle\PizzasBundle\Entity\Personne » or by adding a view transformer that transforms an instance of class HQF\Bundle\PizzasBundle\Entity\Personne to scalar, array or an instance of \ArrayAccess. »

Après un bon moment de recherche, j’ai trouvé ma solution ici.

Dans mon bundle j’avais mon fichier « Bundle/Form/Type/PartenaireType.php » dans lequel j’avais déclaré tout comme il fallait :

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('nom',                    'text');
        $builder->add('site_actif',             'checkbox');
        $builder->add('afficher_img_produits',  'checkbox');
        $builder->add('commande_en_ligne',      'checkbox');
        $builder->add('livraison',              'checkbox');
        $builder->add('livraison_delai',        'integer');
        $builder->add(
            'personnes',
            'collection',
            array(
                'type' => new PersonneType(),
            )
        );
    }

Tout était parfait, et fonctionnait sous Symfony 2.1. Mais lors de la mise à jour, ça ne fonctionnait plus. Il manquait cela : préciser à nouveau que la PersonneType était liée à un type Personne :

'options' => array('data_class' => 'HQF\Bundle\PizzasBundle\Entity\Personne')

Donc dans mon code ça donne ça :

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('nom',                    'text');
        $builder->add('site_actif',             'checkbox');
        $builder->add('afficher_img_produits',  'checkbox');
        $builder->add('commande_en_ligne',      'checkbox');
        $builder->add('livraison',              'checkbox');
        $builder->add('livraison_delai',        'integer');
        $builder->add(
            'personnes',
            'collection',
            array(
                'type' => new PersonneType(),
                'options' => array(
                    'data_class' => 'HQF\Bundle\PizzasBundle\Entity\Personne'
                ),
            )
        );
    }

Un grand merci à Stackoverflow, sinon j’aurais mis bien plus de temps à m’en sortir, je pense !

jQuery et la ré organisation de div / cartes

Si jamais vous voulez faire plein de petits « cartes », ou « article », voire des photos, et que vous vouliez qu’ils soient automatiquement réorganisés, voici ce qu’il vous faut :

Ce plugin en JavaScript pour jQuery est absolument génial : http://masonry.desandro.com/. Essayez de redimensionner les fenêtres et vous verrez comment tout ça est réorganisé.

Css inutilisé : comment supprimer toute information inutile – how to

Si jamais vous avez un site qui utilise plein d’outils et que vous pensez que beaucoup de votre CSS n’est pas utilisé, alors allez jeter un coup d’oeil ici : http://unused-css.com/.

C’est un site qui aide pour dire quels sont tous les styles CSS déclarés, et lesquels ne sont pas utilisés.
Extrêmement pratique.

Notez tout de même que si jamais vous construisez dynamiquement des objets DOM (notamment en jQuery) qui utilisent un CSS particulier, et que ce dernier n’est pas utilisé ailleurs, alors je pense que ça trompe le vérificateur et qu’il pense que ce CSS n’est jamais utilisé.