Obtención de cantidad de registros diferentes por campo en MySQL

A continuación, vamos a aprender cómo obtener el número total de registros diferentes que contengan un campo con el mismo valor en MySQL mediante una única consulta. Por ejemplo, supongamos el caso en que tenemos una base de datos para una biblioteca y exista una tabla de “libros” que contenga la siguiente información:
El objetivo es obtener la cantidad de libros que existen por cada categoría. Esto lo podemos realizar de la siguiente forma (asumiendo que el nombre de la tabla es “biblioteca”):
La consulta anterior nos dará un resultado de aquella cantidad, ordenada de manera descendiente de la siguiente forma:

Subir archivos desde un formulario con PHP

A continuación, vamos a ver cómo subir archivos e imágenes desde un formulario web haciendo uso de PHP. Para esto, necesitamos primero crear un formulario simple en HTML de la siguiente forma:
Hay que tener en cuenta lo siguiente:
  • El método de envío del formulario es de tipo POST
  • Debemos indicar la propiedad “enctype” con el valor “multipart/form-data” para poder subir archivos e imágenes. Si es que no agregamos esto, no se podrá subir nada
Luego, debemos generar el código PHP el cual se encargará de capturar y procesar la información enviada desde el formulario. Esto lo podemos hacer de la siguiente forma:
Debemos notar que la variable global $_FILES nos entrega la lista de archivos subidos. En este caso, como nuestra subida era múltiple y se llamaba “file-1[]”, desde PHP la vamos a leer “file-1”. Esta contendrá todas las propiedades de las imágenes subidas dentro de cada índice “tmp_name“, “name“, etc. Dentro de cada uno de estos índices, vamos a tener un arreglo con la información de cada imagen subida. Además, en la variable $carpeta estamos indicando dónde, en nuestro ordenador, serán subidas las imágenes. Y con la variable $subir, le indicamos el nombre que tendrá nuestra imagen al ser subida.

Archivos involucrados en el Woocommerce Cart (Carrito de Compras de Woocommerce)

Si es que deseamos editar el layout de Woocommerce y la apariencia del mismo, podemos modificar las plantillas que este mismo trae. Usualmente, si es que revisamos el plugin, vamos a encontrar estos archivos en la carpeta llamada templates. Sin embargo, no es recomendable editar estos archivos de manera directa, pues puede generar inconvenientes en un futuro cercano. Por ejemplo, si es que Woocommerce se actualiza, perderemos los cambios realizados (pues los archivos se sobre-escribirán).
En caso queramos modificar el carrito de compras de Woocommerce (Woocommerce Cart), debemos ir a la siguiente ruta:
Donde encontraremos los siguientes archivos:
  • shipping-calculator.php
    • Sección relacionada a la calculadora de envío (usualmente a la derecha)
  • proceed-to-checkout-button.php
    • Botón de continuar a la ventana de pago
  • mini-cart.php
    • Plantilla utilizada para el Widget de Carrito de Compras
  • cross-sells.php
  • cart-totals.php
    • Resumen de totales y montos del carrito de compras (usualmente a la derecha)
  • cart-shipping.php
    • Resumen del método de envío del carrito de compras
  • cart-item-data.php
    • Información de los items del carrito de compras
  • cart-empty.php
    • Mensaje cuando el carrito de compras está vacío
  • cart.php
    • Archivo base para el carrito de compras
Todos estos archivos componen el carrito de compras y he dejado una pequeña descripción de cada uno de ellos debajo de su nombre.

Trabajando con AngularJS y Selects

En esta ocasión, vamos a ver un ejemplo práctico en el que tenemos 2 selects de HTML simples y queremos integrarlos con AngularJS, de tal manera que el segundo select dependa de lo que se haya seleccionado en el primero. Para poder realizar esto, tienemos varias alternativas. Entre las dos que más relevantes pueden ser, están las siguientes:
  • Utilizar la directiva ng-change para asignar una acción al momento de que cambia el valor del primer select (la que utilizaremos).
  • Utilizar $watch para ver cuándo cambia el valor del primer select.
Además, tenemos que tener en cuenta que en AngularJS tenemos diferentes opciones para generar los “option” de ambos select. En este caso, tenemos dos alternativas:
  • Uso de la directiva ng-options (la más recomendable y la que utilizaremos)
  • Uso de ng-repeat para generar options
La forma en que funciona la directiva ng-options podemos encontrarla en el siguiente enlace: https://docs.angularjs.org/api/ng/directive/ngOptions
De todas maneras, vamos a ver su uso práctico unas líneas más abajo. En resumen, para saber cómo funciona ng-options tenemos que tener en cuenta los siguientes conceptos base:
  • Todo select tiene 0 o más options
  • Cada option tiene un “value” que es el valor que se envía cuando selecciono una opción
  • Cada option tiene un “label” que es el valor que se muestra al usuario
Teniendo en cuenta lo anteriormente mencionado, podemos entender mejor ng-options. La sintaxis es la siguiente:
Donde:
  • VALUE es el “value” que queremos que se envíe cuando selecciono una opción
  • LABEL es el “label” que es el valor que se muestra al usuario
  • ELEMENT es el elemento actual del ARRAY que estamos recorriendo
  • ARRAY es el arreglo que vamos a recorrer
Por ejemplo, con la directiva ng-change, podría ser así (asumiendo que el primer select tiene como **ng-model=”select1″** y el segundo select tiene como **ng-model=”select2″**).
Y en el controlador:

Encriptación de contraseñas y Bases de Datos

Usualmente cuando pensamos en guardar una contraseña encriptada se nos ocurre un tipo de dato común y corriente (cadena de texto o String). El equivalente a este tipo de campos en una base de datos usualmente es un VARCHAR. Sin embargo, debemos tener en cuenta que la mayoría de los métodos más comunes de encriptación de contraseñas (MD5 y SHA1) tienen longitudes estáticas (pues son hashes con bits resultantes iguales) y existen diversas formas las cuales nos permiten ahorrar espacio para guardarlos en una base de datos en lugar de utilizar un VARCHAR.
Por ejemplo, si utilizamos MD5, sabemos que la longitud siempre será de 128-bits. Si utilizamos SHA1 sabemos que la longitud siempre será de 160-bits. Es por esto, que en lugar de guardarlos como VARCHAR podemos utilizar CHAR de tamaño estático. Por ejemplo, MD5 siempre tendrá el tamaño de 32 caracteres y SHA1 siempre tendrá el tamaño de 40 caracteres.
Inclusive podemos guardar los datos como Binary si es que queremos ahorrar mucho más espacio. Una forma fácil de convertir de bit a Binary es dividir la lontitud del hash entre 8 de la siguiente forma:
  • MD5 = 128-bit -> Binary(16)
  • SHA1 = 160-bit -> Binary(20)
Cabe recordar que en la mayoría de casos esta optimización realmente no es importante o relevante. Por ejemplo, si tenemos una tabla pequeña con una cantidad de registros pequeña (menos de 10 mil registros) realmente no influirá mucho en el espacio. Sin embargo, cuando empecemos a trabajar con millones de registros, es probable que queramos aplicar este consejo.