Afficher les résultats d'une recherche sans recharger la pag

Mammouth du PHP | 536 Messages

13 juil. 2007, 11:23

Je croyais avoir bien défini le truc, désolé.

Alors voici les règles.

Une pratique s'affiche si les critères sélectionés par l'utilisateur appartiennent et définissent cette pratique.
Exemple, une pratique défiine par les crit 2 de la cat 5 et le crit 4 de la cat 6 ne peut être vu que si l'utilisateur ne sélectionne
- le crit 2 de la cat 5
ou - le crit 4 de la cat 6
ou - les deux crit

Si un utilisateur sélectionne les deux critères plus un autre, la pratique ne s'affiche pas.

Il faut que le moteur de recherche agissent comme un "entonnoir" -> plus on sélectionne de critères, moins on aura de pratiques et moins on sélectionnera de critères, plus on aura de pratiques affichées.

Est-ce que je me suis bien fait comprendre et est-ce que j'ai été assez clair ?
Un prof désespéré à son élève :
- Et maintenant, dessinez-moi un cercle au tableau... Voila... Alors qu'est-ce que c'est?
- Ben un cercle ?
- Non, c'est votre note, sortez !!

Modérateur PHPfrance
Modérateur PHPfrance | 2575 Messages

14 juil. 2007, 00:50

à ce moment là tu crée 2 tableaux de critères :
1° tableau des critères sélectionnés par le formulaire contenant les couples cat/crit
2° tableau des critères xml d'un practice (par link) contenant les couples cat/crit
Et tu fais l'intersection entre les 2 tableaux, si cette intersection est égale au tableau 1 => tous les critères sélectionnés sont inclus dans les critères xml, le practice est alors trouvé
Sinon, si l'intersection est < au tableau 1 => les critères sélectionnés contiennent des critères non trouvés, le practice est non trouvé.
Sinon, si l'intersection est > au tableau 1 => certains critères xml ne sont pas sélectionné mais tous ceux sélectionnés se trouvent dans le tableau 2, le practice est donc trouvé.

Par simplification, on peut retenir donc la compaison suivante entre le tableau 1 et 2:
si (tableau1 inter tableau2) >= tableau1 alors practice trouvé
sinon practice non trouvé.
--------//////----//---//----//////
-------//---//----//---//----//---//
------//////----//////-----//////
-----||--------||--||---||
Prendre le recul n'est pas une perte de temps.


ps: Affrontez moi dans l'arène

Mammouth du PHP | 536 Messages

16 juil. 2007, 09:06

bonjour,

dans ce que tu avais fait, il y avait déjà deux tableaux : 1 tableau des critères sélectionnés et un tableau correspondant aux critères définissant une pratique (depuis fichier xml).

Sauf que toi au lieu de faire une intersection tu avais fait une différence c'est ça ?
Un prof désespéré à son élève :
- Et maintenant, dessinez-moi un cercle au tableau... Voila... Alors qu'est-ce que c'est?
- Ben un cercle ?
- Non, c'est votre note, sortez !!

Modérateur PHPfrance
Modérateur PHPfrance | 2575 Messages

16 juil. 2007, 12:34

oui exact, mais les 2 tableaux étaient organisés différemment. C'est à dire que les critères dedans étaient triés par catégorie et on traitait donc les critères différemment à ce que tu veux faire actuellement.

Maintenant tu veux comparer tous les critères toutes catégories confondues (si c'est bien ce que tu veux) c'est pourquoi, je te suggère d'utiliser les 2 tableaux non triés contenant simplement des couples cat/critère.

Par exemple si l'on choisit dans le formulaire les critères 1 et 2 da la catégorie 1 et le critère 1 de la catégorie 2. Le tableau posté devient:

Code : Tout sélectionner

Array ("1/1", "1/2", "2/1")
tableau qui doit être comparé avec le second tableau qu'il faudra construire à partir du xml pour chaque <link> et qui doit avoir la même structure interne. Bref, un truc comme ça par exemple:
Pour le practice 3:

Code : Tout sélectionner

Array ("1/1", "2/1")
Pour le practice 1:

Code : Tout sélectionner

Array ("5/7")
Je t'ai proposé l'intersection cette fois tout simpelemnt par ce qu'on cherche à savoir si le tableau posté et supérieur à son second xml auquel cas le practice est forcement non trouvé.
--------//////----//---//----//////
-------//---//----//---//----//---//
------//////----//////-----//////
-----||--------||--||---||
Prendre le recul n'est pas une perte de temps.


ps: Affrontez moi dans l'arène

Mammouth du PHP | 536 Messages

16 juil. 2007, 16:24

pu**in sadeq, j'ai essayé de fairece que tu m'as dit car ça l'air cohérent par rapport à ce que je souhaite faire mais je m'emmêle les pinceaux et n'y arrive pas. :cry: :cry:
Un prof désespéré à son élève :
- Et maintenant, dessinez-moi un cercle au tableau... Voila... Alors qu'est-ce que c'est?
- Ben un cercle ?
- Non, c'est votre note, sortez !!

Modérateur PHPfrance
Modérateur PHPfrance | 2575 Messages

16 juil. 2007, 18:07

Mais j'ai une question cruciale car j'ai un doute:
Est-ce que les critères que l'on sélectionne pour limiter le résultat sont ceux d'une catégorie ou de toutes catégories ?
--------//////----//---//----//////
-------//---//----//---//----//---//
------//////----//////-----//////
-----||--------||--||---||
Prendre le recul n'est pas une perte de temps.


ps: Affrontez moi dans l'arène

Mammouth du PHP | 536 Messages

17 juil. 2007, 09:08

les critères que tu sélectionnes peuvent être de plusieurs catégories.
En fait, avant si je comprends bien ce que tu m'avais expliqué, on avait fait un "et" entre critères d'une même catégorie et un "ou" entre catégories. Et là maintenant, il faut en fait faire un "ET" entre tous les critères (de toutes les catégories).
On ne doit voir que les pratiques qui correspondent à ce que l'utilisateur a coché.
Un prof désespéré à son élève :
- Et maintenant, dessinez-moi un cercle au tableau... Voila... Alors qu'est-ce que c'est?
- Ben un cercle ?
- Non, c'est votre note, sortez !!

Modérateur PHPfrance
Modérateur PHPfrance | 2575 Messages

18 juil. 2007, 01:53

OK, un "ET" donc entre tous les critères toutes catégories. Alors c'est bien une inclusion.
L'ensemble des critères sélectionnés doit être inclus dans l'ensemble des critères d'un practice.

C'est donc bien la formule algébrique suivante:
A = ensemble des critères sélectionnés
B(p) = ensemble des critères xml du practice (p)

p est trouvé si : A inclus dans B(p) => A - (A inter B) = vide

ça s'écrit en algorithme PHP:
$inter = array_intersect( $A, $B ); 
$diff = array_diff( $A, $inter );
if ( $diff == array() ) echo "trouvé";
else  echo "non trouvé";
D'où la solution suivante:
/*-----------------------------------------------------*/
//on affiche le résultat en fonction d'un seul critère //
/*-----------------------------------------------------*/
if (!$cfg['ressources_root']) $cfg['ressources_root'] = ".";
$link_file = $cfg['ressources_root'].'/matrix/criteria-practice.xml';
$xml = simplexml_load_file($link_file);//on ouvre le fichier xml

//si les variables ne sont pas vides
if ( ($_POST['cat'] ) and ($_POST['crit'] ) )
{
  foreach ($_POST["crit"] as $index=>$idcrit){
    $idcat = $_POST["cat"][$index]; //trouve la cat du crit
    $params[] ="$idcat/$idcrit" ; //stocke le crit dans son groupe cat
  }
  //echo "<pre>"; print_r($params); 
  $practice = null;
  //Recherche des practices
    foreach($xml->link as $value)
    {     
       //practice en cours
	   $id_practice = $value->practice['id'];
	   //ses critères de recherche
	   $temp = null; //tableau pour ordonner les critères par cat
	   foreach($value->criteria as $criteria){     
		 $idcat = trim($criteria['idcat']);
		 $idcrit = trim($criteria['idcrit']); 
		 //construire le tableau de critères
		 $temp[] = "$idcat/$idcrit";
	   }
	   //print_r($temp);
	   //Rapporochement du tableau $temp et du tableau du $params
		if (is_array($temp) && is_array($params)) {
				//calculer l'intersection entre les critères
				$inter = array_intersect($temp, $params); 
				//print_r($inter);
				//Si les critères $params sont inclus dans $temp alors practice trouvé (différence vide)
				$diff = array_diff( $params, $inter);
				//print_r($diff);				
				if ($diff == array()) $practice[] = $id_practice;
	   }
	 }
	 
   //echo "<pre>"; print_r($practice); echo "</pre>"; 
  //Lecture des practices trouvés
  if ( (isset($practice) and count($practice) >0 )) // si le tableau $practice est rempli 
  {
    foreach ($practice as $id){ 
    //fichier qui contient toutes les practices
    $practicesFile = $cfg['ressources_root'].'/content/practice/'.$id.'.xml';
    $domPractices = new DOMDocument('1.0','UTF-8');
    $domPractices->load($practicesFile);
    $xpPractices = new DOMXPath($domPractices);
    $item_practice = $domPractices->getElementsByTagName('item');    
   
    //recherche xml
    foreach ($item_practice as $item)  
    { 
      foreach ($item->childNodes as $child) 
      { 
        if($child->nodeType != XML_ELEMENT_NODE) continue; 
        if ($child->tagName == 'name') 
        { 
          $name = utf8_decode($child->firstChild->nodeValue); 
		  echo "<p>Name=$name</p>" ;
        } 
        if ($child->tagName == 'short_description') 
        { 
          $short_description = utf8_decode($child->firstChild->nodeValue); 
			echo "<p>Description=$short_description</p>" ;
        } 
     } 
    }
	
   }//fin foreach $practice
  } //fin de si $practice trouvé
  else 
  {  
    echo "<p>There is no practice which corresponds to your request. Please refine your search</p>";
  }
}
else
  { 
    echo "<p>Choose your crireria before starting your search</p>";
  }
?> 
--------//////----//---//----//////
-------//---//----//---//----//---//
------//////----//////-----//////
-----||--------||--||---||
Prendre le recul n'est pas une perte de temps.


ps: Affrontez moi dans l'arène

Mammouth du PHP | 536 Messages

18 juil. 2007, 09:09

nikel... j'ai fait plusieurs tests et l'algorythme que tu m'a proposé correspond tout à fait à ce que je souhaitais. C'est tout à fait ça.

Merci beaucoup sadeq, je ne m'en serais pas sorti sans toi. Tu passes quand tu veux boire un verre à Dijon :wink:
Un prof désespéré à son élève :
- Et maintenant, dessinez-moi un cercle au tableau... Voila... Alors qu'est-ce que c'est?
- Ben un cercle ?
- Non, c'est votre note, sortez !!

Modérateur PHPfrance
Modérateur PHPfrance | 2575 Messages

18 juil. 2007, 12:52

Le plaisir était pour moi :boire9:
"Resolu" alors.
--------//////----//---//----//////
-------//---//----//---//----//---//
------//////----//////-----//////
-----||--------||--||---||
Prendre le recul n'est pas une perte de temps.


ps: Affrontez moi dans l'arène

Mammouth du PHP | 536 Messages

19 juil. 2007, 16:10

Dernière petite question, si je veux garder en mémoire les critères et les catégories cochées, je peux utiliser les variables de sessions. Mais pour cet exemple, vu qu'il s'agit d'un tableau, comment faire ?
Un prof désespéré à son élève :
- Et maintenant, dessinez-moi un cercle au tableau... Voila... Alors qu'est-ce que c'est?
- Ben un cercle ?
- Non, c'est votre note, sortez !!

ViPHP
ViPHP | 5924 Messages

19 juil. 2007, 20:12

Dernière petite question, si je veux garder en mémoire les critères et les catégories cochées, je peux utiliser les variables de sessions. Mais pour cet exemple, vu qu'il s'agit d'un tableau, comment faire ?
Tu le sérializes avec serialize(), et pour le récupérer, tu le désérializes avec deserialize().

Modérateur PHPfrance
Modérateur PHPfrance | 2575 Messages

19 juil. 2007, 22:31

Pourquoi veux-tu mémoriser les critères :?: si ce n'est pas indiscret.
--------//////----//---//----//////
-------//---//----//---//----//---//
------//////----//////-----//////
-----||--------||--||---||
Prendre le recul n'est pas une perte de temps.


ps: Affrontez moi dans l'arène

Mammouth du PHP | 536 Messages

20 juil. 2007, 09:09

je veux les garder car lorsd de l'affichage des résultats avec AJAX, je fais un lien en cliquant sur le nom de la pratique vers une page qui affiche la pratique en entier. Puis sur cette nouvelle pasge, j'ai fais un bouton qui permet de revenir au moteur de recherche. Seulement, lorsqu'on revient sur la page de recherche, ben elle a été rechargée et tous les critères cochés sont effacés, il faut tout recommencer pour l'utilisateur.
Je vousdrais alors créer un bouton sur la page qui affiche la practice "retour aux résultats" qui redirige vers la page de recherche avec les résultats déjà affichés et les critères déjà cochés.

Pourc ela, je pense donc avoir besoin de garder les critères sélectionnés qq part, et j'avais pensé aux variables de session.

Mais la fonction serialize n'a pas l'air mal, comment l'utiliser ?

Sinon c'est pas unserialize() au lieu de deserialize() ?


EDIT :
dans la page result-request.php (celle qui affiche les résultats, j'arrive déjà à récupérer les critères qu'a coché un utilisateur avec ce code :
if ( (isset($practice) and count($practice) >0 )) // si le tableau $practice est rempli 
  {
    //afficher les critères qui ont été cochés par l'internaute
    echo "<div style='margin-left: 10px;'>For this search, you have checked the criteria : ";
    
    $criteriaFile = $cfg['ressources_root'].'/criteria.xml';
    $domCriteria = new DOMDocument('1.0','UTF-8');
    $domCriteria->load($criteriaFile);
    $xpCriteria = new DOMXPath($domCriteria);
    
    foreach ($params as $param) {
      $explode = explode ('/',$param);
      $categorie = $explode[0];
      $critere = $explode[1];
      //echo $categorie."/".$critere;
      $critXml = $xpCriteria->query('//cat[@id="'.$categorie.'"]/criteria[@id="'.$critere.'"]');
      $_SESSION['crit'][] = $critXml;
      echo "<strong>".$critXml->item(0)->getAttribute('name')."</strong> - ";
    }
    echo "</div>";
Mais comment faire pour stocker chaque valeur dans une variable de session, sachant qu'il faut que je fasse la différence entre le critère 1 de a cart 1 et le critere 1 de la cat 3 par exemple. Car tous deux ont le même id. Il faut donc que je stocke la valeur de la cat et du crit.
Un prof désespéré à son élève :
- Et maintenant, dessinez-moi un cercle au tableau... Voila... Alors qu'est-ce que c'est?
- Ben un cercle ?
- Non, c'est votre note, sortez !!

Modérateur PHPfrance
Modérateur PHPfrance | 2575 Messages

20 juil. 2007, 10:55

T'as 2 solutions:
1. Sans mémoire des critères:
La page du practice cliqué peut être affichée dans un Iframe disposé dans la même page que le formulaire comme ça ce dernier ne bouge pas.
La technique est d'utiliser un lien <a href> avec un " target='nom de l'Iframe' " vers l'Iframe sur chaque practice affiché par la recherche.
Ou alors, sans Iframe, tu peux orienter le lien vers une nouvelle fenêtre avec un " target='_blank' "

2. Avec mémoire des crtitères et c'est ça ce que tu veux:
Tu peux stocker directement les tableaux $_POST["cat"] et $_POST["crit"] dans la session.
Car on peut écrire:
$_SESSION["cat"] = $_POST["cat"];
$_SESSION["crit"] = $_POST["crit"];
ou
$_SESSION["cat"] = serialize($_POST["cat"]);
$_SESSION["crit"] = serialize($_POST["crit"]);
Modifié en dernier par sadeq le 20 juil. 2007, 11:04, modifié 1 fois.
--------//////----//---//----//////
-------//---//----//---//----//---//
------//////----//////-----//////
-----||--------||--||---||
Prendre le recul n'est pas une perte de temps.


ps: Affrontez moi dans l'arène