Bilendi Technology - DéveloppementDES TECHNOLOGIES INNOVANTES DÉVELOPPÉES EN INTERNE ET CONÇUES POUR RÉPONDRE AUX BESOINS DE NOS CLIENTS ET PARTENAIRES2022-11-23T08:40:51+01:00Bilendi Technologyurn:md5:449d083a7a76e29cf1c2691e99df25f8DotclearLes composants DevExtremeurn:md5:8fb69c8598ec0ca2db05cdaaede2966b2022-11-22T12:20:00+01:002022-11-23T09:40:51+01:00Hervé PiedvacheDéveloppementangulardevexpressdevextremejQueryReactVueJs<p>La société <a href="https://www.devexpress.com/" hreflang="en" title="DevExpress">DevExpress</a> édite depuis de nombreuses années une solution extrêmement avantageuse pour réaliser des interfaces de présentation et de manipulation de données de façon très simplifiée, un atout pour les équipes de développement. Découvrons les possibilités offertent par la gamme des composants <a href="https://js.devexpress.com" hreflang="en" title="devExtreme">DevExtreme</a>.</p> <h3>Des composants pour l'interface utilisateur</h3>
<p><img src="https://bilendi.tech/public/Capture_d_e_cran_2022-11-22_a__10.50.09.png" alt="DataGrid, nov. 2022" style="float:left; margin: 0 1em 1em 0;" title="DataGrid, nov. 2022" />Grille de données
Le composant côté client de mise en forme et d'édition de données en grilles via des fonctionnalités ultra-rapide</p>
<p><img src="https://bilendi.tech/public/.Capture_d_e_cran_2022-11-22_a__13.32.30_m.png" alt="Exemple de datagrid, nov. 2022" style="display:table; margin:0 auto;" title="Exemple de datagrid, nov. 2022" /></p>
<p><img src="https://bilendi.tech/public/Capture_d_e_cran_2022-11-22_a__10.50.24.png" alt="PivotGrid, nov. 2022" style="float:left; margin: 0 1em 1em 0;" title="PivotGrid, nov. 2022" />Grille Pivot
Le composant côté client optimisé pour l'analyse de données multidimensionnelles</p>
<p><img src="https://bilendi.tech/public/.Capture_d_e_cran_2022-11-22_a__13.34.41_m.png" alt="Grille en pivot, nov. 2022" style="display:table; margin:0 auto;" title="Grille en pivot, nov. 2022" /></p>
<p><img src="https://bilendi.tech/public/Capture_d_e_cran_2022-11-22_a__10.50.44.png" alt="TreeList, nov. 2022" style="float:left; margin: 0 1em 1em 0;" title="TreeList, nov. 2022" />ArbreListe
Vue arborescente et vue liste hybrides hautes performances côté client</p>
<p><img src="https://bilendi.tech/public/.Capture_d_e_cran_2022-11-22_a__13.35.53_m.png" alt="Vue arborescente, nov. 2022" style="display:table; margin:0 auto;" title="Vue arborescente, nov. 2022" /></p>
<p><img src="https://bilendi.tech/public/Capture_d_e_cran_2022-11-22_a__10.51.03.png" alt="Graphiques, nov. 2022" style="float:left; margin: 0 1em 1em 0;" title="Graphiques, nov. 2022" />Graphiques
Une collection entièrement intégrée de composants de visualisation de données hautes performances</p>
<p><img src="https://bilendi.tech/public/.Capture_d_e_cran_2022-11-22_a__13.40.50_m.png" alt="Charts, nov. 2022" style="display:table; margin:0 auto;" title="Charts, nov. 2022" /></p>
<p><img src="https://bilendi.tech/public/Capture_d_e_cran_2022-11-22_a__10.51.23.png" alt="Cartes, nov. 2022" style="float:left; margin: 0 1em 1em 0;" title="Cartes, nov. 2022" />Cartes
Composants Google, Bing et Vector Map interactifs et entièrement personnalisables</p>
<p><img src="https://bilendi.tech/public/.Capture_d_e_cran_2022-11-22_a__13.41.56_m.png" alt="Cartes, nov. 2022" style="display:table; margin:0 auto;" title="Cartes, nov. 2022" /></p>
<p><img src="https://bilendi.tech/public/Capture_d_e_cran_2022-11-22_a__10.51.36.png" alt="Formulaires, nov. 2022" style="float:left; margin: 0 1em 1em 0;" title="Formulaires, nov. 2022" />Formulaires
Composant de mise en page adaptative pour la présentation et l'édition de données</p>
<p><img src="https://bilendi.tech/public/.Capture_d_e_cran_2022-11-22_a__13.42.50_m.png" alt="Formulaires, nov. 2022" style="display:table; margin:0 auto;" title="Formulaires, nov. 2022" /></p>
<p><img src="https://bilendi.tech/public/Capture_d_e_cran_2022-11-22_a__10.52.30.png" alt="Calendrier, nov. 2022" style="float:left; margin: 0 1em 1em 0;" title="Calendrier, nov. 2022" />Calendrier
Le composant côté client pour afficher et modifier les données planifiées à l'aide de différentes vues</p>
<p><img src="https://bilendi.tech/public/.Capture_d_e_cran_2022-11-22_a__13.43.57_m.png" alt="Calendrier, nov. 2022" style="display:table; margin:0 auto;" title="Calendrier, nov. 2022" /></p>
<p><img src="https://bilendi.tech/public/Capture_d_e_cran_2022-11-22_a__10.52.44.png" alt="Composants, nov. 2022" style="float:left; margin: 0 1em 1em 0;" title="Composants, nov. 2022" />Plus de composants
Plus de 50 composants JavaScript pour créer des applications Web réactives intuitives et faciles à utiliser</p>
<p><img src="https://bilendi.tech/public/.Capture_d_e_cran_2022-11-22_a__13.45.17_m.png" alt="Editeur HTML, nov. 2022" style="display:table; margin:0 auto;" title="Editeur HTML, nov. 2022" /></p>
<h3>Intégrations</h3>
<p><img src="https://bilendi.tech/public/Angular_full_color_logo.svg" alt="Angular, nov. 2022" style="float:left; margin: 0 1em 1em 0;" title="Angular, nov. 2022" width="60px" /><strong>Angular</strong></p>
<div><span class="HwtZe" lang="fr"><span class="jCAhz ChMk0b"><span class="ryNqvb">Suite complète de composants Angular avec compilation AOT et prise en charge SSR</span></span></span></div><div><span class="HwtZe" lang="fr"><span class="jCAhz ChMk0b"><span class="ryNqvb"><br /></span></span></span></div><p><img src="https://bilendi.tech/public/React-icon.svg" alt="React, nov. 2022" style="float:left; margin: 0 1em 1em 0;" title="React, nov. 2022" width="60px" /><strong>React</strong> </p>
<p>Plus de 70 composants React prêts pour l'entreprise avec prise en charge de TypeScript et thèmes Material Design</p>
<p><img src="https://bilendi.tech/public/Vue.js_Logo_2.svg" alt="Vuejs, nov. 2022" style="float:left; margin: 0 1em 1em 0;" title="Vuejs, nov. 2022" width="60px" /><strong>Vue</strong> </p>
<p>Plus de 65 composants Vue basés sur des composants DevExtreme</p>
<p><img src="https://bilendi.tech/public/jquery-vertical.svg" alt="jQuery, nov. 2022" style="float:left; margin: 0 1em 1em 0;" title="jQuery, nov. 2022" width="60px" /></p>
<p><strong>jQuery</strong></p>
<p>Plus de 65 widgets d'interface utilisateur tactiles disponibles sous forme de plug-ins jQuery</p>
<h3>Démonstration en live</h3>
<p>Vous pouvez découvrir l'ensemble des fonctionnalités au travers de <a href="https://js.devexpress.com/Demos/WidgetsGallery/" hreflang="en" title="pade de démonstration">pages de démonstration</a>, vous pourrez jouer avec les réglages et les paramètres de chacun des composants en live.</p>
<h3>Documentation</h3>
<p>L'énorme avantage de ces composants réside également dans une <a href="https://js.devexpress.com/Documentation/Guide/UI_Components/ActionSheet/Overview/" hreflang="en" title="Documentation">documentation</a> vraiment bien conçue, et facile à utiliser, qui donne de véritables exemples concrets, avec les différents frameworks et langages. Surtout parcourez-là, vous allez découvrir en profondeur les features de chacun de ces composants.</p>
<h3>Editeur de thème</h3>
<p>Chacun des composants repose bien évidemment sur des feuilles de styles, et des thèmes, qui peuvent permettre de complètement personnaliser la présentation des éléments et naturellement DevExtreme nous met à disposition un <a href="https://devexpress.github.io/ThemeBuilder/" hreflang="en" title="Thème builder">éditeur de thèmes</a> en ligne simple et pratique.</p>Validation d'un formulaire Symfony au sein d'un formulaire DevExtremeurn:md5:512054df390e7cbd3db9e42bba62aa4c2021-03-23T09:14:00+01:002021-03-23T09:23:35+01:00SébastienDéveloppementdevexpressformulairejavascriptsymfonytwig<h2>Introduction</h2>
<p>Bilendi Technology a migré une grande partie de son infrastructure et de ses outils de Zend Framework 1 vers Symfony, comme son programme phare et historique <a href="https://www.maximiles.com">Maximiles</a>.</p>
<p>Afin de suivre l'activité et de gérer nos membres et nos contacts pour mieux comprendre les besoins des clients, nous utilisons de plus en plus les composants de la suite d'outils <a href="https://js.devexpress.com/">DevExtreme</a>. Ils permettent, avec un minimum de Javascript, de manipuler les données avec de nombreuses possibilités visuelles.</p>
<p>A travers un exemple concret, on va montrer comment utiliser un <a href="https://symfony.com/doc/current/forms.html">formulaire Symfony</a> dans un <a href="https://js.devexpress.com/Demos/WidgetsGallery/Demo/Form/Validation/jQuery/Light">composant DevExtreme dxForm</a> et valider les données côté serveur.</p>
<p>Supposons que nous voulions enregistrer un contact, contenant un email, une date de naissance, un pays et un optin (par exemple pour décider d'activer l'envoi d'une newsletter).</p>
<h2>Création du formulaire et du controleur</h2>
<p>On commence par construire le form type. Disons que le mail et la date de naissance sont requis pour l'exemple. Pour simplifier la validation en ajax, on va désactiver ici la <a href="https://symfony.com/doc/current/security/csrf.html">CSRF protection</a>. Après ajout des contraintes de validation, voici ce que donne notre formulaire :</p>
<pre><code class="php"><?php
namespace App\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\CountryType;
use Symfony\Component\Form\Extension\Core\Type\DateType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Validator\Constraints\Email;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Constraints\NotNull;
class RegisterType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('email', EmailType::class, [
'label' => 'Email',
'constraints' => [
new NotBlank(),
new Email(),
]
])
->add('dateOfBirth', DateType::class, [
'label' => 'Date of birth',
'widget' => 'single_text',
'constraints' => [
new NotBlank(),
]
])
->add('country', CountryType::class, [
'label' => 'Country',
'required' => false,
])
->add('optinNewsletter', CheckboxType::class, [
'label' => 'Optin newsletter',
'value' => 'Yes',
'required' => false,
'false_values' => ['no'],
'constraints' => [
new NotNull()
]
]);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'csrf_protection' => false
]);
}
}
</code></pre>
<p>On peut maintenant écrire l'action <code>register</code>. Lorsque le formulaire précédent sera posté, on soumet les données. On retourne une <code>JsonResponse</code> avec un message et un statut différent en fonction de la validité des données :</p>
<pre><code class="php"><?php
namespace App\Controller;
use App\Form\Type\RegisterType;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class IndexController extends AbstractController
{
/**
* @Route("/register", name="app_register", options={"expose"=true})
*/
public function register(Request $request): Response
{
$form = $this->createForm(RegisterType::class);
$form->handleRequest($request);
if ($request->isMethod('POST')) {
$form->submit($request->request->all());
if ($form->isSubmitted() && $form->isValid()) {
return new JsonResponse(['message' => 'The form has been validated successfully']);
}
return new JsonResponse(['message' => 'The form contains errors'], Response::HTTP_BAD_REQUEST);
}
return $this->render('index/register.html.twig', [
'form' => $form->createView(),
'formData' => $form->getData()
]);
}
}
</code></pre>
<h2>Créer une extension Twig</h2>
<p>On va avoir besoin de récupérer certaines propriétés du formulaire Symfony, pour les utiliser dans notre dxForm. Pour cela, on va créer une <a href="https://symfony.com/doc/current/templating/twig_extension.html">extension Twig</a> afin de présenter les données au format attendu par DevExtreme pour construire chaque champs. Voici un exemple de ce que l'on peut faire pour récupérer les données nécessaires :</p>
<pre><code class="php"><?php
namespace App\Twig;
use Symfony\Component\Form\ChoiceList\View\ChoiceView;
use Symfony\Component\Form\FormView;
use Twig\Extension\AbstractExtension;
use Twig\TwigFunction;
class DxFormExtension extends AbstractExtension
{
public function getFunctions()
{
return [
new TwigFunction('dxform_item', [$this, 'getFormItem'], ['is_safe' => ['html']])
];
}
public function getFormItem(FormView $view, array $options = []): string
{
$dxFormItem = [
'dataField' => isset($options['dataField']) ? $options['dataField'] : $view->vars['name'],
'label' => [
'text' => $view->vars['label']
],
'value' => $view->vars['value'],
'isRequired' => $options['isRequired'] ?? $view->vars['required'],
];
if (isset($view->vars['choices'])) {
$dataSource = [];
foreach ($view->vars['choices'] as $groupLabel => $choice) {
if ($choice instanceof ChoiceView) {
$dataSource[] = ['value' => $choice->value, 'label' => $choice->label, 'data' => $choice->data];
}
}
$editorType = $options['editorType'] ?? 'dxSelectBox';
$editorOptions = [
'dataSource' => $dataSource,
'searchEnabled' => true,
'valueExpr' => 'value',
'displayExpr' => 'label',
'switchedOffText' => 'No',
'switchedOnText' => 'Yes'
];
}
$editorType = $editorType ?? ($options['editorType'] ?? '');
if ('' !== $editorType) {
$dxFormItem['editorType'] = $editorType;
}
$editorOptions = array_merge(($options['editorOptions'] ?? []), ($editorOptions ?? []));
if (!empty($editorOptions)) {
$dxFormItem['editorOptions'] = $editorOptions;
}
return json_encode($dxFormItem, JSON_NUMERIC_CHECK);
}
}
</code></pre>
<h2>Ajouter la structure dxForm de DevExtreme</h2>
<p>Du coté javascript, on va :
* charger un fichier qui sera responsable de rendre chaque composant
* construire le dxForm
* écouter le clic sur le bouton "Valider" pour poster le formulaire. On affichera un message de succès ou d'erreur en utilisant le composant <a href="https://js.devexpress.com/Demos/WidgetsGallery/Demo/Button/PredefinedTypes/jQuery/Light/">ui/notify de DevExtreme</a></p>
<p>Voici ce que l'on obtient :</p>
<pre><code class="twig">{# fichier index/register.html.twig #}
{% extends 'base_bo.html.twig' %}
{% block body %}
<h1>Register a contact</h1>
<form id="form-container" method="post">
<div class="row">
<div id="form" class="flex-col-reverse col-xs-12"></div>
</div>
<div class="form-group fix-action-form text-center">
<div class="btn-group">
<button type="input" class="btn btn-primary" name="save">Save</button>
</div>
</div>
</form>
{% endblock %}
{% block javascript_footer %}
{{ parent() }}
{% include 'index/dxform-items.html.twig' %}
<script type="text/javascript">
let form = $('#form').dxForm({
labelLocation: 'top',
showColonAfterLabel: false,
showValidationSummary: true,
items: [
getDxformEmail(),
getDxformDateOfBirth(),
getDxformCountry(),
getDxformOptinNewsletter()
],
}).dxForm('instance')
$('button[name="save"]').on('click', function(e) {
e.preventDefault()
let valid = form.validate()
if (!valid.isValid) {
return
}
const d = $.Deferred()
$.ajax({
url: Routing.generate('app_register'),
type: 'POST',
data: form.option('formData'),
dataType: 'json',
}).fail(function(e) {
DevExpress.ui.notify(e.responseJSON.message, 'error', 1000)
return d.reject()
}).then(function(e) {
DevExpress.ui.notify(e.message, 'success', 1000)
return d.resolve()
})
return d.promise()
})
</script>
{% endblock %}
</code></pre>
<h2>Ajouter des fonctions Javascript pour chaque champ en utilisant l'extension Twig</h2>
<p>Le rendu des composants va se faire en déclarant une fonction JS à chaque fois, qui utilisera la fonction twig <code>dxform_item</code> définie plus haut. Le mail sera validé en asynchrone, par un appel serveur pour valider sa syntaxe lorsque le champs perdra le focus.</p>
<pre><code class="twig">{# fichier index/dxform-items.html.twig #}
{% block dxform_items %}
<script type="text/javascript">
let getDxformEmail = function() {
let email = {{ dxform_item(form.email) }}
email.validationRules = [
{
type: 'required',
message: 'Email is required'
},
{
type: 'async',
validationCallback: function(e) {
const d = $.Deferred()
$.ajax({
url: Routing.generate('app_validate_email'),
type: 'POST',
data: {email: e.value},
dataType: 'json',
}).fail(function(e) {
return d.reject('The email is not valid')
}).then(function(e) {
return d.resolve()
})
return d.promise()
}
}
]
return email
}
let getDxformDateOfBirth = function() {
let dateOfBirth = {{ dxform_item(form.dateOfBirth, {
editorType: 'dxDateBox',
editorOptions: {
inputAttr: {
autocomplete: 'none'
},
dateSerializationFormat: 'yyyy-MM-dd',
invalidDateMessage: 'Date of birth is not valid'
}
}) }}
dateOfBirth.editorOptions.max = new Date()
dateOfBirth.label.type = 'date'
dateOfBirth.label.format = 'dd/MM/yyyy'
dateOfBirth.validationRules = [{
type: 'required',
message: 'Date of birth is required'
}]
return dateOfBirth
}
let getDxformCountry = function() {
return {{ dxform_item(form.country, {
editorOptions: {
inputAttr: {
autocomplete: 'none'
},
searchEnabled: true,
noDataText: 'This country does not exist',
}
}) }}
}
let getDxformOptinNewsletter = function() {
return {{ dxform_item(form.optinNewsletter, {
editorType: 'dxSwitch',
editorOptions: {
value: true,
switchedOffText: 'No',
switchedOnText: 'Yes'
}
}) }}
}
</script>
{% endblock %}
</code></pre>
<h2>Ajouter une méthode pour valider côté serveur l'email</h2>
<p>Il va nous rester à écrire une fonction pour valider le mail à la volée. On peut injecter le <a href="https://symfony.com/doc/current/validation.html#using-the-validator-service">service de validation de Symfony</a> et retourner une 400 si le mail n'est pas bon :</p>
<pre><code class="php">/**
* @Route("/validate-email", name="app_validate_email", condition="request.isXmlHttpRequest()", methods={"POST"}, options={"expose"=true})
*/
public function validateEmail(Request $request, ValidatorInterface $validator): JsonResponse
{
$errors = $validator->validate($request->request->get('email'), [
new Email(['mode' => Email::VALIDATION_MODE_STRICT])
]);
if (0 === count($errors)) {
return new JsonResponse(null, Response::HTTP_NO_CONTENT);
}
return new JsonResponse(['message' => 'This email is not valid'], Response::HTTP_BAD_REQUEST);
}
</code></pre>
<h2>Tests de validation</h2>
<h3>En cas d'erreur</h3>
<p>La liste des erreurs remonte dans un conteneur HTML, ainsi qu'au niveau de chaque champs si on clique dessus :</p>
<p><img src="https://bilendi.tech/public/.error-form-validation_m.png" alt="Error-form, mar. 2021" style="margin: 0 1em 1em 0;" height="179" width="448" /></p>
<h3>En cas de succès</h3>
<p>Lorsque le mail est valide, un indicateur vert apparait à droite au niveau du champs. Un message de succès s'affiche lorsque la validation intégrale du formulaire a réussi :</p>
<p><img src="https://bilendi.tech/public/.sucess-form-validation_m.png" alt="Success-form, mar. 2021" style="margin: 0 1em 1em 0;" height="179" width="448" /></p>
Pratiques agiles, coaching et amélioration continueurn:md5:d30ae5a3b432795cc14f86b49349f4772021-03-04T10:52:00+01:002021-03-04T23:23:58+01:00franckDéveloppementagilecoachingdéveloppementredminescrumtrello<p>La croissance perpétuelle de la plateforme Bilendi, en terme de
marchés, de client, de leurs besoins... amène à l'intégration d'une
multitude de scénarios web différents, des nouvelles solutions et players
de la toile etc.</p>
<p>Le challenge pour la team dev de Bilendi est d'en absorber les
évolutions induites sur sa plateforme, en maintenant le niveau de qualité
de celle-ci (stabilité, performance, flexibilité, potentiel technologique etc.).</p> <p>Cette plateforme est gérée pour cela depuis pas mal d'années en
pratiques de développement agiles (via des outils comme <a href="https://www.redmine.org/">Redmine</a>, <a href="https://trello.com/fr">Trello</a>, <a href="https://www.journaldunet.fr/web-tech/guide-de-l-entreprise-digitale/1443836-sprint-definition-planning-review-retrospective-backlog/">les
sprint</a>, <a href="https://about.gitlab.com/">gitlab</a> ...), avec un
réel focus sur la capitalisation des retours d'expériences collectifs pour
l'amélioration continue de ces pratiques.<br /><em>NB : il n'y a ainsi pas
de "religion qualité" chez Bilendi : les pratiques dites actuelles, comme
<a href="https://fr.wikipedia.org/wiki/Scrum_(d%C3%A9veloppement)">Scrum</a>...
se combinent à de "bonnes vieilles pratiques", comme <a href="https://fr.wikipedia.org/wiki/Capability_Maturity_Model_Integration">CMMI</a>
par exemple, du moment qu'elles apportent une valeur ajoutée !</em></p>
<p>Dans cet article nous décrivons brièvement comment l'équipe s'est organisée
pour mutualiser la connaissance et les bonnes pratiques de la plateforme
dans un principe d'amélioration continue, et comment elle a mis en place
un mode coaching pour que ses membres puissent intégrer régulièrement les
nouvelles pratiques.</p>
<p>La réalisation des tickets de bug fix et/ou l'évolution d'un sprint est
divisée en différentes activités / phases :</p>
<ul>
<li>Analyse/Solution (atelier métier...)</li>
<li>Technical design (framework Symfony / JS ...)</li>
<li><a href="https://fr.wikipedia.org/wiki/Test_driven_development">TDD</a>
(Test Driven Developpment)</li>
<li>Code review / merge request process</li>
<li>Solution demo / End user training/validation</li>
<li>Déploiement automatisés multi-environnement / intégration
continue</li>
<li>Documentation / gestion et partage de connaissance</li>
</ul>
<p>L'équipe fait vivre un document qui recense les diverses pratiques à
valeur ajoutées, qui ont été expérimentées lors de ces phases telles que
:</p>
<ul>
<li>les pratiques assistées par des outils, d'analyse de l'historique de
tickets, de merge requests et/ou logs (comme <a href="https://www.elastic.co/fr/kibana">Kibana</a> par exemple pour
l'analyse de bugs ou encore le monitoring de volume d'activités de nos
divers sites, et/ou de la popularité de leur features etc.),</li>
<li>ou encore des outils de navigation / recherches dans les bases de
code git pour identifier efficacement les parties du code concernées (ou
impactées) par des évolutions,</li>
<li>la gestion de guidelines d'implémentations sur les frameworks majeurs de la plateforme, via des collèges animés par des membres
certifiés,</li>
<li>l'intégration collégiale d'IDE dans les phases de codage (phpstorm
et/ou vim plugins ...),</li>
<li>l'intégration d'outils de tests automatisés et tests coverages (phpunit,
corbertura...) => un sujet majeur de la Team Dev,</li>
<li>des recos de bonnes pratiques dans les échanges/démo avec les end
users (s'approprier le vocabulaire métier...),</li>
<li>l'intégration des pratiques standardisées de développement
collaboratif / gestion de branches et version (gestion de release
candidate / version compatible <a href="https://semver.org/lang/fr/">semver</a>),</li>
<li>l'intégration de pipelines automatisés de déploiement multi-environnement intégrant des test d'intégration continue,</li>
<li>l'intégration de solutions et processus dédiés à la gestion des
contenus de connaissance induit par l'activité de la plateforme, et
permettant la mise à niveau continue.</li>
</ul>
<p>La mutualisation de pratiques sur ces divers thèmes se fait en petit
atelier entre divers membres de la team et animés par les dev leads.</p>
<p>Chaque membre de la team peut ainsi contribuer à celles-ci selon ses
propres retour d'expérience et centres d'intérêts.</p>
<p>Quant à la mise à niveau de l'ensemble de l'équipe sur ces pratiques,
elle est directement intégrée dans le processus agile de sprint, lors
desquels certains tickets sont sélectionnés pour s'approprier certaines
pratiques, en les appliquant avec l'assistance d'un coach référant sur
celles-ci.</p>Bundle Symfony DevExpressurn:md5:a7b6ddee2b71fa44b6b104a7cc6665852021-03-01T11:22:00+01:002021-03-01T11:24:28+01:00Hervé PiedvacheDéveloppementbundledevexpressdevextremedéveloppementsymfony<p>DevExpress produit une suite de composants JavaScript HTML5 pour un développement Web réactif appelée DevExtreme.</p>
<p>D'Angular et React à ASP.NET Core ou Vue, DevExtreme comprend une collection complète de widgets d'interface utilisateur haute performance et réactifs à utiliser dans les applications Web traditionnelles et mobiles de nouvelle génération.
La suite est livrée avec une grille de données complète, des widgets graphiques interactifs, des éditeurs de données et bien plus encore.
Avec DevExtreme, vous offrirez des expériences utilisateur incroyables aux navigateurs Web modernes d'aujourd'hui.
DevExpress est un ensemble de librairies dont vous pouvez avoir le détail précis, avec des démonstrations de toutes les fonctionnalités directement sur le site de <a href="https://js.devexpress.com/" hreflang="en" title="DevExtreme">DevExpress</a>.</p>
<p>Et non nous n'avons pas de part dans DevExpress, mais nous l'utilisons au quotidien et nous avons fait un petit développement que nous vous proposons de partager sous la forme d'un bundle Symfony.</p> <p>Ce bundle est disponible publiquement sur <a href="https://github.com/Elma/DevExpressBundle" hreflang="en" title="Github">notre espace Github</a>.</p>
<p>Et comme le précise immédiatement son introduction :</p>
<ul>
<li>Ce bundle n'est pas un bundle officiel de l'équipe DevExpress.</li>
<li>Ce bundle n'inclut aucun fichier lié aux bibliothèques DevExpress.</li>
<li>Cet ensemble fournit un pont simple (et incomplet) entre les widgets et la doctrine DevExpressJs.</li>
<li>Cet ensemble est un WIP et les relations publiques sont les bienvenues.</li>
</ul>
<p>Actuellement, seul un pont dxDataGrid est fourni.</p>
<p>Je ne vais pas reprendre la documentation, et les examples dans cet article, il est là juste pour vous indiquer l'existence du Bundle Symfony qui pourrait assurément servir à d'autres que l'équipe de Bilendi Technology. Et puis pourquoi pas participer à son amélioration ou à ses évolutions sur d'autres composants DevExtreme.</p>Elma ouvre un pôle de développement à Grenobleurn:md5:3af54c5a8579514949e44f9bc4b40b882014-02-12T12:06:00+01:002022-11-21T16:06:20+01:00Hervé PiedvacheDéveloppementdéveloppementgrenobleéquipe<p>Le nouveau centre de développement a pour mission d'étendre et de renforcer l'ensemble des gammes de produits du Groupe Maximiles.</p> <p>L'ouverture de ce centre s'inscrit dans la continuité des évolutions d'expansion du Groupe Maximiles. Ce nouveau centre travaillera en étroite collaboration avec les équipes de développement Parisienne. Il accueille, à son ouverture, une équipe d'ingénieurs apportant plus de 25 ans d'expérience combinée autour du développement web principalement.
Situé à proximité d'universités et d'écoles d'ingénieurs de renommées mondiales, le nouveau centre de développement permettra à des développeurs talentueux de profiter de l'attractivité, de la qualité de vie et de la richesse de l'écosystème de la ville de Grenoble.</p>PHP : N'abusez pas de POO!urn:md5:d0649619c330cd2fc8aa803b2fee294d2011-04-06T10:02:00+02:002020-02-19T10:30:31+01:00Hervé PiedvacheDéveloppementdéveloppementphppoozend framework <p><img src="https://bilendi.tech/public/code_binaire.jpg" alt="Code" style="float:right; margin: 0 0 1em 1em;" title="Code, avr. 2011" height="240" width="250" />Qui aujourd'hui peut se permettre de faire du développement en PHP sans passer par la Programmation Orienté Object (POO pour les intimes) ?
Personne ... mais attention, programmer en POO c'est bien, mais tous les objets ne sont pas aussi efficaces que les fonctions natives de PHP.</p>
<p>Guillaume Luchet, Directeur de la Recherche et du Développement chez Elma, nous propose un rapide comparatif entre le <a href="https://zendframework.com/" hreflang="en" title="Zend Framework">Zend Framework</a> et les fonctions natives sur <a href="https://geelweb.org/fonctions-natives-vs-objets/" hreflang="fr" title="Fonctions natives vs Objets">son blog</a>.</p>Git en mode collaboratifurn:md5:695465e11b61cddcb0d38c14872e80fd2010-11-24T09:26:00+01:002019-11-05T11:26:04+01:00Hervé PiedvacheDéveloppementdébutantdéveloppeurgitversionning<p><a href="https://git-scm.com/" hreflang="en">Git</a> est un logiciel de gestion de versions décentralisé. C'est un logiciel libre créé par Linus Torvalds, le créateur du noyau Linux, et distribué sous la <a href="https://www.gnu.org/licenses/gpl.html" hreflang="en">GNU GPL version 2</a>. <a href="https://git-scm.com/" hreflang="en">Git</a> permet de gérer tout, des petits aux très grands projets avec rapidité et efficacité. Chaque clone d'un projet géré avec Git est un référentiel à part entière, contenant tout l'historique complet et tous les moyens nécessaire au suivi des modifications, il ne dépend pas de l'accès au réseau ou d'un serveur central. Les branches et les fusions sont rapides et faciles à faire.</p> <p>Guillaume Luchet, Directeur de la Recherche et du Développement chez Elma, nous propose sur son blog un très bon article pour l'utilisation de <a href="https://blog.geelweb.org/2010/11/git-en-mode-collaboratif.html" hreflang="fr">Git en mode collaboratif</a>.</p>
<p>Bonne lecture à tous.</p>Emailing : Implémentation de l'API client de Litmus en PHPurn:md5:e4efceb215da7b170bf1a45a9ec302b42010-08-10T09:47:00+02:002019-11-05T11:24:17+01:00Hervé PiedvacheDéveloppementapiemaillitmusphp<p><a href="https://litmusapp.com" hreflang="en">Litmus</a> est une société qui met à disposition des personnes routant des campagnes d'emailing une batterie d'outils permettant notamment de prévisualiser via une interface web votre email sur plus de 30 clients d'emails (outlook, thunderbird, hotmail, yahoo!, gmail etc.), mais aussi de vérifier si votre email passe les différents filtres antispam et d'obtenir des statistiques avancées de vos campagnes. Litmus met à disposition une API pour intégrer leurs outils dans vos propres applications, mais il reste encore une partie développement à réaliser de votre côté.</p> <p>Un de nos développeurs a réalisé une implémentation en PHP de cette API. Il la met à disposition du grand public. Vous pourrez donc profiter de l'intégration des méthodes de tests et de versions, de la création des emails, et de la récupération des résultats des tests. D'autres améliorations sont prévues dans les mois qui viennent. Vous trouverez les codes sources à l'adresse suivante : <a href="https://tri.mu/UG" hreflang="fr">https://github.com/geelweb/Litmus</a>.</p>
<p>Bon développement à tous.</p>PhoneGap, pour développer vos applications mobilesurn:md5:234f47f64a681faf9b4530e507fad5402010-02-10T23:24:00+01:002020-02-19T10:27:22+01:00eViasDéveloppementdéveloppementmobileopen sourcephonegap<p>Développer des applications pour smartphone sans avoir besoin de s'imprégner du SDK de chaque fabriquant ... à§a vous tente ?</p> <p><ins>PhoneGap qu'est-ce c'est ?</ins></p>
<p>PhoneGap est un framework JavaScript qui met à la disposition de tout développeur des fonctionnalités propres à certains smartphones telles la géolocalisation, l'accès aux contacts SIM, l'utilisation du vibreur ou encore
l'accéléromètre de l'iPhone.</p>
<p>Ce framework séduit par sa simplicité d'utilisation ainsi que son extensibilité. Tout développeur Web peut ainsi développer sa propre application iPhone, sans pour autant apprendre l'Objective-C.</p>
<p>L'intéràªt majeur de cette "librairie" est de permettre le développement, relativement rapide, d'une base d'applications réutilisables sur toute plateforme mobile. Les fonctionnalités à proprement parler sont bien sà»r à implémenter séparément pour chaque plateforme. (iPhone OS, Android, Maemo, etc.).</p>
<p>Le fait de rendre possible l'utilisation de langages comme le HTML combinés à du CSS et du Javascript pour construire une application mobile, qui plus est complète, est, pour moi, très prometteur étant donné le boost en terme de productivité. Simple, extensible, open source. N'est-ce pas là la mixture parfaite ?!</p>
<p>Pour en venir à la plateforme de test que propose PhoneGap sur son site web, je tiens juste à préciser qu'il ne faut pas oublier que votre application est exécutée dans un émulateur qui lui est lancé sur un PC ou un Mac.
Malheureusement, nos smartphones ne sont pas équipés de matériaux équivalents, ainsi les résultats en terme de performances constatés avec PhoneGap ne seront pas toujours comparables aux résultats produits à partir des plateformes visées tels l'iPhone, le BlackBerry ou encore le HTC Hero.</p>
<p>Pour plus d'informations, je vous conseille vivement <a href="https://phonegap.pbworks.com">le wiki de PhoneGap</a> qui regorge d'exemples et de documentations ou encore <a href="https://phonegap.com/projects">la page de projets</a> qui présente un bref listing des différents projets développés à l'aide de PhoneGap .</p>Zend Framework 1.10.0 dans les bacsurn:md5:17f42a8fd86027dce3412c5b369de6242010-02-09T18:31:00+01:002020-02-19T10:27:42+01:00Hervé PiedvacheDéveloppementphpzend framework<p>Depuis la sortie du <a href="https://www.footcow.com/index.php/post/2006/04/28/Zend-Framework" hreflang="fr">Zend Framework</a> en 2006, de nombreuses mise à jour ont vu le jour. La version 1.10.0 stable apporte son lot de nouveautés à ne pas manquer !</p> <p>Principales nouvelles classes apparues dans ZF v1.10.0 :<br /></p>
<ul>
<li>Zend_Barcode, par Mickael Perraud</li>
<li>Zend<sub>Cache</sub>Backend_Static, par Pà¡draic Brady</li>
<li>Zend<sub>Cache</sub>Manager, par Pà¡draic Brady</li>
<li>Zend_Exception - par by Marc Bennewitz</li>
<li>Zend<sub>Feed</sub>Pubsubhubbub, par Pà¡draic Brady</li>
<li>Zend<sub>Feed</sub>Writer, par Pà¡draic Brady</li>
<li>Zend<sub>Filter</sub>Boolean, par Thomas Weidner</li>
<li>Zend<sub>Filter</sub>Compress/Decompress, par Thomas Weidner</li>
<li>Zend<sub>Filter</sub>Null, par Thomas Weidner</li>
<li>Zend_Log::factory(), par Mark van der Velden et Martin Roest</li>
<li>Zend<sub>Log</sub>Writer_ZendMonitor, par Matthew Weier O'Phinney</li>
<li>Zend_Markup, par Pieter Kokx</li>
<li>Zend_Oauth, par Pà¡draic Brady</li>
<li>Zend_Serializer, par Marc Bennewitz</li>
<li>Zend<sub>Service</sub>DeveloperGarden, par Marco Kaiser</li>
<li>Zend<sub>Service</sub>LiveDocx, par Jonathan Marron</li>
<li>Zend<sub>Service</sub>WindowsAzure, par Maarten Balliauw</li>
<li>Zend<sub>Validate</sub>Barcode, par Thomas Weidner</li>
<li>Zend<sub>Validate</sub>Callback, par Thomas Weidner</li>
<li>Zend<sub>Validate</sub>CreditCard, par Thomas Weidner</li>
<li>Zend<sub>Validate</sub>PostCode, par Thomas Weidner</li>
<li>Zend_Pdf parsing la vitesse a été améliorée d'environ 40%</li>
<li>Ajout des ressources Zend_Application, comme Cachemanager, Dojo, Jquery, Layout, Log, Mail, et Multidb (par by Dolf Schimmel)</li>
<li>Refactoring de Zend_Loader::loadClass() pour se conformer au référence d'implémentation du PHP Framework Interop Group, qui permet de gérer l'autoloading des namespace de PHP 5.3</li>
<li>Mise à jour de Dojo version 1.4</li>
</ul>
<p>Zend_Tool a été complètement revu pour éliminer les problèmes internes, mais aussi pour ajouter de nouvelles fonctionnalités :<br /></p>
<ul>
<li>Fonctionnement en CLI (ligne de commande) avec le support d'un répertoire de travail et une configuration</li>
<li>De nouveaux prestataires pour la génération de modèles, configuration de DbAdapter, mise en page et la génération de formulaire</li>
<li>La structure du projet vient par défaut avec une gestion des logs dans ErrorControllerDefault</li>
</ul>Développement sur mesureurn:md5:5f8a51f5565396f10f3bbe917b220e901998-03-29T14:50:00+02:002019-11-05T11:17:47+01:00Hervé PiedvacheDéveloppementcdéveloppementperlphppostgresqlpython<p><img src="https://bilendi.tech/public/code-source.png" alt="Code source" title="Code source, fév. 2010" height="210" width="320" /><br /></p>
<p>Pour répondre aux besoins d'une entreprise, sur un produit, un concept, une organisation informatisée. Vous avez un besoin qui, aujourd'hui, n'est pas satisfait par un logiciel commercial. Votre activité nécessite des paramètres spéciaux de calculs, ou d'organisation informatique.<br /></p>
<p><strong>Nous sommes là pour vous apporter des solutions.</strong></p> <p>Nos équipes sont à màªme de répondre à vos besoins au travers de logiciels spécifiques pour Linux, Mac OS X ou Windows. Nous pouvons rapidement et efficacement répondre à vos besoins, que ce soit de commerce électronique, des applications business-to-business, des bases de données, des systèmes connectés au Web etc.<br /></p>
<p><strong>Domaines de compétences</strong><br /></p>
<p><em>Langage de développement :</em>
C, C++, Pascal, Perl, PHP, Python</p>
<p><em>Base de données :</em>
PostgreSQL, Oracle</p>
<p><strong>Applications de développements sur mesure :</strong></p>
<ul>
<li>Gestion de base de données relationnelles</li>
<li>Internet / Intranet</li>
<li>Applications graphiques et mathématiques distinctes</li>
<li>Traitement de l'image et du signal</li>
<li>Application de vidéo surveillance</li>
<li>Gestion d'entreprise (devis, comptabilité, gestion de stocks, de livraison etc.)</li>
<li>Gestion des commandes en salle pour les cafés-restaurants</li>
</ul>
<p><strong>Exemple de cas réel :</strong></p>
<p>Eurexim
Société commercialisant des produits de sécurité pour les foyers de chauffage.</p>
<p>Leurs besoins :
Traiter la moyenne des 5000 formulaires d'assurance, reà§us quotidiennement. Et permettre une exploitation de cette base de clients pour réaliser des opérations de VPC.</p>
<p>Nos solutions :</p>
<ul>
<li>Un logiciel sur-mesure s'appuyant sur un moteur de base de données Oracle, qui importe les données traitées par un système de reconnaissance optique.</li>
<li>Analyse avancée des doublons potentiels par rapport aux fichiers existant.</li>
<li>àmission d'accusés de réception automatisée.</li>
<li>Gestion de publipostages automatiques selon les différents critères d'achats des clients.</li>
<li>Traitement des commandes en VPC, assistance logistique pour les envois, liaison comptable automatisée avec la gamme Sage, préparation intégrale des données postales.</li>
</ul>
<p><strong>Nos références</strong>
Comité Miss France, ToxLab, SCAP, Maximiles Services, RASG, Résidence Club de Neuilly, Acurio, Eurexim, QuickVidéo</p>
<p>Prenez <a href="https://bilendi.tech/index.php?contact">contact</a> avec nous.</p>