Category: Programación

Redirigir página WordPress a HTTPS

En WordPress existen 3 formas en las que se puede realizar la redirección de nuestra web al nombre de dominio que deseemos.

Esto con frecuencia se hace debido a la necesidad de habilitar la forma segura de mostrar nuestro dominio mediante HTTPS.

La mejor forma de hacerlo es modificando el archivo wpconfig.php porque así te evitas modificar la base de datos y que tengas un error de acceso a tu zona de administración.

En mi opinión creo que se debería hacer una combinación utilizando la primera o la segunda opción y la tercera opción, para asegurarnos que todas las páginas son redirigidas.

WpConfig.php

Editar wpconfig.php y añadir estas dos líneas con el nombre de dominio al que queremos redirigir.

define('WP_HOME','https://example.com');
define('WP_SITEURL','https://example.com');

WordPress Admin

Entrar a Configuración ó Settings -> General

Site Address (URL): https://example.com

WordPress Address (URL):’https://example.com

.Htaccess

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /

RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

# BEGIN WordPress
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

Verificar si el archivo existe Vue Js

¿En qué casos nos podría interesar verificar que un archivo existe o no en nuestro servidor u otro?

Este es un caso real:

Tenemos una plataforma multilenguaje y queremos crear de forma dinámica los archivos en varios lenguajes. Para ello hemos creado un sistema de gestión de archivos en el que se puede utilizar el mismo registro para llamar a los distintos archivos en los distingos lenguajes. Es decir, podemos tener un manual en ES y EN.

Ahora bien, en Vue Js tenemos una estructura en la que no necesitamos decirle manualmente qué archivo escoger, si no que queremos que lo haga dinámicamente al cambiar de idioma. Aquí es donde nos vendrá de lujo esta función.

<a :href=»‘/’+locale+’/media/archivo.pdf'» class=»pdf-link»>{[ translations.label_download ]}</a>

Este es nuestro link que va a variar en los distintos idiomas.

¿Pero qué tal si hemos subido el archivo sólo en un idioma? Podemos evaluar si existe o no con la siguiente función.

He añadido además un caso en el que la evaluación puede estar condicionada a una acción. A la hora de hacer un clic, toggle se accionará y verificará que, para empezar esa estructura de html exista con el .length y a partir de allí empezar a buscar de cada registro encontrado si existe el archivo en el servidor.

Remplazar imagen con CSS

La técnica es sencilla, pero eficaz. Lo que tenemos que hacer es ocultar la imagen aplicando un ancho de 0px (width:0) y luego utilizando las propiedades de background (img y size) + padding para añadir la nueva imagen.

Esta es una buena técnica para realizar la acción remplazar una imagen utilizando sólo CSS, pero tenemos un «contra» y es que tendremos que ir jugando con @media-queries para poder adaptar la imagen a cada uno de los dispositivos.

Descargar PDF base64 con Symfony

Para hacer la recuperación de un archivo, en este caso un PDF, que está almacenado en nuestra base de datos como un BLOB para luego realizar el return añadiendo las cabeceras necesarias para realizar la acción de «Descargar» cuando llamemos a esta URL.

En este ejemplo sencillo, recuperamos el PDF utilizando una función ficticia en la que supuestamente recuperamos los datos del PDF en bruto (raw) y codificado en base64.

El segundo paso es decodificar ese raw utilizando la función base64_decode().

El último paso es crear la respuesta con los métodos que nos da la clase Response. A esta respuesta le vamos a añadir las cabeceras necesarias para poder decirle al navegador que es lo que tiene que hacer con este archivo.

En este caso lo que queremos es descargarlo. Por lo que añadiremos las cabeceras Content-Description y Content-Disposition:

$response->headers->set(‘Content-Description’, ‘File Transfer’);

$response->headers->set(‘Content-Disposition’, ‘attachment; filename=»Archivo.pdf»‘);
Con esto, al realizar una consulta a la ruta creada directamente nos descargará el PDF.
¡Importante! Si vas a realizar la consulta con un formulario, no te olvides de colocar el atributo enctype en tu etiqueta FORM.
<form id="pruebaPDF" method="post" enctype="multipart/form-data">
<?php
namespace App\Controller;
use Symfony\Component\HttpFoundation\Response;
    /**
    * @Route("/show-pdf", name="show_pdf")
    */
    public function getPDFDocument()
    {
        $result = getPdfFromRaw();
        $pdf = base64_decode($result->PDF);
        $response = new Response($pdf);
        $response->headers->set('Content-Type', 'application/octet-stream');
        $response->headers->set('Content-Description', 'File Transfer');
        $response->headers->set('Content-Disposition', 'attachment; filename="Archivo.pdf"');
        // $response->headers->set('Expires', '0');
        // $response->headers->set('Content-Transfer-Encoding', 'binary');
        $response->headers->set('Content-length', strlen($pdf));
        $response->headers->set('Cache-Control', 'no-cache private');
        // $response->headers->set('Pragma', 'public');
        // Send headers before outputting anything
        $response->sendHeaders();
        return $response;
    }

Sustituir icono radio button bootstrap 4

Vamos a sustituir el icono standard del radio button por algo más visible. En este caso práctico vamos a cambiar el modo de visualización de un listado, por lo que vamos a hacer que los iconos sean visiblemente más acorde a lo que se sugiere que es cambiar la vista a modo «Bloque» o modo «Listado».

Para realizar la estructura HTML he usado – bootstrap 4

Para los iconos – fontawesome 5

La estructura CSS tiene que estar bien anidada para no machacar otros estilos.

Detectar dispositivo móvil Javascript / PHP

Estas dos funciones son la manera más simple para poder detectar si se está utilizando un dispositivo móvil en nuestra página web.

Existirán funciones más complejas, pero estas cumplen bien su cometido.

Si vemos, la versión de Javascript parece mucho más compleja, por lo que podríamos utilizar AJAX para realizar nuestras validaciones realizando la llamada a un archivo PHP utilizando la función en este lenguaje.

JAVASCRIPT

PHP

function isMobile() {
    return preg_match("/(android|avantgo|blackberry|bolt|boost|cricket|docomo|fone|hiptop|mini
|mobi|palm|phone|pie|tablet|up\.browser|up\.link|webos|wos)/i", $_SERVER["HTTP_USER_AGENT"]);
}

// Use the function
if(isMobile()){
    // Do something for only mobile users
}
else {
    // Do something for only desktop users
}

Método Click en elementos creados dinámicamente con Javascript o Jquery

Al crear un elemento dinámicamente con javascript o utilizando jquery nos vemos con un problema, el cual muchas veces es un quebradero de cabeza. Estoy hablando de utilizar el elemento con jQuery utilizando los métodos click(), change(), blur(), etc…

Supongamos que hemos creado un elemento <input type=»button» id=»saveBtn» class=»btn» value=»Guardar» /> por javascript y lo incluimos en el documento con «.append()» o «.html()».

Ahora, queremos añadirle un click() method a nuestro nuevo amigo usando jQuery. NO SE PUEDE!

$('#saveBtn').click(function () {alert($(this).attr("id")); }); 

¿Por qué? Porque a la hora de cargar el documento este elemento no existía. Los métodos solamente se asocian (bind) con los elementos que se cargan en el momento de que el navegador ejecute la carga del DOM (Document Object Model), por lo que jQuery directamente pasa del tema.

La solución

Utilizaremos el método on() para decirle al documento que nos busque el elemento que necesitamos, y asociarle el método click de la siguiente manera:

$(document).on('click', '#saveBtn', function () {
    alert($(this).attr("id"));
});

Para acceder al elemento y utilizarlo, haremos algo parecido, buscando el elemento cuyo atributo «id» sea «saveBtn»:

var dataId = $('[id^="saveBtn"]');

Si queremos acceder utilizando la clase:
var dataId = $('[class^="btn"]');

Para casos extremos en el que no podamos realizar acciones con algunos elementos del documento, os dejo además estos métodos nativos de javascript:

El id del elemento: document.getElementById('saveBtn');

La etiqueta html: document.getElementsByTagName('input');

La clase: document.getElementsByClassName('btn');

El selector: document.querySelectorAll('input.btn');

Efecto Inclinado (Skew Effect) HTML + CSS

La inclinación de bordes con CSS (css skew effect) es el efecto en el que los laterales (izquierda y/o derecha) aparecen inclinados. Ejemplo:

El efecto lo logramos utilizando la propiedad transform: skew.  Con esto y un poco más de estilos obtenemos el resultado.

HTML:

<div id="user-config-1" class="square-skew square-dark-blue text-white">
<span>
<label>Config 1</label>
<i type="btn" class="edit-config fas fa-pencil-alt" title="Editar"></i>
<i type="btn" class="remove-config fa fa-times"></i>
</span></div>

CSS:

.square-skew {
    -ms-transform: skew(-30deg, 0deg);
    -webkit-transform: skew(-30deg, 0deg);
    transform: skew(-30deg, 0deg);
    padding: 0.2rem 0;
    position: relative;
    left: 10px;
    float: left;
}

.square-skew label {
    margin: 0 !important;
    font-weight: bold;
}

.square-skew span {
    -ms-transform: skew(30deg, 0deg);
    -webkit-transform: skew(30deg, 0deg);
    transform: skew(30deg, 0deg);
    display: inline-block;
    font-size: 0.625rem;
    padding: 0 0.5rem;
    text-transform: uppercase;
}

.square-dark-blue {
    background-color: #007cb6;
    margin-right: 0.625rem;
}

CSS Media Queries

Una media query consiste de un media type y una o más expresiones, que implican media features, que se resuelve en true o false. El resultado de la consulta es verdadero si el media type especificado en el media query coincide con el tipo de dispositivo sobre el que el documento está siendo mostrado y todas las expresiones del media query son verdaderas. Cuando un media query es verdadero, se aplica la hoja de estilo correspondiente o las reglas de estilo, siguiendo las reglas normales en cascada.

Media Types

screen Intended for non-paged computer screens.

tty Intended for media using a fixed-pitch character grid, such as teletypes, terminals, or portable devices with limited display capabilities.

tv Intended for television-type devices (low resolution, color, limited scrollability).

projection Intended for projectors.

handheld Intended for handheld devices (small screen, monochrome, bitmapped graphics, limited bandwidth).

print Intended for paged, opaque material and for documents viewed on screen in print preview mode.

braille Intended for braille tactile feedback devices.

aural Intended for speech synthesizers.

all or empty value Suitable for all devices.

Ejemplo de Media Queries

TinyMCE + Responsive File Manager

TinyMCE + Responsive File Manager

Todo el mundo conoce TinyMCE, el editor de texto WYSIWYG que funciona en la mayoría de aplicaciones web en la que utilizando unas cuantas opciones personalizadas podemos obtener un editor según nuestras necesidades.

Hasta aquí bien, pero ¿Qué pasa cuando necesitamos añadir un archivo a nuestro texto? Creo que existe una función sencilla pero yo he utilizado un plugin externo que me pareció interesante. El problema es que este plugin se ha actualizado a una nueva versión y no he tenido tiempo de verificar si esto funciona en la nueva versión. Dejaré un enlace para descargar la versión que yo utilizo para poder trabajar con ella.

La Versión de TinyMCE  que estamos utilizando es la V3 pero confirmo que se puede utilizar la V4.

El plugin que añadiremos para gestionar la subida de ficheros será Responsive FileManager.

Instalación

Al descargar el archivo comprimido, lo colocaremos en la carpeta donde tengas instalado el TinyMCE.

Al descomprimir verás una carpeta que dice TinyMCE. Dentro está  una carpeta responsivefilemanager. «Cortamos» para moverlo.

Buscamos la carpeta de TinyMCE > carpeta plugins y «pegamos».

Podríamos meter todo desde la misma carpeta del tinymce, pero preferí separar las cosas para tenerlo mejor controlado.

Iniciar el Plugin

Para iniciar el plugin con el TinyMCE tendremos que añadirlo a la función .init junto a las opciones que tengamos establecidas:

plugins: ['todosNuestrosPlugins responsivefilemanager'],
toolbar: ['nuestrasOpcionesPersonalizadas responsivefilemanager']
external_filemanager_path: root_folder+"js/responsivefilemanager/filemanager/",
filemanager_title:"Gestor de Archivos",
external_plugins: { "filemanager" : root_folder+"tinymce/plugins/responsivefilemanager/plugin.min.js"},

todosNuestrosPlugins se refiere a los plugins que tengamos cargados manualmente.

nuestrasOpcionesPersonalizadas se refiere a las opciones que queremos mostrar en el toolbar.

plugins buscará el nombre del plugin responsivefilemanager en la carpeta de plugins (Tal como lo hemos creado y llamado anteriormente)

toolbar es el sistio donde queremos que aparezca nuestro plugin en la barra de herramientas que se mostrará al cargarse el editor.

external_filemanager_path es donde se cargará la librería. (Dónde la hemos instalado junto al TinyMCE)

external_plugins es el sitio donde hemos instalado el plugin en el tinymce para que la magia se haga realidad.

Para controlar la acción del botón de Búsqueda / Browse de la imagen, crearemos un callback function que realizará la acción de abrir el dialog donde se cargará el responsive file manager.

El código lo añadimos al .init igual que las opciones anteriores:

file_browser_callback: function(field_name, url, type, win) {
var filebrowser = root_folder+"js/responsivefilemanager/filemanager/dialog.php?type=1&fldr=source_"+source_id+"&field_id="+field_name;
tinymce.activeEditor.windowManager.open({
title : "Insertar Fichero",
width : 850,
height : 500,
url : filebrowser,
id : 'tinyMceFileBrowser'
},{
window : win,
input : field_name
});
return false;
}

Ahora les explico qué parametros nos da el callback de TinyMCE. Pero quiero aclarar que hay un parámetro que puede que nos resulte confuso.

Hay un parámetro TYPE que veremos en la URL de «var filebrowser». Yo en un principio pensaba que lo que venía entre los parámetros del callback era lo que había que meter en la URL (pensando que el plugin estaba preparado para interpretarlo) pero no es así.

Lo que nos devuelve el parámetro type del callback del TinyMCE son 3 opciones (‘image’, ‘media’ or ‘file’) y se utiliza en su función nativa
El parámetro que añadimos en la url de «var filebrowser» pueden ser 3: (1:images files 2:all files 3:video files)

Por lo que no tiene nada que ver con lo que nos da el TinyMCE. Hay que tenerlo en cuenta para no confundirlo.

file_browser_callback

Esta opción habilita el buscador de archivos en las opciones de TinyMCE que utilicen la función de buscar/cargar.

Si esta opción está configurada, habilita un botón de «buscar / browse» en los dialogs de «insertar/editar link» o en el de «insertar/editar imagen».

El formato de la función:

fileBrowser(field_name, url, type, win)

field_name es el id/nombre del elemento del formulario (textarea) donde se insertará la url o el archivo.

url es el link del elemento actual (si estuvieses editando uno o quisieses eliminarlo). Por ejemplo al clicar un enlace o imagen dentro del TinyMCE.

type es el tipo de «buscador» que se utilizará. El valor puede ser ‘image’, ‘media’ o ‘file’, dependiendo desde que dialog se esté llamando la función.

win hace referencia al dialog/window que está ejecutando la función.

Configuración para Separar Usuarios

Una de las cosas que era necesario implementar era que cada usuario pueda ver su propia carpeta. Para ello, añadiremos unas cuantas opciones en las sesión. Creo que no hace falta decir que debe añadir estas opciones cuando el usuario incie sesión, pero por si acaso LO CONFIRMO. Estas opciones las cargará automáticamente el plugin, y podemos ver como se utiliza en el archivo de dialog.php y ajax_calls.php

// CARPETA POR DEFECTO PARA SUBIR IMAGENES/FICHEROS DEL EDITOR DE TINYMCE
$_SESSION['RF']["verify"] = "RESPONSIVEfilemanager"; // Verificación para el plugin de File Manager
$_SESSION['RF']['subfolder'] = 'source_'.$_SESSION['user_id'];
$_SESSION['RF']['language'] = $_SESSION['user_lang']; // Tenemos 3 idiomas configurados español (es), inglés (en), italiano (it)
if($sss['lang_entidad'] == 'en') $idioma = 'en_EN'; // Si entramos en la carpeta de responsivefilemanager/lang veremos los distintos idiomas
else $idioma = $_SESSION['user_lang'];
$_SESSION['RF']['language_file'] = 'lang/'.$idioma.'.php'; // Cargamos la configuración según el idioma