<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet title="XSL formatting" type="text/xsl" href="http://blog.netapsys.fr/index.php/feed/rss2/xslt" ?><rss version="2.0"
  xmlns:dc="http://purl.org/dc/elements/1.1/"
  xmlns:wfw="http://wellformedweb.org/CommentAPI/"
  xmlns:content="http://purl.org/rss/1.0/modules/content/"
  xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
  <title>Netapsys Blog</title>
  <link>http://blog.netapsys.fr/index.php/</link>
  <atom:link href="http://blog.netapsys.fr/index.php/feed/author/romain.guefveneu/rss2" rel="self" type="application/rss+xml"/>
  <description></description>
  <language>fr</language>
  <pubDate>Mon, 20 May 2013 16:57:21 +0200</pubDate>
  <copyright>Netapsys 2008 - 2011</copyright>
  <docs>http://blogs.law.harvard.edu/tech/rss</docs>
  <generator>Dotclear</generator>
  
    
  <item>
    <title>Devoxx France : HTML5 et ElasticSearch au programme</title>
    <link>http://blog.netapsys.fr/index.php/post/2012/04/24/Devoxx-France-%3A-HTML5-et-ElasticSearch-au-programme</link>
    <guid isPermaLink="false">urn:md5:d8237e7a23fb22cf7278c0292cde4cd6</guid>
    <pubDate>Thu, 19 Apr 2012 23:50:00 +0200</pubDate>
    <dc:creator>Romain Guefveneu</dc:creator>
        <category>Java J2EE</category>
            
    <description>&lt;p&gt;&lt;strong&gt;L'événement a été l'occasion de revenir sur les dernières bonnes pratiques en matière de développement HTML5, ainsi que sur la modélisation d'applications.&lt;/strong&gt;&lt;/p&gt;


&lt;p&gt;Voici un résumé des conférences auxquelles j'ai assisté lors de la journée du 19 avril 2012 à Devoxx France.&lt;/p&gt;    &lt;p&gt;&lt;strong&gt;ElasticSearch - &quot;Your data, your search&quot;&lt;/strong&gt;&lt;/p&gt;


&lt;p&gt;Le principal problème de la recherche textuelle aujourd'hui est le temps&amp;nbsp;: Comment lancer une recherche sur une énorme quantité de données, sans attendre 10 minutes&amp;nbsp;?
Aujourd'hui, on se contente d'indexer notre base relationnelle, de configurer Hibernate pour améliorer les performances, mais le problème persiste (...), car les SGBD ne sont pas fait pour la recherche.
C'est là qu'intervient les moteurs de recherches, dont ElasticSearch fait partie.
Fondé sur un couple NoSQL/Apache Lucene, il permet d'indexer une énorme quantité de données (Twitter par exemple), tout en concervant des temps de réponse plus que corrects&amp;nbsp;: 20ms pour une recherche sur 500 000 éléments. Son installation est d'une simplicité enfantine, il n'y a aucune configuration. Il se branche via un connecteur à la base de données de votre application, pour mettre à jour sa base NoSQL.
La notion de facettes (grossièrement l'équivalent des group by en SQL), permet de spécifier ses recherches, et permettra par la suite de proposer une interface riche à l'utilisateur final. Celui-ci pourra naviguer entre différents graphiques ou tableaux, en fonction des référentiels de son choix, et ainsi obtenir la meilleure recherche possible sans que le développeur ai à penser toutes les solutions possibles.
ElasticSearch peut facilement indexer jusqu'à 5 milliards d'éléments, et est actuellement utilisé et/ou soutenu par Fotolia, JBoss, Mozilla, Yfrog, Sony, Klout, ...&lt;/p&gt;


&lt;p&gt;&lt;strong&gt;HTML5 + Spring + NoSQL + Mobile&lt;/strong&gt;&lt;/p&gt;


&lt;p&gt;Julien Dubois nous présente l'application web Tatami, un Twitter interne conçu à titre de test pour ces différentes technologies. La problématique était la suivante:  &quot;Avec l'abandon de Flash, Silverlight ou Air, comment construire des applications Web riches et dynamique ?&quot;
Pour cela, l'approche du site web change. Où avant l'idée était&amp;nbsp;: Un page = un contrôleur, les pages des nouvelles applications web invoquent plusieurs sources via des appels REST. On a donc une séparation totale entre le front et le back-end.
Le HTML5 se trouve être une très bonne alternative aux technologies en déclins sus-citées, puisqu'il intègre des nouvelles fonctionnalités qui simplifient le développement, que nous aurions du &quot;bidouiller&quot; (champs numériques, validation de formulaire, prise en compte des terminaux mobiles...).
Pour sa part, le NoSQL a de l'intérêt dès que la montée en charge vous fait peur. Par exemple Cassandra, un moteur NoSQL, est beaucoup plus performant pour tout ce qui est écriture qu'une base de données traditionnelle.&lt;/p&gt;


&lt;p&gt;&lt;strong&gt;Client/Serveur Apps with HTML5 &amp;amp; Java&lt;/strong&gt;&lt;/p&gt;


&lt;p&gt;Suite directe de la conférence précédente, James Ward présente ici sa vision d'une bonne application Web HTML5, qui pourrait se décrire simplement comme ceci&amp;nbsp;:
Stateless, pour des raisons d'extensibilité (scalablility), de facilité de mise à jour et de respect du mode de navigation (retour, rafraichissement, etc.)&amp;nbsp;;
Mise à jour et notifications en temps réel (Facebook, Twitter, etc.)
&quot;The browser as an application plateform&quot;
L'exemple phare étant l'application web Trello qui permet à différents protagonistes de gérer des tâches sous forme de board collaboratif. Les changements étant bien évidemment instantanés.&lt;/p&gt;


&lt;p&gt;&lt;strong&gt;Sencha&lt;/strong&gt;&lt;/p&gt;


&lt;p&gt;Vient ensuite la présentation de Sancha, un framework HTML5/Javascript permettant de créer simplement en Wysiwyg des interfaces mobiles riches. Il répond directement au problème de fragmentation de l'écosystème mobile&amp;nbsp;: Android, iOS, Blackberry, Windows Phone, Nokia, etc. En effet, le point commun entre les 3 grands du mobile est le navigateur basé sur WebKit (on ne parle pas ici de Windows Phone et son IE...).
L'idée est donc de ne plus coder des applications natives en Java ou Objective-C, mais de créer des applications Web Mobiles (Responsive Design).
Sencha propose un environnement de développement propriétaire et payant pour créer ses interfaces en Wysiwyg, mais le framework est lui-même gratuit et Open-Source.
Pour ma part je reste sceptique sur ce genre de framework généralement lourd et qui ne résout pas le problème des différentes UI et UX entre les plateformes.&lt;/p&gt;


&lt;p&gt;&lt;strong&gt;Il n'y a pas de bon modèle métier&lt;/strong&gt;&lt;/p&gt;


&lt;p&gt;Grégory Weinbach nous livre son analyse sur la modélisation des applications. Il part du constat que nos applications ne répondent généralement pas suffisamment aux besoins des clients. Une question de complexité accrue ou de mauvaise expression du besoin.
Il est donc plus que jamais nécessaire de concevoir *pour* et *avec* l'utilisateur, chose généralement faite avec les méthodes Agiles et le Domain-driven Design. Il faut avoir un langage commun entre tous les acteurs du projet, ainsi que peu d'intermédiaires entre le client et le développeur.
Parlons maintenant de modélisation, voire de Modélisme. Comme quelqu'un a dit un jour&amp;nbsp;: &quot;Tout est relatif&quot;. Et ça s'applique à, eh bien, à tout. A la modélisation aussi.
Prenons l'exemple d'un livre. Un livre, pour un auteur, peut se réduire à un fichier Word. Un titre, un contenu et c'est tout. Pour l'informatique, un livre c'est un ISBN. Pour un graphiste, c'est une mise en page particulière. Pour un commerçant, c'est un prix.
Bref, un livre c'est tout cela à la fois, ça dépend du contexte.
En voulant répondre à tous les besoins, on obtient une &quot;chimère&quot;, un modèle difficile à implémenter et impossible à maintenir.
Pour résoudre ce problème, changeons notre vision des choses, et commençons par la fin&amp;nbsp;: l'utilisateur, car au final c'est quand même lui qui utilisera notre application. L'utilisateur à des cas d'utilisations bien spécifiques. Eh bien au lieu de construire les actions à partir du modèle, construisons le modèle à partir des actions. Grégory parle de Behavior Driven Development, et encourage à ne pas essayer de modéliser le Réel, mais de rester dans une vision informatique du réel.&lt;/p&gt;


&lt;p&gt;Cette présentation à provoqué beaucoup de contestations et d'interrogations, car elle remet en cause tout un mode de pensée ;)&lt;/p&gt;


&lt;p&gt;Ces conférences terminées, nous avons fini la journée par l'Android PodCast avec Romain Guy et Nicolas Roard de Google, et par un massage Anma enfin de nous reposer un peu, en attendant la suite demain&amp;nbsp;!&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.netapsys.fr/index.php/post/2012/04/24/Devoxx-France-%3A-HTML5-et-ElasticSearch-au-programme#comment-form</comments>
      <wfw:comment>http://blog.netapsys.fr/index.php/post/2012/04/24/Devoxx-France-%3A-HTML5-et-ElasticSearch-au-programme#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.netapsys.fr/index.php/feed/atom/comments/420</wfw:commentRss>
      </item>
    
  <item>
    <title>Retour sur l'open data à Nantes</title>
    <link>http://blog.netapsys.fr/index.php/post/2011/04/29/Retour-sur-l-open-data-%C3%A0-Nantes</link>
    <guid isPermaLink="false">urn:md5:c72e50c26991d1238ba22a2079a6cf5a</guid>
    <pubDate>Fri, 29 Apr 2011 21:35:00 +0200</pubDate>
    <dc:creator>Romain Guefveneu</dc:creator>
        <category>Actualité</category>
        <category>données</category><category>libertic</category><category>libres</category><category>nantes</category><category>opendata</category>    
    <description>&lt;p&gt;Présent lors de la journée de lancement de l'open data nantais organisée par Libertic, je vous fais ici un petit retour sur cet évènement.&lt;/p&gt;


&lt;p&gt;&lt;img src=&quot;http://blog.netapsys.fr/public/images/open-data/open-data.jpg&quot; alt=&quot;open-data.jpg&quot; style=&quot;float:right; margin: 0 0 1em 1em;&quot; /&gt;&lt;/p&gt;    &lt;h2&gt;Open Data, c'est quoi&amp;nbsp;?&lt;/h2&gt;


&lt;p&gt;On m'a posé plusieurs fois cette question&amp;nbsp;: &quot;Mais, l'open data c'est quoi ?&quot;. Et bien, comme le nom l'indique, il s'agit de données libres. L'idée est de libérer les données publiques afin qu'elles puissent être exploitées par des journalistes — on parle alors de &quot;data-journalisme&quot; (1) — ou bien dans mon cas, des développeurs.&lt;/p&gt;


&lt;h2&gt;Mais quelles données&amp;nbsp;?&lt;/h2&gt;


&lt;p&gt;Horaires d'ouvertures des lieux publics, commerces, transports en commun ou bien budgets des communes sont autant de données qui peuvent être utilisées par le grand public. &lt;br /&gt;
Rennes propose par exemple sur sa plate-forme Open data (2) les catégories suivantes&amp;nbsp;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Accessiblité&lt;/li&gt;
&lt;li&gt;Actualités&lt;/li&gt;
&lt;li&gt;Citoyenneté&lt;/li&gt;
&lt;li&gt;Données budgétaires&lt;/li&gt;
&lt;li&gt;Environnement&lt;/li&gt;
&lt;li&gt;Equipements&lt;/li&gt;
&lt;li&gt;Logement&lt;/li&gt;
&lt;li&gt;Référentiel géographique&lt;/li&gt;
&lt;li&gt;Sports et loisirs&lt;/li&gt;
&lt;li&gt;Stationnement&lt;/li&gt;
&lt;li&gt;Transports&lt;/li&gt;
&lt;li&gt;Urbanisme&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Et pour quoi faire&amp;nbsp;?&lt;/h2&gt;


&lt;p&gt;Des applications pour consulter les horaires de bus par exemple ;) Ou bien encore, des statistiques croisées sur tout et n’importe quoi, comme par exemple recouper les horaires d’ouvertures des commerces de proximités et les périodes d’affluence d’utilisation des bicloos...&lt;/p&gt;


&lt;h2&gt;En France, ça donne quoi&amp;nbsp;?&lt;/h2&gt;


&lt;p&gt;Pour l'instant, Rennes et Paris ont libéré leurs données. D'autres villes suivent, mais 2011 sera l'année Open data nantaise. En effet, la mairie travaille actuellement sur le sujet, et devrait annoncer en juin quelles données seront disponibles (ce que j'attends avec impatience !).&lt;/p&gt;


&lt;h2&gt;Mais le marché des données privées n'est-il pas en danger&amp;nbsp;?&lt;/h2&gt;


&lt;p&gt;Actuellement, les données s'achètent, soit, mais l'Open data ne va pas tout changer du jour au lendemain&amp;nbsp;: les données seront certes accessibles, mais pas forcement exploitables. Format PDF illisibles, Excel mal conçus, pages HTML générées par Word 97, j'en passe et des meilleures :) &lt;br /&gt;
Un second marché s'ouvre ici alors&amp;nbsp;: la mise en forme de ces données&amp;nbsp;; qui est le secteur d'activité, par exemple, de la société Data Publica (3).&lt;/p&gt;


&lt;p&gt;Retrouvez ici la présentation de la mairie de nantes sur l'open data&amp;nbsp;: &lt;br /&gt;
&lt;a href=&quot;http://www.slideshare.net/libertic/presentation-opendata-de-la-ville-de-nantes&quot; hreflang=&quot;fr&quot;&gt;http://www.slideshare.net/libertic/presentation-opendata-de-la-ville-de-nantes&lt;/a&gt;&lt;/p&gt;


&lt;p&gt;Un article à lire sur le sujet&amp;nbsp;: &lt;br /&gt;
&lt;a href=&quot;http://blog.netapsys.fr/index.php/post/2011/04/29/fr&quot;&gt;http://www.entreprenantes.com/magazine/96-open-data-nantes-se-prepare-a-ouvrir-ses-donnees.html&lt;/a&gt;&lt;/p&gt;



&lt;p&gt;(1) &lt;a href=&quot;http://owni.fr/2010/07/07/donnees-publiques-et-journalisme-une-mine-de-richesses/&quot; hreflang=&quot;fr&quot;&gt;http://owni.fr/2010/07/07/donnees-publiques-et-journalisme-une-mine-de-richesses/&lt;/a&gt; &lt;br /&gt;
(2) &lt;a href=&quot;http://www.data.rennes-metropole.fr/les-donnees/catalogue/&quot; hreflang=&quot;fr&quot;&gt;http://www.data.rennes-metropole.fr/les-donnees/catalogue/&lt;/a&gt; &lt;br /&gt;
(3) &lt;a href=&quot;http://www.data-publica.com/&quot; hreflang=&quot;fr&quot;&gt;http://www.data-publica.com/&lt;/a&gt; &lt;br /&gt;&lt;/p&gt;


&lt;p&gt;Crédit photo&amp;nbsp;: Simon Robic (&lt;a href=&quot;http://blog.netapsys.fr/index.php/post/2011/04/29/fr&quot;&gt;http://www.flickr.com/photos/simonrobic&lt;/a&gt;)&lt;/p&gt;


&lt;p&gt;&lt;img src=&quot;http://blog.netapsys.fr/public/images/open-data/open-data2.jpg&quot; alt=&quot;open-data2.jpg&quot; style=&quot;display:block; margin:0 auto;&quot; /&gt;&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.netapsys.fr/index.php/post/2011/04/29/Retour-sur-l-open-data-%C3%A0-Nantes#comment-form</comments>
      <wfw:comment>http://blog.netapsys.fr/index.php/post/2011/04/29/Retour-sur-l-open-data-%C3%A0-Nantes#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.netapsys.fr/index.php/feed/atom/comments/257</wfw:commentRss>
      </item>
    
  <item>
    <title>Module Magento : Ajouter un commentaire à une commande</title>
    <link>http://blog.netapsys.fr/index.php/post/2011/04/07/Module-Magento-%3A-Ajouter-un-commentaire-%C3%A0-une-commande</link>
    <guid isPermaLink="false">urn:md5:1f813b850fe93b3078e7eb18211cfb52</guid>
    <pubDate>Tue, 12 Apr 2011 12:00:00 +0200</pubDate>
    <dc:creator>Romain Guefveneu</dc:creator>
        <category>PHP, Ruby, Python &amp; Co</category>
        <category>magento</category><category>php</category><category>tutoriel</category>    
    <description>&lt;p&gt;Pour mon premier billet sur ce blog, je vais aborder un sujet qui revient souvent sur les forums Magento, mais restant cependant sans réponse satisfaisante&amp;nbsp;:&lt;/p&gt;


&lt;p&gt;Comment permettre aux clients d'ajouter un commentaire (ou tout autre information) à une commande&amp;nbsp;?&lt;/p&gt;


&lt;p&gt;&lt;img src=&quot;http://blog.netapsys.fr/public/images/magento/ordercom/checkout2.png&quot; alt=&quot;Commentaire de la commande&quot; /&gt;&lt;/p&gt;    &lt;p&gt;Pour cela, il y a trois étapes&amp;nbsp;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Stocker l'information en base de données (et la récupérer...)&amp;nbsp;;&lt;/li&gt;
&lt;li&gt;Ajouter une étape dans le processus de validation de la commande (checkout)&amp;nbsp;;&lt;/li&gt;
&lt;li&gt;Ajouter un onglet dans la visualisation de la commande, côté administration.&lt;/li&gt;
&lt;/ol&gt;


&lt;h2&gt;Création d'un module&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;http://blog.netapsys.fr/public/images/magento/ordercom/archi.png&quot; alt=&quot;Architecture du module&quot; /&gt;&lt;/p&gt;


&lt;p&gt;Les sources sont disponibles &lt;a href=&quot;http://blog.netapsys.fr/index.php/post/2011/04/07/Module-Magento-%3A-Ajouter-un-commentaire-%C3%A0-une-commande#download&quot; hreflang=&quot;fr&quot;&gt;à la fin de cette article&lt;/a&gt; sous licence WTFPL.&lt;/p&gt;


&lt;h2&gt;Stocker l'information en base de données&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;http://blog.netapsys.fr/public/images/magento/ordercom/table.png&quot; alt=&quot;Stockage des données&quot; /&gt;&lt;/p&gt;


&lt;p&gt;Notre module utilise une table, &quot;netapsys_ordercom&quot;, dans la base de données. Cette table est créée via le fichier d'installation &lt;strong&gt;mysql4-install-0.1.0.php&lt;/strong&gt; dans &lt;strong&gt;&quot;sql/ordercom_setup&quot;&lt;/strong&gt;.&lt;/p&gt;

&lt;pre&gt;
$installer = $this;
$installer-&amp;gt;startSetup();

$installer-&amp;gt;run(&amp;quot;
-- DROP TABLE IF EXISTS {$this-&amp;gt;getTable('netapsys_ordercom')};
CREATE TABLE {$this-&amp;gt;getTable('netapsys_ordercom')} (
  `order_id` int(10) unsigned NOT NULL,
  `content` text NOT NULL default '',
  PRIMARY KEY (`order_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
&amp;quot;);

$installer-&amp;gt;endSetup();
&lt;/pre&gt;


&lt;p&gt;Modifiez ce script sql si vous voulez ajouter d'autres informations à votre commande.&lt;br /&gt;
Pour forcer la réinstallation d'un module, supprimer la ligne correspondante dans la table &lt;strong&gt;&quot;core_resource&quot;&lt;/strong&gt;.&lt;/p&gt;


&lt;p&gt;On doit ensuite définir notre modèle dans &lt;strong&gt;&quot;Model/Mysql4/Ordercom.php&quot;&lt;/strong&gt;. Dans cette classe, on indique quelle est la table à utiliser (définie dans le &lt;strong&gt;config.xml&lt;/strong&gt;), et la clé primaire (ici &quot;order_id&quot;);&lt;/p&gt;

&lt;pre&gt;
class Netapsys_Ordercom_Model_Mysql4_Ordercom extends Mage_Core_Model_Mysql4_Abstract {
	public function _construct(){
		$this-&amp;gt;_init('ordercom/ordercom', 'order_id');
		$this-&amp;gt;_isPkAutoIncrement = false;		
	}
}
&lt;/pre&gt;


&lt;p&gt;L'attribut &quot;isPkAutoIncrement&quot; est ici essentiel, car nous voulons nous même définir la valeur de cette clé, à savoir l'id de la commande. Cette attribut doit donc être défini à &quot;false&quot;.&lt;/p&gt;


&lt;h2&gt;Ajouter une étape dans le checkout&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;http://blog.netapsys.fr/public/images/magento/ordercom/checkout.png&quot; alt=&quot;Checkout&quot; /&gt;&lt;/p&gt;


&lt;p&gt;Notre étape est définie dans &lt;strong&gt;&quot;Block/Onepage/Ordercom.php&quot;&lt;/strong&gt;. C'est dans cette classe que l'id et le nom de l'étape est indiqué (&quot;ordercom&quot; et &quot;Commentaire&quot;).&lt;/p&gt;
&lt;pre&gt;
class Netapsys_Ordercom_Block_Onepage_Ordercom extends Mage_Checkout_Block_Onepage_Abstract
{
    protected function _construct()
    {    	
        $this-&amp;gt;getCheckout()-&amp;gt;setStepData('ordercom', array(
            'label'     =&amp;gt; Mage::helper('checkout')-&amp;gt;__('Commentaire'),
            'is_show'   =&amp;gt; true
        ));
        
        parent::_construct();
    }
}
&lt;/pre&gt;


&lt;p&gt;Une fois l'étape créée, il faut encore l'insérer dans le checkout. On surcharge donc la classe &quot;Mage_Checkout_Block_Onepage&quot; dans le fichier &lt;strong&gt;&quot;Block/Onepage.php&quot;&lt;/strong&gt;&lt;/p&gt;

&lt;pre&gt;
class Netapsys_Ordercom_Block_Onepage extends Mage_Checkout_Block_Onepage
{
    public function getSteps()
    {
        $steps = array();

        if (!$this-&amp;gt;isCustomerLoggedIn()) {
            $steps['login'] = $this-&amp;gt;getCheckout()-&amp;gt;getStepData('login');
        }
		
        //Ajouter notre étape 'ordercom'
        $stepCodes = array('billing', 'shipping', 'shipping_method', 'payment', 'ordercom', 'review');

        foreach ($stepCodes as $step) {
            $steps[$step] = $this-&amp;gt;getCheckout()-&amp;gt;getStepData($step);
        }
        
        return $steps;
    }
}
&lt;/pre&gt;


&lt;p&gt;Nous allons maintenant surcharger le controleur de cette page checkout pour deux raisons&amp;nbsp;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;rediriger vers notre étape après &quot;Informations de paiement&quot;&amp;nbsp;;&lt;/li&gt;
&lt;li&gt;sauvegarder nos informations en sessions.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Notre nouveau contrôleur se situe dans le fichier &lt;strong&gt;&quot;Ordercom/Block/controllers/OnepageController.php&quot;&lt;/strong&gt;.&lt;/p&gt;


&lt;p&gt;La redirection se fait via la méthode savePaymentAction&amp;nbsp;:&lt;/p&gt;

&lt;pre&gt;
public function savePaymentAction()
{
  parent::savePaymentAction();

  //Rediriger vers notre étape Ordercom
  $redirectUrl = $this-&amp;gt;getOnePage()-&amp;gt;getQuote()-&amp;gt;getPayment()-&amp;gt;getCheckoutRedirectUrl();

  if (empty($result['error']) &amp;amp;&amp;amp; !$redirectUrl) {
    $this-&amp;gt;loadLayout('checkout_onepage_ordercom');
    $result['goto_section'] = 'ordercom';
  }
  if ($redirectUrl) {
    $result['redirect'] = $redirectUrl;
  }
  $this-&amp;gt;getResponse()-&amp;gt;setBody(Zend_Json::encode($result));
}
&lt;/pre&gt;


&lt;p&gt;Pour la sauvegarde, avec le Onepage Checkout, les données de chaque étape sont stockées en session via ajax. Nous allons donc créer une méthode &quot;saveOrdercomAction&quot;, qui récupère les données envoyées en POST&amp;nbsp;:&lt;/p&gt;

&lt;pre&gt;
public function saveOrdercomAction()
{
		$this-&amp;gt;_expireAjax();
		if ($this-&amp;gt;getRequest()-&amp;gt;isPost()) {

			//Récuprer la valeur du formulaire
			$orderComment = $this-&amp;gt;getRequest()-&amp;gt;getPost('comment');
			Mage::getSingleton('core/session')-&amp;gt;setNetapsysOrdercom(trim($orderComment));

			$result = array();

			$redirectUrl = $this-&amp;gt;getOnePage()-&amp;gt;getQuote()-&amp;gt;getPayment()-&amp;gt;getCheckoutRedirectUrl();
			if (!$redirectUrl) {
				$this-&amp;gt;loadLayout('checkout_onepage_review');

				$result['goto_section'] = 'review';
				$result['update_section'] = array(
                    'name' =&amp;gt; 'review',
                    'html' =&amp;gt; $this-&amp;gt;_getReviewHtml()
				);

			}

			if ($redirectUrl) {
				$result['redirect'] = $redirectUrl;
			}

			$this-&amp;gt;getResponse()-&amp;gt;setBody(Zend_Json::encode($result));
		}
}
&lt;/pre&gt;


&lt;p&gt;Les données maintenant en session, il ne reste plus qu'à les sauvegarder dans la table une fois la commande validée&amp;nbsp;! Nous allons créer un hook lors de l'enregistrement de la commande.&lt;/p&gt;

&lt;pre&gt;
public function hookToOrderSaveEvent()
{
  //Récupérer l'id de la commande
  $orderId = Mage::getSingleton('checkout/session')-&amp;gt;getLastOrderId();

  //Lire nos données depuis la session
  $content = Mage::getSingleton('core/session')-&amp;gt;getNetapsysOrdercom();
  $code = Mage::getSingleton('core/session')-&amp;gt;getNetapsysOrdercode();

  if (($content != '') || ($code != '')){
    // Enregistrer tout le toutim en base
    $orderCom = Mage::getModel('ordercom/ordercom');
    $orderCom-&amp;gt;setId($orderId);
    $orderCom-&amp;gt;setData('content', $content );
    $orderCom-&amp;gt;save();
  }
}
&lt;/pre&gt;


&lt;p&gt;C'est presque fini, il faut encore créer le front de notre étape.
Pour cela, je vous laisse regarder les fichiers &lt;strong&gt;&quot;/design/frontend/default/default/layout/ordercom.xml&quot;&lt;/strong&gt; et &lt;strong&gt;&quot;/design/frontend/default/default/template/checkout/onepage/ordercom.phtml&quot;&lt;/strong&gt;.&lt;/p&gt;


&lt;p&gt;Enfin, une étape très importante pour que tout ça fonctionne ensemble&amp;nbsp;: la configuration du fichier &lt;strong&gt;&quot;etc/config.xml&quot;&lt;/strong&gt;.
Vous devez définir le modèle, les blocks, la surchage du checkout, etc. Le fichier étant assez long, je ne le décris pas ici.&lt;/p&gt;


&lt;p&gt;Passons maintenant à l'affichage de ces données dans le back office.&lt;/p&gt;


&lt;h2&gt;Ajouter un onglet dans la visualisation de la commande, côté administration.&lt;/h2&gt;


&lt;p&gt;&lt;img src=&quot;http://blog.netapsys.fr/public/images/magento/ordercom/menu-order.png&quot; alt=&quot;Menu&quot; /&gt;&lt;/p&gt;


&lt;p&gt;Pour gérer le back office de notre module, nous avons besoin de 3 fichiers&amp;nbsp;:&lt;/p&gt;


&lt;h3&gt;Le layout&lt;/h3&gt;


&lt;p&gt;Nous décrivons ici l'emplacement de notre onglet et le block le définissant :&lt;br /&gt;
&lt;strong&gt;&quot;/app/design/adminhtml/default/default/layout/ordercom.xml&quot;&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot;?&amp;gt;
&amp;lt;layout version=&amp;quot;0.1.0&amp;quot;&amp;gt;

	&amp;lt;adminhtml_sales_order_view&amp;gt;
		&amp;lt;reference name=&amp;quot;sales_order_tabs&amp;quot;&amp;gt;
			&amp;lt;action method=&amp;quot;addTab&amp;quot;&amp;gt;
				&amp;lt;name&amp;gt;order_coms&amp;lt;/name&amp;gt;
				&amp;lt;block&amp;gt;ordercom/adminhtml_sales_order_view_tab_view&amp;lt;/block&amp;gt;
			&amp;lt;/action&amp;gt;
		&amp;lt;/reference&amp;gt;
	&amp;lt;/adminhtml_sales_order_view&amp;gt;

&amp;lt;/layout&amp;gt;
&lt;/pre&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h3&gt;Le block&lt;/h3&gt;


&lt;p&gt;Ce block va récupérer la commande en cours de visualisation et permettre à la vue d'afficher le commentaire correspondant.&lt;br /&gt;
&lt;strong&gt; &quot;/app/code/local/Netapsys/Ordercom/Block/Adminhtml/Sales/Order/View/Tab/View.php&quot;&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;
class Netapsys_Ordercom_Block_Adminhtml_Sales_Order_View_Tab_View
extends Mage_Adminhtml_Block_Template
implements Mage_Adminhtml_Block_Widget_Tab_Interface
{
	private $_orderCom = null;
	private $_order = null;

	protected function _construct()
	{
		parent::_construct();
		$this-&amp;gt;setTemplate('sales/order/view/tab/ordercom.phtml');

		//Récupérer la commande en cours
		$this-&amp;gt;_order = Mage::getModel('sales/order')-&amp;gt;load($this-&amp;gt;getRequest()-&amp;gt;getParam('order_id'));

		//Récupérer les données de notre table selon l'id de la commande en cours
		$this-&amp;gt;_orderCom = Mage::getModel('ordercom/ordercom')-&amp;gt;load( $this-&amp;gt;_order-&amp;gt;getId() )-&amp;gt;getData();
	}

	/**
	 * Récupérer le commentaire de la commande en cours
	 */
	public function getComment(){
		$comment = null;
		if ($this-&amp;gt;_orderCom != null){
			$comment = $this-&amp;gt;_orderCom[&amp;quot;content&amp;quot;];
		}
		return  $comment;
	}

	/**
	 * ######################## TAB settings #################################
	 */
	public function getTabLabel(){return Mage::helper('sales')-&amp;gt;__('Commentaire');}
	public function getTabTitle(){return Mage::helper('sales')-&amp;gt;__('Commentaire');}
	public function canShowTab(){	return true;}
	public function isHidden(){return false;}
}
&lt;/pre&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h3&gt;La vue&lt;/h3&gt;


&lt;p&gt;Notre vue va tout simplement afficher le commentaire donné par notre block.&lt;br /&gt;
&lt;strong&gt;&quot;/app/design/adminhtml/default/default/template/sales/order/view/tab/ordercom.phtml&quot;&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;
&amp;lt;div class=&amp;quot;entry-edit&amp;quot;&amp;gt;
	&amp;lt;div class=&amp;quot;entry-edit-head&amp;quot;&amp;gt;
		&amp;lt;h4 class=&amp;quot;icon-head head-edit-form fieldset-legend&amp;quot;&amp;gt;
		&amp;lt;?php echo $this-&amp;gt;getTabLabel() ?&amp;gt;
		&amp;lt;/h4&amp;gt;
	&amp;lt;/div&amp;gt;

	&amp;lt;div id=&amp;quot;group_fields4&amp;quot; class=&amp;quot;fieldset fieldset-wide&amp;quot;&amp;gt;
		&amp;lt;div class=&amp;quot;hor-scroll&amp;quot;&amp;gt;
			&amp;lt;table class=&amp;quot;form-list&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;
				&amp;lt;tbody&amp;gt;
					&amp;lt;tr&amp;gt;
						&amp;lt;td class=&amp;quot;label&amp;quot;&amp;gt;&amp;lt;label&amp;gt;Commentaire :&amp;lt;/label&amp;gt;&amp;lt;/td&amp;gt;
						&amp;lt;td class=&amp;quot;value&amp;quot;&amp;gt;&amp;lt;textarea id=&amp;quot;order_comment&amp;quot; style=&amp;quot;height: 20em; width: 99%;&amp;quot; cols=&amp;quot;5&amp;quot; rows=&amp;quot;10&amp;quot; name=&amp;quot;order[comment]&amp;quot; readonly=&amp;quot;readonly&amp;quot;&amp;gt;&amp;lt;?php echo $this-&amp;gt;getComment(); ?&amp;gt;&amp;lt;/textarea&amp;gt;
						&amp;lt;/td&amp;gt;
					&amp;lt;/tr&amp;gt;
				&amp;lt;/tbody&amp;gt;
			&amp;lt;/table&amp;gt;

		&amp;lt;/div&amp;gt;
	&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/pre&gt;

&lt;p&gt;&lt;br /&gt;
Vous avez maintenant le commentaire dans votre commande&amp;nbsp;!&lt;/p&gt;


&lt;p&gt;&lt;img src=&quot;http://blog.netapsys.fr/public/images/magento/ordercom/order-comment.png&quot; alt=&quot;Commentaire de la commande&quot; /&gt;
&lt;a name=&quot;download&quot;&gt;&lt;/a&gt;&lt;/p&gt;</description>
    
          <enclosure url="http://blog.netapsys.fr/public/images/magento/ordercom/netapsys-ordercom.zip"
      length="18884" type="application/zip" />
    
    
          <comments>http://blog.netapsys.fr/index.php/post/2011/04/07/Module-Magento-%3A-Ajouter-un-commentaire-%C3%A0-une-commande#comment-form</comments>
      <wfw:comment>http://blog.netapsys.fr/index.php/post/2011/04/07/Module-Magento-%3A-Ajouter-un-commentaire-%C3%A0-une-commande#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.netapsys.fr/index.php/feed/atom/comments/254</wfw:commentRss>
      </item>
    
</channel>
</rss>