Développer avec RBS Change : [Résolu] change:input et beans

  • 81962.1

    21/11/2013 12:58


    Mathias
    Rang : Expert
    Bonjour,

    j'ai réalisé un extend + inject du document user pour ajouter 1 propriété de type boolean que l'on appellera mybeanfieldname :
    <add name="mybeanfieldname" type="Boolean" default-value="false"/>
    .

    sur le formulaire d'inscription, j'ai modifié le template de base pour y ajouter mon champs correspondant à ma propriété à l'aide de l'extension phptal "change:field".

    1er point :
    Dans le wiki, il est mentionné que le typage boolean génère un code XHTML
    <input type=“checkbox” />
    . Or c'est bien un champs de type radio qui est généré.

    2ème point :

    si j'utilise un champs de type change:checkboxinput avec comme attribut :
    <input change:checkboxinput="name mybeanfieldname" value="off" />

    ce champs est bien affiché comme je le souhaite, mais n'est pas présent dans ma variable f_mvc_Request $request , et sa valeur n'est donc pas prise en compte dans mon bean.

    J'ai essayé aussi d'entourer mybeanfieldname de quote, mais sans succès.

    Comment faire du coup ?

    Développe sous linux Ubuntu 12.04 LTS Desktop
    Projet ecommerce core 3.6.7
  • 81962.2 en réponse à 81962.1 écrit par Mathias

    22/11/2013 13:40


    Jean-Michel
    Titre : Community Manager
    Rang : Expert
    Bonjour Mathias,

    Effectivement il y a une erreur dans le wiki , par oubli de mise à jour, je viens de mettre à jour le tableau de la page concernée ;).

    Concernant l'absence du champ, il peut y avoir plusieurs raisons. On va donc chercher progressivement.

    1 - Le type de bean
    De quel type de bean parle-t-on ; généré directement à partir d'un document ou construit à partir d'une classe (comme dans "modules/order/lib/bean/IdentifyStepBean.class.php")? S'il s'agit du second cas, la déclaration de "mybeanfieldname" est-elle bien précédée des commentaires de typage?

    2 - Le bean et la balise form
    Quelque soit le type de bean, il ne faut pas oublier de l'indiquer dans la balise form et de fournir également le nom de classe.
    <form change:form="beanClass module_MaClasseObjet; beanName monObjet">


    Ainsi on peut être sûr que dans le code de traitement du formulaire "$monObjet" sera une instance de "module_MaClasseObjet".

    3 - Cas d'une propriété ne faisant pas partie du bean dans un formulaire
    Il est parfaitement possible d'ajouter un champ dans un formulaire de bean mais qui n'appartient pas au modèle du bean, dans ce cas pour la retrouver dans le traitement, tout dépend de la manière dont on la déclare dans le formulaire :
    <input type="checkbox" name="mybeanfieldname" checked="on" />

    Implique le code PHP suivant pour récupérer la valeur :
     // $this->getHTTPRequest() returns f_mvc_HTTPRequest
    $mybeanfieldname = $this->getHTTPRequest()->getParameter("mybeanfieldname");


    La déclaration suivante dans le formulaire :
    <input type="checkbox" name="monmoduleParam['mybeanfieldname']" checked="on" />

    Implique le code PHP suivant pour récupérer la valeur :
    // @var f_mvc_Request $request
    $mybeanfieldname = $request->getParameter("mybeanfieldname");


    4 - La méthode populate<NomBeanDansForm>Bean
    Il est possible que vous ayez un filtrage qui se fait au niveau de votre bean par l'intermédiaire de la méthode répondant à la charte de nommage décrite ci-dessus et qui demande à ce que la propriété "mybeanfieldname" ne soit pas prise en compte. Il faudrait donc modifier la manière dont le bean se fait peupler en modifiant cette méthode. Ce qui donnerait (selon la balise form un peu plus haut) :
    function populateMonObjetBean(module_MaClasseObjet $monObjet, $request)
        {
            $include = array('label', 'mybeanfieldname');
            // standard population process, excluding some properties
            $excludedProperties = array();
    
            return BeanUtils::populate($monObjet, $request->getParameters(), $include, $excludedProperties);
        }

    Ce qui a pour effet de peupler le bean avec uniquement les propriétés "label" et "mybeanfieldname" transmises par le formulaire.


    Je pense que parmi les points ci-dessus se trouve celui qui permettra de résoudre le problème rencontré.


    Pour une meilleure réponse, pensez à indiquer la version sur laquelle vous rencontrez des difficultés, ainsi que son type (CMS ou eCommerce core).
    Pour tout problème d'installation indiquez le nom de l'hébergeur et s'il s'agit d'un serveur mutualisé ou dédié.
  • 81962.3 en réponse à 81962.2 écrit par Jean-Michel

    22/11/2013 17:57


    Mathias
    Rang : Expert
    Hello Jean Michel,

    Merci pour tous ces détails.
    Pour être plus précis, j'ai étendu le document users_persistentdocument_user en l'injectant et en ajoutant :
    - company (string)
    - function (sring)
    - phone (string)
    - optin (boolean)
    - optintiers (boolean)

    Effectivement, il aurait été plus judicieux d'étendre le document users_persistentdocument_websitefrontenduser, vu que ça ne concerne que les utilisateurs FO, mais bon, le mal est fait et logiquement, grâce à l'héritage, le websitefronteduser bénéficie lui aussi de ces champs.

    J'ai surchargé dans mon thème le template :
     Users-Block-Register-Input.all.all.html


    et j'ai donc ajouté mes champs sur le formulaire :
    //je n'ai pas touché aux infos beanClass et beanName après surcharge
    <form id="registration-form" change:form="beanClass users_persistentdocument_websitefrontenduser; beanName user">
    
    [...] // les champs du formulaire initial
    // + mes champs de type String qui sont bien pris en compte si j'utilise change:field
        <li><input change:field="name company"/></li>
        <li><input change:field="name function"/></li>
        <li><input change:field="name phone"/></li>
    // + mes champs de type boolean qui ne sont pas pris en compte si j'utilise  change:checkboxinput
        <li class="option-li">
    	<input change:checkboxinput="name optin" checked="true" labeled="false" value="off"/>
    	<input change:label="withcolon false" for="optin" labeli18n="m.project.fo.registration-optin"/>
        </li>
        <li class="option-li">
    	<input change:checkboxinput="name optintiers" labeled="false" value="off"/>
    	<input change:label="withcolon false" for="optintiers" labeli18n="m.project.fo.registration-optintiers"/>
         </li>
    [...]// les champs hidden du formulaire et le bouton submit
    </form>
    


    Normalement, vu que j'utilise le un bean de document, je ne suis pas dans le cas3.
    Je n'ai pas trouvé dans la classe users_BlockRegisterAction, de méthode populateUserBean... du coup je ne pense pas non plus être dans le cas 4...

    Vois-tu la solution de ton côté ?

    Édité par Mathias 24/11/2013 00:31


    Développe sous linux Ubuntu 12.04 LTS Desktop
    Projet ecommerce core 3.6.7
  • 81962.4 en réponse à 81962.3 écrit par Mathias

    22/11/2013 18:05


    Mathias
    Rang : Expert
    Petite précision, je n'ai fait que surcharger le template indiqué, je n'ai pas injecté le block register du module user, je n'ai donc pas touché à quoi que ce soit côté PHP.

    Développe sous linux Ubuntu 12.04 LTS Desktop
    Projet ecommerce core 3.6.7
  • 81962.5 en réponse à 81962.4 écrit par Mathias

    28/11/2013 14:54


    Mathias
    Rang : Expert
    précision supplémentaire : si j'utilise pour mes 2 champs boolean, l'extension phptal change:field, mes champs sont biens pris en compte.

    Développe sous linux Ubuntu 12.04 LTS Desktop
    Projet ecommerce core 3.6.7
  • 81962.6

    29/11/2013 12:14


    Gaël Port
    Titre : Développeur RBS Change
    Rang : Expert
    Bonjour,

    Utilisez-vous le mode strict sur les (configuration projet modules/website/useBeanPopulateStrictMode par défaut à true sur les nouveaux projets) ?

    Si oui il faudra injecter le bloc pour compléter la méthode getUserBeanInclude() qui définit les champs pouvant être effectivement mis à jour par le bloc. Cette fonction a été introduite par la version 3.6.5 pour combler une faille de sécurité.
  • 81962.7 en réponse à 81962.6 écrit par Gaël Port

    29/11/2013 12:24


    Mathias
    Rang : Expert
    Etant donné que je suis en 3.6.5, j'imagine que cela vient de là...
    Je test ça et je te dis ;)

    Développe sous linux Ubuntu 12.04 LTS Desktop
    Projet ecommerce core 3.6.7
  • 81962.8 en réponse à 81962.7 écrit par Mathias

    29/11/2013 12:46


    Mathias
    Rang : Expert
    Bon je n'ai pas vraiment eu de succès... voici ce que j'ai implémenté.

    Je suis en 3.6.5, mais je n'ai pas la configuration mentionnée dans mon project.xml.
    Je l'ai donc (dans un 1er tps) ajoutée à la main.

    Puis, mon block qui inject le block register :
    <?php
    /**
     * project_BlockInjectRegisterAction
     * @package modules.project.lib.blocks
     */
    class project_BlockInjectRegisterAction extends users_BlockRegisterAction
    {
    	/**
    	 * @param f_mvc_Request $request
    	 * @param f_mvc_Response $response
    	 * @return String
    	 */
    	public function execute($request, $response)
    	{
    		return parent::execute($request, $response);
    	}
      
      /**
       * @return string[]|null
       */
      public function getUserBeanInclude()
      {
         if (Framework::getConfigurationValue('modules/website/useBeanPopulateStrictMode') != 'false'){
          $include = array('email', 'login','company', 'function', 'phone', 'optin', 'optintiers');
          $config = $this->getConfiguration();
          if ($config->getShowPersonalFields())
          {
            $include[] = 'titleid';
            $include[] = 'firstname';
            $include[] = 'lastname';
          }
          return $include;
         }
      return null;
      }
    }


    A la validation du formulaire, je fais un "var_export" de l'objet $request et voici l'output dans mes logs :
    website_BlockActionRequest::__set_state(array(
       'parameters' => 
      array (
        'website_FormHelper_relkey' => 'registration-form',
        'titleid' => '10820',
        'firstname' => 'qdf',
        'lastname' => 'qsdfsqdf',
        'email' => 'test@9sdf.com',
        'password' => 'abc123',
        'password_confirm' => 'abc123',
        'company' => '',
        'function' => '',
        'phone' => '',
        'beanId' => '-1',
        'website_BlockAction_submit' => 
        array (
          'registerb_10' => 
          array (
            'save' => 'Créer mon compte',
          ),
        ),
      ),
       'attributes' => 
      array (
        'invalidProperties' => 
        array (
        ),
      ),
       'moduleName' => 'users',
       'actionName' => 'register',
       'errors' => 
      array (
      ),
       'messages' => 
      array (
      ),
       'files' => 
      array (
        'name' => 
        array (
        ),
        'type' => 
        array (
        ),
        'tmp_name' => 
        array (
        ),
        'error' => 
        array (
        ),
        'size' => 
        array (
        ),
      ),
       'fileInstances' => NULL,
    ))
    


    Toujours aucune trace de mes champs optin / optintiers...
    A savoir que si j'enlève la condition sur la présence de la configuration useBeanPopulateStrictMode, afin de forcer la methode getUserBeanInclude(), j'ai toujours le même résultat...

    <UPDATE>
    Voici mon bean user que je "var_export" dans la méthode executeSave de mon block register. Les valeurs de optin / optintiers sont celles par défaut et ne représentent pas la saisie réalisée (false + false).
    users_persistentdocument_websitefrontenduser::__set_state(array(
       'm_websiteid' => NULL,
       'm_phone' => '',
       'm_function' => '',
       'm_company' => '',
       'm_optintiers' => false,
       'm_optin' => true,
       'password' => NULL,
       'generatepassword' => false,
       'm_author' => NULL,
       'm_authorid' => NULL,
       'm_creationdate' => NULL,
       'm_modificationdate' => NULL,
       'm_publicationstatus' => 'DRAFT',
       'm_modelversion' => '1.0',
       'm_documentversion' => 0,
       'm_startpublicationdate' => NULL,
       'm_endpublicationdate' => NULL,
       'm_metastring' => NULL,
       'm_titleid' => 10820,
       'm_firstname' => 'qdf',
       'm_lastname' => 'qsdfsqdf',
       'm_email' => 'test@9sdf.com',
       'm_login' => NULL,
       'm_passwordmd5' => NULL,
       'm_groups' => NULL,
       'm_lastlogin' => NULL,
       'm_lastping' => NULL,
       'm_changepasswordkey' => NULL,
       'm_persistentState' => 0,
       'm_id' => -1,
       'm_treeId' => NULL,
       'm_providerId' => NULL,
       'm_i18nInfo' => 
      I18nInfo::__set_state(array(
         'm_vo' => 'fr',
         'm_labels' => 
        array (
        ),
      )),
       'validationErrors' => NULL,
       'modifiedProperties' => 
      array (
        'titleid' => true,
        'firstname' => true,
        'lastname' => true,
        'email' => true,
        'company' => true,
        'function' => true,
        'phone' => true,
      ),
       'modifiedPropertyValues' => 
      array (
      ),
       'm_documentInverse' => NULL,
       'is_i18InfoModified' => false,
       'insertInTree' => true,
       '_parentNodeId' => NULL,
       'm_metas' => NULL,
       'metasModified' => false,
       'i18nVoObject' => NULL,
       'm_phone' => NULL,
       'm_function' => NULL,
       'm_company' => NULL,
       'm_optintiers' => NULL,
       'm_optin' => NULL,
    ))


    Penses - tu qu'une migration en 3.6.6 résoudra ce problème ?

    Édité par Mathias 29/11/2013 13:52


    Développe sous linux Ubuntu 12.04 LTS Desktop
    Projet ecommerce core 3.6.7
  • 81962.9 en réponse à 81962.8 écrit par Mathias

    30/11/2013 13:00


    Mathias
    Rang : Expert
    Yes ! Ticket Resolved :)

    J'ai réalisé une montée de version en 3.6.6, et depuis, plus quelques ajustements c'est désormais fonctionnel.
    Malheureusement je ne peux pas vraiment dire, avec certitude, si c'est la montée de version seule qui a débloqué la situation, ou si ce sont les quelques ajustements, ou les 2...

    Mais voici mes retours d'expérience.

    1 / Les champs de type Checkbox sont un peu filou, s'ils ne sont pas cochés, ils ne sont pas passés en paramètres POST. Du coup, il faut bien commencer par tester en cochant les cases plutôt que l'inverse ;)

    2 / Il ne faut pas, déclarer sa propriété "boolean" avec un default-value="true". Car, étant donné qu'il n'est pas passé en POST, par défaut, Change va lui affecter la valeur TRUE qd même. Cela nécessiterai donc de faire des traitements supplémentaires qui ne sont pas utiles. Autant utiliser la valeur checked="true" de la balise checkbox.

    3 / Dans le même esprit, pour ne pas faire de traitement supplémentaire côté PHP pour valoriser automatiquement le champs, je conseil de renseigner l'attribut obligatoire "value" du champs "checkbox" par la valeur "true". Comme ça, Change va automatiquement prendre en compte cette valeur sans avoir besoin de faire de traitements supplémentaires.

    Par rapport à ton message Gaël, j'ai bien dû ajouter la méthode getUserBeanInclude() :

    /**
       * @return string[]|null
       */
      public function getUserBeanInclude()
      {
          if (Framework::getConfigurationValue('modules/website/useBeanPopulateStrictMode') != 'false')
          {
            $include = array('email', 'login','company', 'function', 'phone', 'optin', 'optintiers');
            $config = $this->getConfiguration();
            if ($config->getShowPersonalFields())
            {
              $include[] = 'titleid';
              $include[] = 'firstname';
              $include[] = 'lastname';
            }
            return $include;
          }
          return null;
      }


    Mais désormais tout fonctionne !

    Merci !

    Développe sous linux Ubuntu 12.04 LTS Desktop
    Projet ecommerce core 3.6.7
  • 81962.10 en réponse à 81962.9 écrit par Mathias

    02/12/2013 13:02


    Gaël Port
    Titre : Développeur RBS Change
    Rang : Expert
    De mémoire il y avait deux version très rapprochées parce que certains commits n'étaient pas passés... c'était peut-être bien 3.6.5 et 3.6.6. Donc ce n'est pas exclus que ce soit bien cette mise à jour qui ait réglé le problème.
 
Merci de prendre connaissance et de respecter les règles des forums.
 
1471 membres
Aucun membre connecté