AnsweredAssumed Answered

Formularios de búsqueda dependiendo de los grupos en Share

Question asked by nemrp on Apr 27, 2011
Latest reply on Apr 4, 2012 by wgonzalez
Buenas.

Voy a realizar este aporte, aunque espero encontrarme con modificaciones y críticas (constructivas :D). Espero que pueda servir.

· Aplicación: Alfresco Share 3.4.0.

· Problema: Presentar en la pantalla de búsqueda avanzada los distintos formularios de búsqueda dependiendo de los grupos a los que pertenezca el usuario.

· Precondición:
  1. Debe tenerse previamente creado un tipo de contenido con sus metadatos asociados.

  2. Los nombres de los grupos deben ser iguales que los identificadores de los formularios de búsqueda.
· Pasos:
  1. Crear un tipo de contenido
  2. Para esto hay muchos tutoriales que nos ayudan a realizarlo. Yo me encontré con varios problemas al hacerlo para Alfresco Share y que éste mostrara los formularios de búsqueda asociados a los mismos. Más detalles en este hilo. Los archivos que importan para este caso son los siguientes:

    · share-config-custom.xml (\shared\classes\alfresco\web-extension\).

    <!– Viewing Content Models in the Advanced Search –>   
    <config replace="true" evaluator="string-compare" condition="AdvancedSearch">
         <advanced-search>
              <!– Forms for the advanced search type list –>
              <forms>
                   <!–
                   The 'form' config element contains the name of the model type
                   of the form to display.
                  
                   The element supports the following optional attributes:
                        id = form id, the id of "search" will be assumed if not set
                        label = label text to display - defaults to model type if
                        not set
                        labelId = I18N message id of label text to display
                        description = description text to display
                        descriptionId = I18N message id of description text to
                        display
                   –>
                   <form labelId="search.form.label.cm_content"
                   descriptionId="search.form.desc.cm_content">cm:content</form>
                  
                   <form labelId="search.form.label.cm_folder"
                   descriptionId="search.form.desc.cm_folder">cm:folder</form>

                   <!– Definition of new Content Type: MyContentType –>
                   <form id="search.form.id.myModel_myContentType"
                   labelId="search.form.label.myModel_myContentType"
                   descriptionId="search.form.desc.myModel_myContentType">
                   myModel:myContentType
                   </form>
              </forms>
         </advanced-search>
    </config>
    <!– –>

    <!– Definition of new Content Type: MyContentType –>
    <config evaluator="model-type" condition="myModel:myContentType">
         <forms>
              <!– Search form –>
              <form id="MY_GROUP_FORM">
                   <field-visibility>
                        <show id="cm:name" />
                        <show id="cm:title" force="true" />
                        <show id="cm:description" force="true" />
                        <show id="mimetype" />
                   </field-visibility>
                   <appearance>
                        <field id="mimetype">
                             <control
                             template="/org/alfresco/components/form/controls/
                             mimetype.ftl" />
                        </field>
                   </appearance>
              </form>
         </forms>
    </config>
    <!– End of Definition of new Content Type: MyContentType –>
    NOTA: por la precondición es muy importante que el atributo "id" del objeto "form" coincida con el nombre del grupo creado en Alfresco Share.

    · myModel.properties (\shared\classes\alfresco\messages\).


    # Definition of new Content Type: MyContentType
    search.form.id.myModel_myContentType=MY_GROUP_FORM
    search.form.label.myModel_myContentType=My search form
    search.form.desc.myModel_myContentType=Description of my search form.
    # End of Definition of new Content Type: MyContentType
    NOTA: por la precondición es muy importante que el atributo "search.form.id.myModel_myContentType" coincida con el nombre del grupo creado en Alfresco Share.

  3. Modificación del script de carga de formularios
  4. Para ello hay que realizar una copia del archivo "advsearch.get.js", que se encuentra en "\webapps\share\WEB-INF\classes\alfresco\site-webscripts\org\alfresco\components\search\" y ponerla en "\shared\classes\alfresco\web-extension\site-webscripts\org\alfresco\components\search\".

    Dentro de la función "main" de dicho archivo en primer lugar realizo la carga de los grupos del usuario y "limpio" los nombres. Esto lo realizo porque en los nombres de los grupos añado las siglas "ADMIN", "COLAB", etc, para identificar si es un grupo de administradores, colaboradores, etc. Además , se "limpian" aquellos nombres de grupos que comienzan por "sites_" (se explica en el mismo código).

    Dependiendo de cada caso se necesitará una "limpieza" distinta o no será necesaria realizarla.


    // Declaracion de variables.
    var groups = new Array();
    var groupsNames = new Array();
    var groupName;
    var length;
    var status = false;
    var result = remote.call("/api/people/" + stringUtils.urlEncode(user.name) + "?groups=true");
       
    // Se obtienen los grupos del usuario y se guarda el nombre de los mismos en
    // otro array. No entran aquellos nombres que comiencen por "sites_", ya que
    // estos hacen referencia a permisos de Share y no a grupos concretos.
    if (result.status == 200 && result != "{}") {
         status = true;
         var users = eval('(' + result + ')');
         groups = users.groups;
         length = groups.length;
         var j = 0;
          
         for (var i = 0; i < length; i++) {
              groupName = groups[i].displayName;

              if (groupName.lastIndexOf("site_") < 0) {
                   groupsNames[j] = groups[i];
                   j++;
              }
         }
          
         length = groupsNames.length;
         for (var i = 0; i < length; i++) {
              groupName = groupsNames[i].displayName;
              j = groupName.lastIndexOf("_");
              var nameLength = groupName.length;
              var groupNameMin = groupName.substr(j, nameLength);
              groupNameMin = groupNameMin.toUpperCase();
             
              if (groupNameMin.indexOf("ADMIN") > 0 ||
                   groupNameMin.indexOf("COLAB") > 0 ||
                   groupNameMin.indexOf("CONTR") > 0 ||
                   groupNameMin.indexOf("CONSU") > 0) {
                   groupsNames[i].displayName = groupName.substr(0, j);
              }
         }
    }
    A continuación se incluye dentro del segundo bucle "for" la casuística que permite valorar qué tipo de formulario se está tratando, si concuerda o no con el grupo del usuario y si debe presentarse aún no habiendo concordancia.

    Además, he añadido algunas comprobaciones adicionales para hacer la carga de formularios (creación del objeto en la lista definitiva "searchForms") más rápida sin tener que realizar comprobaciones en ese momento. Todo esto está comentado en el código.


    // fetch the request params required by the advanced search component template
    var siteId = (page.url.templateArgs["site"] != null) ? page.url.templateArgs["site"] : "";
       
    // get the search forms from the config
    var formsElements = config.scoped["AdvancedSearch"]["advanced-search"].getChildren("forms");
    var searchForms = [];
      
    for (var x = 0, forms; x < formsElements.size(); x++) {
         forms = formsElements.get(x).childrenMap["form"];
         
         for (var i = 0, form, formId, label, desc; i < forms.size(); i++) {
              form = forms.get(i);
            
              // get optional attributes and resolve label/description text
              formId = form.attributes["id"];
             
              // Se anade esta casuistica para dar un valor desde el inicio a la variable
              // "formId".         
              if (formId == null || formId == "") {
                   formId = "search";
              } else {
                   formId = msg.get(formId);
              }

              // Se anaden las siguientes casuisticas para evitar que las variables
              // "label" y "desc" queden vacias.
              label = form.attributes["label"];
              if (label == null || label =="") {
                   label = form.attributes["labelId"];
                   if (label != null && label != "") {
                        label = msg.get(label);
                   } else {
                        label = form.value;
                   }
              }
            
              desc = form.attributes["description"];
              if (desc == null || desc == "") {
                   desc = form.attributes["descriptionId"];
                   if (desc != null && desc != "") {
                        desc = msg.get(desc);
                   } else {
                        desc = "No existe una descripcion para este aspecto.";
                   }
              }
    Y por último, continuando dentro del segundo bucle "for", se almacenan los formularios de búsqueda, teniendo en cuenta que sólo aquellos que coincidan con los grupos del usuario y los dos que vienen por defecto (para buscar contenidos y para buscar carpetas) serán los elegidos.


    // Se anade el siguiente bloque para evitar que se almacenen los formularios de busquedas
    // que no correspondan con los grupos a los que pertenece el usuario.
    if (label == "Contenido" || label == "Carpetas") {
         // create the model object to represent the form definition
         searchForms.push(
         {
              id: formId,
              type: form.value,
              label: label,
              description: desc
         });
    } else {
         if (status) {
              length = groupsNames.length;
             
              for (var m = 0; m < length; m++) {
                   groupName = groupsNames[m].displayName;
                      
                   if (groupName == formId) {
                        // create the model object to represent the form definition
                        searchForms.push(
                        {
                             id: formId,
                             type: form.value,
                             label: label,
                             description: desc
                        });
                   }
              }
         } else {
              // create the model object to represent the form definition
              searchForms.push(
              {
                   id: formId,
                   type: form.value,
                   label: label,
                   description: desc
              });
         }
    }
· Puntos positivos:
  1. La lógica está en un único sitio

  2. Se evita utilizar código en la plantilla "ftl" dejando toda la lógica al script. Realicé la programación haciendo lo contrario (código en el "ftl") y no funcionaba correctamente.
  3. Modificación siempre en los mismos archivos

  4. Sólo hay que mantener archivos que se deben modificar cuando se quiera añadir nuevos formularios. Es decir, cada vez que se quiera dar de alta un nuevo formulario para un nuevo tipo de contenido, hay que modificar los mismos archivos que para la búsqueda avanzada ("share-config-custom.xml" y "myModel.properties"), a no ser que se cree un nuevo modelo.
· Puntos negativos:
  1. Anclaje del código

  2. Hay secciones de código que están realizadas de manera directa. Es decir, se pregunta, por ejemplo, por "Carpetas" o por "Contenido".
  3. Nombres de los grupos / identificadores

  4. Hay que tener muy en cuenta que el nombre del grupo ha de ser el mismo que el especificado en distintas partes de los archivos implicados. Esto conlleva que el administrador de Alfresco Share debe conocer qué nombre se le da desde la parte de desarrollo; o lo inverso, los desarrolladores deben conocer qué nombre se le da al grupo.
  5. Caracteres en los nombres de los grupos

  6. Es recomendable que los nombres de los grupos sean esquemáticos y evitar tíldes y caracteres especiales.
· Agradecimientos: Evidentemente, sin este foro no me hubiera sido posible realizar esta labor. Así pues, muchas gracias a tod@s.

Un saludo :wink:.

Outcomes