diff --git a/application/modules/admin/controllers/ZoneController.php b/application/modules/admin/controllers/ZoneController.php
index cba055c472eac28e2ca15897a9fd2f2b52d4dc0d..fd67a43913ad08180276cb841823c73f36be1160 100644
--- a/application/modules/admin/controllers/ZoneController.php
+++ b/application/modules/admin/controllers/ZoneController.php
@@ -16,9 +16,9 @@
  *
  * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
  * along with BOKEH; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA 
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
  */
-class Admin_ZoneController extends Zend_Controller_Action
+class Admin_ZoneController extends ZendAfi_Controller_Action
 {
 
 	//---------------------------------------------------------------------
@@ -33,11 +33,11 @@ class Admin_ZoneController extends Zend_Controller_Action
 	protected function _checkPost($zone) {
 		$this->view->zone = $zone;
 
-		if (!$this->_request->isPost()) 
+		if (!$this->_request->isPost())
 			return;
 
 		if ($zone->updateAttributes($_POST)->save())
-				$this->_redirect('admin/zone/index');
+			$this->_redirect('admin/zone/index');
 	}
 
 	//---------------------------------------------------------------------
@@ -78,47 +78,35 @@ class Admin_ZoneController extends Zend_Controller_Action
 	//---------------------------------------------------------------------
 	// placer les bibliotheques sur la carte
 	//---------------------------------------------------------------------
-	function placerbibsAction()
-	{
-		$this->view->titre = 'Placement des bibliothèques sur la carte';
-		$id_zone=$this->_request->getParam("id_zone");
+	function placerbibsAction()	{
+		$this->view->titre = $this->view->_('Placement des bibliothèques sur la carte');
 
-		$bibs = fetchAll("select * from bib_c_site where ID_ZONE=$id_zone and VISIBILITE > 0");
-		// Validation
-		if ($this->_request->isPost())
-		{
-			$i = 0;
-			foreach($bibs as $bib)
-			{
-				// Positions des bibs
-				$id_bib=$bib['ID_SITE'];
-				$data = array();
-				$data["libelle"]=$_POST["libelle_".$i];
-				$data["posX"]=$_POST["posX_".$i];
-				$data["posY"]=$_POST["posY_".$i];
-				$data["posPoint"]=$_POST["posPoint_".$i];
-				$data["profilID"]=$_POST["profilID_".$i];
-				$props=addslashes(ZendAfi_Filters_Serialize::serialize($data));
-				sqlExecute("update bib_c_site set AFF_ZONE='$props' where ID_SITE=$id_bib");
-
-				// Proprietes du label
-				$couleur_texte=$_POST["couleur_texte"];
-				$couleur_ombre=$_POST["couleur_ombre"];
-				$taille_fonte=$_POST["taille_fonte"];
-				sqlExecute("update bib_c_zone set COULEUR_TEXTE='$couleur_texte', COULEUR_OMBRE='$couleur_ombre', TAILLE_FONTE='$taille_fonte' where ID_ZONE=$id_zone");
-				$i++;
-			}
+		if(!$zone = Class_Zone::find($this->_request->getParam('id_zone')))
+			$this->_redirect('admin/zone/index');
+
+		if(!$bibs = $zone->getVisibleBibs())
 			$this->_redirect('admin/zone/index');
+
+		if ($this->_request->isPost()) {
+			foreach($bibs as $bib) {
+				$bib_id = $bib->getId();
+				$data = ['posX' => $this->_request->getParam('posX_' . $bib_id, 0),
+								 'posY' => $this->_request->getParam('posY_' . $bib_id, 0),
+								 'posPoint' => $this->_request->getParam('posPoint_' . $bib_id),
+								 'profilID' => $this->_request->getParam('profilID_' . $bib_id, 0)];
+
+				$aff_zone = ZendAfi_Filters_Serialize::serialize($data);
+				$bib->setAffZone($aff_zone)->save();
+			}
+
+			$zone->setCouleurTexte($this->_request->getParam('couleur_texte'))
+					 ->setCouleurOmbre($this->_request->getParam('couleur_ombre'))
+					 ->setTailleFonte($this->_request->getParam('taille_fonte'))
+					 ->save();
 		}
 
-		// Entree formulaire
-		$this->view->zone= Class_Zone::getLoader()->find($id_zone);
-		if(!$this->view->zone->COULEUR_TEXTE) $this->view->zone->COULEUR_TEXTE="#ffffff";
-		if(!$this->view->zone->COULEUR_OMBRE) $this->view->zone->COULEUR_OMBRE="#000000";
-		if(!$this->view->zone->TAILLE_FONTE) $this->view->zone->TAILLE_FONTE="12";
-		
-		// Caracteristiques de l'image
-		$this->view->image=$this->view->zone->getImageZone($this->view->zone->IMAGE,true);
-		$this->view->bibs=$bibs;
+		$this->view->zone = $zone;
+		$this->view->image= $this->view->zone->getImageZone($zone->getImage(), true);
+		$this->view->bibs = $bibs;
 	}
 }
\ No newline at end of file
diff --git a/application/modules/admin/views/scripts/zone/placerbibs.phtml b/application/modules/admin/views/scripts/zone/placerbibs.phtml
index d2b9ff513bbce6b60b192e660d40fb6b57db39ae..8a6877bf9f3c53adf8ab836d19d4043f34306c17 100644
--- a/application/modules/admin/views/scripts/zone/placerbibs.phtml
+++ b/application/modules/admin/views/scripts/zone/placerbibs.phtml
@@ -4,114 +4,122 @@
 <script type="text/javascript" src="<?php echo URL_ADMIN_JS?>color_picker/jquery.vreboton.ColorPicker.js"> </script>
 
 <script type="text/javascript">
-var current_index=0;
-// Color picker
-	jQuery(function($)
-	{
-		$("#couleur_texte").attachColorPicker();
-		$("#couleur_texte").change(function()	{	$('span').css('color',$('#couleur_texte').val()) });
-		$("#couleur_ombre").attachColorPicker();
-		$("#couleur_ombre").change(function()	{	$('span').css('text-shadow','1px 0px 5px ' + $('#couleur_ombre').val()) });
-	});
-
-// Change valeur proprietes
-	$(function()
-	{
-		$('#posPoint_aff').change(function()
-		{
-			$('#posPoint_'+current_index).attr('value',$(this).val());
-			memoPos(current_index,parseInt($('#bib'+current_index).css('left')),parseInt($('#bib'+current_index).css('top')));
-		});
-
-		$('#select_clef_profil').change(function()
-		{
-			$('#profilID_'+current_index).attr('value',$(this).val());
-		});
-
-		$('#libelle_aff').keyup(function()
-		{
-			$('#libelle_'+current_index).attr('value',$(this).val());
-			$('#bib'+current_index).text($(this).val());
-			memoPos(current_index,parseInt($('#bib'+current_index).css('left')),parseInt($('#bib'+current_index).css('top')));
-		});
-	});
-
-// Memo coordonnees
-	function memoPos(index,nX,nY)
-	{
-		// Memo des coordonnées
-		var posContainer=$('#image_container').offset();
-		$('#posX_'+index).attr('value',parseInt(nX-posContainer.left));
-		$('#posY_'+index).attr('value',parseInt(nY-posContainer.top));
-
-		// Positionnement du point
-		var oPoint=$('#point_'+index);
-		var hauteur_point=oPoint.outerHeight(true);
-		var largeur_point=oPoint.outerWidth(true);
-		var hauteur=$('#bib'+index).outerHeight(true);
-		var largeur=$('#bib'+index).outerWidth(true);
-		var position=$('#posPoint_'+index).val();
-
-		//		if(position=="dessus") par défaut
-		pointY=nY-hauteur_point;
-		pointX=nX+(largeur/2)-(largeur_point/2);
-
-		if(position=="dessous")
-		{
-			pointY=nY+hauteur;
-			pointX=nX+(largeur/2)-(largeur_point/2);
-		}
-		if(position=="droite")
-		{
-			pointY=nY+(hauteur/2)-(hauteur_point/2);
-			pointX=nX+largeur+2;
-		}
-		if(position=="gauche")
-		{
-			pointY=nY+(hauteur/2)-(hauteur_point/2);
-			pointX=nX-largeur_point-2;
-		}
-		oPoint.css('left',parseInt(pointX)+'px');
-		oPoint.css('top',parseInt(pointY)+'px');
-	}
-
-	// Changement de la fonte
-	function changeFonte()
-	{
-		$('span').css('font-size',$('#taille_fonte').val()+'px');
-		$('span').each(function (i)
-		{
-			memoPos(i,parseInt(this.style.left),parseInt(this.style.top));
-		});
-	}
+ var current_index=0;
+ // Color picker
+ jQuery(function($)
+				{
+	 $("#couleur_texte").attachColorPicker();
+	 $("#couleur_texte").change(function()	{	$('span').css('color',$('#couleur_texte').val()) });
+	 $("#couleur_ombre").attachColorPicker();
+	 $("#couleur_ombre").change(function()	{	$('span').css('text-shadow','1px 0px 5px ' + $('#couleur_ombre').val()) });
+ });
+
+ // Change valeur proprietes
+ $(function()
+	 {
+	 $('#posPoint_aff').change(function()
+														 {
+		 $('#posPoint_'+current_index).attr('value',$(this).val());
+		 memoPos(current_index,parseInt($('#bib'+current_index).css('left')),parseInt($('#bib'+current_index).css('top')));
+	 });
+
+	 $('#select_clef_profil').change(function()
+																	 {
+		 $('#profilID_'+current_index).attr('value',$(this).val());
+	 });
+
+	 $('#libelle_aff').keyup(function()
+													 {
+		 $('#libelle_'+current_index).attr('value',$(this).val());
+		 $('#bib'+current_index).text($(this).val());
+		 memoPos(current_index,parseInt($('#bib'+current_index).css('left')),parseInt($('#bib'+current_index).css('top')));
+	 });
+ });
+
+ // Memo coordonnees
+ function memoPos(index,nX,nY)
+ {
+	 // Memo des coordonnées
+	 var posContainer=$('#image_container').offset();
+	 $('#posX_'+index).attr('value',parseInt(nX-posContainer.left));
+	 $('#posY_'+index).attr('value',parseInt(nY-posContainer.top));
+
+	 // Positionnement du point
+	 var oPoint=$('#point_'+index);
+	 var hauteur_point=oPoint.outerHeight(true);
+	 var largeur_point=oPoint.outerWidth(true);
+	 var hauteur=$('#bib'+index).outerHeight(true);
+	 var largeur=$('#bib'+index).outerWidth(true);
+	 var position=$('#posPoint_'+index).val();
+
+	 //		if(position=="dessus") par défaut
+	 pointY=nY-hauteur_point;
+	 pointX=nX+(largeur/2)-(largeur_point/2);
+
+	 if(position=="dessous")
+	 {
+		 pointY=nY+hauteur;
+		 pointX=nX+(largeur/2)-(largeur_point/2);
+	 }
+	 if(position=="droite")
+	 {
+		 pointY=nY+(hauteur/2)-(hauteur_point/2);
+		 pointX=nX+largeur+2;
+	 }
+	 if(position=="gauche")
+	 {
+		 pointY=nY+(hauteur/2)-(hauteur_point/2);
+		 pointX=nX-largeur_point-2;
+	 }
+	 oPoint.css('left',parseInt(pointX)+'px');
+	 oPoint.css('top',parseInt(pointY)+'px');
+ }
+
+ // Changement de la fonte
+ function changeFonte()
+ {
+	 $('span').css('font-size',$('#taille_fonte').val()+'px');
+	 $('span').each(function (i)
+									{
+		 memoPos(i,parseInt(this.style.left),parseInt(this.style.top));
+	 });
+ }
 </script>
 
-<?php 
-echo '<h3>Territoire : '.$this->zone->LIBELLE.'</h3>';
+<?php
+echo '<h3>Territoire : '.$this->zone->getLibelle.'</h3>';
 
 echo '<div class="form" align="center">';
 echo '<div id="image_container" style="width:'.$this->image[0].'px;height:'.$this->image[1].'px;background-image:url(\''.$this->image["url"].'\');" align="left">';
-if($this->bibs)
-{
-	$index=0;
+if($this->bibs) {
 	$hidden='';
-	foreach($this->bibs as $bib)
-	{
-		// Proprietes
-		$props=ZendAfi_Filters_Serialize::unserialize($bib["AFF_ZONE"]);
-		if (!$libelle = $props["libelle"]) $libelle=$bib["VILLE"];
-		if (!$posX = $props["posX"]) $posX=0;
-		if (!$posY = $props["posY"]) $posY=12*$index;
-		if (!$posPoint = $props["posPoint"]) $posPoint="gauche";
-		if (!$profilID = $props["profilID"]) $profilID = 1;
-		if($index==0){$libelle_aff=$libelle; $posPoint_aff=$posPoint;$nomBib_aff=$bib["LIBELLE"];}
+	$default_position = 0;
+	foreach($this->bibs as $bib) {
+		$index = $bib->getId();
+
+		$props = ['libelle' => $bib->getVille(),
+							'posX' => 0,
+							'posY' => 0,
+							'posPoint' => 'gauche',
+							'profilID' => 0];
+
+		$props = array_merge($props, ZendAfi_Filters_Serialize::unserialize($bib->getAffZone()));
+
+		if (0 == $props["posY"])
+			$posY = $default_position = 12 + $default_position;
+
+		$libelle = $props['libelle'];
+		$posX = $props['posX'];
+		$posY = $props['posY'];
+		$posPoint = $props['posPoint'];
+		$profilID = $props['profilID'];
 
 		// Champ draggable
-		echo'<span id="bib'.$index.'" style="position:absolute;cursor:pointer;font-family:Verdana;font-size:'.$this->zone->TAILLE_FONTE.'px;font-weight:bold;color:'.$this->zone->COULEUR_TEXTE.';white-space:nowrap;text-shadow: 1px 0px 5px '.$this->zone->COULEUR_OMBRE.'">'.$libelle.'</span>';
+		echo'<span id="bib'.$index.'" style="position:absolute;cursor:pointer;font-family:Verdana;font-size:'.$this->zone->getTailleFonte().'px;font-weight:bold;color:'.$this->zone->getCouleurTexte().';white-space:nowrap;text-shadow: 1px 0px 5px '.$this->zone->getCouleurOmbre().'">'.$libelle.'</span>';
 
 		// Champs du post
-		$hidden.='<input id="idbib_'.$index.'" name="idbib_'.$index.'" type="hidden" value="'.$bib["ID_SITE"].'">';
-		$hidden.='<input id="nomBib_'.$index.'" type="hidden" value="'.$bib["LIBELLE"].'">';
+		$hidden.='<input id="idbib_'.$index.'" name="idbib_'.$index.'" type="hidden" value="'.$bib->getId().'">';
+		$hidden.='<input id="nomBib_'.$index.'" type="hidden" value="'.$bib->getLibelle().'">';
 		$hidden.='<input id="posX_'.$index.'" name="posX_'.$index.'" type="hidden" value="'.$posX.'">';
 		$hidden.='<input id="posY_'.$index.'" name="posY_'.$index.'" type="hidden" value="'.$posY.'">';
 		$hidden.='<input id="libelle_'.$index.'" name="libelle_'.$index.'" type="hidden" value="'.$libelle.'">';
@@ -120,108 +128,112 @@ if($this->bibs)
 		$hidden.='<img id="point_'.$index.'" src="'.URL_ADMIN_IMG.'picto/point_map.png" style="position:absolute;">';
 
 		// Javascript d'initialisation
-		?>
-			<script>
-			$(function()
-			{
-				posContainer=$('#image_container').offset();
-				posX=parseInt(<?php echo $posX ?>+posContainer.left);
-				posY=parseInt(<?php echo $posY ?>+posContainer.top);
-				memoPos(<?php echo $index ?>,posX,posY)
-				oObj=$('#bib<?php echo $index ?>');
-				oObj.draggable
-				({
-					containment: 'parent',
-					drag: function(event, ui)
-					{	memoPos(<?php echo $index ?>,ui.position.left,ui.position.top)}
-				})
-				.css('left',posX+'px')
-				.css('top',posY+'px')
-				.mousedown(function()
-				{
-					$('#nomBib_aff').attr('value',$('#nomBib_<?php echo $index ?>').val());
-					$('#libelle_aff').attr('value',$('#libelle_<?php echo $index ?>').val());
-
-					var valeur=$('#posPoint_<?php echo $index ?>').val();
-					$('#posPoint_aff > option').attr('selected','');
-					$('#posPoint_aff option[value='+valeur+']').attr('selected','selected');
-
-					var profil_id=$('#profilID_<?php echo $index ?>').val();
-					$('#select_clef_profil option').attr('selected', '');
-					$('#select_clef_profil option[value='+profil_id+']').attr('selected','selected');
-
-					current_index=<?php echo $index ?>;
-				});
-			});
-
-			</script>
-		<?php
-		$index++;
+?>
+	<script>
+	 $(function()
+		 {
+		 posContainer=$('#image_container').offset();
+		 posX=parseInt(<?php echo $posX ?>+posContainer.left);
+		 posY=parseInt(<?php echo $posY ?>+posContainer.top);
+		 memoPos(<?php echo $index ?>,posX,posY)
+		 oObj=$('#bib<?php echo $index ?>');
+		 oObj.draggable
+		 ({
+			 containment: 'parent',
+			 drag: function(event, ui)
+			 {	memoPos(<?php echo $index ?>,ui.position.left,ui.position.top)}
+		 })
+				 .css('left',posX+'px')
+				 .css('top',posY+'px')
+				 .mousedown(function()
+										{
+			 $('#nomBib_aff').attr('value',$('#nomBib_<?php echo $index ?>').val());
+			 $('#libelle_aff').attr('value',$('#libelle_<?php echo $index ?>').val());
+
+			 var valeur=$('#posPoint_<?php echo $index ?>').val();
+			 $('#posPoint_aff > option').attr('selected','');
+			 $('#posPoint_aff option[value='+valeur+']').attr('selected','selected');
+
+			 var profil_id=$('#profilID_<?php echo $index ?>').val();
+			 $('#select_clef_profil option').attr('selected', '');
+			 $('#select_clef_profil option[value='+profil_id+']').attr('selected','selected');
+
+			 current_index=<?php echo $index ?>;
+		 });
+	 });
+
+	</script>
+	<?php
+	$index++;
 	}
 	echo '</div>';
+
+	$nomBib_aff = '';
+	$libelle_aff = '';
+	$posPoint_aff = '';
 	?>
 
-<br />
-<form name="form" action="<?php echo BASE_URL ?>/admin/zone/placerbibs/id_zone/<?php echo $this->zone->ID_ZONE; ?>" method="post">
-<fieldset>
-	<legend>Propriétés</legend>
-	<table>
-		<tr>
-			<td class="droite" style="width:150px">Bibliothèque</td>
-			<td class="gauche"><input type="text" id="nomBib_aff" size="40" value="<?php echo $nomBib_aff ?>" readonly="readonly"></td>
-		</tr>
-		<tr>
-			<td class="droite">Libellé à afficher</td>
-			<td class="gauche"><input type="text" id="libelle_aff" size="40" value="<?php echo $libelle_aff ?>"></td>
-		</tr>
-		<tr>
-			<td class="droite">Position du point</td>
-			<td class="gauche"><?php echo $this->formSelect("posPoint_aff",$posPoint_aff,"",array("dessus" => "au dessus","gauche"=>"à gauche","droite"=>"à droite","dessous"=>"en dessous"))?></td>
-		</tr>
-		<tr>
-			<td class="droite">Lien vers la page</td>
-			<td class="gauche"><?php echo $this->comboProfils(); ?></td>
-		</tr>
-
-		<tr>
-			<td colspan="2"><h3>Etiquettes</h3></td>
-		</tr>
-
-		<tr>
-			<td class="droite">Taille de la police</td>
-			<td class="gauche"><?php echo $this->tagSlider("taille_fonte",$this->zone->TAILLE_FONTE,5,40,1,"changeFonte();") ?></td>
-		</tr>
-		
-		<tr>
-			<td class="droite">Couleur du texte</td>
-			<td class="gauche"><input type="text" id="couleur_texte" name="couleur_texte" size="8" value="<?php echo $this->zone->COULEUR_TEXTE;?>" /></td>
-		</tr>
-
-		<tr>
-			<td class="droite">Couleur de l'ombre</td>
-			<td class="gauche"><input type="text" id="couleur_ombre" name="couleur_ombre" size="8" value="<?php echo $this->zone->COULEUR_OMBRE;?>" /></td>
-		</tr>
-
-	</table>
-</fieldset>
-
-	<?php echo $hidden; ?>
+	<br />
+	<form name="form" action="<?php echo BASE_URL ?>/admin/zone/placerbibs/id_zone/<?php echo $this->zone->getId(); ?>" method="post">
+		<fieldset>
+			<legend>Propriétés</legend>
+			<table>
+				<tr>
+					<td class="droite" style="width:150px">Bibliothèque</td>
+					<td class="gauche"><input type="text" id="nomBib_aff" size="40" value="<?php echo $nomBib_aff ?>" readonly="readonly"></td>
+				</tr>
+				<tr>
+					<td class="droite">Libellé à afficher</td>
+					<td class="gauche"><input type="text" id="libelle_aff" size="40" value="<?php echo $libelle_aff ?>"></td>
+				</tr>
+				<tr>
+					<td class="droite">Position du point</td>
+					<td class="gauche"><?php echo $this->formSelect("posPoint_aff",$posPoint_aff,"",array("dessus" => "au dessus","gauche"=>"à gauche","droite"=>"à droite","dessous"=>"en dessous"))?></td>
+				</tr>
+				<tr>
+					<td class="droite">Lien vers la page</td>
+					<td class="gauche"><?php echo $this->comboProfils('ALL', 'ALL', 0, false, true); ?></td>
+				</tr>
+
+				<tr>
+					<td colspan="2"><h3>Etiquettes</h3></td>
+				</tr>
+
+				<tr>
+					<td class="droite">Taille de la police</td>
+					<td class="gauche"><?php echo $this->tagSlider("taille_fonte",$this->zone->TAILLE_FONTE,5,40,1,"changeFonte();") ?></td>
+				</tr>
+
+				<tr>
+					<td class="droite">Couleur du texte</td>
+					<td class="gauche"><input type="text" id="couleur_texte" name="couleur_texte" size="8" value="<?php echo $this->zone->getCouleurTexte();?>" /></td>
+				</tr>
+
+				<tr>
+					<td class="droite">Couleur de l'ombre</td>
+					<td class="gauche"><input type="text" id="couleur_ombre" name="couleur_ombre" size="8" value="<?php echo $this->zone->getCouleurOmbre();?>" /></td>
+				</tr>
+
+			</table>
+		</fieldset>
+
+		<?php echo $hidden; ?>
 		<table>
 			<tr>
 				<td align="right" style="padding-right:5px;"><?php echo $this->bouton('type=V'); ?> </td>
-				<td align="left" style="padding-left:5px;"> <?php echo $this->bouton('id=29','picto=del.gif','texte=Annuler','url='.BASE_URL.'/admin/zone','largeur=120px'); ?></td>
+				<td align="left" style="padding-left:5px;"> <?php echo $this->bouton('id=29','picto=back.gif','texte=Retour','url='.BASE_URL.'/admin/zone','largeur=120px'); ?></td>
 			</tr>
 		</table>
 	</form>
 	<?php
-}
-else
-{
+	}
+	else
+	{
+		echo '</div>';
+		echo BR.BR.'<p class="error">Il n\'y a aucune bibliothèque visible dans ce territoire.</p>';
+		echo BR.'<div align="center">'.$this->bouton('id=29','picto=retour.gif','texte=Retour','url='.BASE_URL.'/admin/zone','largeur=120px').'</div>'.BR;
+	}
 	echo '</div>';
-	echo BR.BR.'<p class="error">Il n\'y a aucune bibliothèque visible dans ce territoire.</p>';
-	echo BR.'<div align="center">'.$this->bouton('id=29','picto=retour.gif','texte=Retour','url='.BASE_URL.'/admin/zone','largeur=120px').'</div>'.BR;
-}
-echo '</div>';
 
 
-?>
+	?>
diff --git a/library/Class/Bib.php b/library/Class/Bib.php
index aa0f0870f0d3e5d00f6f8a9354d7deec72ab270b..5eb33bb5e7fa52ef8ee541026007d90203940e1b 100644
--- a/library/Class/Bib.php
+++ b/library/Class/Bib.php
@@ -250,7 +250,7 @@ class Class_Bib extends Storm_Model_Abstract {
 		if (!$aff_zone = ZendAfi_Filters_Serialize::unserialize($this->getAffZone()))
 			$aff_zone = [];
 
-		return array_merge(['profilID' => null,
+		return array_merge(['profilID' => '',
 												'libelle' => '',
 												'posX' => 0,
 												'posY' => 0,
@@ -267,12 +267,43 @@ class Class_Bib extends Storm_Model_Abstract {
 							'id' => $this->getId()];
 
 		if($profil = Class_Profil::find($props["profilID"]))
-			$parts = array_merge( $parts, $profil->getUrlParts());
+			$parts = $profil->getUrlParts();
 
 		return Class_Url::assemble($parts, null, true);
 	}
 
 
+	public function getPosX() {
+		return $this->getAffZoneKey('posX');
+	}
+
+
+	public function getPosY() {
+		return $this->getAffZoneKey('posY');
+	}
+
+
+	public function getPosPoint() {
+		return $this->getAffZoneKey('posPoint');
+	}
+
+
+	public function getProfilId() {
+		return $this->getAffZoneKey('profilID');
+	}
+
+
+	public function getAffZoneKey($key) {
+		if (!$aff_zone = ZendAfi_Filters_Serialize::unserialize($this->getAffZone()))
+			return 0;
+
+		if(!isset($aff_zone[$key]))
+			return 0;
+
+		return $aff_zone[$key];
+	}
+
+
 	public function getBibsBySite($id_site=0)	{
 		$where = '';
 		if($id_site!=0)
diff --git a/library/Class/Zone.php b/library/Class/Zone.php
index 8e11ae508b359ee8a4071b82e8740b4053265035..f8d05c5ba57a4b4716c622e5483a87791be18bd4 100644
--- a/library/Class/Zone.php
+++ b/library/Class/Zone.php
@@ -16,10 +16,10 @@
  *
  * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
  * along with BOKEH; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA 
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
  */
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-//  OPAC 3 -                                                    Table Name 
+//  OPAC 3 -                                                    Table Name
 //
 // @TODO@ : A nettoyer
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -28,24 +28,29 @@ class BibCZone extends Zend_Db_Table_Abstract
 	protected $_name = 'bib_c_zone';
 }
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-//  OPAC 3 -                                             Class_Zone -> gestion des territoires 
+//  OPAC 3 -                                             Class_Zone -> gestion des territoires
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 class Class_Zone extends Storm_Model_Abstract {
 	private $sql;
 	private $_dataBaseError = "Problème d'accès à  la base de données";
-	private $statut_bib = array('Invisible','N\'envoie pas de données','Envoie des données');
+	private $statut_bib = ['Invisible',
+												 'N\'envoie pas de données',
+												 'Envoie des données'];
 
 	protected $_table_name = 'bib_c_zone';
 	protected $_table_primary = 'id_zone';
-	protected $_has_many = array('bibs' => array( 'model' => 'Class_Bib',
-																								 'role' => 'zone',
-																								 'referenced_in' => 'ID_ZONE',
-																								 'order' => 'libelle'));
+	protected $_has_many = ['bibs' => ['model' => 'Class_Bib',
+																		 'role' => 'zone',
+																		 'referenced_in' => 'ID_ZONE',
+																		 'order' => 'libelle']];
 
-	protected $_default_attribute_values = array('libelle' => '',
-																							  'couleur' => '',
-																							  'map_coords' => '',
-																							  'image' => '');
+	protected $_default_attribute_values = ['libelle' => '',
+																					'couleur' => '#fff',
+																					'map_coords' => '',
+																					'couleur_texte' => '#fff',
+																					'couleur_ombre' => '#000',
+																					'taille_fonte' => '12',
+																					'image' => ''];
 
 
 
@@ -53,7 +58,7 @@ class Class_Zone extends Storm_Model_Abstract {
 		return self::getLoaderFor(__CLASS__);
 	}
 
-	
+
 	public function __construct()	{
 		$this->sql = Zend_Registry::get('sql');
 	}
@@ -71,7 +76,7 @@ class Class_Zone extends Storm_Model_Abstract {
 
 
 	public function setCouleur($couleur) {
-		if (substr($couleur,0,1)!="#") 
+		if (substr($couleur,0,1)!="#")
 			$couleur="#".$couleur;
 		parent::_set('couleur', $couleur);
 		return $this;
@@ -88,7 +93,7 @@ class Class_Zone extends Storm_Model_Abstract {
 		$data=fetchAll("select * from bib_c_zone ".$where. " order by LIBELLE");
 		return $data;
 	}
-	
+
 	// Lire tous les territoires  == OLD FUNCTION =======
 	public function getAllZone()
 	{
@@ -100,7 +105,7 @@ class Class_Zone extends Storm_Model_Abstract {
 			return $this->_dataBaseError;
 		}
 	}
-	
+
 	public function getZoneById($id_zone)
 	{
 		try{
@@ -124,7 +129,7 @@ class Class_Zone extends Storm_Model_Abstract {
 		return $img_infos;
 	}
 
-	
+
 	public function getImageWithInfos($image = null) {
 		if (!$image)	$image = $this->getImage();
 		$img = "/userfiles/photobib/".$image;
@@ -139,8 +144,8 @@ class Class_Zone extends Storm_Model_Abstract {
 		$ret["url"]=BASE_URL.$img;
 		return $ret;
 	}
-	
-	
+
+
 	// Rend un select avec la liste des zones pour la page d'accueil
 	public function getComboZoneAvecUrl($id_selected =0)
 	{
@@ -159,7 +164,7 @@ class Class_Zone extends Storm_Model_Abstract {
 	}
 
 	//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-	//                                                      méthode ADMIN 
+	//                                                      méthode ADMIN
 	//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
   //---------------------------------------------------------------------
 	// Insert zone
@@ -168,7 +173,7 @@ class Class_Zone extends Storm_Model_Abstract {
 	{
 		$id_zone=sqlInsert("bib_c_zone",$data);
 	}
-	
+
   //---------------------------------------------------------------------
 	// Update zone
 	//---------------------------------------------------------------------
@@ -181,12 +186,12 @@ class Class_Zone extends Storm_Model_Abstract {
 				$adresse_img=getcwd()."/userfiles/photobib/".$old_img;
 				if(file_exists($adresse_img)) unlink($adresse_img);
 			}
-		
+
 		// Ecriture
 		sqlUpdate("update bib_c_zone set @SET@ where ID_ZONE=$id_zone",$data);
 	}
 
-	
+
   //---------------------------------------------------------------------
 	// supprimer zone
 	//---------------------------------------------------------------------
@@ -217,7 +222,7 @@ class Class_Zone extends Storm_Model_Abstract {
 		$html[]='</select>';
 		return implode('',$html);
 	}
-	
+
   //---------------------------------------------------------------------
 	// Vérification de saisie
 	//---------------------------------------------------------------------
diff --git a/library/ZendAfi/Filters/Serialize.php b/library/ZendAfi/Filters/Serialize.php
index 6ef9f02a4530b0853ce98840ebea8b713b00ef5b..1b82eb9b7f70eca3578e4ad0581b5bd4e1eb5323 100644
--- a/library/ZendAfi/Filters/Serialize.php
+++ b/library/ZendAfi/Filters/Serialize.php
@@ -16,46 +16,32 @@
  *
  * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
  * along with BOKEH; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA 
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
  */
-//////////////////////////////////////////////////////////////////////////////////////////////////////////
-// OPAC3 :	FILTRE POUR LES SERIALIZE ET UNSERIALIZE
-//////////////////////////////////////////////////////////////////////////////////////////////////////////
 
-class ZendAfi_Filters_Serialize
-{	
-	
-//----------------------------------------------------------------
-// Encodage
-//----------------------------------------------------------------
-	static function serialize($valeurs)
-	{
-		if(!$valeurs) return false;
-		$cls=new ZendAfi_Filters_Serialize();
-		array_walk_recursive($valeurs, array(&$cls,'encodeItem'));
-		$chaine=serialize($valeurs);
+class ZendAfi_Filters_Serialize {
 
-		$chaine=utf8_encode($chaine);
+	public static function serialize($valeurs)	{
+		if(!$valeurs)
+			return false;
+
+		$cls = new ZendAfi_Filters_Serialize();
+		array_walk_recursive($valeurs, [&$cls,'encodeItem']);
+		$chaine = serialize($valeurs);
+		$chaine = utf8_encode($chaine);
 		return $chaine;
 	}
-	
-//----------------------------------------------------------------
-// Decodage
-//----------------------------------------------------------------
-	static function unserialize($valeur)
-	{
-		$valeur=utf8_decode($valeur);
-		$valeurs=unserialize($valeur);
+
+
+	public static function unserialize($valeur)	{
+		$valeur = utf8_decode($valeur);
+		$valeurs = unserialize($valeur);
 		return $valeurs;
 	}
 
-//----------------------------------------------------------------
-// Fonction callback pour l'encodage 
-//----------------------------------------------------------------
-	private function encodeItem(&$valeur,$key)
-	{
-		$valeur=stripslashes($valeur);
+
+	protected function encodeItem(&$valeur, $key)	{
+		$valeur = stripslashes($valeur);
 		return $valeur;
 	}
-
 }
\ No newline at end of file
diff --git a/tests/application/modules/admin/controllers/ZoneControllerTest.php b/tests/application/modules/admin/controllers/ZoneControllerTest.php
index 21e019877aa5890a6de8947feb5ddb780c6ad0a7..62ca1ff430ba7f246778f3db8e03363b42e23244 100644
--- a/tests/application/modules/admin/controllers/ZoneControllerTest.php
+++ b/tests/application/modules/admin/controllers/ZoneControllerTest.php
@@ -16,7 +16,7 @@
  *
  * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
  * along with BOKEH; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA 
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
  */
 require_once 'AbstractControllerTestCase.php';
 
@@ -41,7 +41,7 @@ abstract class ZoneControllerTestCase extends AbstractControllerTestCase {
 			->whenCalled('findAll')
 			->answers(array($this->zone_annecy, $this->zone_pringy))
 			->getWrapper();
-	}	
+	}
 }
 
 
@@ -69,18 +69,122 @@ class ZoneControllerIndexActionTest extends ZoneControllerTestCase {
 class ZoneControllerPlacerBibsActionTest extends ZoneControllerTestCase {
 	public function setUp() {
 		parent::setUp();
-		$this->dispatch('admin/zone/placerbibs/id_zone/2');
+		$this->dispatch('admin/zone/placerbibs/id_zone/2', true);
 	}
 
 
 	/** @test */
 	public function titreShouldBePlacementDesBibSurLaCarte() {
-		$this->assertXPathContentContains('//h1', 'Placement des bibliothèques sur la carte');
+		$this->assertXPathContentContains('//h1', 'Placement des bibliothèques sur la carte', $this->_response->getBody());
+	}
+}
+
+
+
+abstract class ZoneControllerPlacerBibsPostActionTestCase extends Admin_AbstractControllerTestCase {
+	public function setUp() {
+		parent::setUp();
+
+		$this->fixture('Class_Profil',
+									 ['id' => 1,
+										'libelle' => 'Home']);
+
+		$this->fixture('Class_Profil',
+									 ['id' => 2,
+										'libelle' => 'Bib d\'Annecy']);
+
+		$this->fixture('Class_Bib',
+									 ['id' => 1,
+										'libelle' => 'Annecy',
+										'id_zone' => 2,
+										'visibilite' => 1]);
 	}
 }
 
 
 
+class ZoneControllerPlacerBibsPostActionWithProfilTest extends ZoneControllerPlacerBibsPostActionTestCase {
+
+	public function setUp() {
+		parent::setUp();
+
+
+		$data = ['posX' => '25',
+						 'posY' => '65',
+						 'posPoint' => 'above',
+						 'profilID' => '1'];
+
+		$aff_zone = ZendAfi_Filters_Serialize::serialize($data);
+
+		Class_Bib::find(1)->setAffZone($aff_zone)->save();
+
+
+
+		$this->postDispatch('admin/zone/placerbibs/id_zone/2', ['posX_1' => '50',
+																														'posY_1' => '150',
+																														'posPoint_1' => 'left',
+																														'profilID_1' => '2']);
+	}
+
+
+  /** @test */
+	public function urlForAnnecyShouldBeProfil() {
+		$this->assertEquals('/index/index/id_profil/2', Class_Bib::find(1)->getUrl());
+	}
+
+
+	/** @test */
+	public function annecyPosXShouldBe50() {
+		$this->assertEquals('50', Class_Bib::find(1)->getPosX());
+	}
+
+}
+
+
+
+class ZoneControllerPlacerBibsPostActionWithOutTest extends ZoneControllerPlacerBibsPostActionTestCase {
+
+	public function setUp() {
+		parent::setUp();
+		$this->postDispatch('admin/zone/placerbibs/id_zone/2', ['posX_1' => '50',
+																														'posY_1' => '150',
+																														'posPoint_1' => 'left']);
+	}
+
+
+  /** @test */
+	public function urlForAnnecyShouldBeBeBibView() {
+		$this->assertEquals('/bib/bibview/id/1', Class_Bib::find(1)->getUrl());
+	}
+
+
+	/** @test */
+	public function annecyPosXShouldBe50() {
+		$this->assertEquals('50', Class_Bib::find(1)->getPosX());
+	}
+
+
+	/** @test */
+	public function annecyPosYShouldBe150() {
+		$this->assertEquals('150', Class_Bib::find(1)->getPosY());
+	}
+
+
+	/** @test */
+	public function posPointForAnnecyShouldBeLeft() {
+		$this->assertEquals('left', Class_Bib::find('1')->getPosPoint());
+	}
+
+
+	/** @test */
+	public function profilForAnnecyShouldBeEmpty() {
+		$this->assertEquals('0', Class_Bib::find('1')->getProfilId());
+	}
+}
+
+
+
+
 class ZoneControllerEditAnnecyTest extends ZoneControllerTestCase {
 	public function setUp() {
 		parent::setUp();
@@ -163,7 +267,7 @@ class ZoneControllerPostValidDataForAnnecyTest extends ZoneControllerTestCase {
 
 	/** @test */
 	function shouldRedirectToIndexPage() {
-		$this->assertRedirect('admin/zone/index');	
+		$this->assertRedirect('admin/zone/index');
 	}
 
 
@@ -195,7 +299,7 @@ class ZoneControllerPostEmptyLabelForAnnecyTest extends ZoneControllerTestCase {
 
 	/** @test */
 	function shouldNotRedirectToIndexPage() {
-		$this->assertNotRedirect('admin/zone/index');	
+		$this->assertNotRedirect('admin/zone/index');
 	}
 
 	/** @test */
diff --git a/tests/application/modules/opac/controllers/BibControllerTest.php b/tests/application/modules/opac/controllers/BibControllerTest.php
index 7de4eed68c7d637cddf1d4d58a5d4037d894d337..924241e9fc9b9ea897902f8ebccf9232251555f0 100644
--- a/tests/application/modules/opac/controllers/BibControllerTest.php
+++ b/tests/application/modules/opac/controllers/BibControllerTest.php
@@ -204,12 +204,21 @@ class BibControllerMapViewTest extends BibControllerWithZoneTestCase {
 		$this->fixture('Class_Profil',
 									 ['id' => 3,
 										'libelle' => 'Annecy']);
+	}
+}
+
+
+class BibControllerMapViewWithProfilTest extends BibControllerMapViewTest {
+
+	public function setUp() {
+		parent::setUp();
 
 		$aff_zone = ['profilID' => '3',
 								 'libelle' => 'Annecy',
 								 'posX' => 2,
 								 'posY' => 5,
 								 'posPoint' => 'droite'];
+
 		$this->bib_annecy->setAffZone(ZendAfi_Filters_Serialize::serialize($aff_zone));
 
 		$this->dispatch('bib/mapzoneview/id/1');
@@ -236,7 +245,32 @@ class BibControllerMapViewTest extends BibControllerWithZoneTestCase {
 
 	/** @test */
 	public function bibAnnecyShouldBeVisibleOnMap() {
-		$this->assertXPathContentContains("//span[contains(@onclick, '/bibview/id/4/id_profil/3')]", "Annecy", $this->_response->getBody());
+		$this->assertXPathContentContains("//span[contains(@onclick, 'index/index/id_profil/3')]", "Annecy", $this->_response->getBody());
+	}
+}
+
+
+
+class BibControllerMapViewWithoutProfilTest extends BibControllerMapViewTest {
+
+	public function setUp() {
+		parent::setUp();
+
+		$aff_zone = ['profilID' => '',
+								 'libelle' => 'Annecy',
+								 'posX' => 2,
+								 'posY' => 5,
+								 'posPoint' => 'droite'];
+
+		$this->bib_annecy->setAffZone(ZendAfi_Filters_Serialize::serialize($aff_zone));
+
+		$this->dispatch('bib/mapzoneview/id/1');
+	}
+
+
+	/** @test */
+	public function bibAnnecyShouldBeVisibleOnMap() {
+		$this->assertXPathContentContains("//span[contains(@onclick, 'bibview/id/4')]", "Annecy", $this->_response->getBody());
 	}
 }