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

Invité
Invité n'ayant pas de compte PHPfrance

06 juil. 2007, 15:06

ici, pour traiter un practice parmis les practices trouvés
if ( (isset($id_practice) and count($id_practice) >0 ) // si $id_practice est trouvé 
  {  
    

    foreach ($id_practice as $practice){
    //on ouvre le document xml qui correspond à la recherche 
    $practiceFile = $cfg['ressources_root'].'/content/practice/'.$practice.'.xml'; 
    $domPractice = new DOMDocument('1.0','UTF-8'); 
    $domPractice->load($practiceFile); 
    $xpPractice = new DOMXPath($domPractice); 
    $item_practice = $domPractice->getElementsByTagName('item'); 
    //recherche xml
    foreach ($item_practice as $item)  
    { 
      foreach ($item->childNodes as $child) 
      { 
        if($child->nodeType != XML_ELEMENT_NODE) continue; 
        if($child->tagName == 'title') 
        { 
          $titre = utf8_decode($child->firstChild->nodeValue); 
        } 
        elseif ($child->tagName == 'short_description') 
        { 
          $short_description = utf8_decode($child->firstChild->nodeValue); 
        } 
      } 
      $msg = "<p>$titre<br/>$short_description</p>"; 
    } 
   }//fin foreach $id_practice
  } 
  else 
  {  
    $msg = "<p>There is no practice which corresponds to your request. Please refine your search</p>"; 
}

Modérateur PHPfrance
Modérateur PHPfrance | 2575 Messages

06 juil. 2007, 15:07

dicédemment, c'est contagieux l'expiration de session :wink:
--------//////----//---//----//////
-------//---//----//---//----//---//
------//////----//////-----//////
-----||--------||--||---||
Prendre le recul n'est pas une perte de temps.


ps: Affrontez moi dans l'arène

Mammouth du PHP | 536 Messages

06 juil. 2007, 15:34

ouais ça c'est ce que j'avais fait. Mais c'est toujours pas ca

C'est à dire que si je coche 3 critères et que dans ces 3 critères, il y en a deux qui correspondent à 1 practice et un critère qui correspond à aucune practice :
j'obtiens deux fois le message qui contient le nom et la description et une fois le message "il n'y a pa des résultat."

Ce que je n'arrive pas à faire, c'est que dans le cas précédent, je devrais avoir afficher uniquement et une seule fois "pas de résultat" en revanche j'aurais sélectionner uniquement les deux critères qui correspondent a ma practice (sans le troisième), j'aurais eu un seul message qui correspond à ma practice (nom + description).

Tu comprends ce que je recherche à 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 !!

Modérateur PHPfrance
Modérateur PHPfrance | 2575 Messages

06 juil. 2007, 15:45

Oui, ça c'est dù au formulaire qui envoit les critères par couple (cat/crit) à la fois et au programme de recherche qui reçoit le post d'un couple (cat/crit) à la fois.

Dans ce cas il faut augmenter le volume du postage. c'est à dire : envoyer et recevoir tous les couples (cat/crit) cochés. Et tu sais ce que ça veut dire. :?
Modifié en dernier par sadeq le 06 juil. 2007, 15:48, modifié 1 fois.
--------//////----//---//----//////
-------//---//----//---//----//---//
------//////----//////-----//////
-----||--------||--||---||
Prendre le recul n'est pas une perte de temps.


ps: Affrontez moi dans l'arène

Mammouth du PHP | 536 Messages

06 juil. 2007, 15:47

oui et ça se traduit comment ? je ne vois pas trop ce que tu veux dire.

C'est cette fonction qui faudrait modifier :

Code : Tout sélectionner

function AfficheResult() { ////vider le div de reponse avant de lancer la recherche document.getElementById('div_reponse').innerHTML = ""; //Elements du form à traiter var critInputs = document.criteria.elements; var myInput; for ( var i = 0 ; i < critInputs.length ; i++ ) { myInput = critInputs[i]; //traiter seulement les checkbox cochées if ( myInput.type == 'checkbox' && myInput.checked ) { //Déterminer les paramètres de recherche id_cat et id_crit (seront envoyés par Post via Ajax) var explode = myInput.value.split('/'); var id_cat = explode[0]; var id_crit = explode[1]; var post_params = "cat=" + id_cat + "&crit=" + id_crit; //Envoit le postage au serveur de recherche via Ajax et attend la réponse getByAjax('result-request.php', document.getElementById('div_reponse'), post_params); } } }
ou celle ci

Code : Tout sélectionner

function getByAjax(serveur, reponse, parametres){ var xhr = getXhr(); //Nouvelle instance Ajax if (xhr && serveur){ // On défini la fonction observant la communication Ajax/serveur xhr.onreadystatechange = function(){ // le code 4/200: détermine que Ajax a reçu une réponse du serveur if(xhr.readyState == 4 && xhr.status == 200){ reponse.innerHTML += xhr.responseText; //Ecrit la réponse du serveur } } // Déclenchement de l'appel Ajax/serveur (avec passage de paramètres en POST) xhr.open("POST" ,serveur ,true); xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded'); xhr.send(parametres); } }
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

06 juil. 2007, 16:21

Des modifs du côté du formulaire et du programme de recherche.

Côté formulaire:
- Ne pas toucher à son contenu il est écrit pour envoyer le post d'un tableau crit[] et ça nous intéresse
- Par contre, il faut modifier dans la fonction AfficheResult(): il faut déplacer le getByAjax après la boucle for pour effectuer le postage une fois pas plusieurs fois par Ajx.
Le rôle de la boucle for devient de sérialiser les valeurs des checkbox cochées pour obtenir des paramètres post corrrect, sous forme de tableau, sous la forme standard:

Code : Tout sélectionner

cat[0]=...&cat[1]=...&...&crit[0]=...&crit[1]=....
- La fonction getByAjax ne doit plus faire de cumul dans la réponse Ajax (+=)


Côté programme de recherche:
- le $_POST['cat'] et $_POST['crit'] recevront donc des tableaux il faut les parcourir pour traiter les couples cat/crit par le même code de recherche xml qu'on a
--------//////----//---//----//////
-------//---//----//---//----//---//
------//////----//////-----//////
-----||--------||--||---||
Prendre le recul n'est pas une perte de temps.


ps: Affrontez moi dans l'arène

Mammouth du PHP | 536 Messages

06 juil. 2007, 16:24

ok je vois ce que tu veux dire, je vais essayer de mettre ça en application ce soir et ce weekend. Si problème, je reviendrais ici :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 !!

Invité
Invité n'ayant pas de compte PHPfrance

09 juil. 2007, 09:17

Bonjour tout le monde, bon weekend ?

Je reviens, car je ne vois pas comment faire dans la buocle for pour passer des éléments d'un tbaleau en paramèetres dans une url comme tu disais sadeq

Code : Tout sélectionner

cat[0]=...&cat[1]=...&...&crit[0]=...&crit[1]=....
SI tu pouvais m'aider dans ton raisonnement..

Mammouth du PHP | 536 Messages

09 juil. 2007, 09:27

Désolé,j'ai pu de connection automatique..

Donc oui je disais que avec ça, ça ne marchait pas :

voici ma fonction Afficheresult():

Code : Tout sélectionner

function AfficheResult() { ////vider le div de reponse avant de lancer la recherche document.getElementById('div_reponse').innerHTML = ""; //Elements du form à traiter var critInputs = document.criteria.elements; var myInput; for ( var i = 0 ; i < critInputs.length ; i++ ) { myInput = critInputs[i]; //traiter seulement les checkbox cochées if ( myInput.type == 'checkbox' && myInput.checked ) { //Déterminer les paramètres de recherche id_cat et id_crit (seront envoyés par Post via Ajax) var explode = myInput.value.split('/'); var id_cat = explode[0]; var id_crit = explode[1]; var cat = new Array; var crit = new Array; var post_params = "cat=" + id_cat + "&crit=" + id_crit; } } //Envoit le postage au serveur de recherche via Ajax et attend la réponse getByAjax('result-request.php', document.getElementById('div_reponse'), post_params); }
pourtant, je pense bien passer un tableau en paramètres non ?


[EDIT]
Donc j'ai retouché encore mon code de ma fonction AfficheResult(), sadeq (ou quelqu'un d'autre) peux tu me dire si elle est correcte par rapport à ce que je veux faire et par rapport à l'algorythme que tu m'avais dit.

Je suis pas expert en javascript, mais en tout cas, je n'ai pas de message d'erreur.
Seulement, là comme ça le résultat que je souhaite est presque obtenu. Il reste un petit défaut : lorrsqu'il y a une "méthode de travail "qui n'est définie que par un seul critère il ne faut pas qu'elle aparraisse lorsqu'on en coche plusieurs dont celui auquel elle correpond. Comment faire ceci ?
Là je ne vois pas.

Voici ma nouvelle fonction :

Code : Tout sélectionner

function AfficheResult() { ////vider le div de reponse avant de lancer la recherche document.getElementById('div_reponse').innerHTML = ""; //Elements du form à traiter var critInputs = document.criteria.elements; var myInput; var cat =new Array; var crit = new Array; var post_params = new Array; for ( var i = 0 ; i < critInputs.length ; i++ ) { myInput = critInputs[i]; //traiter seulement les checkbox cochées if ( myInput.type == 'checkbox' && myInput.checked ) { //Déterminer les paramètres de recherche id_cat et id_crit (seront envoyés par Post via Ajax) var explode = myInput.value.split('/'); var id_cat = explode[0]; var id_crit = explode[1]; post_params[i] = "cat=" + id_cat + "&crit=" + id_crit + "&"; } } //Envoit le postage au serveur de recherche via Ajax et attend la réponse var post_param = post_params.join(""); //alert(post_param); getByAjax('result-request.php', document.getElementById('div_reponse'), post_param); }
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

09 juil. 2007, 12:11

C'est presque ça, il faut ajouter les index [0], [1],... aux paramètres cat et crti. On peut les mettre car on est dans une boucle for i. Voici un essai:
function AfficheResult() {
  ////vider le div de reponse avant de lancer la recherche
  document.getElementById('div_reponse').innerHTML = "";
 
  //Elements du form à traiter
  var critInputs = document.criteria.elements;
  var myInput;
 
  var cat  =new Array;
  var crit = new Array;
  var post_params = new Array;
     
  for ( var i = 0 ; i < critInputs.length ; i++ ) {
     myInput = critInputs[i];
     
    //traiter seulement les checkbox cochées
    if ( myInput.type == 'checkbox' && myInput.checked ) {
   
      //Déterminer les paramètres de recherche id_cat et id_crit (seront envoyés par Post via Ajax)
      var explode = myInput.value.split('/');
      var id_cat = explode[0];
      var id_crit = explode[1];   
      post_params[i] = "cat[" +i+ "]=" + id_cat + "&crit[" +i+ "]=" + id_crit ;  //pour obtenir la forme cat[0]=valeur&crit[0]=valeur ....
    }
  }
  //Envoit le postage au serveur de recherche via Ajax et attend la réponse
  var post_param = post_params.join("&");
  //alert(post_param);
  getByAjax('result-request.php', document.getElementById('div_reponse'), post_param);
}
Mais je te rappelle que le programme de recherche xml doit changer la façon de recevoir les paramètres POST (cat et crit) car ils sont désormais des tableaux.
Pour tester fais un print_r($_POST["cat"]); au début du programme result-request.php
--------//////----//---//----//////
-------//---//----//---//----//---//
------//////----//////-----//////
-----||--------||--||---||
Prendre le recul n'est pas une perte de temps.


ps: Affrontez moi dans l'arène

Mammouth du PHP | 536 Messages

09 juil. 2007, 12:18

ok d'accord, j'y étais presque. mais là, je n'ai aucun résultat qui s'affiche mais systématiquement la phrase disant qu'il n'y a pas de résultat correspondant à ma recherche.

Comment on fait alors pour récupérer par exemple cat[28]=2&crit[28]=3 dans notre page qui affiche les résultat. Et comment faire la recherche à partir de ces élément que l'on vient de passer en paramètres.

Faut-il modifier alors quelque chose (je pense aux POST) dans la page result-request.php qui permet l'affichage des résultats :
<?
/*-----------------------------------------------------*/
//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

//on vérifie l'existence des varaibles passées par le formulaire si elles n'existent pas, on meur affecte une valeur vide
if (!isset($_POST['cat'])) { $_POST['cat'] = ''; }
if (!isset($_POST['crit'])) { $_POST['crit'] = ''; }

//si les variables ne sont pas vides
if ( ($_POST['cat'] != '') or ($_POST['crit'] != '') )
{
  $id_practice = null;
  foreach($xml->link as $value)
  {
    
      foreach($value->criteria as $criteria)
      {     
       if( (string)$criteria['idcat'] == $_POST['cat'] and (string)$criteria['idcrit'] == $_POST['crit'] )
         {
          
          $practice = $value->practice;
          $id_practice = Array();
          $id_practice[] = $practice['id'];
          //break;
         }
    }
  }
  if ( (isset($id_practice) and count($id_practice) >0 )) // si $id_practice est trouvé 
  {
    foreach ($id_practice as $practice){
    //on ouvre le document xml qui correspond à la recherche  //fichier qui contient la practice de la recherche
    $practiceFile = $cfg['ressources_root'].'/content/practice/'.$practice.'.xml';
    $domPractice = new DOMDocument('1.0','UTF-8'); 
    $domPractice->load($practiceFile); 
    $xpPractice = new DOMXPath($domPractice); 
    $item_practice = $domPractice->getElementsByTagName('item'); 
    
    //fichier qui contient toutes les practices
    $practicesFile = $cfg['ressources_root'].'practice.xml';
    $domPractices = new DOMDocument('1.0','UTF-8');
    $domPractices->load($practicesFile);
    $xpPractices = new DOMXPath($domPractices);
    $practice_practices = $domPractices->getElementsByTagName('practice');    
    
    
    //recherche xml
    foreach ($item_practice as $item)  
    { 
      foreach ($item->childNodes as $child) 
      { 
        if($child->nodeType != XML_ELEMENT_NODE) continue; 
        if ($child->tagName == 'short_description') 
        { 
          $short_description = utf8_decode($child->firstChild->nodeValue); 
        } 
      } 
    } //fin de foreach $item_practice
    foreach ($practice_practices as $practices)  
    {      
        $name = $xpPractices->query('//practice[@id="'.$practice.'"]')->item(0)->getAttribute('name');
        $viewed = $xpPractices->query('//practice[@id="'.$practice.'"]')->item(0)->getAttribute('viewed');
        $used = $xpPractices->query('//practice[@id="'.$practice.'"]')->item(0)->getAttribute('used');
    } //fin de foreach $practice_practices
        $msg = "<table width='100%'><tr><th>".TITLE_OF_THE_GOOD_PRACTICE." </th><th>".SHORT_DESCRIPTION_GOOD_PRACTICE."</th><th>".VIEWED."</th><th>".USED."</th></tr>";
        $msg .= "<tr width='100%'><td>$name</td><td>$short_description</td><td>$viewed time</td><td>$used time</td></tr>";
        $msg .= "</table>";
   }//fin foreach $id_practice
  } //fin de si $id_practice trouvé
  else 
  {  
    $msg = "<table width='100%'>"; 
    $msg .= "<tr><td colspan='4'>There is no practice which corresponds to your request. Please refine your search</td></tr>";
    $msg .= "</table>";
  }
}
else
  { 
    $msg = "<p>Choose your crireria before starting your search</p>";
  }
echo $msg;
exit;

?>
[EDIT]
J'ai avancé dans mon travail sadeq.

Voila le nouveau code de ma page qui affiche les résultats de la recherche :
 
<?
/*-----------------------------------------------------*/
//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

//on vérifie l'existence des varaibles passées par le formulaire si elles n'existent pas, on meur affecte une valeur vide
if (!isset($_POST['cat'])) { $_POST['cat'] = ''; }
if (!isset($_POST['crit'])) { $_POST['crit'] = ''; }


//si les variables ne sont pas vides
if ( ($_POST['cat'] != '') and ($_POST['crit'] != '') )
{
  $id_practice = null;
  $categorie = $_POST['cat'];
  foreach($categorie as $index=>$cat) 
  {
    foreach($xml->link as $value)
    {      
        foreach($value->criteria as $criteria)
        {     
         if( (string)$criteria['idcat'] == $_POST['cat'][$index] and (string)$criteria['idcrit'] == $_POST['crit'][$index] )
           {
            $practice = $value->practice;
            $id_practice = Array();
            $id_practice[] = $practice['id'];
            //break;
           }
      }
    }
  }
  if ( (isset($id_practice) and count($id_practice) >0 )) // si $id_practice est trouvé 
  {
    foreach ($id_practice as $practice){
    //on ouvre le document xml qui correspond à la recherche  //fichier qui contient la practice de la recherche
    $practiceFile = $cfg['ressources_root'].'/content/practice/'.$practice.'.xml';
    $domPractice = new DOMDocument('1.0','UTF-8'); 
    $domPractice->load($practiceFile); 
    $xpPractice = new DOMXPath($domPractice); 
    $item_practice = $domPractice->getElementsByTagName('item'); 
    
    //fichier qui contient toutes les practices
    $practicesFile = $cfg['ressources_root'].'practice.xml';
    $domPractices = new DOMDocument('1.0','UTF-8');
    $domPractices->load($practicesFile);
    $xpPractices = new DOMXPath($domPractices);
    $practice_practices = $domPractices->getElementsByTagName('practice');    
    
    
    //recherche xml
    foreach ($item_practice as $item)  
    { 
      foreach ($item->childNodes as $child) 
      { 
        if($child->nodeType != XML_ELEMENT_NODE) continue; 
        if ($child->tagName == 'short_description') 
        { 
          $short_description = utf8_decode($child->firstChild->nodeValue); 
        } 
      } 
    } //fin de foreach $item_practice
    foreach ($practice_practices as $practices)  
    {      
        $name = $xpPractices->query('//practice[@id="'.$practice.'"]')->item(0)->getAttribute('name');
        $viewed = $xpPractices->query('//practice[@id="'.$practice.'"]')->item(0)->getAttribute('viewed');
        $used = $xpPractices->query('//practice[@id="'.$practice.'"]')->item(0)->getAttribute('used');
    } //fin de foreach $practice_practices
        $msg = "<table width='100%'><tr><th>".TITLE_OF_THE_GOOD_PRACTICE." </th><th>".SHORT_DESCRIPTION_GOOD_PRACTICE."</th><th>".VIEWED."</th><th>".USED."</th></tr>";
        $msg .= "<tr width='100%'><td>$name</td><td>$short_description</td><td>$viewed time</td><td>$used time</td></tr>";
        $msg .= "</table>";
   }//fin foreach $id_practice
  } //fin de si $id_practice trouvé
  else 
  {  
    $msg = "<table width='100%'>"; 
    $msg .= "<tr><td colspan='4'>There is no practice which corresponds to your request. Please refine your search</td></tr>";
    $msg .= "</table>";
  }
}
else
  { 
    $msg = "<p>Choose your crireria before starting your search</p>";
  }
echo $msg;
?> 
Mais là ça ne convient pas tout a fait encore. Car en fait le truc, c'est que je voudrais que une méthode de travail définies par n critères ne soit visible si au moins 1 des critères la définissant est sélectionné. Mais elle ne pourra être visible si n+1 critères sont sélectionné par l'utilisateur.
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

09 juil. 2007, 17:23

Mais là ça ne convient pas tout a fait encore. Car en fait le truc, c'est que je voudrais que une méthode de travail définies par n critères ne soit visible si au moins 1 des critères la définissant est sélectionné. Mais elle ne pourra être visible si n+1 critères sont sélectionné par l'utilisateur.
Je n'est bien suvi là, donne moi un exemple.
En fait, il faut faire une pause de programmation jusqu'à bien comprendre cette histoire de critères. :cry:
--------//////----//---//----//////
-------//---//----//---//----//---//
------//////----//////-----//////
-----||--------||--||---||
Prendre le recul n'est pas une perte de temps.


ps: Affrontez moi dans l'arène

Mammouth du PHP | 536 Messages

09 juil. 2007, 17:30

En fait voilà :

une practie peut être définie par n critères (1<n<31).
Un utilsateur peut faire des recherches multicritères de practice a l'aide d'un formulaire de chechbox.

Suivant les critères de recherches qu'il aura sélectionnés, on lui affiche les résultats.

Par exemple, un practice est définie avec le critère 2 de la cat 3 et le critère 3 de la cat 1.
Cette practice ne sera alors visible uniquement si l'utilisateur coche les checkbox correspondant au critère 2 de la cat 3 ou la checkbox correpondant au critère 3 de la cat 1 ou les deux et c'est tout (s'il coche e critère 2 de la cat 3 et le critère 3 de la cat 1 et un autre critère, on lui dit qu'il n'y a pas de résultat correspondant à sa requête).

En effet, la recherche considèrent les critères (représenté ici avec des checkbox) comme des ET (et non des OU) dans la recherche. Ainsi, plus l'utilisateur coche de checkbox, plus la recherche est pointue et détaillée et donc moins il y a de résultats.

C'est plus clair ainsi ?
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

10 juil. 2007, 00:42

ok, on est sur la bonne voie.
Je récapitule ce que j'ai compris:
Dans le fichier xml: criteria.xml on trouve la liste des critères (crit) regroupée par catégorie (cat) ce qui permet de les afficher dans cette forme de regroupement dans le formulaire de recherche.
regroupement de la forme:

Code : Tout sélectionner

<root> <cat id="1" name="cat1"> <criteria id="1" name="crit1" /> <criteria id="2" name="crit2" /> <criteria id="3" name="crit3" /> ... </cat> <cat id="2" name="cat2"> <criteria id="1" name="crit1" /> .... </cat> .... </root>
Dans le fichier xml: criteria-practice.xml on trouve les associations de critères cat/crit qui déterminent un practice. association de la forme par exemple:

Code : Tout sélectionner

<root> <link id="1"> <criteria idcat="1" idcrit="3" /> <criteria idcat="2" idcrit="1" /> ... <practice id="2" /> </link> .... </root>
ici, le practice ayant l'id = 2 est déterminé par les couples de critères (cat/crit) = (1/3) ou (2/1)
C'est à dire que si l'utilisateur choisit dans la catégorie (cat) 1 seulement le critère (crit) 3, le practice 2 doit être trouvé par le programme de recherche et idem pour la (cat) 2 et le (crit) 1
Mais si l'on choisi dans la (cat) 1 le (crit) 3 et un autre (crit) de la (cat) 1, le practice ne doit pas être trouvé. Et idem pour la (cat) 2.

Je croix que la solution est de procéder par élimination d'un practice car si parvient à vérifier pour un (crit) x d'une (cat) y que ce (crit) x ne se trouve pas dans les <link> où sa (cat) existe, on peut alors éliminer le <link> est donc son practice.
Pour celà il faut regroupes les (crit) postés par (cat) posté et ça techniquement c'est possible car on reçoit les (cat) dans un tableau et les (crit) dans un autre dans cette forme envoyée par le formulaire.
Voici un exemple de postage du formulaire si l'on choisit les critères suivants:
  • Dans la catégorie cat= 1, les critères: crit =1 et crit=2
    Et Dans la catégorie cat= 2, les critères: crit =1 et crit=2
Alors:
$_POST["cat"] =

Code : Tout sélectionner

Array ( [0] => 1 [1] => 1 [6] => 2 [7] => 2 )
$_POST["crit"] =

Code : Tout sélectionner

Array ( [0] => 1 [1] => 2 [6] => 1 [7] => 2 )
On voit bien que la catégorie 1 se trouve 2 fois dans le tableau $_POST["cat"] car elle a été implicitement sélectionnée 2 fois en sélectionnant 2 de ses critères (crit)
cette redondonce est utile pour permettre l'association entre (cat) et (crit) dans les 2 tableaux, le lien étant le n° des cases.

Donc $_POST["cat"][0] est lié à $_POST["crit"][0],
$_POST["cat"][1] est lié à $_POST["crit"][1], etc...

Pour regrouper alors les critères (crit) par leur (cat) il faut faire un rapprochement entre ces 2 tableaux en utilisant le n° des cases comme indice relationnel et créer une nouvelle organisation: un tableau indexé par catégorie (ce qui permet de représenter une cat une seule fois) qui contient la liste des crit de cette cat.

Pour avoir le résultat de regroupement suivant:
$cat["1"] =

Code : Tout sélectionner

Array ( [0] => 1 [1] => 2 )
$cat["2"] =

Code : Tout sélectionner

Array ( [0] => 1 [1] => 2 )
le tableau $cat est indexé par catégorie ($cat["1"] et $cat["2"]) le "1" et "2" sont les catégories.

Ce qui permet de repèrer tous les critères d'une catégorie et les traiter ensemble. Et donc appliquer le processus de recherche des practices par élimination.
Par exemple:
pour cat=1, on prend le crit 1 (qui se trouve dans $cat["1"][0]) et on le cherche dans le fichier xml, dans les <link> où cat=1 se trouve, s'il n'existe pas alors le practice du <link> ne doit être sélectionné comme résultat.

Voici, le code du regroupement des critères par catégorie (tableau $cat)
foreach ($_POST["crit"] as $index=>$idcrit){
    $idcat = $_POST["cat"][$index]; //trouve la cat du crit
    $cat["$idcat"][] = $idcrit; //stocke le crit dans son groupe cat
}
il faut donc respecter cette organisation pendant la recherche, la logique est la suivante:
lors de l'exploration du xml criteria-practice.xml on le parcourt <link> par <link> et puisque chaque <link> désigne un practice et ses critères, on vérifie chaque critère avec ceux du tableau $cat dans le cadre de la même cat par l'alternative suivante:

Code : Tout sélectionner

SI le critère xml vérifié correpond au crit posté dans $cat on marque le practice comme trouv (true) Sinon SI ce même critère xml ne correspond pas au crit posté on marque le practice comme non trouvé (false) et on arrête le marquage pour ce practice.
On remarque que si le marquage veut dire non trouvé (false), la vérif s'arrête immédiatement par contre quand le marquage veut dire trouvé (true) la vérif continue. C'est exactement l'équivalent d'une combinaison logique ET séquentielle (règle que tu veux établir)

Si le marquage ne s'arrête pas à non trouvé (false) la vérif continue alors et peut retrouver un état de marquage trouvé (true) qui remplace le précédent (false) et là on aura une combinaison logique OU séquentielle (que tu ne veux pas d'aileurs)

En utilisant le même marqueur par practice, la boucle de recherche met à jour le marquage selon l'alternative SI et marque par conséquant une séquence dont les états possible sont les suivants:

Code : Tout sélectionner

séquence possible pour 3 crit d'une même cat recherchés: true, true, true => practice trouvé séquence possible pour 3 crit d'une même cat recherchés: false => practice non trouvé séquence possible pour 3 crit d'une même cat recherchés: true, false => practice non trouvé séquence possible pour 3 crit d'une même cat recherchés: true, true, false => practice non trouvé
Pour marquer les états d'un practice on peut utiliser un tableau de practices dont les practices doivent être uniques. Pour celà il faut indexer ce tableau par id practice.

L'algorithme est le suivant:
  $practice = null;
  //Recherche des practices
    foreach($xml->link as $value)
    {     
      foreach($value->criteria as $criteria)
       {     
         //practice en cours
		 $id = $value->practice['id'];
         //echo "<pre>"; print_r($criteria); echo "</pre>";
		 
		 //Chercher selon les critères de recherche imposés
		 foreach($cat as $idcat=>$crit) 
		   foreach($crit as $idcrit) //critères groupés par cat
    	   {		 
			//si la cat est touvée
			if( trim($criteria['idcat']) == trim($idcat) )
				//vérifier le crit de cette cat
				if ( trim($criteria['idcrit']) == trim($idcrit) ) //si crit existe
            	{
            		$practice["$id"] = true; //sélectioner le practice en cours
            	}
				else //au mois un crit de cette cat n'est pas trouvé
				{
					$practice["$id"] = false; //élinminer le practice en cours
					break; //Arrêter si éliminé
				}
      	  }
       }
   }
echo "<pre>"; print_r($practice); echo "</pre>"; 
A la suite de cette moulinette, on aura un tableau $practice dont les indexes sont les id des practices rencontrés dans les <link> du xml et dont chaque case practice contient une valeur false (vide) ou true (1)
La suite du programme doit en principe utliser ce tableau pour accèder et afficher le practices trouvés. Le seul changement dans ce module existant est qu'il ne doit pas traiter les cases false du tableau practice. Pour celà on peut écrire:
  //Lecture des practices trouvés
  if ( (isset($practice) and count($practice) >0 )) // tableau des practices
  {
    foreach ($practice as $id=>$trouvé){
	if (!$trouvé) continue; //sauter les practices marqués non trouvés

    //fichier qui contient toutes les practices
    $practicesFile = $cfg['ressources_root'].'/content/practice/'.$id.'.xml';
  ....
--------//////----//---//----//////
-------//---//----//---//----//---//
------//////----//////-----//////
-----||--------||--||---||
Prendre le recul n'est pas une perte de temps.


ps: Affrontez moi dans l'arène

Mammouth du PHP | 536 Messages

10 juil. 2007, 09:44

Avec ce code donc
<?php
//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
      $cat["$idcat"][] = $idcrit; //stocke le crit dans son groupe cat
    }
    $practice = null;
    //Recherche des practices
    foreach($xml->link as $value)
    {     
      foreach($value->criteria as $criteria)
      {     
        //practice en cours
        $id = $value->practice['id'];
        //echo "<pre>"; print_r($criteria); echo "</pre>";
           
        //Chercher selon les critères de recherche imposés
        foreach($cat as $idcat=>$crit) 
        foreach($crit as $idcrit) //critères groupés par cat
        {         
          //si la cat est touvée
          if( trim($criteria['idcat']) == trim($idcat) )
          //vérifier le crit de cette cat
            if ( trim($criteria['idcrit']) == trim($idcrit) ) //si crit existe
            {
              $practice["$id"] = true; //sélectioner le practice en cours
            }
            else //au mois un crit de cette cat n'est pas trouvé
            {
              $practice["$id"] = false; //élinminer le practice en cours
              //break; //Arrêter si éliminé
            }
        }
      }
    }
  //echo "<pre>"; print_r($practice); echo "</pre>"; 
  //Lecture des practices trouvés
  if ( (isset($practice) and count($practice) >0 )) // tableau des practices
  {
    
    foreach ($practice as $id=>$trouve){
    if (!$trouve) continue; //sauter les practices marqués non trouvés

    //fichier qui contient une practice
    $practiceFile = $cfg['ressources_root'].'/content/practice/'.$id.'.xml';
    $domPractice = new DOMDocument('1.0','UTF-8'); 
    $domPractice->load($practiceFile); 
    $xpPractice = new DOMXPath($domPractice); 
    $item_practice = $domPractice->getElementsByTagName('item'); 
    
    //fichier qui contient toutes les practices
    $practicesFile = $cfg['ressources_root'].'practice.xml';
    $domPractices = new DOMDocument('1.0','UTF-8');
    $domPractices->load($practicesFile);
    $xpPractices = new DOMXPath($domPractices);
    $practice_practices = $domPractices->getElementsByTagName('practice');    
    
    
    //recherche xml
    foreach ($item_practice as $item)  
    { 
      foreach ($item->childNodes as $child) 
      { 
        if($child->nodeType != XML_ELEMENT_NODE) continue; 
        if ($child->tagName == 'short_description') 
        { 
          $short_description = utf8_decode($child->firstChild->nodeValue); 
        } 
      } 
    } //fin de foreach $item_practice
    foreach ($practice_practices as $practices)  
    {      
        $name = $xpPractices->query('//practice[@id="'.$id.'"]')->item(0)->getAttribute('name');
        $viewed = $xpPractices->query('//practice[@id="'.$id.'"]')->item(0)->getAttribute('viewed');
        $used = $xpPractices->query('//practice[@id="'.$id.'"]')->item(0)->getAttribute('used');
    } //fin de foreach $practice_practices
        $msg = "<table width='100%'><tr><th>".TITLE_OF_THE_GOOD_PRACTICE." </th><th>".SHORT_DESCRIPTION_GOOD_PRACTICE."</th><th>".VIEWED."</th><th>".USED."</th></tr>";
        $msg .= "<tr width='100%'><td>$name</td><td>$short_description</td><td>$viewed time</td><td>$used time</td></tr>";
        $msg .= "</table>";
   }//fin foreach $id_practice
  } //fin de si $id_practice trouvé
  else if ($practice["$id"] == false)
  {  
    $msg = "<table width='100%'>"; 
    $msg .= "<tr><td colspan='4'>There is no practice which corresponds to your request. Please refine your search</td></tr>";
    $msg .= "</table>";
  }
}
else
  { 
    $msg = "<p>Choose your crireria before starting your search</p>";
  }
echo $msg;
?>  
j'ai le message d'erreur suivant :

Code : Tout sélectionner

Notice: Undefined variable: msg in F:\www\...\result-request.php on line 111
le message d'erreur n'est pas systématiquement défini. Et j'ai relevé un autre problème, si on coche deux critères correspondant à deux practices, il n'en affiche qu'une.
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 !!