Bastien Donjon

Développeur web à Bordeaux

Author Archive

Friday

9

September 2016

0

COMMENTS

Set local default on your Angular 2 RC6 app

Written by , Posted in Javascript, typescript

Juste set LOCALE_ID in your app.module.ts file :

import {NgModule, ReflectiveInjector, LOCALE_ID}      from '@angular/core';

@NgModule({
    imports: [
        BrowserModule,
        FormsModule,
        HttpModule,
        routing
    ],
    declarations: [
        AppComponent,
    ],
    providers: [
        {provide: LOCALE_ID, useValue: 'fr-FR'},
        BaseRequestOptions
    ],
    bootstrap: [AppComponent]
})

Tuesday

6

September 2016

0

COMMENTS

Round number with Angular 2, pipe and Typescript

Written by , Posted in Javascript, typescript

// round.pipe.ts
import {Pipe, PipeTransform} from "@angular/core";

/**
 *
 */
@Pipe({name: 'round'})
export class RoundPipe implements PipeTransform {
    /**
     *
     * @param value
     * @returns {number}
     */
    transform(value: number): number {
        return Math.round(value);
    }
}
// app.module.ts
@NgModule({
    imports: [
        BrowserModule,
        FormsModule,
        HttpModule,
        routing
    ],
    declarations: [
        AppComponent,
        RoundPipe
    ],
    providers: [
        BaseRequestOptions
    ],
    bootstrap: [AppComponent]
})
<!-- exemple -->
<span>{{ yournumber | round }}</span>

Builded with TypeScript 1.8 for Angular 2.RC5

Friday

27

November 2015

0

COMMENTS

ISO8601 Date validator for Laravel 5

Written by , Posted in PHP

date_format rule for Laravel 5 Validator don’t work.

So here is a validation rule for Laravel :

<?php

// file : app/Provider/AppServiceProvider.php

namespace App\Providers;

use Illuminate\Support\Facades\Validator;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{

    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        // Validation
        Validator::extend(
            'iso_date',
            function ($attribute, $value, $parameters, $validator) {
                $regex = '/^(?:[1-9]\d{3}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1\d|2[0-8])|' .
                         '(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[1-9]' .
                         '\d(?:0[48]|[2468][048]|[13579][26])|(?:[2468][048]|[13579][26])00)' .
                         '-02-29)T(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:Z|[+-][01]\d:[0-5]\d)$/';

                return preg_match_all($regex, $value) > 0;
            }
        );
    }

    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        //
    }
}

Original answer on Stackoverflow

Wednesday

14

January 2015

0

COMMENTS

[Javascript] For in extended Array prototype

Written by , Posted in Javascript

If you have extended Array prototype with functions like this :

Array.prototype.inArray = function(){
    console.log('inArray function');
}

The result of your ‘for’ will contain the properties and new functions.

var values = ['value1', 'value2'];
console.log(testArray);

// => ["value1", "value2", inArray: function]

for(var i in values){
    console.log(i + ' : ' + values[i]);
}

// =>
// 0 : value1
// 1 : value2
// inArray : function (){
//   console.log('inArray function');
// }

To fix this issue :

Case 1 with hasOwnProperty

for(var i in values){
    if (values.hasOwnProperty(i)) {
        console.log(i + ' : ' + values[i]);
    }
}

// =>
// 0 : value1
// 1 : value2

Case 2 with forEach

function logArrayElements(element, index, array) {
    console.log("a[" + index + "] = " + element);
}
values.forEach(logArrayElements);

// =>
// 0 : value1
// 1 : value2

Run on JsFiddle

Tuesday

2

December 2014

0

COMMENTS

Install and use Grunt in Vagrant and Windows

Written by , Posted in Uncategorized

If you have many errors with Grunt in Vagrant and Windows this is probably due to symlinks.

To fix it :

1 – Add this lines in Vagrantfile

config.vm.provider "virtualbox" do |v|
    v.customize ["setextradata", :id, "VBoxInternal2/SharedFoldersEnableSymlinksCreate/vagrant", "1"]
end

2 – Run this command in an admin console on Windows

fsutil behavior set SymlinkEvaluation L2L:1 R2R:1 L2R:1 R2L:1

3 – And start your Vagrant

vagrant up

4 – Install Grunt globally

npm install -g grunt-cli
npm install -g grunt --no-bin-links

5 – Go in your project directory and install NPM Packages without errors

npm install --no-bin-links

6 – Use Grunt

grunt --version

Wednesday

22

October 2014

0

COMMENTS

[Service] Des petites difficultés pour prioriser vos projets ?

Written by , Posted in web services

SortinProject | Service de priorisation de projets

En tant que développeur web j’ai beaucoup de projets et d’idées en tête. Mon mail explose de prise de notes dans ce sens …

Malheureusement, entre les projets fun, compliqués, potentiellement rémunérateurs, à faire en solo ou en équipe, il est difficile de les classer pour savoir quel sera le prochain à développer.

Dans l’idée des matrices de priorisation de projets j’ai donc conçu un petit service en ligne bien utile pour centraliser vos projets et mettre en évidence les projets ayant le plus d’intérêt. Ce service c’est SortingProject.com

Simple et efficace, vous n’avez qu’à créer vos propres critères de sélection et à définir leurs poids dans le calcul de priorisation.

Bientôt en version Beta, n’hésitez pas à vous inscrire pour être les premiers à tester SortingProject.com

Wednesday

27

August 2014

0

COMMENTS

Remove duplicate documents from a search in Elasticsearch

Written by , Posted in Uncategorized

If you have many documents with the same value of the same field, this source code can help you. Using terms aggregator and top hits aggregator is required.

My index :

  • Doc 1 {domain: ‘domain1.fr’, name: ‘name1′, date: ’01-01-2014’}
  • Doc 2 {domain: ‘domain1.fr’, name: ‘name1′, date: ’01-02-2014’}
  • Doc 3 {domain: ‘domain2.fr’, name: ‘name2′, date: ’01-03-2014’}
  • Doc 4 {domain: ‘domain2.fr’, name: ‘name2′, date: ’01-04-2014’}
  • Doc 5 {domain: ‘domain3.fr’, name: ‘name3′, date: ’01-05-2014’}
  • Doc 6 {domain: ‘domain3.fr’, name: ‘name3′, date: ’01-06-2014’}

My result (deduplication result by domain field) :

  • Doc 6 {domain: ‘domain3.fr’, name: ‘name3′, date: ’01-06-2014’}
  • Doc 4 {domain: ‘domain2.fr’, name: ‘name2′, date: ’01-04-2014’}
  • Doc 2 {domain: ‘domain1.fr’, name: ‘name1′, date: ’01-02-2014’}

Elasticsearch query :

/POST http://localhost:9200/test/dedup/_search?search_type=count&amp;pretty=true
"aggs":{
    "dedup" : {
      "terms":{
        "field": "domain"
       },
       "aggs":{
         "dedup_docs":{
           "top_hits":{
             "size":1
           }
         }
      }
    }
  }
}

I originally asked a question here.

Tuesday

17

June 2014

0

COMMENTS

Plinks.io helps you find your links

Written by , Posted in web services

plinks.io

Today, i opened a landing page for plinks.io, my new web service.

This web service must meet one of my problems and probably full of other people.  How to find a page view there several days ?

There is no way to find a link to a page appropriately…

Plinks.io should be simple for you to have the minimum action to do, to push and to find your links.

This service should interest all those who consulted a lot of web page.

Plinks is not like xmarks, delicious or more ! It’s more fun.

See you soon for more details !

Thursday

24

April 2014

0

COMMENTS

Basic authentification with AngularJs and Laravel

Written by , Posted in Javascript, PHP

Here’s a simple solution to install basic authentication system with AngularJs.

This is a subject that is not much developed. Probably because of the different authentication methods and functional needs.

For me I needed:
– Authentication Required
– To authenticate the user on my RESTful API
– Not to send the user name and password to each request
– Not to make cross-domain
– To have a persistent connection (F5 or close browser window)
– To block access to the application if the authentication server is lost

Laravel configuration

route.php
// Route with basic authentification and custom method
Route::group(
    [ 'before' => 'auth.basicCustom' ], function () {
        // User authenticate with sesssion
        Route::post('authenticate', function(){
            echo 'ok';
        });
    }
);

// Logout current user
Route::get('/logout', function(){
    Auth::logout();
});

// Check state of current user authentification
Route::get('/guest', function(){
    if(Auth::guest()){
        throw new \Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException('x-Basic')
    }else{
        echo 'ok';
    }
});

filters.php

Route::filter(
    'auth.basicCustom', function () {
        $credentials = [ 'email' => Request::getUser(), 'password' => Request::getPassword() ];

        if (!Auth::check()) {
            if (!Auth::once($credentials)) {
                throw new \Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException('x-Basic');
            }
        }
    }
);

Configuration AngularJs

app.js

angular.module('App', [
    'LocalStorageModule',
    'authServices'
  ])

  .config(['$httpProvider' ,
    function ($httpProvider) {

      /* -- Add your routes or states -- */

      // Authentification provider
      $httpProvider.interceptors.push('authInterceptor');
  }]);

authInterceptor.js

'use strict';

/**
 * Authentification Services
 */
angular.module('authServices', [])

  /**
   * Add callback after/befor http request
   */
  .factory('authInterceptor', ['$rootScope', '$q', '$window', 'localStorageService',
      function ($rootScope, $q, $window, localStorageService) {
        return {

          /**
           * Before request
           * @param config
           * @returns {*}
           */
          request: function (config) {
            config.headers = config.headers || {};
            return config;
          },

          /**
           * After success request
           * @param response
           * @returns {*|Promise}
           */
          response: function (response) {
            return response || $q.when(response);
          },

          /**
           * After error request
           * @param rejection
           * @returns {Promise}
           */
          responseError: function (rejection) {
            localStorageService.add('authenticate', false);
            $rootScope.authenticate = false;
            return $q.reject(rejection);
          }
        };
    }]);

userController.js

angular.module('App')

  .controller('UserCtrl', ['$rootScope', '$scope', '$http', '$window', 'localStorageService',
    function ($rootScope, $scope, $http, $window, localStorageService) {
      $scope.submit = function () {
        $http
          .post('/api/authenticate', {}, {
            // Forcage du type d'authentification
            headers: {
              Authorization : 'Basic ' + btoa($scope.user.username + ":" + $scope.user.password)
            }
          })
          .success(function (data, status, headers, config) {
            localStorageService.add('authenticate', true);
            $rootScope.authenticate = true;
            // Suppression des informations utilisation pour ne pas les garder en claire dans le scope
            delete $scope.user;
          })
          .error(function (data, status, headers, config) {
            localStorageService.add('authenticate', false);
            $rootScope.authenticate = false;
          });
      };
  }]);

directives.js

'use strict';

angular.module('App')
  .directive('ngLogin', function () {
    return {
      restrict: 'E',
      templateUrl: 'partials/login.html'
    };
  });

login.html

<div id="login-wrapper">
    <table>
        <tbody>
            <tr>
                <td>
                    <form id="login-form" role="form">
                        <div class="form-group"><a id="login-logo" href="#/"><img alt="Chilican" src="/images/logo.png" /></a></div>
                        <div class="form-group">
                              <label for="userEmail">Adresse email</label>
                              <input class="form-control" id="userEmail" type="email" name="user" placeholder="ex : email@domain.com" />
                        </div>
                        <div class="form-group">
                              <label for="userPassword">Mot de passe</label>
                              <input class="form-control" id="userPassword" type="password" name="pass" />
                        </div>
                        <button class="btn btn-default" type="submit">Se connecter</button></form>
                 </td>
             </tr>
       </tbody>
   </table>
</div>

sources :

Thursday

3

April 2014

0

COMMENTS

Basic authentification with EmberJs and Laravel

Written by , Posted in Javascript, PHP

The following example uses the ember-simple-auth plugin. This is an early implementation for the Basic authentication with Laravel session and RestFul Api.

Currently, it can :

  • Require authentication to the IndexRoute and DashboardRoute
  • Refresh authentication if you refresh the page

Not being a specialist EmberJs this code is incomplete like :

  • Retrieving information form
  • Error handling in a loss of authentication with an API call
  • Proper use of the accessToken property

For safety reasons use the HTTPS protocol.

I am at your service if you have any comments or questions.

Ember configuration

Template : login.hbs

</pre>
<form action=""><label for="identification">Login</label>
 {{input id='identification' placeholder='Enter Login' value=identification}}
 <label for="password">Password</label>
 {{input id='password' placeholder='Enter Password' type='password' value=password}}
 <button type="submit">Login</button></form>
<pre>

app.js


// Defining a custom authentication with Basic method.
var CustomAuthenticator = Ember.SimpleAuth.Authenticators.Base.extend({
    // Check session if you refresh browser (F5)
    restore: function(properties) {
        return new Ember.RSVP.Promise(function(resolve, reject){
            Ember.$.ajax({
                url: 'http://localhost.com/api/guest',
                success : function(datas){
                    resolve(properties);
                },
                error: function(datas){
                    reject();
                }
            });
         });
    },
    // Initialized authentification
    authenticate: function(options) {
        return new Ember.RSVP.Promise(function(resolve, reject){
            Ember.$.ajax({
                url: 'http://localhost.com/api/profile',
                success : function(datas){
                    resolve({accessToken : 'fddfgdfgfdgfg'});
                },
                headers: {
                    "Authorization": "Basic " + btoa("email4@domain.fr:password4")
                }
            });
        });
    },
    invalidate: function(options) {
        return new Ember.RSVP.Promise(function(resolve, reject){
            Ember.$.ajax({
                url: 'http://localhost.com/api/logout',
                success : function(datas){
                    resolve({accessToken : 'fddfgdfgfdgfg'});
                }
            }).then(function(response){
                Ember.run(resolve);
            }, function(xhr, status, error){
                Ember.run(reject);
            });
        });
    }
});

// Initialied a custom authentication.
Ember.Application.initializer({
    name: 'authentication',
    initialize: function(container, application) {
        container.register('authenticators:custom', CustomAuthenticator);
        Ember.SimpleAuth.setup(container, application);
    }
});

BackendWebapp.LoginController = Ember.Controller.extend(Ember.SimpleAuth.LoginControllerMixin, {
    authenticatorFactory: 'authenticators:custom'
});

// Add authentification for Route Index
BackendWebapp.IndexRoute = Ember.Route.extend(Ember.SimpleAuth.AuthenticatedRouteMixin);

// Add authentification for DashBoardIndex
BackendWebapp.IndexRoute = Ember.Route.extend(Ember.SimpleAuth.AuthenticatedRouteMixin);

Laravel configuration

route.php

// Logout current user
Route::get('/logout', function(){
    Auth::logout();
});

// Chech current authentification state
Route::get('/guest', function(){
    if(Auth::guest()){
        throw new \Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException();
    }else{
        echo 'ok';
    }
});

filters.php

Change Authentification method “Basic” to “x-Basic” to desactivate authentification popup in Google Chrome with ajax request.

Route::filter(
    'auth.basicCustom', function () {
        $credentials = [ 'email' => Request::getUser(), 'password' => Request::getPassword() ];

        if (!Auth::once($credentials)) {
            throw new \Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException('x-Basic');
        }
    }
);

sources :