Joomladay francophone 2018 à Paris 18 et 19 mai

Enregistrement simultané Community Builder + JS JOBS + GMAccess

Réduire
X
  • Filtrer
  • Heure
  • Afficher
Tout effacer
nouveaux messages

  • [Astuce] Enregistrement simultané Community Builder + JS JOBS + GMAccess

    Bonjour à tous,
    J'ai un léger soucis.
    Ma config :
    Joomla 1.5.15
    CB - 1.2.1
    JS JOBS - 1.0.5.2 beta
    GMAccess - 5.15
    Que je vous explique ce que je souhaite faire :

    1 - J'ai créé 2 types de profil supplémentaires dans jos_users (en plus des profils existants)
    2 - J'ai créé les mêmes profils dans CB et JS JOBS et GMA

    Lors de l'inscription des utilisateurs j'aimerais que CB envoie les infos de profils à JS JOBS et GMA.
    J'ai donc essayé de faire plusieurs requètes dans le fichier comprofiler.php.
    J'ai ajouté le code suivant

    Code PHP:
    //ajout des donnees dans jos_js_job_userroles
        //recuperation de userId
        
    $db=&JFactory::getDBO();
        
    $query "SELECT #__comprofiler.user_id FROM  #__comprofiler WHERE #__comprofiler.confirmed == 0";
        
    $db->setQuery($query);
        
    $id_tempo $db->insertid();
        
        
    //insertion du userId dans jos_js_job_userroles
        
    $db=&JFactory::getDBO();
        
    $query "INSERT INTO #__js_job_userroles (uid) VALUES (".$id_tempo.")";
        
    $db->setQuery($query);
        
        
    //insertion dans jos_js_job_userroles.role de la valeur de jos_users.gid
        //rem pb resultat 31 ou 32, les entrees sont 1 ou 2 . solution passer par : jos_js_job_userroles.title et jos_users.usertype (valeur CANDIDAT ou RECRUTEUR)
        
        //recuperation usertype temporaire
        
    $db=&JFactory::getDBO();
        
    $query "SELECT #__users.usertype FROM  #__users WHERE #__users.id == ".$id_tempo."";
        
    $db->setQuery($query);
        
    $usertype_tempo $db->insertid();

        
        
    //recuperation le rolefor de jos_js_job_roles
        
    $db=&JFactory::getDBO();
        
    $query "SELECT #__js_job_roles.rolefor FROM  #__js_job_roles WHERE #__js_job_roles.title == ".$usertype_tempo."";
        
    $db->setQuery($query);
        
    $rolefor_tempo $db->insertid();

        
        
    // insertion du title dans jos_js_roles
        
    $db=&JFactory::getDBO();
        
    $query "UPDATE #__js_job_roles SET role=".$rolefor_tempo." WHERE #__js_job_roles.id =(".$id_tempo.")";
        
    $db->setQuery($query);
        
        
    //Fin modifs des insertion dans jos_js_job_userroles 
    à la fin de la fonction
    Code PHP:
    function saveRegistration$option ) { 
    avant l'instruction
    Code PHP:
        echo "\n<div>" implode"</div>\n<div>"$messagesToUser ) . "</div>\n";


    Et là cata... pas de problème, l'enregistrement se fait, l'email avec le confirmcode est envoyé mais le user n'est pas activé et rien ne s'est passé dans ma base...

    Auriez-vous une ch'tite lueur pour moi, avant-veille de noël je sais que l'on a autre chose à faire, mais bon, silvousplait...?
    En toi cas merci d'avance et je vous souhaite à toutes et tous d'excellentes fêtes de fin d'année.

    BLOAVEZ MAD
    La truffe
    Dernière édition par titine71 à 07/01/2010, 13h47 Raison: J'ai trouvé la solution

  • #2
    J'avance bien mais encore un coic !

    Salut et surtout
    Bonne et heureuse année à tous

    Bon je relance un peu mon sujet ! J'ai avancé mais encore un petit coic et je ne comprends pas trop pourqueoi.

    J'ai modifié le fichier /components/com_profiler/comprofiler.php vers la ligne 2770 dans la fonction
    Code PHP:
    function saveRegistration$option 
    qui débute vers la ligne 2538 :

    Code PHP:
    //ajout des donnees dans jos_js_job_userroles
        //recuperation de userId
        
    $_CB_database->setQuery("SELECT id FROM  #__comprofiler WHERE confirmed = '0'");
        
    $id_tempo=$_CB_database->LoadResult() or die('Erreur SQL !<br>'.$query.'<br>'.mysql_error());
        echo 
    $id_tempo "<br />";
        
        
    //insertion dans jos_js_job_userroles.role de la valeur de jos_users.gid
        //rem pb resultat 31 ou 32, les entrees sont 1 ou 2 . solution passer par : jos_js_job_userroles.title et jos_users.usertype (valeur CANDIDAT ou RECRUTEUR)
        
        //recuperation usertype temporaire
        
    $_CB_database->setQuery("SELECT cb_usertype FROM  #__comprofiler WHERE id = ".$id_tempo."");
        
    $usertype_tempo $_CB_database->LoadResult() or die('Erreur SQL !<br>'.$query.'<br>'.mysql_error());
        echo 
    $usertype_tempo "<br />" ;
        
        
    //recuperation le rolefor de jos_js_job_roles pour insertion dans jos_js_job_userroles
        
    $_CB_database->setQuery("SELECT rolefor FROM #__js_job_roles WHERE title = '".$usertype_tempo."'"); //-----Attention qd texte a afficher ajouter '' apres le =//
        
    $rolefor_tempo $_CB_database->LoadResult() or die('Erreur SQL !<br>'.$query.'<br>'.mysql_error());
        echo 
    $rolefor_tempo "<br />" ;
            
        
    //insertion du rolefor pour role et id pour uid dans jos_js_job_userroles
        
        
    $_CB_database->setQuery("INSERT INTO #__js_job_userroles (uid, role, dated ) VALUES (.$id_tempo->uid. , .$rolefor_tempo->role. , NULL)");
        
        
    //Fin modifs des insertion dans jos_js_job_userroles 
    Tout va bien jusqu'à ce que j'envoie les valeurs dans la base de données.
    Si j'envoie cette ligne :
    Code PHP:
    $_CB_database->setQuery("INSERT INTO #__js_job_userroles (uid, role, dated ) VALUES (12 , 3650 , NULL)"); 
    pas de problème les valeurs s'intègrent bien dans la base, mais dès que j'envoie la requête avec les variables
    Code PHP:
    $_CB_database->setQuery("INSERT INTO #__js_job_userroles (uid, role, dated ) VALUES (.$id_tempo->uid. , .$rolefor_tempo->role. , NULL)"); 
    ben là ... rien n'est envoyé dans la Bdd !
    J'ai essayé de mettre les variables entre simple et/ou double quote celà ne change rien.

    Est-ce qu'un oeil nouveau peut m'aider, vois plus très clair ?!
    Merci d'avance

    Et Bloavezh Mat
    Titine71
    Dernière édition par titine71 à 05/01/2010, 08h00

    Commentaire


    • #3
      Ja patauge voir je coule........

      RE salut ! N'arrivant pas à récupérer mes variables $id_tempo, $usertype_tempo et $role_tempo, j'ai voulu contourner le problème en créant une nouvelle table (jos_js_job_usertempo) avec 4 champs (mes 3 varaibles + date_tempo)
      J'arrive bien à remplir la table avec le code suivant :
      Code PHP:
      //recuperation de la date de creation du compte dans jos_users pour insertion dans jos_js_job_userroles
          
      $_CB_database->setQuery("SELECT registerDate FROM #__users WHERE id = ".$id_tempo.""); 
          
      $date_tempo $_CB_database->LoadResult();
          echo 
      $date_tempo "<br />" ;
          
          
          
      //insertion des donnees dans la nouvelle table jos_js_job_usertempo
          
      $_CB_database->setQuery("INSERT INTO #__js_job_usertempo (id_tempo, usertype_tempo, rolefor_tempo, date_tempo) VALUES ('".$id_tempo."' , '".$usertype_tempo."' , '".$rolefor_tempo."', '".$date_tempo."')");
          
      $user_tempo $_CB_database->LoadResult(); 
      Ya juste une fichue erreur qui s'affiche
      Code HTML:
      Warning: mysql_fetch_row(): supplied argument is not a valid MySQL result resource in C:\wamp\www\beemploi-joomla\libraries\joomla\database\database\mysql.php on line 358
      
      Warning: mysql_free_result(): supplied argument is not a valid MySQL result resource in C:\wamp\www\beemploi-joomla\libraries\joomla\database\database\mysql.php on line 361
      Je comprends plus rien, suis carrément paumée !

      Je fais une requête pour récupérer les infos de la table jos_js_job_usertempo pour alimenter la table jos_js_job_userroles

      Code PHP:
      $_CB_database->setQuery("INSERT INTO #__js_job_userroles (id, uid, role, dated) SELECT ('', id_tempo->uid, rolefor_tempo->role, date_tempo->dated) FROM  #__js_job_usertempo)";
          
      $_CB_database->setQuery$query ); 
      et devinez .... toujours rien dans cette maudite table !

      HELP ME... POR FAVOR
      MUCHAS GRACIAS

      Commentaire


      • #4
        J'avance, j'avance

        Bonjour !
        Pour ceux que çà intéresse j'ai avancé sur le schmilblick !
        Alors, j'ai modifié la requête comme suit :
        Code PHP:
        $query_userroles "INSERT INTO jos_js_job_userroles (uid, role, dated) VALUES ('".$id_tempo."' , '".$rolefor_tempo."', '".$date_tempo."')";
        $result_roles mysql_query ($query_userroles); 
        et l'enregistrement simultané Community Builder et JS Jobs se fait nickel ...mais car il y a un MAIS si le dernier enregistrement n'est pas encore confirmé et qu'un autre enregistrement se fait.... BLING... soucis la requête renvoie pas le bon enregistrement ! Et je sais pourquoi...
        Sur la première variable que je récupère
        Code PHP:
        //recuperation de userId
        $_CB_database->setQuery("SELECT id FROM  #__comprofiler WHERE confirmed = '0'");
        $id_tempo=$_CB_database->LoadResult() 
        Il faut en fait que je récupère le LAST_INSERT_ID ().
        Je déclare donc une variable pour récupérer cette info comme ceci :
        Code PHP:
        $user_lastId mysql_query("SELECT LAST_INSERT_ID()"); 
        Mais ce que je ne sais pas faire, c'est intégrer cette condition dans ma variable $id_tempo ou ma requête de récupération de l'ID.

        Je pense qu'il faut que ma requête soit du genre
        SELECT id FROM jos_comprofiler WHERE confirmed ='0' AND $user_lastId=mysql_query("SELECT LAST_INSERT_ID()")

        Mais j'arrive pas à l'écrire correctement !
        Je sais, suis une vraie truffe, mais là je bloque !

        Merci d'avance
        La Truffe

        J'ai résolu mon problème et tout marche comme il faut !
        Si ça vous intéresse, je vous envoie la fonction en MP

        @pluche
        Dernière édition par titine71 à 05/01/2010, 15h45 Raison: [RESOLU]

        Commentaire


        • #5


          Tu es certainement bien meilleur que moi en dev

          Je suis très intéressé par ton travail

          De mon côté j'ai pas mal bloqué ces derniers temps mais la j'ai un peu avancé

          Tu peux voir le site en préprod sur

          http://www.goes-asso.com

          tu peux créer un compte de test (employeur et candidat)
          N'oubliez pas de passer vos post en "réglé" c'est très utile à celui qui cherche, ...et qui se perd http://forum.joomla.fr/announcement.php?f=133 mais trouvera grâce à vous
          profil : http://quelprestataire.fr/robert-suzanne+texier"

          Commentaire


          • #6
            Le bout de code...

            Salut à tous !
            Allez aujourd'hui est un jour neigeux, je suis d'humeur partageuse, je vous donne donc le bout de code à ajouter au fichier /components/com_profiler/comprofiler.php :
            Code PHP:
            //ajout des donnees dans jos_js_job_userroles
                //recuperation de userId
                
            $_CB_database->setQuery("SELECT id FROM jos_users WHERE block = '1'");
                
            $id_tempo=$_CB_database->LoadResult() or die('Erreur SQL !<br>'.$query.'<br>'.mysql_error());
                    
                
            //recuperation usertype temporaire
                
            $_CB_database->setQuery("SELECT usertype FROM  jos_users WHERE id = ".$id_tempo."");
                
            $usertype_tempo $_CB_database->LoadResult() or die('Erreur SQL !<br>'.$query.'<br>'.mysql_error());
                
                
            //recuperation le rolefor de jos_js_job_roles pour insertion dans jos_js_job_userroles
                
            $_CB_database->setQuery("SELECT rolefor FROM #__js_job_roles WHERE title = '".$usertype_tempo."'"); 
                
            $rolefor_tempo $_CB_database->LoadResult() or die('Erreur SQL !<br>'.$query.'<br>'.mysql_error());
                
                
            //recuperation de la date de creation du compte dans jos_users pour insertion dans jos_js_job_userroles
                
            $_CB_database->setQuery("SELECT registerDate FROM #__users WHERE id = ".$id_tempo.""); 
                
            $date_tempo $_CB_database->LoadResult();
                    
                
            //insertion du rolefor pour role et id pour uid dans jos_js_job_userroles
                
            $query_userroles "INSERT INTO jos_js_job_userroles (uid, role, dated) VALUES ('".$id_tempo."' , '".$rolefor_tempo."', '".$date_tempo."')";
                
            $result_roles mysql_query ($query_userroles) or die('Erreur SQL !<br>'.$query.'<br>'.mysql_error());
                
                
            //Fin modifs des insertion dans jos_js_job_userroles 
            Maintenant je vais attaquer la partie pour renvoyer les infos dans GMAccess, je vous tiens au jus ...

            @pluche,
            La Truffe
            Dernière édition par titine71 à 06/01/2010, 10h37

            Commentaire


            • #7
              Merci
              N'oubliez pas de passer vos post en "réglé" c'est très utile à celui qui cherche, ...et qui se perd http://forum.joomla.fr/announcement.php?f=133 mais trouvera grâce à vous
              profil : http://quelprestataire.fr/robert-suzanne+texier"

              Commentaire


              • #8
                Petite question supplémentaire

                Tu l'insères à quel niveau ton bout de code ?

                Pas n'importe ou je suppose
                N'oubliez pas de passer vos post en "réglé" c'est très utile à celui qui cherche, ...et qui se perd http://forum.joomla.fr/announcement.php?f=133 mais trouvera grâce à vous
                profil : http://quelprestataire.fr/robert-suzanne+texier"

                Commentaire


                • #9
                  Le bout de code...

                  Salut !
                  tu insères le code à la fin de la fonction
                  Code PHP:
                  function saveRegistration$option ) { 
                  qui commence vers la ligne 2538 après :
                  Code PHP:

                      
                  if ( $_PLUGINS->is_errors() ) {

                          echo 
                  $_PLUGINS->getErrorMSG();

                          
                  HTML_comprofiler::registerForm$option$ueConfig['emailpass'], $userComplete$_POST$_PLUGINS->getErrorMSG() );

                          return;

                      } 
                  et avant :
                  Code PHP:
                      echo "\n<div>" implode"</div>\n<div>"$messagesToUser ) . "</div>\n";


                  voili, j'espère que çà pourra d'aider.

                  Une tite question au passage :
                  comment faire par requête sql la chose suivante ?
                  J'ai la valeur d'un champs de type int(11) qui est égale à 1 par exemple et je veux qu'elle devienne 6. Comment que je fais çà MOA ?
                  Je continue de chercher...

                  @pluche

                  Commentaire


                  • #10
                    Un truc comme ça

                    $sql = 'UPDATE `nom_base`.`nom_table` SET `Nom_champs` = \'nouvelle_valeur\' WHERE `nom_table`.`Primary_id` = valeur_id LIMIT 1;';
                    Par contre j'ai l'impression que nous n'avons pas le même fichier comprofiler.php

                    Quel est ta version de CB ?
                    N'oubliez pas de passer vos post en "réglé" c'est très utile à celui qui cherche, ...et qui se perd http://forum.joomla.fr/announcement.php?f=133 mais trouvera grâce à vous
                    profil : http://quelprestataire.fr/robert-suzanne+texier"

                    Commentaire


                    • #11
                      Ca progresse !

                      Envoyé par abmag Voir le message

                      Quel est ta version de CB ?
                      j'ai la version 1.2.1, je t'envoie la fonction en entier si tu veux ?

                      Commentaire


                      • #12
                        avec plaisir

                        ça marche la requête sql ?
                        N'oubliez pas de passer vos post en "réglé" c'est très utile à celui qui cherche, ...et qui se perd http://forum.joomla.fr/announcement.php?f=133 mais trouvera grâce à vous
                        profil : http://quelprestataire.fr/robert-suzanne+texier"

                        Commentaire


                        • #13
                          Enregistrement dans GMAccess

                          Re !
                          En fait je ne veux pas modifier la valeur du champs, je veux la récupérer, et définir une nouvelle valeur du genre :
                          si la valeur du champs_machin = 1 alors la valeur du champs_truc = 15
                          et si la valeur du champs_machin = 2 alors la valeur du champs_truc = 17.

                          Est-ce que je suis clair ?
                          Je te montre le code que j'ai fait :
                          Code PHP:
                          // ajout des donnees dans jos_gm_membre
                          //recuperation des nom_groupe et id_groupe dans jos_gm_groupe
                          $_CB_database->setQuery("SELECT id_groupe FROM jos_gm_groupe WHERE nom_groupe = 'CANDIDAT'"); 
                          $idGroupeCandidat $_CB_database->LoadResult() or die('Erreur SQL !<br>'.$query.'<br>'.mysql_error());
                              
                          $_CB_database->setQuery("SELECT id_groupe FROM jos_gm_groupe WHERE nom_groupe = 'RECRUTEUR'"); 
                          $idGroupeRecruteur $_CB_database->LoadResult() or die('Erreur SQL !<br>'.$query.'<br>'.mysql_error());
                              
                          //recuperation de gid de jos_users 
                          $_CB_database->setQuery("SELECT gid FROM jos_users WHERE block = '1'");
                          $gid_tempo=$_CB_database->LoadResult() or die('Erreur SQL !<br>'.$query.'<br>'.mysql_error());
                          echo 
                          $gid_tempo ."<br/>" 
                          Jusque là nickel, je récupère ce que je souhaite dans des variables que je vais utiliser plus tard pour l'insertion qui sera comme suit :

                          Code PHP:
                          //insertion dans jos_gm_membre pour GMAccess
                          //$query_insert_membre = "INSERT INTO jos_gm_membre (id_groupe, id_membre) VALUES ('".$et_la_ca_le_mystere."' , '".$id_tempo."')";
                          //$result_insert_membre = mysql_query ($query_insert_membre) or die('Erreur SQL !<br>'.$query.'<br>'.mysql_error()); 
                          C'est pour trouver la valeur $et_la_ca_le_mystere qu'il faut que je compile un truc ! Et là suis un peu paumée !!
                          Je sais que je dois faire un truc du genre :
                          Code PHP:
                          // modification de la valeur de gid_tempo
                          //if ($gid_tempo = $idGroupeCandidat) {
                          //echo $id_groupe_Candidat = '6';
                          //} and if ($gid_tempo = $idGroupeRecruteur) {
                          //echo $id_groupe_tempo = '7';
                          ...
                          //} 
                          et après je sais pas !

                          Voili, je précise que je ne fais que de la bidouille et ne suis pas du tout dev, alors j'ai du mal à rédiger la prog. Je comprends ce qu'il faut faire et vois à peu près comment le faire, et le php et moi on est pas marié depuis longtemps !

                          Commentaire


                          • #14
                            Le fichier

                            Envoyé par abmag Voir le message
                            avec plaisir

                            ça marche la requête sql ?
                            Je n'ai pas tester, vais voir !

                            function_saveRegistration.zip

                            Commentaire


                            • #15
                              Pour un bidouilleur tu bidouille plutôt pas mal faut dire qu'au début du mariage c'est souvent les meilleurs moments

                              Je vois à peu prêt ce que tu veux faire mais je suis encore plus limité que toi en dev et t'a pris beaucoup d'avance.

                              De mon côté j'ai une erreur sql sur
                              //recuperation le rolefor de jos_js_job_roles pour insertion dans jos_js_job_userroles
                              $_CB_database->setQuery("SELECT rolefor FROM #__js_job_roles WHERE title = '".$usertype_tempo."'");
                              $rolefor_tempo = $_CB_database->LoadResult() or die('Erreur SQL2 !<br>'.$query.'<br>'.mysql_error());
                              Je pense qu'il y a une incohérence entre entre mes tables cb et jsjob, je vais creusé par là

                              Merci pour la fonction
                              N'oubliez pas de passer vos post en "réglé" c'est très utile à celui qui cherche, ...et qui se perd http://forum.joomla.fr/announcement.php?f=133 mais trouvera grâce à vous
                              profil : http://quelprestataire.fr/robert-suzanne+texier"

                              Commentaire

                              Annonce

                              Réduire
                              1 sur 2 < >

                              C'est [Réglé] et on n'en parle plus ?

                              A quoi ça sert ?
                              La mention [Réglé] permet aux visiteurs d'identifier rapidement les messages qui ont trouvé une solution.

                              Merci donc d'utiliser cette fonctionnalité afin de faciliter la navigation et la recherche d'informations de tous sur le forum.

                              Si vous deviez oublier de porter cette mention, nous nous permettrons de le faire à votre place... mais seulement une fois
                              Comment ajouter la mention [Réglé] à votre discussion ?
                              1 - Aller sur votre discussion et éditer votre premier message :


                              2 - Cliquer sur la liste déroulante Préfixe.

                              3 - Choisir le préfixe [Réglé].


                              4 - Et voilà… votre discussion est désormais identifiée comme réglée.

                              2 sur 2 < >

                              Assistance au forum - Outil de publication d'infos de votre site

                              Compatibilité: PHP 4.1,PHP4, 5, 6DEV MySQL 3.2 - 5.5 MySQLi from 4.1 ( @ >=PHP 4.4.9)

                              Support Version de Joomla! : | J!3.0 | J!2.5.xx | J!1.7.xx | J!1.6.xx | J1.5.xx | J!1.0.xx |

                              Version française (FR) D'autres versions sont disponibles depuis la version originale de FPA

                              UTILISER À VOS PROPRES RISQUES :
                              L'exactitude et l'exhaustivité de ce script ainsi que la documentation ne sont pas garanties et aucune responsabilité ne sera acceptée pour tout dommage, questions ou confusion provoquée par l'utilisation de ce script.

                              Problèmes connus :
                              FPA n'est actuellement pas compatible avec des sites Joomla qui ont eu leur fichier configuration.php déplacé en dehors du répertoire public_html.

                              Installation :

                              1. Téléchargez l'archive souhaitée : http://afuj.github.io/FPA/

                              Archive zip : https://github.com/AFUJ/FPA/zipball/master

                              2. Décompressez le fichier de package téléchargé sur votre propre ordinateur (à l'aide de WinZip ou d'un outil de décompression natif).

                              3. Lisez le fichier LISEZMOI inclus pour toutes les notes de versions spécifiques.

                              4. LIRE le fichier de documentation inclus pour obtenir des instructions d'utilisation détaillées.

                              5. Téléchargez le script fpa-fr.php à la racine de votre site Joomla!. C'est l'endroit que vous avez installé Joomla et ce n'est pas la racine principale de votre serveur. Voir les exemples ci-dessous.

                              6. Exécutez le script via votre navigateur en tapant: http:// www. votresite .com/ fpa-fr.php
                              et remplacer www. votresite .com par votre nom de domaine


                              Exemples:
                              Joomla! est installé dans votre répertoire web et vous avez installé la version française du fichier FPA:
                              Télécharger le script fpa-fr.php dans: /public_html/
                              Pour executer le script: http://www..com/fpa-fr.php

                              Joomla! est installé dans un sous-répertoire nommé "cms" et vous avez installé la version française du fichier FPA:
                              Télécharger le script fpa-fr.php dans: /public_html/cms/
                              Pour executer le script: http://www..com/cms/fpa-fr.php

                              En raison de la nature très sensible de l'information affichée par le script FPA, il doit être retiré immédiatement du serveur après son utilisation.

                              Pour supprimer le script de votre site, utilisez le lien de script de suppression fourni en haut de la page du script. Si le lien de suppression échoue pour supprimer le script, utilisez votre programme FTP pour le supprimer manuellement ou changer le nom une fois que le script a généré les données du site et le message publié sur le forum. Si le script est toujours présent sur le site, il peut être utilisé pour recueillir suffisamment d'informations pour pirater votre site. Le retrait du script empêche des étrangers de l'utiliser pour jeter un oeil à la façon dont votre site est structuré et de détecter les défauts qui peuvent être utilisé à vos dépends.
                              Voir plus
                              Voir moins
                              Travaille ...
                              X