Archivo de la etiqueta: Drupal 6

Druplicon

Drupal: El “view” de un cck no está disponible cuando hago node_load() [Solución]

Cuando cargamos un nodo con node_load(), si quisiéramos hacer uso de la propiedad “view” de un campo CCK veríamos que la misma no existe:

$node = node_load(999);
var_dump($node->field_precio[0]);
 
array(2) {
  ["amount"]=> string(6) "100.00"
  ["currency"]=> string(3) "EUR"
}

Esto pasa porque CCK solo prepara esta propiedad cuando un nodo se esta por imprimir mediante node_view(). Si lo que necesitas es usar node_load() en lugar de node_view() la solución es inyectarle la propiedad “view” mediante la función que el mismo modulo de CCK utiliza:

$node = node_load(999);
$node->field_precio[0]['view'] = content_format("field_precio", $node->field_precio[0]);
 
var_dump($node->field_precio[0]);
 
array(3) {
  ["amount"]=> string(6) "100.00"
  ["currency"]=> string(3) "EUR"
  ["view"]=> string(11) "100.00 EUR"
}

bye!.

Druplicon

Drupal 6: db_last_insert_id() no funciona correctamente [Solución]

Es curioso como un error de este tipo se les llega a escapar y entra en producción.

¿Por qué no funciona? porque a algun iluminado se le ocurrio que solo lanzando la query ‘SELECT LAST_INSERT_ID()’ sin especificar la tabla sobre la que se quiere obtener el ultimo registro insertado Drupal iba automagicamente a obtenerlo…. ERROR. Ah y por cierto incluso la query ‘SELECT LAST_INSERT_ID()’ bien armada también suele fallar.

/**
 * Returns the last insert id.
 *
 * @param $table
 *   The name of the table you inserted into.
 * @param $field
 *   The name of the autoincrement field.
 */
function db_last_insert_id($table, $field){
    return db_result(db_query('SELECT LAST_INSERT_ID()'));
}

La función que soluciona este problema es esta:

/**
 * Version modificada del analogo de drupal que soluciona un problema comentado en foros.
 *
 * @param string $table tabla sobre la que se quiere obtener el ultimo id insertado
 * @param string $field cual es la columna que tiene el id
 * @return int
 */
function custom_db_last_insert_id($table, $field) {
    $result = db_query("SELECT $field FROM {$table} ORDER BY $field DESC LIMIT 1");
    $row = db_fetch_object($result);
    return $row->$field;
}

Solo resta agregar que uso esta solución hace mas de un año y funciona bien.

Druplicon

Drupal: Error “HTTP request status”

Si ves que drupal te dice en el reporte de estado (admin/reports/status) algo como esto:

Your system or network configuration does not allow Drupal to access web pages, resulting in reduced functionality. This could be due to your webserver configuration or PHP settings, and should be resolved in order to download information about available updates, fetch aggregator feeds, sign in via OpenID, or use other network-dependent services.

Podes decirle a Drupal que ignore este error poniendo la siguiente linea al final del archivo settings.php:

$conf[‘drupal_http_request_fails’] = FALSE;

Al que le interese profundizar mas en el asunto aca esta el hilo:

http://drupal.org/node/245990


PD: lo estoy ignorando al error porque en mi servidor si hay comunicación y aunque Drupal me dice que no la hay, el mismo es capaz de avisarme cuando hay actualizaciones… curioso.

Druplicon

Drupal: Porque usar Drupal.behaviors en lugar de $(document).ready();

Durante mucho tiempo estuve usando $(document).ready(); para poner mi js en Drupal, y funcionaba la mar de bien. Esto me permitía ejecutar javascript inmediatamente después que el DOM estuviera cargado evitando así errores de referencias a objetos que todavía no existieran al querer manipularlos.

Ahora bien, hay un problema que vamos a encontrar por medio de un ejemplo simple:

Si tuviéramos un listado de nodos y a ese listado hiciéramos que al pinchar sobre sus enlaces hiciera un alert de su atributo “title” usando jQuery:

jQuery(document).ready(function($) {
    $("#listado_de_nodos a").click(function(e) {
        alert($(this).attr("title"));
    });
});

¿Qué pasa si por medio de AJAX se agregaran nuevos nodos? te lo digo, que no reaccionarían al hacer click sobre ellos, y es por que el método .click() de jQuery se ejecuta una sola vez en busca de elementos que macheen con su criterio y una vez finalizado ya está, no hace mas. Es un comportamiento de lo mas entendible ya que imaginemos que estuviera escaneando constantemente por nuevos elementos ese selector mas los otros 50 que estemos usando para hacer mas cosas…. Google Chrome lo soportaría sin apenas darle carga al procesador y RAM, pero piensen en la basura de IE…..

Perdonen que me vaya por las ramas, como les decía, dado el problema que se planteo para el listado de nodos que di como ejemplo, se implemento una solucion (bueno cubre mas problemas pero este es de los mas comunes) la solución fue usar al objeto Drupal.behaviors a modo de controlador. Drupal.behaviors relanza todas las funciones que almacena por cada vez que se lance una petición AJAX, dándonos la oportunidad de re procesar cosas. Así pues en el ejemplo anterior lo podemos poner dentro de un behavior para poder aplicar nuestra funcionalidad incluso a los nuevos elementos provenientes de la petición:

Drupal.behaviors.alertarEnlaces = function(context) {
    $("#listado_de_nodos a").click(function(e) {
        alert($(this).attr("title"));
    });
}

Como ven lo único que hay que reemplazar en nuestros actuales ficheros de javascript es jQuery(document).ready(function($) {}) por Drupal.behaviors.alertarEnlaces = function(context) {} y no se preocupen por el hecho de que su código este ahora asignado dentro de una función(“Drupal.behaviors.alertarEnlace() “), porque esta se ejecuta solita, y veanlo incluso como una ventaja, pueden invocarla ustedes mismos cuando quieran ademas.

Druplicon

Drupal: Cambio o actualización masiva de alias con Pathauto

(Antes de que leas los primeros párrafos, que sepas que hay dos soluciones así que lee todo) :)
Un problemita con el que me di hoy es que tenía que cambiar la estructura de las URL de un Content-type, conservando las creadas anteriormente…. ¿y saben que? no hay una opción en la configuración de Pathauto que haga justamente eso:
No dije que no existe, solo que no esta ahí. por raro que parezca, los creadores de Pathauto en lugar de poner entre las opciones generales esta opción, como todas las demás, la han puesto un poco escondida. Y la encontré, estaba escondida en la gestión de contenido (admin/content/node) entre las opciones de acciones masivas:
Content update url alias
Ahora que sabemos donde esta solo tenemos que aplicar un filtro para para que solo se vean los nodos de un determinado Content-Type, marcar todos los de esa pagina, seleccionar la acción “Update url alias“, y así en todas las paginas subsiguientes (si es que las hay).
Hasta acá la solución mas “ligera” porque no hace falta ningún modulo especial para esta tarea siempre y cuando no tengas miles de nodos.
En el caso de que SI tengas un huevo montón de nodos, vas a necesitar de la ayuda de “Views” y del modulo “Views Bulk Operations“.
Views trae habilitada por defecto una vista llamada “admin_content(admin/content/node2) que viene a ser la versión mejorada del gestor de contenidos que viene por defecto en Drupal (el que usamos en la primera solución).
Lo anterior sumado a que “Views Bulk Operations” nos da la capacidad de aplicar acciones masivas a todo lo que views pueda listar…
A la solución: Seguí estos pasos para configurar “Views Bulk Operations” / Pathauto y Views para que operen armoniosamente:
Eso claramente nos va a ahorrar una ingente cantidad de tiempo a la hora de actualizar si tenemos miles de nodos.
Chau.
tomcat-logo

Cerrar, bloquear o restringir el puerto 8080 en Apache Solr / Tomcat 6

Si instalaste un Apache Solr y lo estas usando por medio de Drupal 6, otro CMS o una propia implementación, seguramente no te interese que dicho servicio se pueda acceder por medio del puerto 8080 (o el puerto asignado en tu servidor para Tomcat).

Bueno, un ejemplo es mucho mas claro que casos hipotéticos, así que les planteo mi necesidad:
Tengo un Ubuntu con un Drupal configurado con el modulo “apachesolr” que se conecta a localhost en el puerto 8080. Hasta ahí todo normal, el problema es que si a alguien se le ocurre tipear la URL de mi pagina montada en Drupal pero por el puerto 8080… va a poder ver Tomcat, y lo que es mas peligroso, Apache Solr y su administrador (Solr carece de mecanismos de seguridad porque los delega a Tomcat).

Bueno en el ejemplo que comente antes tenemos una solución ideal: Capar el puerto 8080 para que solo se pueda acceder por “localhost”.

Para lograr nuestro cometido solamente tenemos que editar un XML: “server.xml“:

sudo gedit /etc/tomcat6/server.xml

Busca la linea:

<connector port="8080" protocol="HTTP/1.1"
       connectionTimeout="20000"
       redirectPort="8443"></connector>

Comentarla:

<!--
<Connector port="8080" protocol="HTTP/1.1"
       connectionTimeout="20000"
       redirectPort="8443" />
-->

Y poner por dejado de la linea anterior lo siguiente:

<connector port="8080"
        address="127.0.0.1"
        maxHttpHeaderSize="8192"
        maxThreads="15"
        minSpareThreads="2"
        maxSpareThreads="7"
        enableLookups="false"
        redirectPort="8443"
        acceptCount="100"
        connectionTimeout="20000"
        disableUploadTimeout="true"
        compression="on"
        compressionMinSize="0"
        noCompressionUserAgents="gozilla, traviata"
        compressableMimeType="text/html,text/xml"></connector>

Guarda los cambios y reinicia Tomcat:

sudo service tomcat6 restart

Gualá. Comprobemos que haya funcionado:

Primero mira cual es la ip que tiene tu servidor haciéndole ping:
Usa “ifconfig” para ver la ip, que seguramente tenga la pinta “192.168.1.xxx” o “10.0.2.xx”

bien, ahora suponiendo que seguis en Ubuntu (es mi ejemplo y uso Ubuntu :) ) abri un navegador y proba a acceder a:

http://localhost:8080

y a:

http://192.168.1.xxx:8080 (las xxx reemplazalas por el resto de tu IP).

Como pudiste ver, podes acceder a localhost pero no por medio de la IP, incluso si probas a acceder a esa IP desde otra maquina/ordenador/PC/ipad/ipod/android/o-lo-que-sea XD

Hemos acabado.

BD

Resetear/recuperar la contraseña del usuario “admin” con phpMyAdmin

NOTA: esta solución es útil para cualquier sistema que almacene las claves de usuarios en MYSQL por medio de MD5 o SHA1.

Hecha la aclaración, comento el caso concreto de Drupal que nos va a servir de idea para el resto:

Si no te acordás la clave de “admin” en Drupal y tenes acceso a phpMyAdmin, lo único que tenes que hacer es abrir la base de datos, localizar al usuario “admin” dentro de la tabla “usersy editarlo. Una vez que lo tengas abierto tenes que poner la clave nueva en el campo “pass”. Por ultimo solo queda decirle a phpMyAdmin que esa clave la guarde en MD5 (ver imagen).

Listo. Guarda los cambios y accede a tu usuario “admin” como de costumbre.

Druplicon

Drupal 6: El tag http-equiv=”Content-type” de
sale duplicado

Un curioso bug en Drupal y de facil solucion. Solamente tenes que poner el siguiente snippet en el template.php de tu theme o bien en algún modulo de tu propia factoría :)

function TU_THEME_preprocess_page(&$vars) {
    $matches = array();
    preg_match_all('/(]*>)/', $vars['head'], $matches);
    if (count($matches) >= 2) {
        $vars['head'] = preg_replace('/]*>/', '', $vars['head'], 1); // strip 1 only
    }
}
internet-explorer-logo

Algunos CSS no cargan en Internet Explorer

Me rompí un poco la cabeza con este asunto: Hago unas modificaciones que se ven mas que bien en todos los navegadores menos en IE como siempre, y por ello tengo un ie.css puntual para hacer todas las cosas raras que se suelen hacer con CSS para que IE trague.

El problema me lo di con que Internet Explorer 7 (no recuerdo si el 8 también) no reflejaba los cambios de mi CSS destinado a el…. :S

Pero ya se cual es el problema y como no, la solución ;)

El problema es que Internet Explorer por algún misterioso motivo solo carga hasta 31 CSS (los <style> inline también cuentan o_O), y mi CSS especial ya estaba por el puesto 32…

La primera solución que se me ocurrió es activar la compresión de CSS para que se haga uno o dos CSS, pero lo que tiene de malo eso es que si estas maquetando te vas a querer pegar un tiro a la 10º vez que tengas que borrar el cache para ver si el texto que estas maquetando se termina de ver bien en la bass.. Internet Explorer.
Así que fui a darme una vuelta por los módulos de Drupal… Bingo. Hay un modulo que nos salva las papas. Se llama “IE CSS Optimizer”, y lo que hace básicamente es añadir dos opciones más a la compresión de los CSS:

Y lo que hace es algo de lo más simple. Comprime todo el CSS en un archivo pero sin cachearlo.

Con este modulito ya no vas a tener que preocuparte del rarísimo límite de 31 archivos.

Una ultima anotación a todo esto es que andar va a andar bien, pero no vayas a olvidar de poner de nuevo la configuración de la compresión del CSS a “Full optimization” para producción.

Drupal 6: devel generate y “Access denied”

Estas son las cosas que mas me gustan de drupal: Resolver sus “misterios”.

Resulta que estoy haciendo cientos de miles de nodos (no es broma o_O) con el modulo Devel generate para hacer unas pruebas, y cuando los creo de a 10.000 no hay problema, se tarda un huevo en hacerlos pero el batch que lanza este modulo no falla.

Pero la historia cambia cuando quiero dejar haciendo la friolera de 500.000 (quinientos mil) XD.

Bueno Marcelo deja de dar vueltas y decime que carajo pasa que no me anda bien devel generate!: ok, te cuento que resulta que Devel generate tanto como cualquier otro modulo que haga uso de batch, almacena dicho batch en la tabla correspondiente en una sola fila, osea que si son 10 ciclos de batch almacena los diez en una sola fila asi como si son 500.000. El problema se hace evidente en este punto: Me estoy excediendo en el limite que mysql tiene previsto para el envió de packets de datos.

Mysql por defecto viene configurado para recibir por fila 1MB. y esta es la parte donde les muestro esa imagen que vale mas que mil palabras :)

35.2 MB de batch…

La solución: aumentar el limite que tiene mysql claro :)

NOTA: ni en broma hagan esto en un servidor de producción salvo que sean un DBA o por lo menos tengan una clara idea de las consecuencias que implica hacer algo asi.

Para aumentar el limite simplemente tenes que seguir estos pasos: Drupal 6 XAMPP Windows XP y “MySQL Server has gone away”