jeudi 4 février 2010

Corriger le bug Zend Dojo Editor sous firefox

Après mes péripéties sous IE avec le Zend_Dojo_Editor, voilà que j'en ai avec Firefox. Impossible de rendre le champs descriptif (éditeur de texte) obligatoire sous Firefox.  J'ai donc fais un debug des variables que me transmet le formulaire lorsque je laisse le champs vide dans le formulaire. Sous IE, Chrome, Safari j'ai :

Array (1)(
[descriptif] =>  string(0) ""
)
Sous Firefox j'ai eu la surprise de voir :
Array (1)(
[descriptif] =>  string(36) "<br _moz_editor_bogus_node="TRUE" />"
)
C'est quoi ce bordel ! Pour reprendre mon exemple précédent, voici ce que j'avais au départ :
class Default_Form_Demande extends Zend_Dojo_Form
{
//...

/**
*
* @see    http://framework.zend.com/manual/en/zend.form.html
* @return void
*/
public function init()
{
//...
$this->descriptif = new Zend_Dojo_Form_Element_Editor('descriptif');
$this->descriptif->setLabel('Descriptif de la demande')
->setRequired(true)
->setFilters(array('StringTrim'))
->setEditActionInterval(2)
->setHeight('250px');
$this->addElement($this->descriptif);
//...
}
//...
}  
Pour corriger ce problème lier à Firefox j'ai donc ajouter un filtre sur le champs descriptif. Maintenant j'ai :
class Default_Form_Demande extends Zend_Dojo_Form
{
//...

/**
*
* @see    http://framework.zend.com/manual/en/zend.form.html
* @return void
*/
public function init()
{
//...
$this->descriptif = new Zend_Dojo_Form_Element_Editor('descriptif');
$this->descriptif->setLabel('Descriptif de la demande')
->setRequired(true)
->setFilters(array('StringTrim',
                        array('PregReplace',array('#<br _moz_editor_bogus_node="TRUE" \/>#i',''))
            ))
->setEditActionInterval(2)
->setHeight('250px');
$this->addElement($this->descriptif);
//...
}
//...
}
Après l'ajout de ce petit filtre :
array('PregReplace',array('#<br _moz_editor_bogus_node="TRUE" \/>#i',''))
Le formulaire reprend son fonctionnement normal, et les champs Zend_Dojo_Form_Element_Editor qui sont requis redeviennent obligatoires.

mercredi 6 janvier 2010

Corriger le bug zend form dojo editor sous IE

Voilà en développant un petit formulaire avec le framework de Zend, j'ai utiliser le Zend_Dojo_Form_Element_Editor histoire d'avoir un textarea dans lequel on pouvais faire un peu de mise en forme. Voici comment j'ai déclaré mon élément dans ma class :

class Default_Form_Demande extends Zend_Dojo_Form
{
//...

/**
*
* @see    http://framework.zend.com/manual/en/zend.form.html
* @return void
*/
public function init()
{
//...
$this->descriptif = new Zend_Dojo_Form_Element_Editor('descriptif');
$this->descriptif->setLabel('Descriptif de la demande')
->setRequired(true)
->setFilters(array('StringTrim'))
->setEditActionInterval(2)
->setHeight('250px');
$this->addElement($this->descriptif);
//...
}
//...
}  
Seulement voilà lorsque je suis passé aux tests, j'ai eu une drôle de surprise. En fonction du navigateur, le formulaire ne retourne pas la même structure de donnée. Sous IE6, Chrome, Safari j'ai eu :
Array (
[descriptif] => Array (
[Editor] => "bug test 2"
)
)
Sous Firefox j'ai eu :
Array (
[descriptif] =>  "bug test 2"
)
Ce qui n'est pas tout à fait la même chose. Google étant mon ami, j'ai chercher une solution. Après plusieurs essaies le seul truc qui tenais la route a été de modifier la class suivante : Zend/Dojo/View/Helper/Editor.php. Voici donc ce que j'ai fais:
  • j'ai renommé la méthode editor en editor_old (vers la ligne 66)
  • et je l'ai remplacé par celle-ci :
/**
* dijit.Editor
*
* @param  string $id
* @param  string $value
* @param  array $params
* @param  array $attribs
* @return string
*/
public function editor($id, $value = null, $params = array(), $attribs = array())
{
$hiddenName = $id;
if (array_key_exists('id', $attribs)) {
$hiddenId = $attribs['id'];
} else {
$hiddenId = $hiddenName;
}
$hiddenId = $this->_normalizeId($hiddenId);

$hiddenAttribs = array(
'id'    => $hiddenId,
'name'  => $hiddenName,
'value' => $value,
'type'  => 'hidden',
);

$editorAttribs = array(
'id'    => $hiddenId . '-Editor',
'name'  => $this->_normalizeEditorName($hiddenName)
);

$editorAttribs = $this->_prepareDijit($editorAttribs, $params, 'textarea');

$this->_createGetParentFormFunction();
$this->_createEditorOnSubmit($hiddenId, $hiddenId . '-Editor');

$html = '<input' . $this->_htmlAttribs($hiddenAttribs) . $this->getClosingBracket()
. '<div dojoType="' . $this->_module . '" ' . $this->_htmlAttribs($editorAttribs) .'>'.$value.'</div>';

return $html;
}
Alors je sais, c'est pas bien j'ai touché au code source du Zend Framework, donc attention lors des mises à jour de pas écraser cette modif (sauf si Zend à apporter une mise à jour concernant ce point).
Pour en revenir au sujet, pourquoi ce bug ? bah d'après les explications que j'ai réussit a traduire. Il semblerait que lorsque zend à implémenter l'éditeur de Dojo, celui-ci utilisait un textarea. Or depuis il a dû y avoir des mises à jour de Dojo, qui utilise maintenant un div pour faire le rendu. Voilà j'espère que ce post vous aura aidé.

lundi 4 janvier 2010

Pourquoi ajouter des header "expires" dans htaccess vos .htaccess ?

Tout simplement pour améliorer le chargement de votre site. A chaque visite sur votre site, plusieurs requêtes HTTP sont effectuées pour charger le contenu de votre page. Une requête par image, par fichier CSS et/ou Javascript inclus dans la page... Ajouter une entête "Expires" à ces ressources, va indiquer au navigateur, que cette ressource peut être mise en cache jusqu'à la date que vous spécifiez. Donc une fois les ressources images, javascript, ... mis en cache, le nombre de requête HTTP vers votre serveur devrait diminuer.
Pour ce faire il vous suffit d'ajouter ces petites lignes dans vos .htaccess :
ExpiresActive On
ExpiresDefault "access plus 1 month"
Ces instructions, vont mettre une date d'expiration de 1 mois sur les ressources. 1 mois en plus par rapport à la première date d'accès à la ressource. Bien entendu le mieux est de personnaliser cette date en fonction du type de ressources. Effectivement, on change pas la mécanique tout les jours lorsque ça fonctionne. Par contre la peinture (style, image) peux être amener à changer un plus souvent. On peux donc ajouter en plus des deux ligne ci dessus :
ExpiresByType text/html "access plus 2 hours"
ExpiresByType text/javascript "access plus 2 month"
ExpiresByType image/gif "access plus 5 hours 3 minutes"
Ici je définis la date d'expiration pour les ressources de type HTML à 2 heures, pour les ressources de type javascript à 2 mois et pour les ressources de type images gif à 5 heures et 3 minutes. Les autres type de ressources images jpeg, png auront la date d'expiration par défaut de 1 mois.
Voilà, j'espère que ce petit post vous seras utile.

jeudi 31 décembre 2009

Protéger les images de son site web

Il n'y a rien de plus embêtant de ce faire piquer une image et de la retrouver sur un autre site web. C'est encore plus gênant lorsque la personne qui a subtiliser l'image ne prend même pas la peine de recopier l'image sur son propre serveur et fais un lien direct vers votre serveur. C'est ce que l'on appel le "hotlink".
Voici donc une petite astuce pour protéger les images de votre site web du hotlinking. Tout va se jouer au niveau du .htaccess et de la réécriture d'URL. Il vous suffit d'ajouter ces quelques lignes sous la ligne RewriteEngine On :

RewriteEngine On
#Protection des images
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http://(www\.)?votre-domaine.fr/.*$ [NC]
RewriteCond %{HTTP_REFERER} !^http://(www\.)?votre-domaine2.fr/.*$ [NC]
ReWriteRule .*\.(gif|png|jpe?g)$ - [F]
Dans cet exemple, seul les domaine "votre-domaine.fr" et "votre-domaine2.fr" peuvent afficher les images hébergé sur votre serveur. La régle ce lis ainsi :
pour tous domaines différents de "votre-domaine.fr" et "votre-domaine2.fr" les URI se terminant par .gif ou .png ou .jpg ou .jpeg recevront une erreur 403 ( c'est ce que signifie [F] Forbidden)
Maintenant on est pas obliger de renvoyer une erreur de type 403. Mais on peux par exemple renvoyer une images par défaut, ou pointer vers un script PHP qui ajoute un watermark sur l'image. Pour celà il suffit de modifier la dernière ligne par :

#redirection lien vers une images
ReWriteRule .*\.(gif|png|jpe?g)$ http://www.votre-domaine.fr/images/hotlink.png [R,NC]
#redirection lien vers une images
ReWriteRule (.*\.(gif|png|jpe?g))$ http://www.votre-domaine.fr/watermark.php?src=$1 [NC]
Voilà, je vous expliquerais une autre fois la manipulation des images en php pour ajouter le watermark. En attendant, Google est votre ami.

mercredi 30 décembre 2009

Transparence / Opacité en CSS

Avoir des éléments transparent sur un site peux être sympa. Notamment pour redonné un petit look web2.0 à ses popup. Mais la gestion de la transparence en CSS n'est pas gérer de la même manière dans tout les navigateurs. Certain me diront d'attendre l'arrivé de CSS 3.0, pour avoir accès à ses nouvelles propriétés. Mais moi je trouve dommage d'attendre alors que beaucoup de navigateurs modernes les supportent déjà.Voici donc un petit bout de code CSS pour faire de la transparence en HTML à l'aide des CSS:

 .monLayer{
opacity: 0.7; /* Modern Browsers */
-moz-opacity: 0.7; /* Netscape */
-khtml-opacity: 0.7; /* Safari 1 */
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=70)"; /* IE 8 */
filter: alpha(opacity=70); /* IE 5-7 */
}
Je dois cependant vous mettre en garde. L'élément HTML ayant la class "monLayer" seras transparent, mais également tout les enfants de cet élément. A l'heure actuel je n'ai pas trouvé de solutions pour résoudre ce problème. Si ce n'est attendre le support des couleurs RGBa qu'apporteras CSS3.

vendredi 18 décembre 2009

Minifier le rendu HTML avec ZEND

Voici quelques bouts de code que j'implémente dans les développements que je réalise avec le Zend Framework. Le but de ce code est de supprimer tout ce qui est inutile dans le code HTML

  • Les commentaire
  • L'indentation
  • Les retours à la ligne
Certains diront que c'est inutile, que ça sert à rien. Bah je suis pas d'accord ! Cela permet de gagner quelques octets par page. Et donc d'accélérer un peu le chargement d'une page. Ce qui n'est pas négligeable par les temps qui court lorsque l'on développe un site à destination des plateformes Mobile (iPhone, Android, ...)
Donc le premier truc à faire est de créer un plugin de controller. Dont voici la source :

class My_Controller_Plugin_CompressHtml extends Zend_Controller_Plugin_Abstract
{
public function dispatchLoopShutdown()
{
$response = $this->getResponse();
$body = preg_replace('#(?:(?:(^|>[^<]*?)[\t\s\r\n]*)|(?:[\t\s\r\n]*(<|$)))#', '$1$2',$response->getBody());
$response->setBody($body);
}
}
Si vous débuter avec Zend il faut placer cette classe dans VOTRE_DOSSIER_PROJET/Librairy/My/Controller/Plugin/CompressHtml.php.

Je vais pas vous faire un cours sur les expressions régulières. Le seul truc à savoir c'est que ce plugin de controller est appeler tout à la fin du processus de distribution de la requête.

Une fois cette classe créer, il faut la déclarer. Pour celà il faut éditer le fichier VOTRE_DOSSIER_PROJET/application/Bootstrap.php et ajouter les quelques lignes de code suivantes :

class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
protected function _initAutoload()
{
$autoloader = new Zend_Application_Module_Autoloader(array(
'namespace' => '',
'basePath' => APPLICATION_PATH,
));
Zend_Loader_Autoloader::getInstance()->registerNamespace('My_');
return $autoloader;
}

protected function _initFrontController()
{
$frontController = Zend_Controller_Front::getInstance();
$frontController->registerPlugin(new My_Controller_Plugin_CompressHtml());

return $frontController;
}

public function run()
{
$frontController = Zend_Controller_Front::getInstance();
$frontController->dispatch();
}

}
Pour ceux qui ce demande ce qu'est le Bootstrap.php ? C'est le fichier contenant la classe d'amorçage de votre application. Tout passe par ce fichier.
Voilà ! Normalement si vous avez bien suivit, tout le code HTML de vos pages seras minifié lors du rendu HTML. Alors bien sûr on peut encore améliorer. Par exemple en m'étant en cache le résultat obtenu mais ça sera l'objet d'un autre post.

jeudi 17 décembre 2009

Hightcharts : des graphiques interactif en javascript

hightchart graphique interactif javascriptHightCharts est une librairie Javascript gratuite permettant d'ajouter facilement des graphiques interactifs (histogramme, camembert, courbes, ...).

C'est une librairie en pure javascript qui ne nécessite pas de plugin du coté client (flash, JAVA, ...). Elle fonctionne sur tout les navigateurs modernes y compris Safari pour iPhone et Interner Explorer.
Voici un petit aperçu des graphiques réalisés avec cette librairie.

hightchart graphique interactif javascript
Allez voir le site officiel : Hightcharts graphique javascript intéractif