Comparer deux intervalles de date

Un problème classique avec les bases de données est la comparaison de deux intervalles de date. Mon intervalle A est il compris dans mon intervalle B ?
Avec un peu de réflexion c’est un problème très simple a résoudre.

L’illustration précente définie un intervalle de base (le gris) et toute les possibilités de bons (vert) et mauvais (rouge) intervalles.
Mon intervalle B est donc compris dans A si il ne fini pas avant le début de A et qu’il ne commencent pas après la fin de A.

En supposant que votre intervalle de date est décrit par deux champs date , on pourrait traduire cela par :

SELECT * FROM maTable WHERE NOT(date_debut > 2011-12-31 OR date_fin < 2011-01-01);

Dans cet exemple je cherche donc toute les dates qui ne commencent pas (NOT) après le 31 décembre 2011 ou qui ne se finisse pas avant le 1er janvier 2011.

En modifiant un peu la logique on peut supprimer le NOT qui n’aide pas forcément à la compréhension :

SELECT * FROM maTable WHERE date_debut < 2011-12-31 AND date_fin > 2011-01-01;

Cette fois je récupère donc toutes les dates qui commencent avant le 31/12/2011 et qui se termine après le 01/01/2011

Ajouter un Custom Listener à un Widget personnalisé

Lorsque que l’on écrit un widget ou vue personalisé , les Listeners de base tel que onClickListener ne sont parfois pas suffisants. On peut avoir besoin de déclarer ses propres listeners qui répondront à des cas très précis.

Voici un exemple générique d’implémentation de listener personalisé ou custom listener.

Interface :

Nous supposons que votre widget est déjà en partie crée. Dans notre exemple il s’appelera MyCustomView.
La première étape est de créer une interface qui va gérer le Listener :

public interface OnMyCustomeEventListener {
	public abstract void onMyCustomEvent();
}

Cette interface ne comporte qu’une méthode abstraite pour rester simple , mais il est bien entendu possible de faire quelque chose de plus complexe avec plusieurs méthodes à redéfinir.

Modification de la vue personnalisée :

Passons à la vue. je n’ai garder que le code qui nous intéresse ici :

class MyCustomView extends View
{
	private OnMyCustomEventListener eventListener = null;

	/*
	* Le code de votre widget
	*/

	public void setOnMyCustomEventListener(OnMyCustomeEventListener listener)
	{
		this.eventListener = listener;
	}

	private void onMyCustomEvent()
	{
		if(eventListener != null)
			eventListener.onMyCustomEvent();
	}
}

1- On commence avec une variable qui contiendra une instance de notre listener.
2- On ajoute ensuite un setter setOnMyCustomEventListener pour que l’on puisse définir notre listener depuis l’activity.
3- On termine ensuite avec une méthode onMyCustomEvent que vous pourrez appelez ou vous voudrez dans votre code.

L’intérêt de cette dernière méthode c’est que l’on va y faire tous les tests nécessaires à la réalisation de l’événement. Nous testons dans l’exemple l’existance d’une instance de OnMyCustomeEventListener mais on pourrait imaginer vérifier d’éventuels paramètres conditionnant l’execution de l’événement.
Une fois ces 3 étapes ajoutées à votre widget , le plus gros du travail est fait. Il ne reste plus qu’à définir votre listener dans l’activity

Ajout du Listener :

public class MyActivity extends Activity
{
	private OnMyCustomeEventListener MyCustomViewListener = new OnMyCustomeEventListener () {
		@Override
		public void onMyCustomEvent()
		{
			//Ecrire ici votre événement
		}
	}

	public void onCreate(Bundle savedInstanceState)
	{
		MyCustomView myView = (MyCustomView) findViewById(R.id.myView);
		myView.setOnMyCustomEventListener(MyCustomViewListener);
	}
}

Dans notre activity on créer une variable qui instancie notre interface. Cette variable est donc notre listener. Ne reste ensuite qu’à passer ce listener à notre vue personnalisée via le setter précédemment défini.

Partager un arrayList d’objet entre activity via Parcelable

Imaginons le cas classique d’une activité A , d’une activité B et d’un objet Personne. Comment transférer un arrayList de Personne entre A et B ?

Il faut simplement implémenter Parcelable pour l’objet personne et créer un liste d’objet elle même Parcelable.

Commençons par notre objet Personne très simple :

Class Personne
{
	private String nom;
	private String prenom;

	public Personne(){}
	public Personne(String nom,String prenom)
	{
		this.nom 		= nom;
		this.prenom = prenom;
	}

	public void setNom(String nom){ this.nom = nom;}
	public void setPrenom(String prenom){ this.nom = prenom;}

	public String getNom(){return this.nom;}
	public String setNom(){return this.prenom}
}

Rendre l’objet Parcelable

Implémentons l’interface Parcelable :

Class Personne implements Parcelable
{
	//Même chose que précédent
	[...]

	//Second constructeur qui sera appelé lors de la "Deparcelablisation"
	public Personne(Parcel in)
	{
		this.getFromParcel(in);
	}

	@SuppressWarnings("rawtypes")
	public static final Parcelable.Creator CREATOR = new Parcelable.Creator()
	{
		public Personne createFromParcel(Parcel in)
		{
			return new Personne(in);
		}

		@Override
		public Object[] newArray(int size) {
			return null;
		}
	};

	@Override
	public int describeContents() {
		return 0;
	}

	//On ecrit dans le parcel les données de notre objet
	@Override
	public void writeToParcel(Parcel dest, int flags)
	{
		dest.writeString(this.nom);
		dest.writeString(this.prenom);
	}

	//On va ici hydrater notre objet à partir du Parcel
	public void getFromParcel(Parcel in)
	{
		this.setNom(in.readString());
		this.setPrenom(in.readString());
	}
}

Les deux méthodes importantes sont writeToParcel et getFromParcel qui permettent respectivement d’écrire dans le Parcel et de lire dedans. Pour simplifier on « sérialise » l’objet avec writeToParcel et on le « déserialise » avec getFromParcel.
Notez que getFromParcel peut se nommer comme bon vous semble.
L’ordre des variables dans writeToParcel est important puisque vous devrez utiliser le même dans getFromParcel.
Vous avez à cet instant un objet Parcelable , ce qui veux dire que vous pouvez le passer d’une activité à une autre au travers d’un Bundle. Notre but étant de passer une liste il nous reste encore un peu de travail.

Créer un arrayList Parcelable

Pour pouvoir transférer une liste d’objet on va créer une liste de personne qui dérive de ArrayList et qui implémente parcelable. On reprend exactement le même principe que pour notre objet :

class PersonneList extends ArrayList<Personne> implements Parcelable
{
	public PersonneList()
	{

	}

	public PersonneList(Parcel in)
	{
		this.getFromParcel(in);
	}

	@SuppressWarnings("rawtypes")
	public static final Parcelable.Creator CREATOR = new Parcelable.Creator()
	{
		public PersonneList createFromParcel(Parcel in)
		{
			return new PersonneList(in);
		}

		@Override
		public Object[] newArray(int size) {
			return null;
		}
	};

	@Override
	public int describeContents() {
		return 0;
	}

	@Override
	public void writeToParcel(Parcel dest, int flags)
	{
		//Taille de la liste
		int size = this.size();
		dest.writeInt(size);
		for(int i=0; i < size; i++)
		{
			Personne pers = this.get(i); //On vient lire chaque objet personne
			dest.writeString(pers.nom);
			dest.writeString(pers.prenom);
		}
	}

	public void getFromParcel(Parcel in)
	{
		// On vide la liste avant tout remplissage
		this.clear();

		//Récupération du nombre d'objet
		int size = in.readInt();

		//On repeuple la liste avec de nouveau objet
		for(int i = 0; i < size; i++)
		{
			Personne pers = new Personne();
			pers.setNom(in.readString());
			pers.setPrenom(in.readString());
			this.add(pers);
		}

	}
}

Nous avons donc désormais un objet parcelable ainsi qu’une liste. Il ne nous reste plus qu’à peupler la liste d’objet et de transmettre la liste entre les activités :

Intent myIntent = new Intent(Activity_A.this,Activity_B.class);
myIntent.putExtra("identifiantListe",(Parcelable)monObjet_personneList);
startActivity(myIntent);

Pour récupérer la liste d’objet dans l’autre activité il suffit de récupérer le bundle :

public void onCreate(Bundle savedInstanceState)
{
	super.onCreate(savedInstanceState);
	setContentView();

	Bundle b 	= getIntent().getExtras();
    PersonneList maliste 	= b.getParcelable("identifiantListe");
}

Et si mon objet contient d’autres objets ?

Il n’est pas rare d’avoir un objet qui en contient d’autre. Dans ce cas comment faire puisque Parcel n’a que des méthode de lecture et d’écriture de type primitifs ?
Et bien tout d’abord il faut que cet objet inclus soit lui aussi Parcelable. Puis dans les deux méthodes writeToParcel et getFromParcel il vous suffit d’écrire/lire cet objet via writeParcelable et readParcelable.
Exemple :

//On ecrit dans le parcel les données de notre objet
@Override
public void writeToParcel(Parcel dest, int flags)
{
	dest.writeString(this.nom);
	dest.writeString(this.prenom);
	dest.writeParcelable(this.listeAnimaux,flags); // On écrit la liste des animaux de la personne
}

//On va ici hydrater notre objet à partir du Parcel
public void getFromParcel(Parcel in)
{
	this.setNom(in.readString());
	this.setPrenom(in.readString());
	// On lit la liste des animaux de la personne
	this.listeAnimaux = in.readParcelable(ListeAnimaux.class.getClassLoader());
}

Vous devriez normalement avec cette méthode faire transitez tous les objets ou liste d’objets que vous souhaitez entre deux activités.

Débuter Android : Les liens utiles

Ayant récemment eu besoin de me mettre au développement sur mobile android j’ai écumé le web à la recherche de lien pour débuter et faire une appli de base. Je partage ici les liens qui m’on semblé utiles voir indispensable. n’hésitez pas à faire par des vôtres dans les commentaires !

LA bible , indispensable , la doc officielle Google :

Tutomobile.fr un site avec plein de tutoriaux sur les mobiles dont android. Excellent pour débuter : Consulter

Developpez.com section android : Des tutos , une FAQ et un forum ! : http://android.developpez.com/

ActionBar simple pour android. Un peu plus avancé mais vous en aurez sans doute vite besoin : Github

Comment faire un splashScreen pour android : Splashscreen

Sans doute la plus grosse communauté d’aide en développement et donc pour android.

OVH wordpress table crashed

Petite surprise agréable aujourd’hui en découvrant que tous les posts du blog avait disparus … évidemment la dernière sauvegarde datait un peu.

J’ai été faire un tour dans phpmyadmin pour me rendre compte que tout espoir n’était pas perdu , la table était « simplement »  crashed.

Si jamais il vous arrivent la même chose vous devriez pouvoir récupérer votre table et la grande majorité de son contenu avec :

REPAIR TABLE wp_posts QUICK

Exemple simple avec SplObjectStorage

La classe SplObjectStorage est comme son nom l’indique issue de la SPL. Elle permet à l’instar des tableaux de stocker des collections d’objets. Cependant SplObjectStorage est nettement plus rapide qu’un simple tableau.Elle implémente de plus les interfaces Countable , Iterator , Traversable , Serializable , ArrayAccess qui rendent sont utilisation vraiment confortable.Voici un petit exemple pratique d’utilisation de cette class.Admettons que nous ayons une classe Groupe qui est charger de contenir plusieurs instance d’une classe Personne (un groupe composé de plusieurs personnes pour ceux qui suivent pas)
On commence par une classe Personne très simple :

class Personne
{
    private $nom;
    private $prenom;
    private $age;

    public function __construct($nom,$prenom,$age)
    {
        $this->nom      = $nom;
        $this->prenom   = $prenom;
        $this->age      = intval($age);
    }

    public function getAge()
    {
        return $this->age;
    }

}

Notre classe groupe étant supposée être une collection d’objet nous allons la faire dériver de SplObjectStorage :

class Groupe extends SplObjectStorage
{
    public function attach(Personne $personne)
    {
        parent::attach($personne);
    }

    public function detach(Personne $personne)
    {
        parent::detach($personne);
    }

    public function getMoyenneAge()
    {
        $nbObjet = $this->count();
        $total = null;
        foreach($this as $personne) {
            $total += $personne->getAge();
        }

        return floor($total / $nbObjet);
    }
}

On redéfini attach et detach pour n’accepter que des objet de type Personne (au lieu de n’importe quel objet).On ajoute ensuite une méthode qui va calculer la moyenne d’age du groupe.Pour celà il faut parcourir tous les objets de la collection. Un simple foreach suffit pour itérer sur le contenu de Groupe tout comme un simple count() nous retourne le nombre de Personne !
Ne reste ensuite plus qu’a créer quelques personnes et former un groupe :

$pierre = new Personne('Dupond','Pierre',30);
$paul   = new Personne('Dupont','Paul',28);
$jack   = new Personne('Dupon','Jack',60);

$groupe = new Groupe();
$groupe->attach($pierre);
$groupe->attach($paul);
$groupe->attach($jack);
echo $groupe->getMoyenneAge().'<br />';
//Jack décède tragiquement
$groupe->detach($jack);

echo $groupe->getMoyenneAge();

Jquery UI Dialog : Désactiver un bouton

Il peut être intéressant de pouvoir désactiver un bouton d’une boite de dialog jQuery UI. Une méthode simple et flexible consiste à utiliser les sélecteurs :button et :contains.

On peut alors désactiver un bouton en particulier :

$(":button:contains('Texte de mon bouton')").attr("disabled","disabled").addClass( 'ui-state-disabled' );

Et le réactiver le moment venu :

$(":button:contains('Texte de mon bouton')").removeAttr("disabled").removeClass( 'ui-state-disabled' );

PDO et sql server

Le driver PDO pour sqlserver étant en phase expérimental et carrément non supporté en PHP 5.3.x comment profiter de PDO pour se connecter à des bases sql server ?
Et bien tout simplement en passant par le driver ODBC qui lui est pleinement fonctionnel :
$dsn = "odbc:Driver={SQL Server Native Client 10.0};Server=127.0.0.1;Database=myDB;Uid=myUser;Pwd=myPass;"
$sql = new PDO($dsn);
$sql->query(...);
Les identifiants de connexion étant inclus dans le DSN il ne faut pas les inclures dans l’instanciation de PDO.

Webservice REST récupération des données

Lorsque l’on souhaite mettre en place un webservice REST en php on se heurte souvent au problème de la récupération des données quand on utilise une méthode autre que POST ou GET.
En effet PHP dispose des superglobales $_GET et $_POST mais qu’en est-il pour PUT,HEAD ou DELETE ?

Ces données sont bien transmises , il faut simplement passer par le flux php://input pour les retrouver :

 echo file_get_contents('php://input');

va retourner les données sous forme de query string (comme les paramètres en GET). Il ne reste donc qu’a parser cette chaine pour avoir un tableau facilement exploitable :

$method = $_SERVER['REQUEST_METHOD'];
if($method == 'GET')
    $datas = $_GET;
elseif($method == 'POST')
    $datas = $_POST;
else
    parse_str(file_get_contents('php://input'),$datas);

De cette manière quelque soit le type de méthode utilisée vous serez en mesure de récupérer les données envoyées.

Bouton type iphone CSS3

Voici comment réaliser un bouton de retour type Iphone sans aucune image et en css3.
Ce type bouton ayant pour cible les webapps des téléphone embarquant un navigateur webkit , il ne sont pas combatible avec d’autre navigateur. Il reste cependant ttrès simple d’ajouter les règles css propre à chaque navigateur.

Etape 1 forme générale

Commençons par une structure simple :

<div class="back-btn">
    <a href="#">Retour</a>
</div>

en ajoutant un peu de css à tout ceci

div.back-btn {
    position:absolute;
	text-shadow:none;
    height: 34px;
    min-width: 45px;
    width:auto;
    padding: 0 4px 0 4px;
    top:4px;
    left:16px;
    color:#fff;
    background: -webkit-gradient(linear, left top, left bottom, from(#849cbb), to(#4a6c9b),
                                                    color-stop(50%, #849cbb)
                                     );
    -webkit-border-radius: 5px;
    border:1px solid #384963;
}

div.back-btn a {
    position:relative;
    display:block;
    min-width: 45px;
    width:auto;
    height:34px;
    z-index: 100;
    font-size: 10pt;
    padding:0;
    color:#fff;
    line-height: 33px;
    text-decoration: none;
}

On obtient un semblant de bouton. Vous remarquerez l’utilisation des propriétés de dégradé de couleur plutôt que d’utiliser une image.

Notre bouton prend forme mais il lui manque tout de même la partie pointue, la flèche :

Etape 2 : La pointe

Pour obtenir la pointe nous allons profiter des propriétés de transformation du CSS3. L’idée générale étant d’utiliser un div que l’on fait pivoter de 45° pour que l’angle de la boite puisse servir de pointe.
On rajoute donc un div à notre structure html , qui devient :

<div class="back-btn">
    <a href="#">Retour</a>
    <div></div>
</div>

Il nous reste ensuite à mettre en forme ce div supplémentaire :

div.back-btn div {
    position: absolute;
    width: 24px;
    height: 24px;
    -webkit-transform: rotate(45deg);
    top: 5px;
    left: -11px;
    background: -webkit-gradient(linear, left top, right bottom, from(#849cbb), to(#4a6c9b),
                                                    color-stop(50%, #849cbb)
                        );
    -webkit-border-radius: 3px;
    border-bottom:1px solid #384963;
    border-left:1px solid #384963;
}

Voir le résultat final