Un lector me ha escrito consultando sobre un post algo antiguo, sobre cómo poner un sencillo mensaje de cookies en una web. La verdad es que no me he explicado muy bien en aquel post, los navegadores han cambiado durante estos últimos años, JavaScript también.. así que aquí estoy compartiendo otro mensaje de aceptar cookies más actual.
Este mensaje de aceptar cookies es una actualización de aquel antiguo que vengo usando en nuevos proyectos. Es un mensaje hecho artesanalmente que puedes copiar y pegar para tu web. El único requisito que tiene es que necesitas usar la librería de jQuery para que funcione. jQuery hoy día es como un estándar, hace tan bien su trabajo de acceder al DOM de las páginas web, que cómo no usarlo en todos los proyectos.
Vengo a traer un pequeño truco que es algo complicado de encontrar. Es decir, traigo un HOWTO para una configuración en concreto de una joya del software. Se trata de la API Platform para Symfony, con la que implementamos en muy poco tiempo una API web en un proyecto completo.
Con esta API Platform tendremos acceso remoto, mediante las clásicas llamadas GET, POST, PUT, DELETE a las entidades del proyecto. Podemos limitar el acceso a cada usuario a cada elemento de una entidad de la que sea propietario.
Magento es un gran CMS para montar tiendas online. Está muy desarrollado teniendo en cuenta el SEO, el marketing, para tener muchos dominios con la misma web, muchas configuraciones de impuestos, de precios distintintos por web, distintas plantillas para cada sitio web.. todo desde un mismo panel de control.
Es tan flexible desde el mismo panel de control, que ha llegado a extremos de tal forma de que necesita todo tipo de cacheados, tablas temporales donde guardar indexada la información, así como también Varnish y Redis. Todo esto junto es una combinación explosiva y todo un reto hacerlo funcionar todo. Así que en este post vengo a hacer una review del funcionamiento de estos índices de datos.
Aquí estoy de nuevo compartiendo otro CODE-KATA, ahora para hacer una tarea muy interesante conectando dos sistemas informáticos. Es decir, tenemos un Magento 1 en algún lugar, y vamos a permitir conectarnos desde otra plataforma en PHP para la creación de pedidos de forma remota.
Lo primero que necesitamos tener es la información del pedido por completo. Necesitamos saber los datos del cliente, direcciones de envío y facturación, en este caso el correo electrónico del cliente registrado en Magento, y de los productos necesitamos el SKU y la cantidad que queremos pedir.
Otra vez, de nuevo, me repito más que el ajo xDD vengo a traer otro CODE-KATA o HOWTO. Esta vez sobre la API Soap de Magento. Se trata de un pequeño script para ver la información de un pedido.
El punto de partida es que tenemos ya configurada la API Soap de Magento, con un usuario de la API, con los suficientes privilegios para hacer peticiones de información sobre los pedidos. Entonces conectamos a dicho proyecto, a su endpoint, con las credenciales de acceso, y obtenemos los datos del pedido.
Hoy de nuevo vengo con otro CODE-KATA o HOWTO, esta vez para montar un gestor de archivos web. Recopilando joyas de la informática vengo a traer el FMElfinderBundle. Subir ficheros a una web, renombrarlos, editarlos es una tarea compleja. Si usamos este bundle, que es un vendor de Composer preparado para Symfony Flex, nos podremos olvidar de construir todo esto haciéndonos la vida mucho más fácil.
Es decir, que tenemos un bundle o vendor para Symfony, que nos permite gestionar archivos mediante el navegador. Así podemos subir ficheros de imagen para luego usarlos en la web. También permite otro tipo de ficheros una vez configurado. Incluso te permite editarlos si son de texto dentro del mismo gestor de archivos.
Ya tenemos el código fuente, ¿y ahora? ¿cuál es la magia que hace posible que un código fuente se ejecute?
Todo programa necesita un traductor, que compile o interprete el código fuente para que pueda ser ejecutado. Es una primera diferencia que puede marcarse entre los lenguajes de programación, ya que un lenguaje puede ser interpretado, compilado, o incluso ambas cosas. Además, la ejecución puede ser dependiente de la máquina, o ejecutarse en una máquina virtual, que te independiza de la máquina.
Por ejemplo los lenguajes funcionales o lógicos suelen usarse primeramente interpretados, como Prolog o Haskell mientras se desarrolla, pero también tenemos disponible un compilador para mejorar su eficiencia. PHP es interpretado, aunque ha habido compiladores para mejorar su eficiencia de ejecución. Cabe destacar como curiosidad la Hip Hop Virtual Machine de Facebook que crearon para agilizar PHP, que precisamente compila los ficheros fuente a un código objeto intermedio más rápido de ejecutar. Javascript, Typescript, Ruby, también son interpretados. C, C++, VB, C# son compilados, es decir, se necesita compilar el código fuente a códigos objeto, estos códigos objeto a su vez se linkan, se retraducen, para ejecutarse finalmente en la máquina.
Una respuesta a porqué Symfony es tan productivo son los comandos de consola. Con simples comandos podemos crear un proyecto nuevo, añadir nuevos componentes, lanzar un servidor de pruebas, chequear las URLs, crear entidades que vamos a guardar en base de datos, probar el envío de emails. También podemos modificar las tablas de datos, añadir nuevos elementos, editar los existentes, actualizar la base de datos, preparar nuevos elementos para almacenar, generar pantallas de listado de datos, ediciones de datos, borrados o creaciones. Generamos formularios automáticamente, con recepción de sus datos y guardado de dichos formularios en bases de datos. Podemos importar una base de datos de otro proyecto, generando todo el código fuente de una aplicación web que consulte los datos de dicha BD en apenas un rato. Podemos crear controladores, estructurando todas las zonas de la web, con sus plantillas, rutas, y URLs en poco tiempo. Y mucho más..
No tenemos que gastar tiempo en tediosas tareas repetitivas de construcción, y podremos centrarnos en lo especial de la aplicación web que estemos creando. Todas estas herramientas de generación de código las tenemos mediante comandos de consola. Cuantos más módulos añadas probablemente más comandos tendrás que te harán mucho más productivo. Te ahorrarán muchísimo tiempo, pero tienes que saber que estan ahí, saber cómo funcionan, y usarlos siempre que puedas. Hay que coger práctica con los comandos para aprovechar la productividad que te da Symfony. Continuar leyendo..
Continuando con el post anterior, traigo otro code-kata, o HOWTO, para hacer ping a una web, para empezar. Digo para empezar, porque esto no es más que el comienzo de una serie de acciones muy potentes sobre servidores web. Así podemos interactuar con un sitio web automática y remotamente. Este es uno de los mecanismos básicos de comunicación entre sistemas informáticos. Es decir, esto se puede reutilizar para que una web se comunique con otra web, con otro sistema informático, leyendo información o enviándola.
Para esto vamos a usar el gran CURL, que va muy bien para trabajar con el protocolo de las webs. Aunque como reza en su web, es compatible con muchos otros protocolos:
DICT, FILE, FTP, FTPS, Gopher, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, POP3, POP3S, RTMP, RTSP, SCP, SFTP, SMB, SMBS, SMTP, SMTPS, Telnet and TFTP. curl supports SSL certificates, HTTP POST, HTTP PUT, FTP uploading, HTTP form based upload, proxies, HTTP/2, cookies, user+password authentication (Basic, Plain, Digest, CRAM-MD5, NTLM, Negotiate and Kerberos), file transfer resume, proxy tunneling and more..
Esta forma de hacer un simple ping web se puede escalar todo lo que quieras. Es decir, de esta forma es como trabajan internamente los módulos de métodos de pago, envío/lectura de feeds, las APIs de los CMSs, por ejemplo. Las acciones que se ejecutan mediante la comunicación con APIs sobre HTTP/HTTPS. Y claro, cómo no, para las archiconocidas y tan queridas API REST sobre HTTP. Todas estas acciones tienen un origen (cliente) y un destino (servidor).
Vamos a usar en este caso CURL, que es una herramienta del sistema operativo que podemos usar desde PHP. Si estás en GNU/Linux, puedes instalar tanto CURL como el módulo de PHP que lo usa así:
sudo apt-get install curl php7.2-curl
Si estás en Windows, Mac, o cualquier otro sistema operativo tendrás que ir a:
Si ejecutamos esto desde línea de comandos veremos algo tal que así:
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>301 Moved Permanently</title>
</head><body>
<h1>Moved Permanently</h1>
<p>The document has moved <a href="https://jnjsite.com/">here</a>.</p>
</body></html>
El contenido de la web se está pintando por pantalla: jnjsite.com te invita a redirigirte a https://jnjsite.com que es la versión segura de la web.
Viendo información de la respuesta
Para esto podemos modificar el script anterior y sacamos mucha información de la respuesta:
En este caso nos está pidiendo hacer una redirección 301 a la web con HTTPS. En teoría deberíamos de seguir esta redirección. Así que..
Siguiendo redirecciones
Modificando el script anterior, tenemos haciendo las redirecciones lo siguiente:
<?php
$curlHandler = curl_init('jnjsite.com');
$response = curl_exec($curlHandler);
while(curl_getinfo($curlHandler)['http_code'] >= 300
and curl_getinfo($curlHandler)['http_code'] < 400){
// new URL to be redirected
curl_setopt($curlHandler, CURLOPT_URL, curl_getinfo($curlHandler)['redirect_url']);
$response = curl_exec($curlHandler);
}
var_dump(curl_getinfo($curlHandler));
curl_close($curlHandler);
Ejecutamos, y revisando por pantalla el resultado tendremos que finalmente se paran las redirecciones en https://jnjsite.com/ con un código de respuesta 200. He marcado en negrita lo nuevo con respecto al script anterior para redirigir hasta la página de destino.
Terminando
Para dejarlo limpio el script, sólo quedaría comprobar finalmente si la página ha dado un código OK de respuesta. Marco en negrita lo nuevo:
<?php
$curlHandler = curl_init('jnjsite.com');
curl_setopt($curlHandler, CURLOPT_RETURNTRANSFER, true);
curl_exec($curlHandler);
while (curl_getinfo($curlHandler)['http_code'] >= 300
and curl_getinfo($curlHandler)['http_code'] < 400) {
// new URL to be redirected
curl_setopt($curlHandler, CURLOPT_URL, curl_getinfo($curlHandler)['redirect_url']);
curl_exec($curlHandler);
}
if (curl_getinfo($curlHandler)['http_code'] >= 200
and curl_getinfo($curlHandler)['http_code'] < 300) {
echo 'OK'.PHP_EOL;
} else {
echo 'KO'.PHP_EOL;
}
curl_close($curlHandler);
A partir de aquí sólo queda hacer las acciones que consideres si tienes un OK o un KO.
Una tarea bastante importante a la hora de posicionar una página web es asegurarte de que sigues online. Si has contratado el alojamiento a una empresa no tendrás que preocuparte mucho por el estado del sistema operativo del servidor. Pero hay otros aspectos aparte del servidor que necesitan de tu atención. Puedes pensar que una página web basta con montarla con un buen CMS, que puedes dejarla online y ahí seguirá porque no hay razón para que deje de funcionar. Pues nada más lejos de la realidad, cuantas más cosas tenga tu web, más cosas pueden fallar.
Es decir, si tienes una página artesanal de un único fichero estático es difícil que deje de funcionar. Pero si tienes un CMS, quizá un WordPress, Prestashop, Drupal o Magento.. ya empiezas a tener más elementos que mantener. Los módulos pueden ser inestables, pueden engancharse las arañas de los buscadores, usuarios que llegan a bugs involuntariamente, etcétera.. No digamos ya si tienes muchas visitas que generan contenido dinámicamente.
Las páginas web son como los coches, necesitan un mantenimiento, unas revisiones. Sino, tarde o temprano, dejarán de funcionar. Así que si quieres curarte en salud, puedes tener un sencillo script que compruebe si sigue online una web.
En el post anterior escribí sobre cómo crear una landing page rápido con Symfony 4, y se me quedó pendiente el enviar por email los mensajes del formulario. Es decir, ya tenemos en un rato una rudimentaria ‘landing page’ donde un maquetador o el equipo de marketing disfrutará poniendo cualquier cosa. Será como maquetar con HTML, CSS y Javascript sin tener ningún engorroso CMS por debajo limitándonos lo que podemos hacer. Además tendremos la base de un buen Symfony para después añadir lo que queramos.
Ya tenemos la captación de contactos (o capture leads para los entendidos), que se guardan en una base de datos embebida en la propia web. Sin complicadas instalaciones ni configuraciones SQL, directamente con una base de datos SQLite embebida.
Sólo queda entonces hacer 3 cosas:
Instalar el módulo de Swiftmailer.
Configurarlo.
Y poner la acción de enviar el email.
Vamos al grano..
1. Instalando Swiftmailer
Para esto basta con poner en el terminal lo siguiente:
composer require symfony/swiftmailer-bundle
..esperamos, y si todo ha ido bien tenemos que ver en el terminal algo como lo siguente:
Using version ^3.2 for symfony/swiftmailer-bundle
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 3 installs, 0 updates, 0 removals
- Installing egulias/email-validator (2.1.4): Loading from cache
- Installing swiftmailer/swiftmailer (v6.0.2): Loading from cache
- Installing symfony/swiftmailer-bundle (v3.2.2): Loading from cache
Writing lock file
Generating autoload files
ocramius/package-versions: Generating version class...
ocramius/package-versions: ...done generating version class
Symfony operations: 1 recipe (8c3c4103f30ebcc7579093a6f39dc028)
- Configuring symfony/swiftmailer-bundle (>=2.5): From github.com/symfony/recipes:master
Executing script cache:clear [OK]
Executing script assets:install --symlink --relative public [OK]
Some files may have been created or updated to configure your new packages.
Please review, edit and commit them: these files are yours.
2. Configurar swiftmailer
Ahora las principales variables de configuración son variables de entorno. Esto es mucho más seguro ya que se pueden incluso no guardar en ningún fichero, pero la forma más sencilla es usar el fichero .env que debemos tener en el directorio raiz del proyecto. Si lo abrimos veremos que tenemos añadida la configuración de Swiftmailer:
###> symfony/swiftmailer-bundle ###
# For Gmail as a transport, use: "gmail://username:password@localhost"
# For a generic SMTP server, use: "smtp://localhost:25?encryption=&auth_mode="
# Delivery is disabled by default via "null://localhost"
MAILER_URL=null://localhost
###< symfony/swiftmailer-bundle ###
Como bien explica en los comentarios, así hacemos. Pero para evitarte problemas te recomiendo usar siempre SMTP con un buen servidor de correo electrónico. Por Internet hay muchos ejemplos, uno puede ser este:
Estas configuraciones usando SMTP son compatibles con la mayoría de los servidores de correo electrónico, sino todos. Tales como Mandrill, Amazon SES, Gmail, etcétera.. podrás configurarlos así, sólo tienes que encontrar las configuraciones que le pondrías a tu Outlook o Thunderbird y ponerlas en el proyecto de Symfony.
3. Enviar el email
Remitiéndome al post anterior, sólo nos queda en el controlador donde recibimos el contenido del formulario el enviarnos un email informándonos de que alguien nos ha dejado un mensaje. Para esto ponemos algo como esto en el controlador, marco en negrita lo nuevo:
<?php
namespace App\Controller;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use App\Form\ContactType;
use App\Entity\Contact;
class MainController extends Controller
{
/**
* @Route("/", name="main")
*/
public function index(Request $request, \Swift_Mailer $mailer)
{
$contact = new Contact();
$theForm = $this->createForm(ContactType::class, $contact);
$theForm->handleRequest($request);
if ($theForm->isSubmitted() && $theForm->isValid()) {
// save in database
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($contact);
$entityManager->flush();
// send email
$message = (new \Swift_Message('JnjSite.com:: mensaje desde la web'))
->setFrom(['info@jnjsite.com' => 'Web JnjSite.com'])
->setTo([
'info@jnjsite.com', ])
->setBody(
$this->renderView(
'main/email.html.twig',
array('data' => $theForm->getData())
),
'text/html'
);
if ($mailer->send($message)) {
// Email enviado correctamente, vamos a limpiar el formulario.
$theForm = $this->createForm(ContactType::class);
} else {
// Aquí podemos hacer algo más porque no se han enviado bien el email.
}
}
return $this->render('main/index.html.twig', [
'theForm' => $theForm->createView(),
]);
}
}
Verás que no hay que complicarse mucho. Y por último necesitamos también la plantilla del correo electrónico, que la he puesto en templates/main/email.html.twig:
¡Hola!<br>
Hemos recibido un mensaje en el formulario.<br>
<br>
Nombre: <strong>{{ data.name }}</strong><br>
Email: <strong>{{ data.email }}</strong><br>
Asunto: <strong>{{ data.subject }}</strong><br>
Mensaje:<br>
<strong>{{ data.message }}</strong><br>
Terminando
Si todo ha ido bien, ahora podemos probar el formulario arrancando el proyecto en local, si ponemos esto en el terminal:
php bin/console server:start
Y visitamos http://localhost:8000/ nos enviamos un formulario y debemos de ver algo como esto:
..sino me he explicado bien, o quieres decir algo, no dudes en dejar un comentario aquí abajo 😉
Es habitual que cuando haces cambios en Magento necesites flushear la caché. Esto es resetear, borrar los ficheros o datos temporales, que almacena Magento para agilizar sus tareas.
Magento va guardando ficheros intermedios que se ejecutan más rápido que los originales. También guarda variables, combina ficheros de configuración de los módulos, traducciones, bloques, layouts de las plantillas, etc.. Todos estos ficheros agilizan mucho la ejecución, así que si no tienes la caché activada deberias de activarla ya mismo.
Problema
Puede ser que tengas que estar instalando y desinstalando módulos y de repente deja de funcionar Magento. Quizá has modificado en la base de datos algún dato y no se ven los cambios. O quizá incluso modificando algunos ficheros te deja de funcionar Magento.
El problema viene cuando no puedes entrar al panel de control de Magento y darle al botón de ‘Flush Magento Cache’.