docs: sección 23 LOPDP Ecuador — router, bugs, verificación, requisitos para nuevos temas
This commit is contained in:
+122
-1
@@ -22,7 +22,8 @@ Sitio web personal de **hoja de vida / currículum ejecutivo** de **Patricia Sol
|
|||||||
```
|
```
|
||||||
pflores.linkedcorp.net/
|
pflores.linkedcorp.net/
|
||||||
├── backend/
|
├── backend/
|
||||||
│ ├── start-wordpress.sh # Arrancar el servidor PHP
|
│ ├── start-wordpress.sh # Arrancar el servidor PHP (usa router.php)
|
||||||
|
│ ├── router.php # Router PHP — permite URLs tipo /politica-de-privacidad/
|
||||||
│ └── wordpress/ # Instalación WordPress 7.0
|
│ └── wordpress/ # Instalación WordPress 7.0
|
||||||
│ ├── wp-config.php # Config dinámica (URL, auto-updates OFF)
|
│ ├── wp-config.php # Config dinámica (URL, auto-updates OFF)
|
||||||
│ ├── favicon.ico # Foto de Patricia, circular, 16/32/48px
|
│ ├── favicon.ico # Foto de Patricia, circular, 16/32/48px
|
||||||
@@ -458,6 +459,38 @@ Los temas deben manejar ambos formatos de competencias:
|
|||||||
</a>
|
</a>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### LOPDP — 3 requisitos obligatorios en todo tema nuevo
|
||||||
|
|
||||||
|
**1. Navegación con URLs absolutas** — en `functions.php`, la función que genera el menú debe usar `home_url('/')` como base cuando no se está en el front page:
|
||||||
|
|
||||||
|
```php
|
||||||
|
function NOMBRE_render_nav(): string {
|
||||||
|
// ...
|
||||||
|
$base = is_front_page() ? '' : home_url('/');
|
||||||
|
$items = [
|
||||||
|
$base . '#sobre-mi' => 'Sobre mí',
|
||||||
|
$base . '#experiencia' => 'Experiencia',
|
||||||
|
// ... resto de anclas igual
|
||||||
|
];
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Sin esto, los links del menú quedan como `#sobre-mi` en la página de política de privacidad y no llevan de vuelta al CV.
|
||||||
|
|
||||||
|
**2. `index.php` estilizado** — reescribir con el estilo del tema, botón "Volver al CV" y tipografía coherente. Ver los existentes como referencia: `frontend/persona-cv-theme/index.php`.
|
||||||
|
|
||||||
|
**3. Link de privacidad en el footer** — en `footer.php` o en la sección del copyright de `front-page.php`:
|
||||||
|
|
||||||
|
```php
|
||||||
|
<a href="<?php echo esc_url(home_url('/politica-de-privacidad/')); ?>"
|
||||||
|
style="opacity:.5;text-decoration:underline;font-size:.75rem;color:inherit">
|
||||||
|
Política de Privacidad · LOPDP
|
||||||
|
</a>
|
||||||
|
```
|
||||||
|
|
||||||
|
> El banner LOPDP y la página de política son globales — están en el plugin `pflores-cv-fields.php`, no en cada tema. Solo el link del footer y el index.php deben adaptarse por tema.
|
||||||
|
|
||||||
### `inc/cv-data.php` — función de fallback
|
### `inc/cv-data.php` — función de fallback
|
||||||
|
|
||||||
Debe contener **todos los datos reales** de Patricia Flores, idénticos a los que están en la BD. Copiar la función de otro tema y renombrar a `NOMBRE_cv_data()`.
|
Debe contener **todos los datos reales** de Patricia Flores, idénticos a los que están en la BD. Copiar la función de otro tema y renombrar a `NOMBRE_cv_data()`.
|
||||||
@@ -866,3 +899,91 @@ for f in os.listdir(src):
|
|||||||
"
|
"
|
||||||
rm -rf /tmp/wp.zip /tmp/wp_extract
|
rm -rf /tmp/wp.zip /tmp/wp_extract
|
||||||
```
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 23. LOPDP Ecuador — Implementación completa
|
||||||
|
|
||||||
|
### ¿Qué es y por qué existe?
|
||||||
|
|
||||||
|
La **Ley Orgánica de Protección de Datos Personales del Ecuador (LOPDP)** exige informar a los visitantes sobre el tratamiento de sus datos. Este sitio usa estadísticas anónimas de visitas (transients de WordPress, eliminados cada hora) con base legal en el **Art. 26 LOPDP — interés legítimo**.
|
||||||
|
|
||||||
|
### Componentes implementados
|
||||||
|
|
||||||
|
Todo el código LOPDP vive en `backend/wordpress/wp-content/plugins/pflores-cv-fields/pflores-cv-fields.php` (sección 3).
|
||||||
|
|
||||||
|
| Componente | Función | Dónde |
|
||||||
|
|---|---|---|
|
||||||
|
| `router.php` | Permite URLs bonitas (`/politica-de-privacidad/`) en el servidor PHP integrado | `backend/router.php` |
|
||||||
|
| Página de política | Creada automáticamente en `admin_init` con contenido completo | BD: `cv_posts`, `post_name = politica-de-privacidad` |
|
||||||
|
| Banner LOPDP | `wp_footer` — aparece en todos los temas, se acepta con `localStorage` | `pflores-cv-fields.php` función `pflores_lopd_banner()` |
|
||||||
|
| Widget dashboard | Estadísticas de visitas por tema + total | `pflores-cv-fields.php` función `pflores_visitas_widget()` |
|
||||||
|
| Link en footer | Cada tema tiene un enlace discreto "Política de Privacidad · LOPDP" | `footer.php` o `front-page.php` de cada tema |
|
||||||
|
| Nav con home_url | Menú funciona desde páginas internas | `functions.php` de cada tema |
|
||||||
|
| `index.php` estilizado | Páginas internas con estilo del tema + "Volver al CV" | `index.php` de cada tema |
|
||||||
|
|
||||||
|
### Infraestructura de URLs (router.php)
|
||||||
|
|
||||||
|
Sin el router, PHP built-in server devuelve 404 para `/politica-de-privacidad/`.
|
||||||
|
|
||||||
|
El archivo `backend/router.php`:
|
||||||
|
```php
|
||||||
|
<?php
|
||||||
|
$path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
|
||||||
|
$file = __DIR__ . '/wordpress' . $path;
|
||||||
|
if ($path !== '/' && file_exists($file) && !is_dir($file)) { return false; }
|
||||||
|
require_once __DIR__ . '/wordpress/index.php';
|
||||||
|
```
|
||||||
|
|
||||||
|
El `start-wordpress.sh` lo usa así:
|
||||||
|
```bash
|
||||||
|
exec php -S "${WP_HOST}:${WP_PORT}" -t "$WP_DIR" "$ROOT_DIR/backend/router.php"
|
||||||
|
```
|
||||||
|
|
||||||
|
Los permalinks en BD deben estar en `/%postname%/` (ya configurado en dev y prod).
|
||||||
|
|
||||||
|
### Bugs conocidos del banner — NO repetir
|
||||||
|
|
||||||
|
| Bug | Descripción | Fix correcto |
|
||||||
|
|---|---|---|
|
||||||
|
| `display:flex!important` en CSS | Impide que el JS pueda ocultar el banner (`style.display='none'` no funciona) | Usar `display:flex` sin `!important` |
|
||||||
|
| `banner.removeAttribute('hidden')` | No muestra el banner correctamente en todos los navegadores | Usar `banner.style.display = 'flex'` |
|
||||||
|
|
||||||
|
### Actualizar la página de política de privacidad
|
||||||
|
|
||||||
|
Desde el admin de WordPress: **Páginas → Política de Privacidad → Editar**.
|
||||||
|
|
||||||
|
O directamente en BD:
|
||||||
|
```bash
|
||||||
|
mysql -u "paty.wordpress" -p"PASSWORD" -h HOST "paty.wordpress" --ssl=0 -e "
|
||||||
|
UPDATE cv_posts SET post_content='NUEVO_CONTENIDO'
|
||||||
|
WHERE post_name='politica-de-privacidad' AND post_type='page';"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Si la página de política no existe en producción
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Verificar
|
||||||
|
mysql -u "paty.wordpress" -p"gS0mFSQrdnhSDN2b" -h 192.168.222.32 "paty.wordpress" --ssl=0 \
|
||||||
|
-e "SELECT ID, post_name, post_status FROM cv_posts WHERE post_name='politica-de-privacidad';" 2>/dev/null
|
||||||
|
|
||||||
|
# Si no existe, forzar creación visitando el admin:
|
||||||
|
curl -s http://127.0.0.1:8081/wp-admin/admin.php > /dev/null
|
||||||
|
# O insertar directamente en BD (ver PRODUCCION.md sección "Problemas conocidos")
|
||||||
|
```
|
||||||
|
|
||||||
|
### Verificación rápida
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Banner presente en el HTML
|
||||||
|
curl -s http://127.0.0.1:8081/ | grep -c "pflores-lopd-banner" # debe ser 5
|
||||||
|
|
||||||
|
# Página de política accesible
|
||||||
|
curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:8081/politica-de-privacidad/ # debe ser 200
|
||||||
|
|
||||||
|
# Contenido correcto
|
||||||
|
curl -s http://127.0.0.1:8081/politica-de-privacidad/ | grep -c "Art. 26\|LOPDP" # debe ser >= 1
|
||||||
|
|
||||||
|
# Sin cédula en el HTML público
|
||||||
|
curl -s http://127.0.0.1:8081/ | grep "1103591648" # debe retornar vacío
|
||||||
|
```
|
||||||
|
|||||||
Reference in New Issue
Block a user