Diferencias entre isset(), empty() e is_null() en PHP

Entre las múltiples funciones que existen en PHP para testear los valores de una variable encontramos tres que resultan de gran ayuda para conocer si una variable está definida y/o es nula, que son isset(), empty() e is_null(). Rehaciendo código de alguna gente en mantenimientos o actualizaciones de proyectos me he encontrado con dos hechos:

  1. Muchos no las usan (y luego vienen los errores por usar una variable vacía)
  2. Muchos no tienen muy claro cómo y cuándo usarlas

La cosa es muy sencilla si se explica bien. Vamos a ver en qué consisten las tres, y veréis qué rápido lo entendéis:

  • isset(): Determina si una variable ha sido definida y no es nula. Devuelve FALSE en caso de le pasemos una variable sin definir, una variable definida pero sin valor o con el valor puesto a null, y en el resto de casos devuelve TRUE.
  • empty(): Determina si la variable tiene un valor vacío, por llamarlo de alguna forma. En este caso devuelve TRUE en muchos supuestos: una cadena vacía (es decir «», si es una cadena con un espacio en blanco tal que » » devolverá FALSE), un número 0 (sea tanto un entero, un float o una cadena con el número cero tal que «0»), una variable con el valor FALSE, una variable con el valor NULL, una variable definida pero sin valor y un array vacío. Al contrario que isset(), no puede evaluar variables que no hayan sido definidas.
  • is_null(): En cierto modo es la complementaria a isset(), ya que devuelve TRUE en caso de que la variable sea NULL o que sea una variable definida pero sin valor, y en el resto de los casos FALSE. La diferencia es que no puede evaluar variables que no estén definidas, provocará un error.

Como podéis ver no es especialmente complicado comprender el funcionamiento de estas tres funciones, y su uso os salvará de muchos quebraderos de cabeza. Por ejemplo trabajando con variables pasadas por formularios o recogidas de una tabla de base de datos que acepte nulos, que todavía hay gente que va a lo loco, así, sin comprobación ni condón… y luego vienen las rupturas en el código.

Envío masivo de email a lista de contacto con PHPMailer

Seguimos con el PHPMailer tras la introducción y la entrada sobre usar Gmail. Ahora, y recordando un poco el ejemplo de cómo automatizar acciones con cURL, vamos a ver la forma de enviar un correo a una lista de direcciones guardada en una base de datos.

La idea es simple, si recordáis cómo era el script de php de los anteriores ejemplos todo consiste en hacer lo mismo pero con una llamada a la base de datos y un bucle de envíos. En el ejemplo de abajo ya podéis ver el código, explicado punto por punto. en este caso no voy a usar el ejemplo que viene en los docs de la librería, porque está anticuado, usando mysql en lugar de mysqli (es más, creo que lo voy a subir a GitHub):

<?php
//lo primero cargar la librería
require '../PHPMailerAutoload.php';
//lo segundo, crear el objeto mail
$mail = new PHPMailer();
//Vamos a meter el cuerpo (cargado desde un html externo) en una variable
$body = file_get_contents('contents.html');
//definimos el uso de smtp
$mail->isSMTP();
//definimos el servidor que aloja nuestro correo
$mail->Host = 'smtp.tuserver.com';
//activamos la autenticación smtp
$mail->SMTPAuth = true;
//Con esta línea dejamos abierta la conexión al servidor smtp
$mail->SMTPKeepAlive = true; 
//Definimos la seguridad, si nuestro server lo permite lo mejor es usar tls
$mail->SMTPSecure = 'tls';
//el puerto cambia según la seguridad. Para tls este, para ssl 456 y sin seguridad el 25
$mail->Port = 587;
//definimos usuario y contraseña
$mail->Username = 'tucorreo@tudominio.com';
$mail->Password = 'tu contraseña';
//ahora definimos remitente y si hace falta, réplica
$mail->setFrom('miwebe@midominio.com', 'Lista');
$mail->addReplyTo('miwebe@midominio.com', 'Lista');

$mail->Subject = "Ejemplo de lista con phpmailer";

//Vamos ahora a crear un objeto de conexión a la base de datos
//Tras eso, vamos a recuperar los datos que necesitamos:
$mysqli = new mysqli('server', 'username', 'password', 'db');
$mysqli->set_charset("utf8")
$result = $mysqli->query("SELECT nombre, email FROM mailinglist");

//ahora en bluce vamos recorriendo los resultados y enviando correos

while ($row = $result->fetch_array()) {
    $mail->AltBody = 'Para ver el menasje, please use un  visor de email compatible con HTML';
    $mail->msgHTML($body);
    $mail->addAddress($row['email'], $row['nombre']);
    
    if (!$mail->send()) {
        echo "Mailer Error:" . $mail->ErrorInfo . "<br />";
        break; //forzamos la salida del bucle en caso de error
    } 
    // Limpiamos los datos par próximos envíos
    $mail->clearAddresses();
    $mail->clearAttachments();
}

Como podéis ver no es demasiado complejo gestionar una lista de correo desde PHP y MySQL.

Display inline-block en Explorer 6, Explorer 7 y Explorer 8

Si maquetáis web es posible que utilizáseis alguna vez la propiedad display:inline-block en vuestro CSS a la hora de posicionar divs o elementos de lista, ya que funciona de una forma muy cómoda. ¿Problemas de usarla? Que en en las versiones anteriores a Explorer 8 no va (este inclusive).

Actualmente, por suerte, casi nadie tiene Explorer 7 (y menos Explorer 6) y los que queden se irán al guano cuando Microsoft deje de dar soporte a XP en 2014, pero todavía hay varios Windows Vista con Explorer 8 rulando por ahí, además también hay administraciones, clínicas o empresas con equipos arcaicos y sin actualizar. ¿Solución? Algunos te dirán «no la uses»… pues no, hay un simple hack, que podéis ver en el ejemplo:

elementoAPosicionar {
    display: inline-block;
    *display: inline;
    zoom: 1;
}

Con esto usamos un Safe CSS Hack para que IE7 interprete bien nuestro CSS. Otra posibilidad es que no funcione por culpa de la declaración del DOCTYPE (Explorer es muy puñetero). Si pasáis de Explorer 7 y sólo os preocupa el 8, basta añadir esto al principio del archivo HTML:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

Y creo que si lo declaráis como HTML5 con esta cabecera también funciona:

<!DOCTYPE html>

Por suerte a partir de Explorer 9 muchas de estas cosas se han ido estandarizando, y de momento en Explorer10 lo único que me ha fallado ha sido una animación CSS3, lo cual respecto a hace años es un enorme avance para los chicos de Microsoft. Igual en IE12 ya no hace falta hacer un CSS específico para Explorer.

Enviar un email con PHPMailer usando una cuenta de Gmail

Ya hace un tiempo hablamos aquí de cómo enviar correos desde un script de php usando PHPMailer. He decidido hacer una serie de artículos ampliando un poco más el tema.

Una cuestión que puede ser interesante, sobre todo para aquellos que a lo mejor están en un hosting gratuito y no tienen cuentas de correo vinculadas a su dominio, es utilizar una cuenta de Gmail para enviar los correos. Ya que Gmail nos permiter usarlo como cualquier otro correo SMTP esto es factible.

Configurar PHPMailer para usar Gmail es simple, y podéis ver cómo se haría en el siguiente ejemplo (va comentado línea a línea):

/*Lo primero es añadir al script la clase phpmailer desde la ubicación en que esté*/
require '../class.phpmailer.php';

//Crear una instancia de PHPMailer
$mail = new PHPMailer();
//Definir que vamos a usar SMTP
$mail->IsSMTP();
//Esto es para activar el modo depuración. En entorno de pruebas lo mejor es 2, en producción siempre 0
// 0 = off (producción)
// 1 = client messages
// 2 = client and server messages
$mail->SMTPDebug  = 0;
//Ahora definimos gmail como servidor que aloja nuestro SMTP
$mail->Host       = 'smtp.gmail.com';
//El puerto será el 587 ya que usamos encriptación TLS
$mail->Port       = 587;
//Definmos la seguridad como TLS
$mail->SMTPSecure = 'tls';
//Tenemos que usar gmail autenticados, así que esto a TRUE
$mail->SMTPAuth   = true;
//Definimos la cuenta que vamos a usar. Dirección completa de la misma
$mail->Username   = "tucuenta@gmail.com";
//Introducimos nuestra contraseña de gmail
$mail->Password   = "tucontraseña";
//Definimos el remitente (dirección y, opcionalmente, nombre)
$mail->SetFrom('tucuenta@gmail.com', 'Mi nombre');
//Esta línea es por si queréis enviar copia a alguien (dirección y, opcionalmente, nombre)
$mail->AddReplyTo('replyto@correoquesea.com','El de la réplica');
//Y, ahora sí, definimos el destinatario (dirección y, opcionalmente, nombre)
$mail->AddAddress('destinatario@sucorreo.com', 'El Destinatario');
//Definimos el tema del email
$mail->Subject = 'Esto es un correo de prueba';
//Para enviar un correo formateado en HTML lo cargamos con la siguiente función. Si no, puedes meterle directamente una cadena de texto.
$mail->MsgHTML(file_get_contents('correomaquetado.html'), dirname(ruta_al_archivo));
//Y por si nos bloquean el contenido HTML (algunos correos lo hacen por seguridad) una versión alternativa en texto plano (también será válida para lectores de pantalla)
$mail->AltBody = 'This is a plain-text message body';
//Enviamos el correo
if(!$mail->Send()) {
  echo "Error: " . $mail->ErrorInfo;
} else {
  echo "Enviado!";
}

Esencialmente es casi lo mismo que viene en los DOCS que acompañan a los archivos, pero traducido.

Espero que os sirva. Próximamente más PHPMailer, y más programación web.

Automatizar la ejecución de scripts PHP en servidores Linux con cron y cURL

En el pasado ya hablamos en este blog de automatizar tareas en MySQL y de hacer uso de cURL para procesar formularios y enviarlos a un servicio web REST. ¿Y si os digo que cURL también se puede usar para atomatizar la ejecución de scripts PHP?

Seguro que más de una vez has pensado «Molaba que mi página enviara un correo a todos aquellos usuarios que están de cumpleaños» o cosas así. Puedes pensar que da mucho la vara, pero para nada. No sé si lo comenté la otra vez, pero cURL además de poder ser usado desde PHP también puede ser llamado desde la línea de comandos, así que nos permite, desde una consola, llamar a un script de php por protocolo http (bueno, de hecho cURL puede usar varios protocolos como FTP, FTPS, HTTP, HTTPS, GOPHER, TELNET, DICT, FILE o LDAP) para que se ejecute. Ahora a esto súmale que en un servidor Linux tenemos cron, que nos permite automatizar tareas, como la ejecución de archivos. Solución: programamos que cron ejecute la la llamada a nuestro script de PHP mediante cURL todos los días a una hora concreta.

Veamos un ejemplo en el que ejecutamos un script llamado cumple.php (imagináos que sea un script que felicita el cumpleaños a los usuarios de nuestra web, nos da igual el contenido del script, aquí la clave es automatizar la llamada) todos los días un minuto después de medianoche. Basta con editar el fichero de cron (por ejemplo con crontab -e) y añadir esta línea:

1 0 * * * /usr/bin/curl http://alojamiento/miweb/cumple.php

Bueno, el primer parámetro es el minuto, el segundo la hora y luego irían día del mes, mes y día de la semana (que en este caso van con * porque queremos que sea todos los días, no un día en concreto). Tras los parámetros temporales metemos la orden a ejecutar. En este caso llamamos a cURL (que suele estar en la carpeta /usr/bin/) seguido de la dirección donde esté el script para que sea llamado por protocolo http.

Para mis info sobre cURL puedes buscar aquí, y sobre cron mismamente te ayuda la Wikipedia.

Procedimientos almacenados con parámetros variables en el WHERE

Me excusaba ayer en Twitter, tengo un nuevo empleo y menos tiempo para escribir en el blog. No os preocupéis, que no lo dejaré de lado pero sí es cierto que el ritmo de publicaciones bajará un poquillo. Pero lo bueno de tener un nuevo trabajo es que al afrontar nuevos retos tengo material para nuevos artículo sobre programación (aparte de lo de cobrar regularmente a fin de mes y hacer currículum).

Y una cosa con la que estoy trabajando estos días mucho es con procedimientos almacenados en MySQL. Hoy se me planteada una cuestión, que era un procedimiento que recibe varios parámetros desde un formulario en PHP (para otro día dejo «Llamar a procedimientos almacenados desde PHP») para realizar una búsqueda. El problema: hay parámetros que pueden ir vacíos, ya que el usuario puede estar buscando por todos o por uno. Y el procedimiento almacenado no permite definir parámetros opcionales, como sí podría hacer en una función de PHP. ¿Solución? Simple y fácil.

Lo primero es pasar todos los parámetros que no están definidos al procedimiento con valor NULL. Lo siguiente es que cada comparación que se haría en el WHERE ahora formará parte de un OR donde también comprobamos si el parámetro enviado es nulo. Esto que suena a churro se explica fácilmente con un supuesto y un ejemplo de código:

Imaginemos que queremos hacer una búsqueda en una lista de, por ejemplo, alumnos de un centro. Podemos buscar por nombre, apellidos y un máximo y un mínimo de edad. Bueno, pues el procedimiento sería algo así:

DELIMITER $$ --esto para no tener conflicto con el punto y coma, puede valer otra opción
CREATE PROCEDURE ps_BusquedaVarParam(IN nombre_in varchar(30), apellidos_in varchar(50), minEdad int, maxEdad int)
BEGIN
  SELECT * FROM alumnos WHERE (nombre_in is null or Nombre = nombre_in) and (apellidos_in is null or Apellidos = apellidos_in) and (minEdad is null or Edad>=minEdad) and (maxEdad is null or Edad<=maxEdad);
END $$
DELIMITER;

La idea de hacer así este tipo de comparación es que si le pasamos un nulo la comparación con null devolverá TRUE. De esa forma si es NULL devuelve TRUE, si se da la condición también devuelve TRUE y si no es nulo pero no comple devuelve FALSE. O lo que es lo mismo, si va un NULL te devuelve TRUE y así ese parámetro no te jode que se cumple el AND de la comparativa. Así logramos que no haya problema para hacer la búsqueda sin mandar todos los parámetros.

Y listo, tranquilos, irán más espaciados, pero seguirá habiendo movimientos en este blog. Y de calidad, como siempre.

Ojo a los nombres de variables, por cierto. Si el parámetro tiene el mismo nombre que el campo, aunque uno esté en mayúsculas y otro en minúsculas, fallará. En teoría debería no dar problemas, pero dependiendo de la configuración de MySQL puede fallar o no (de hecho tuve que modificar la consulta, porque en una base de datos me funcionaba pero en otra fallaba), así que mejor les añadís a las variables un prefijo o sufijo y vía (en este caso le puse _in)

Descargar magnet links con Firefox en Ubuntu

Es habitual, en sitios como The Pirate Bay, encontrar Magnet Links para descargar los torrents. La mayoría de los clientes de torrent funcionan con este tipo de enlaces, pero los navegadores no los interpretan, al clickar en principio no saben qué hacer, no los descargan automáticamente. Sólo necesitas seguir una serie de pasos simples para poder arreglar esto:

Lo primero, en Firefox, escribes about:config en la barra de direcciones. Te va a dar un aviso, acepta. Haciend click derecho tienes un menú donde eliges Nuevo->Booleano.

Configurar Firefox descargar magnet links
Insertando el nombre

Como ves en la foto te pedirá un nombre, le pones network.protocol-handler.expose.magnet y tira p’alante. Luego te pedirá un valor, le metes False. El ponerlo como False hará que Firefox pregunte qué software se utilizará. Generalmente los clientes de P2P están en la carpeta /usr/bin así que mirad alli y seleccionad. Por defecto Ubuntu ya trae preinstalado el cliente Transmission, pero podéis buscar otro si no os gusta, hay múltiples opciones.

Eurobasket 2013 – Favoritos

Alguno estaba esperando a que hable del Eurobasket 2013, y la verdad es que no tengo nada claro cómo irá este torneo. Parece que en esta edición todo el mundo haya decidido hacer huelga de brazos caídos y la mayoría de los equipos se presentan con muchas bajas, sin sus puntas de lanza. Esto modifica un poco el cuadro de favoritos. Por ejemplo Rusia, que con toda la plantilla sería un serio candidato al título, llega con una plantilla de circunstancias que les hace caer del bloque de cabeza. La anfitriona Eslovenia se presenta sin Lorbek ni Udrih. Alemania sin Ohlbrecht, Nowitzki, Kaman, Hamman ni Harris. Italia no sería favorita, pero sin Bargnani ni Gallinari directamente es vagón de cola; y lo mismo pasa con UK que sin Ben Gordon, Luol Deng, Byron Mullens, Joel Freeland y Pops Mensah-Bonsu pasa de equipo que podría sorprender en segunda ronda a equipo que se queda fuera de primeras, y eso en un grupo fácil.

En ese sentido Orenga ha tenido suerte. Se antojaba muy complejo el tener que afrontar la transición en España, un torneo sin Felipe Reyes, Navarro ni Pau Gasol, los jugadores que marcaron la etapa más exitosa del balonesto español y cuya era empieza a tocar fin (puede que vuelvan para el mundial 2014, pero más allá…). Además tampoco está Ibaka, y Mirotic ha rechazado la convocatoria por las dudas que le plantea ir ahora y quedarse fuera en el futuro por la presencia del congoleño. Con un entrenador sin experiencia profesional que se dedica a tener a Claver 20 minutos en pista y que deja fuera a Corbacho y Nacho Martín para meter a Mumbrú o Xabi Rey no daría un duro por ellos, pero una plantilla con Calderón, Marc Gasol, Ricky Rubio y Rudy Fernández, además de un Chacho Rodríguez en estado de gracia y un San Emeterio que siempre aporta cojones y garra no puede ser descartada. Y mucho menos en un torneo plagado de bajas como este, ya que todos los equipos llegan debilitados. Con el que para mi es el mejor pivot de la actualidad no se puede enterrar a un equipo.

Marc Gasol
«No me joder que me pongo serio»

¿Puede España revalidar el título y hacerse con tres oros consecutivos? Puede, pero no será como en anteriores Eurobaskets. Si con el gominas podían ganar a pesar de él aquí la cosa cambia, no están Pau y Navarro para romper cualquier situación complicada a base de su talento inagotable, por lo que hará falta más cabeza desde el banquillo. Con ellos en forma España ganaba jugando a medio gas, ahora tienen que dar el 100%.

Una de las que presenta menos bajas para este torneo es Lituania, en fase de transición. Jasikevicius, Kaukenas y Songaila tocan a su fin, y es el turno de Motiejunas y Valanciunas. Si los jóvenes responden y Kleiza  está en forma son de los equipos a tener en cuenta, capaz de hacer daño tanto por dentro como por fuera en ataque y sólidos defensivamente. El baloncesto es un juego de balances, y Lituania tiene jugadores para todas las situaciones (cosa que hecho en falta en España, donde creo que por ejemplo falta un tirador experto o alguien que pueda defender a los aleros altos con garantías).

Donatas Motiejunas
La hora de demostrar si es más Nowitzki o Milicic

Grecia para mi tiene el mejor equipo, a pesar de cuatro bajas de renombre. Llegan sin Koufos (siguiendo un programa de musculación para la próxima temporada NBA), Schortsanitis (lesionado antes de la concentración), Diamantidis (retirado hace un par de años de la selección) ni Calathes (recién incorporado a los Grizzlies, no se unió porque estaba negociando su contrato), y no se sabe cómo estará de forma Bouroussis tras la lesión en la costilla. Pero son un equipazo, con la columna vertebral del bicampeón Olympiacos, con un Spanoulis en estado de gracia, con el prometedor Papanikolau aportando energía, con Zisis reconvertido en el timón por las circunstancias… sin bajas serían el principal favorito, pero a pesar de ellas siguen siendo una de las plantillas más potentes y compensadas.

Finalmente Francia, aunque no le haya ganado a España en la preparación sí demostró que tienen plantilla para plantarle cara a cualquiera. Faltan Noah, Seraphin, Traore y Turiaff, pero cuentan con tres jugones con Batum, Diaw y, por encima de todos, Tony Parker. Un equipo potente, pero algo descompensado en el juego interior, muy físico pero algo falto de técnica. Parker es la piedra angular, y de su acierto dependerá el camino francés.

Tony Parker
Oh là là Parker!

Luego lo típico, a los balcánicos no puedes descartarlos nunca porque pueden sorprender: Macedonia, Serbia, Montenegro, Croacia… ninguno en su mejor momento, pero en un momento dado te pueden dar un susto. Y si me apuras Polonia debe venir con el mejor equipo de su historia, con la pareja interior Gortat/Lampe tienen un buen quinteto, pero les falta banquillo para poder hacer algo. Turquía es una incógnita, no tiene mala plantilla pero en la preparación no han jugado bien.

Mi apuesta personal: Grecia oro, Lituania plata, España bronce y Francia 4º puesto. A la vista de las plantillas presentadas creo que esa sería la clasificación final más lógica, claro que en torneos así es difícil mojarse. ¿Revelación? Voy a hacer una apuesta arriesgada, pero yo creo que Polonia y la República Checa van a dar más juego del que se espera, sobre todo estos segundos porque nadie da un duro por ellos, y son una plantilla muy rocosa.

Eliminar Globososo.com de nuestro equipo

Etos tres últimos días he visto que he recibido varias visitas a través de Globososo.com, lo cual me ha hecho pensar «debe ser un browser-hijacker y seguro que más de un lector se lo quiere cargar«. El adware últimamente prolifera mucho, así que como siempre os digo, ojito cuando instaláis cosas, leed bien los mensajes que os da el instalador porque este coñazo de software suele instalarse como si fuera software legítimo.

En todo caso lo primero es iros al Panel de Control de Windows, a Eliminar Programas y allí lo desinstaláis. Si no os deja porque «está en uso» (o alguna milonga similar) pues Ctrl+alt+supr y allí matáis el proceso (creo que se llama Globososo.exe). Ahora hay que quitarlo de los navegadores. Ahí «asegún», porque depende del que tengáis:

  • Mozilla Firefox: Tenéis que ir al menú de Ayuda. Ahí entráis en Información para Solucionar Problemas y cuando estéis dentro pulsáis el botón gordo de Restablecer Firefox.
  • Google Chrome: Primero te vas a Herramientas, y allí buscas Extensiones, y te fijas que no haya una herramienta de Globososo. Luego te vas a Configuración y en la sección Busca eliges de nuevo Google (o el motor de búsqueda que quieras por defecto).
  • IE: Vas a Herramientas/Opciones de Internet. Ahí vas a la pestaña de Opciones Avanzadas y pulsas Restablecer. Te dará unos warnings de que se van a borrar tus configuraciones personales. En fin, mala suerte pero al carajo se van.

Ok, ya tienes limpios los navegadores, pero todavía no hemos acabado. Ahora toca hacer varias cosas. La primera es que te descargues el AT-Destroyer que de buen rollo nos proporcionan los colegas de Infospyware. Lo siguiente es que hagas lo mismo con Adwcleaner y de terceras me metéis también en el pack el CCleaner. Los instaláis, desconectáis vuestro antivirus habitual (ya lo pondréis a andar de nuevo cuando la cosa esté acabada, pero si lo tenéis activado durante la limpieza es posible que provoque conflictos con las herramientas que vamos a usar), reiniciáis y, durante el reinicio, pulsáis F8 hasta que os salga el menú donde podéis seleccionar «Iniciar en Modo Seguro».

Una vez en modo seguro lo primero es que lancéis el AT-Destroyer antes descargado. Le pulsáis a Search and Destroy y esperáis. Cuando acabe os pedirá reiniciar. Obedeced.

Tras este nuevo reinicio ejecutáis Adwcleaner, pulsáis Delete (o Suprimir, o Supresión, depende del idioma en que instaléis) y esperáis a que acabe. Cuando termine reiniciáis.

Ahora lo mejor es que paséis un antivirus en la nube, probad en este caso con Panda Cloud, aunque si tenéis otro preferido también valdrá. El caso es comprobar que no haya nada raro por el equipo.

Y para finalizar, como siempre desinstaláis todo lo que habéis necesitado para la limpieza, y ejecutáis CCleaner  para limpiar coockies y basurillas varias, y de paso ponéis un poco en orden el registro.

Con esto Globososo debería ser historia en vuestro equipo.

Convertir m4a a mp3 en Ubuntu y Mint (o a ogg, FLAC…)

De vez en cuando acaba en mi disco duro alguna carpeta con archivos de audio en m4a (debe haber mucha gente con iCacharros por el mundo). Problema 1, mi viejo reproductor de mp3 no soporta ese formato. Problema 2, el Mixxx, que uso para pinchar, tampoco lo reconoce. En todo caso, convertir archivos de audio m4a a mp3 no es complicado.

Lo primero es iros a la consola e instalar el conversor de archivos que ya está en los repositorios:

sudo apt-get install soundconverter

Ok, all right, yeah man. Ya tienes tu programilla conversor. En el menú Preferencias podrás elegir el tipo de archivo al que quieres convertir (mp3, FLAC, ogg, opus o wav) y la calidad del mismo. Por defecto creo que convierte a ogg si no defines algo distinto.

Preferencias Soundconverter
Ventana de preferencias de Soundconverter.

Luego el procedimiento es simple. Si quieres añadir una carpeta entera pulsas el botón gordo de Añadir Carpeta, si es para archivos sueltos pulsas el de Añadir Archivo. Cuando estén cargados pulsáis Convertir. Aquí estoy a punto de convertir los temas de la primera maqueta de Mutant Squad (Reset the World) a mp3.

conversor soundconverter
Convirtiendo a mp3 Reset The World, de Mutant Squad

Y aquí están en proceso:

convertir audio soundconverter
Proceso de conversión.

Y con esto ya tenéis solucionada la cuestión de la conversión de formatos.