¡Bienvenido a PHPost!

Para participar en el foro, descargar complementos y acceder al chat, necesitas una cuenta activa.

Descarga Risus Nova 2.0 para comenzar tu comunidad.

Regístrate Descargar Risus Nova

¿Ya tienes cuenta? Inicia sesión aquí

Últimos temas

Estadísticas del foro
  • Mensajes del foro:1,957
  • Temas del foro:614
  • Miembros:1,036
  • Último miembro:carlos007r


Enviado por: Tronlar
05-28-2026, 03:11 PM
Foro: Terminados
- Sin respuestas

Captcha en Login v1.0
Mejora de seguridad para Risus Nova 2.0 — PHPost


Captura
[img]Registrate o inicia tu sesión para ver este contenido[/img]


Añade el captcha de Cloudflare Turnstile al formulario de login, el mismo que ya tiene el registro. Evita ataques de fuerza bruta automatizados y bots que intenten acceder a cuentas.



🛡️ Características
 
  • Usa el mismo Cloudflare Turnstile ya configurado en el registro
  • Sin instalador ni base de datos
  • Solo 2 cambios en 2 archivos
  • Si no hay clave configurada el captcha se omite — no rompe nada
  • Compatible con el mod de Protección de Login y 2FA
 


📋 Requisitos
 
  • Risus Nova 2.0 instalado y funcionando
  • Cloudflare Turnstile configurado (clave pública y secreta en los ajustes del admin)
 


🛠️ Instalación

Paso 1 — Añadir el widget en head_menu.tpl

Abre themes/default/templates/sections/head_menu.tpl y busca:

 
Código:
<input type="submit" title="Entrar" value="Entrar" style="width:198px; margin-top:5px;" class="mBtn btnOk">

Cámbialo por:
 
Código:
<div class="cf-turnstile" data-sitekey="{$tsConfig.pkey}" data-size="compact" style="margin:8px 0;"></div>
<input type="submit" title="Entrar" value="Entrar" style="width:198px; margin-top:5px;" class="mBtn btnOk">

Paso 2 — Añadir el script de Turnstile en main_header.tpl

Abre themes/default/templates/sections/main_header.tpl y añade antes de </head>:

 
Código:
<script src="Registrate o inicia tu sesión para ver este contenido" async defer></script>

Paso 3 — Verificar el captcha en ajax.login.php

Abre inc/php/ajax/ajax.login.php y busca:

 
Código:
if(empty($user) or empty($pass)) {
    echo '0: Faltan datos';
} else {

Cámbialo por:
 
Código:
if(empty($user) or empty($pass)) {
    echo '0: Faltan datos';
} else {
    // ── Verificar Turnstile ──
    $captcha = $_POST['cf-turnstile-response'] ?? '';
    if (!empty($tsCore->settings['pkey']) && !empty($tsCore->settings['skey'])) {
        $opts = ['http' => ['method' => 'POST', 'header' => 'Content-type: application/x-www-form-urlencoded', 'content' => http_build_query(['secret' => $tsCore->settings['skey'], 'response' => $captcha, 'remoteip' => $tsCore->getIP()])]];
        $res  = json_decode(@file_get_contents('Registrate o inicia tu sesión para ver este contenido false, stream_context_create($opts)), true);
        if (empty($res['success'])) { echo '0: Verifica que no eres un robot.'; break; }
    }
    // ────────────────────────

Paso 4 — Borrar la caché

Borra el contenido de la carpeta /cache/ del sitio.


🗑️ Desinstalar

Restaura las líneas originales en head_menu.tpl y ajax.login.php.

 
¿Tienes dudas o encuentras algún problema? Déjalo en los comentarios.






Imprimir


Enviado por: Tronlar
05-28-2026, 01:20 PM
Foro: Terminados
- Sin respuestas

Doble Factor de Autenticación (2FA) v1.0
Nuevo módulo para Risus Nova 2.0 — PHPost


Captura
[img]Registrate o inicia tu sesión para ver este contenido[/img]
 
[img]Registrate o inicia tu sesión para ver este contenido[/img]
 
[img]Registrate o inicia tu sesión para ver este contenido[/img]
 


Cada usuario puede activar el 2FA desde su cuenta. Al iniciar sesión, si las credenciales son correctas, se le pide un código de 6 dígitos enviado a su email antes de entrar.


🛡️ Características
 
  • Código de 6 dígitos criptográficamente seguro
  • Expira en 5 minutos
  • Solo se puede usar una vez
  • Máximo 3 intentos fallidos antes de invalidar
  • Reenvío con límite de 60 segundos
  • Cada usuario activa/desactiva desde su cuenta
  • Email con diseño moderno
  • Compatible con el mod de Protección de Login
 


📋 Requisitos
 
  • Risus Nova 2.0 instalado y funcionando
  • PHP 8.0+
  • Correo mail() configurado en el servidor
 


🛠️ Instalación

Paso 1 — Ejecutar el instalador

Sube la carpeta install/ a la raíz y accede a:

 
Código:
Registrate o inicia tu sesión para ver este contenido

⚠️ Elimina la carpeta install/ cuando termine.

Paso 2 — Subir los archivos
 
Código:
inc/class/c.2fa.php                      →  inc/class/
inc/php/2fa.php                          →  inc/php/
inc/php/ajax/ajax.2fa.php               →  inc/php/ajax/
themes/default/templates/t.2fa.tpl     →  themes/default/templates/

Paso 3 — En ajax.login.php

Dentro del case 'login-user', donde se llama a loginUser, buscar:
Código PHP:
if(empty($user) or empty($pass)) echo '0: Faltan datos';
else echo 
$tsUser->loginUser($user$pass$reme); 


Reemplazar por:
 
Código:
if(empty($user) or empty($pass)) {
    echo '0: Faltan datos';
} else {
    $resultado = $tsUser->loginUser($user, $pass, $reme);

    if ($resultado === TRUE || is_numeric($resultado)) {
        // ── 2FA ──
        require_once TS_CLASS . 'c.2fa.php';
        $ts2FA = new ts2FA();
        if ($ts2FA->tieneActivo($tsUser->uid)) {
            $tsUser->logoutUser($tsUser->uid, null);
            $_SESSION['ts_2fa_pending']  = $tsUser->uid;
            $_SESSION['ts_2fa_remember'] = $reme;
            $ts2FA->enviarCodigo($tsUser->uid);
            echo '3: ' . $tsCore->settings['url'] . '/2fa/';
            break;
        }
        // ────────
        echo $resultado;
    } else {
        echo $resultado;
    }
}

Paso 4 — En m.cuenta_cuenta.tpl

Buscar:
Código PHP:
<div class="buttons">
<
input type="button" value="Guardar" onclick="cuenta.save(1)" class="mBtn btnOk">
<
input type="button" value="Siguiente" onclick="cuenta.save(1, true)" class="mBtn btnOk">
</
div


Arriba agregar:
 
Código:
<div class="field">
    <label>Verificación en dos pasos (2FA):</label>
    <div style="padding:10px; background:#f8f9fa; border-radius:6px; border:1px solid #eee;">
        <label style="display:flex; align-items:center; gap:10px; cursor:pointer;">
            <input type="checkbox" name="2fa"
                   {if $tsUser->info.user_2fa}checked{/if}
                   onchange="cuenta.toggle2FA(this.checked)"/>
            <span>
                <strong>Activar 2FA</strong><br>
                <small style="color:#888; font-weight:400;">Al iniciar sesión se te pedirá un código enviado a tu email.</small>
            </span>
        </label>
    </div>
</div>

Y en cuenta.js buscar:
Código PHP:
}

}

var 
avatar = { 


Reemplazar por:
 
Código:
},

    toggle2FA: function(activo) {
        $.ajax({
            type: 'POST',
            url: global_data.url + '/2fa-toggle.php',
            data: { activo: activo ? 1 : 0 },
            dataType: 'json',
            success: function(r) {
                if (r.ok) {
                    cuenta.alert(1, activo ? '2FA activado' : '2FA desactivado', activo ? 'Ahora se pedirá un código al iniciar sesión.' : 'La verificación en dos pasos ha sido desactivada.');
                }
            }
        });
    }

}

var avatar = {

Paso 5 — Borrar la caché

Borra el contenido de la carpeta /cache/ del sitio.


🗑️ Desinstalar
 
Código:
ALTER TABLE u_miembros DROP COLUMN user_2fa;
DROP TABLE IF EXISTS w_2fa_tokens;

Elimina los archivos y quita el hook de ajax.login.php.

 
Descarga


Mediafire
http://Registrate o inicia tu sesión par... contenido

Google Drive
http://Registrate o inicia tu sesión par... contenido



¿Tienes dudas o encuentras algún problema? Déjalo en los comentarios.




Imprimir


Enviado por: Tronlar
05-28-2026, 12:16 PM
Foro: Terminados
- Sin respuestas

Historial de Búsquedas v1.0
Nuevo módulo para Risus Nova 2.0 — PHPost


Captura
[img]Registrate o inicia tu sesión para ver este contenido[/img]


Guarda las últimas 10 búsquedas del usuario en la sesión y las muestra debajo del campo de búsqueda como píldoras clicables para repetirlas con un clic.


🔍 Características
 
  • Sin base de datos ni instalador
  • Solo 2 archivos a sustituir
  • Guarda hasta 10 búsquedas por sesión
  • No guarda duplicados — si buscas lo mismo lo mueve al principio
  • Clic en una búsqueda anterior la repite directamente
  • Botón para borrar el historial con un clic
  • Solo visible cuando hay historial guardado
 


📋 Requisitos
 
  • Risus Nova 2.0 instalado y funcionando
  • PHP 8.0+
 


🛠️ Instalación

Solo hay que sustituir 2 archivos:
 
Código:
inc/php/buscador.php          →  inc/php/
themes/default/templates/t.buscador.tpl  →  themes/default/templates/

Borra la caché después de subir.


🗑️ Desinstalar

Restaura los archivos originales de buscador.php y t.buscador.tpl. No hay tablas que borrar.

 
 
Descarga

Mediafire
http://Registrate o inicia tu sesión par... contenido

Google Drive
http://Registrate o inicia tu sesión par... contenido


¿Tienes dudas o encuentras algún problema? Déjalo en los comentarios.






Imprimir


Enviado por: Tronlar
05-28-2026, 11:45 AM
Foro: Terminados
- Sin respuestas

Chat en Tiempo Real v1.0
Nuevo módulo para Risus Nova 2.0 — PHPost


Captura
[img]Registrate o inicia tu sesión para ver este contenido[/img]


Sala de chat global en /chat/ con actualización automática cada 3 segundos. Solo usuarios registrados. Muestra los últimos 100 mensajes y la lista de usuarios conectados en tiempo real.


💬 Características
 
  • Polling cada 3 segundos — funciona en cualquier hosting compartido
  • Solo usuarios registrados pueden chatear
  • Anti-flood — máximo 1 mensaje cada 2 segundos
  • Mensajes guardados 24 horas y luego borrados automáticamente
  • Lista de usuarios conectados en tiempo real
  • Admins pueden borrar mensajes con un clic
  • Máximo 500 caracteres por mensaje
  • Compatible con el sistema de palabras prohibidas del script
 


📋 Requisitos
 
  • Risus Nova 2.0 instalado y funcionando
  • PHP 8.0+
  • MySQL 5.7+ / MariaDB 10.4+
 


🛠️ Instalación

Paso 1 — Ejecutar el instalador

Sube la carpeta install/ a la raíz y accede a:

 
Código:
Registrate o inicia tu sesión para ver este contenido

⚠️ Elimina la carpeta install/ cuando termine.


Paso 2 — Subir los archivos
 
Código:
inc/php/chat.php                        →  inc/php/
inc/class/c.chat.php                    →  inc/class/
inc/php/ajax/ajax.chat.php              →  inc/php/ajax/
themes/default/templates/t.chat.tpl    →  themes/default/templates/

Paso 3 — En head_menu.tpl

Pon esto donde quieras:
 
Código:
<li class="tabbed {if $tsPage == 'chat'}here{/if}" id="tabbedchat">
    <a href="{$tsConfig.url}/chat/">
        <i class="fa-solid fa-comments"></i> Chat
    </a>
</li>

Paso 4 — Borrar la caché

Borra el contenido de la carpeta /cache/ del sitio.


🗑️ Desinstalar
 
Código:
DROP TABLE IF EXISTS w_chat;
DROP TABLE IF EXISTS w_chat_presencia;

Elimina los archivos y quita la ruta del .htaccess.

 
Descarga

Mediafire
http://Registrate o inicia tu sesión par... contenido

Google Drive
http://Registrate o inicia tu sesión par... contenido



¿Tienes dudas o encuentras algún problema? Déjalo en los comentarios.



Imprimir


Enviado por: Tronlar
05-28-2026, 11:05 AM
Foro: Terminados
- Sin respuestas

Tiempo de Lectura v1.0
Nuevo módulo para Risus Nova 2.0 — PHPost


Captura
[img]Registrate o inicia tu sesión para ver este contenido[/img]
 


Muestra el tiempo estimado de lectura en la cabecera de cada post, justo debajo del título. Basado en una velocidad media de 200 palabras por minuto, igual que Medium o Dev.to.


⏱️ Características
 
  • Sin base de datos ni instalador
  • Solo 2 cambios en 2 archivos
  • Calcula el tiempo en PHP — sin JavaScript
  • Muestra mínimo 1 minuto
  • Ignora el HTML del cuerpo — cuenta solo el texto

Ejemplos:
  • Post de 400 palabras → 2 min de lectura
  • Post de 50 palabras → 1 min de lectura
  • Post de 1000 palabras → 5 min de lectura
 


🛠️ Instalación

Paso 1 — En posts.php

Buscar en inc/php/posts.php:

 
Código:
$smarty->assign("tsPost",$tsPost);

Agregar debajo:
 
Código:
// ── Tiempo de lectura ──
$texto_plano = strip_tags(html_entity_decode($tsPost['post_body'], ENT_QUOTES, 'UTF-8'));
$palabras    = str_word_count($texto_plano);
$minutos     = max(1, (int)ceil($palabras / 200));
$smarty->assign('tsTiempoLectura', $minutos);
// ───────────────────────

Paso 2 — Añadir en m.posts_content.tpl

Buscar:
 
Código:
<h1>{$tsPost.post_title}</h1>

Añade justo después:
 
Código:
{if $tsTiempoLectura}
<div style="font-size:12px; color:#999; margin-top:4px; font-weight:400;">
    <i class="fa-regular fa-clock"></i> {$tsTiempoLectura} min de lectura
</div>
{/if}

O sube directamente el m.posts_content.tpl que dejo adjunto que ya incluye el cambio.


🗑️ Desinstalar

Quita las líneas añadidas en posts.php y el bloque del título en m.posts_content.tpl.

 
Descarga

Mediafire
http://Registrate o inicia tu sesión par... contenido

Google Drive
http://Registrate o inicia tu sesión par... contenido


¿Tienes dudas o encuentras algún problema? Déjalo en los comentarios.



Imprimir


Enviado por: Tronlar
05-28-2026, 10:38 AM
Foro: Terminados
- Sin respuestas

Sistema de Referidos v1.0
Nuevo módulo para Risus Nova 2.0 — PHPost


Capturas
 
[img]Registrate o inicia tu sesión para ver este contenido[/img]
 
[img]Registrate o inicia tu sesión para ver este contenido[/img]
 
[img]Registrate o inicia tu sesión para ver este contenido[/img]
 


Cada usuario tiene un enlace de invitación único. Cuando alguien se registra con ese enlace y activa su cuenta, el que invitó gana 10 puntos automáticamente y recibe una notificación.


🤝 Características
 
  • Enlace de referido único por usuario: tudominio.com/registro?ref=NICK
  • Puntos solo al activar la cuenta — evita cuentas falsas
  • Un usuario solo puede tener un referidor
  • Nadie puede referirse a sí mismo
  • Notificación automática al ganar los puntos
  • Widget en el perfil con enlace, estadísticas y lista de invitados
  • Botón copiar enlace con un clic
  • El ref se guarda en sesión — no se pierde si el usuario navega antes de registrarse
 


📋 Requisitos
 
  • Risus Nova 2.0 instalado y funcionando
  • PHP 8.0+
  • MySQL 5.7+ / MariaDB 10.4+
 


🛠️ Instalación

Paso 1 — Ejecutar el instalador

Sube la carpeta install/ a la raíz y accede a:

 
Código:
Registrate o inicia tu sesión para ver este contenido

⚠️ Elimina la carpeta install/ cuando termine.


Paso 2 — Subir los archivos
 
Código:
inc/class/c.referidos.php                              →  inc/class/
themes/default/templates/modules/m.perfil_referidos.tpl →  themes/default/templates/modules/

Paso 3 — En c.registro.php

Buscar:
 
Código:
$tsData['user_id'] = db_exec('insert_id');

Añade justo después:
 
Código:
// ── Referidos ──
require_once TS_CLASS . 'c.referidos.php';
$ref_nick = isset($_SESSION['ref_nick']) ? $_SESSION['ref_nick'] : ($tsCore->setSecure($_GET['ref'] ?? '') ?: $tsCore->setSecure($_POST['ref'] ?? ''));
if (!empty($ref_nick)) {
    $tsRef = new tsReferidos();
    $tsRef->guardarReferido($tsData['user_id'], $ref_nick);
}
// ────────────────

Paso 4 — En c.user.php — userActivate()

Abre inc/class/c.user.php y busca dentro de userActivate() esta línea:
 
Código:
if(db_exec(array(__FILE__, __LINE__), 'query', 'UPDATE u_miembros SET user_activo = 1 WHERE user_id = \''.$tsUserID.'\'' )) {
    return $tsData;

Cambiar por:
 
Código:
if(db_exec(array(__FILE__, __LINE__), 'query', 'UPDATE u_miembros SET user_activo = 1 WHERE user_id = \''.$tsUserID.'\'' )) {
    require_once TS_CLASS . 'c.referidos.php';
    $tsRef = new tsReferidos();
    $tsRef->procesarActivacion((int)$tsUserID);
    return $tsData;

Esto cubre tanto la activación por email como la activación directa sin email.

Paso 5 — Guardar ref en sesión (header.php)

Al final de header.php añade:
 
Código:
// ── Guardar ref en sesión ──
if (!empty($_GET['ref'])) {
    $_SESSION['ref_nick'] = $tsCore->setSecure($_GET['ref']);
}
// ───────────────────────────

Paso 6 — Widget en el perfil

En perfil.php buscar:
Código PHP:
$smarty->assign("tsGeneral",$tsGeneral); 

Debajo agregar:
 
Código:
// ── Referidos ──
require_once TS_CLASS . 'c.referidos.php';
if ($tsUser->uid == $usuario['user_id']) {
    $tsRef = new tsReferidos();
    $ref_data = $tsRef->getReferidos($tsUser->uid);
    $ref_data['url'] = tsReferidos::getUrl($tsUser->nick);
    $ref_data['puntos_por_referido'] = tsReferidos::PUNTOS_POR_REFERIDO;
    $smarty->assign('tsReferidos', $ref_data);
}
// ────────────────

En m.perfil_sidebar.tpl añade donde quieras:
Código:
{include file='modules/m.perfil_referidos.tpl'}
 


⚙️ Configurar puntos

Los puntos por referido se configuran en inc/class/c.referidos.php:
Código:
const PUNTOS_POR_REFERIDO = 10;
 


🗑️ Desinstalar
 
Código:
DROP TABLE IF EXISTS u_referidos;

Elimina los archivos y quita los hooks añadidos.

 
Descarga

Mediafire
http://Registrate o inicia tu sesión par... contenido

Google Drive
http://Registrate o inicia tu sesión par... contenido



¿Tienes dudas o encuentras algún problema? Déjalo en los comentarios.



Imprimir


Enviado por: Tronlar
05-28-2026, 09:45 AM
Foro: Terminados
- Sin respuestas

Reacciones en Posts v1.0
Nuevo módulo para Risus Nova 2.0 — PHPost


Capturas
[img]Registrate o inicia tu sesión para ver este contenido[/img]
 
[img]Registrate o inicia tu sesión para ver este contenido[/img]
 
[img]Registrate o inicia tu sesión para ver este contenido[/img]


Añade un sistema de reacciones con 6 emojis en cada post. Convive con el sistema de puntos existente — son completamente independientes. Un usuario puede dar puntos Y reaccionar al mismo post.


😊 Reacciones disponibles
 
  • 👍 Me gusta
  • ❤️ Me encanta
  • 😂 Divertido
  • 😮 Sorprendente
  • 😢 Triste
  • 😡 Enfadado
 


⚡ Características
 
  • Un usuario solo puede tener una reacción por post
  • Cambiar de reacción reemplaza la anterior automáticamente
  • Pulsar la misma reacción la quita (toggle)
  • Solo usuarios registrados pueden reaccionar
  • Resumen visual con emojis y total de reacciones
  • Actualización instantánea sin recargar la página
  • Convive con el sistema de puntos — no lo reemplaza
 


📋 Requisitos
 
  • Risus Nova 2.0 instalado y funcionando
  • PHP 8.0+
  • MySQL 5.7+ / MariaDB 10.4+
 


🛠️ Instalación

Paso 1 — Ejecutar el instalador

Sube la carpeta install/ a la raíz y accede a:
 
Código:
Registrate o inicia tu sesión para ver este contenido

Pulsa Instalar ahora. Crea la tabla p_reacciones.

⚠️ Elimina la carpeta install/ cuando termine.


Paso 2 — Subir los archivos
 
Código:
inc/class/c.reacciones.php                          →  inc/class/
inc/php/ajax/ajax.reacciones.php                    →  inc/php/ajax/
themes/default/templates/modules/m.reacciones.tpl  →  themes/default/templates/modules/

Paso 3 — En posts.php

Busca en inc/php/posts.php la línea:

 
Código:
$smarty->assign("tsPost",$tsPost);

Añade justo después:
 
Código:
// ── Reacciones ──
require_once TS_CLASS . 'c.reacciones.php';
$tsReac = new tsReacciones();
$smarty->assign('tsReacciones', $tsReac->getReacciones($tsPost['post_id']));
// ────────────────

Paso 4 — Añadir en m.posts_metadata.tpl

Busca el bloque de estadísticas que termina con </ul>:
 
Código PHP:
<div style="margin-top: 5px;">
<
strong style="color: #333; font-size: 15px; display: block; line-height: 1;">{$tsPost.post_seguidores}</strong>
<
span style="color: #999; font-size: 11px; text-transform: uppercase;">Seguidores</span>
</
div>
</
li>
</
ul

Debajo agregar:
 
Código:
{include file='modules/m.reacciones.tpl'}

Paso 5 — Borrar la caché

Borra el contenido de la carpeta /cache/ del sitio.


🗑️ Desinstalar
 
Código:
DROP TABLE IF EXISTS p_reacciones;

Elimina los archivos subidos y quita los hooks añadidos.

 
Descarga

Mediafire
http://Registrate o inicia tu sesión par... contenido

Google Drive
http://Registrate o inicia tu sesión par... contenido


¿Tienes dudas o encuentras algún problema? Déjalo en los comentarios.




Imprimir


Enviado por: Tronlar
05-27-2026, 08:48 PM
Foro: Terminados
- Sin respuestas

Posts Programados v1.0
Nuevo módulo para Risus Nova 2.0 — PHPost


Capturas
 
[img]Registrate o inicia tu sesión para ver este contenido[/img]
 
[img]Registrate o inicia tu sesión para ver este contenido[/img]
 
[img]Registrate o inicia tu sesión para ver este contenido[/img]
 
[img]Registrate o inicia tu sesión para ver este contenido[/img]
 
[img]Registrate o inicia tu sesión para ver este contenido[/img]
 
[img]Registrate o inicia tu sesión para ver este contenido[/img]
 


Permite a administradores y moderadores programar la publicación de posts en una fecha y hora concretas. El post se guarda como "programado" y se publica automáticamente cuando llega la hora, sin que nadie tenga que hacer nada.


🕐 Características
 
  • Solo admins y moderadores pueden programar posts
  • Mínimo 5 minutos en el futuro, máximo 1 año
  • Publicación automática al cargar cualquier página
  • Panel en el admin para ver todos los posts programados
  • Publicar manualmente antes de la hora con un clic
  • Cancelar devuelve el post a borradores
  • Validación estricta de fechas — no se puede manipular desde el frontend
 


📋 Requisitos
 
  • Risus Nova 2.0 instalado y funcionando
  • PHP 8.0+
  • MySQL 5.7+ / MariaDB 10.4+
 


🛠️ Instalación

Paso 1 — Ejecutar el instalador

Sube la carpeta install/ a la raíz y accede a:

 
Código:
Registrate o inicia tu sesión para ver este contenido

Pulsa Instalar ahora. Añade la columna post_publish_at en la tabla p_posts.

⚠️ Elimina la carpeta install/ cuando termine.


Paso 2 — Subir los archivos
 
Código:
inc/class/c.scheduled.php                              →  inc/class/
inc/php/ajax/ajax.scheduled.php                        →  inc/php/ajax/
themes/default/templates/modules/m.scheduled_form.tpl →  themes/default/templates/modules/
themes/default/templates/modules/m.scheduled_admin.tpl →  themes/default/templates/admin_mods/

Paso 3 — En c.posts.php

Busca el return $postID; al final de newPost() y añade justo antes:
 
Código:
// ── Posts programados ──
if (!empty($_POST['post_publish_at']) && $tsUser->is_admod) {
    require_once TS_CLASS . 'c.scheduled.php';
    $tsSched = new tsScheduled();
    $ts = tsScheduled::parseFecha($_POST['post_publish_at']);
    if ($ts > 0) {
        $tsSched->programar($postID, $ts);
    }
}
// ────────────────────────

Paso 4 — En header.php

Abre header.php de la raíz y añade al final, antes del cierre:
 
Código:
// ── Publicar posts programados ──
require_once TS_CLASS . 'c.scheduled.php';
(new tsScheduled())->publicarPendientes();
// ────────────────────────────────

Paso 5 — En m.agregar.form.tpl

Buscar:
{if ($tsUser->is_admod > 0 || $tsUser->permisos.moedpo) && $tsDraft.b_title && $tsDraft.b_user != $tsUser->uid}

Arriba agregar:
 
Código:
{include file='modules/m.scheduled_form.tpl'}

Paso 6 — Panel en el admin

En admin.php añade antes de :
 
Código PHP:
} elseif($action == 'feed'){ 

Agregar:
 
Código:
} elseif($action == 'scheduled'){
    require_once TS_CLASS . 'c.scheduled.php';
    $tsSched = new tsScheduled();
    $smarty->assign('tsProgramados', $tsSched->getProgramados());

En t.admin.tpl añade antes del {/if} final:
 
Código:
{elseif $tsAction == 'scheduled'}
{include file='admin_mods/m.scheduled_admin.tpl'}

En m.admin_sidemenu.tpl añade donde prefieras:
 
Código:
<li id="a_scheduled">
    <a href="{$tsConfig.url}/admin/scheduled">
        <span class="nav-icon">🕐</span> Posts Programados
    </a>
</li>

Paso 7 — Borrar la caché

Borra el contenido de la carpeta /cache/ del sitio.


🗑️ Desinstalar
 
Código:
ALTER TABLE p_posts DROP COLUMN post_publish_at;

Elimina los archivos subidos y quita los hooks añadidos.

 
Descarga

Mediafire
http://Registrate o inicia tu sesión par... contenido

Google Drive
http://Registrate o inicia tu sesión par... contenido


¿Tienes dudas o encuentras algún problema? Déjalo en los comentarios.


Imprimir


Enviado por: Tronlar
05-27-2026, 05:41 PM
Foro: Terminados
- Sin respuestas

Protección de Login v1.0
Nuevo módulo para Risus Nova 2.0 — PHPost


Protección contra ataques de fuerza bruta en el login. Bloquea automáticamente por IP y por nick tras demasiados intentos fallidos, con bloqueo progresivo y log completo de accesos visible desde el panel de admin.


Capturas
[img]Registrate o inicia tu sesión para ver este contenido[/img]
 
[img]Registrate o inicia tu sesión para ver este contenido[/img]
 
[img]Registrate o inicia tu sesión para ver este contenido[/img]
 
[img]Registrate o inicia tu sesión para ver este contenido[/img]


🛡️ Características
 
  • Doble bloqueo — por IP y por nombre de usuario de forma independiente
  • Bloqueo progresivo — 1er bloqueo 15 min, 2do 1 hora, 3er bloqueo y siguientes 24 horas
  • 5 intentos antes de bloquear (configurable en el código)
  • Admin nunca se bloquea
  • Login correcto resetea los contadores
  • Log completo — fecha, IP, nick y resultado de cada intento (guardado 7 días)
  • Panel en el admin — ver intentos y desbloquear manualmente con un clic
  • Aviso al usuario — muestra cuántos intentos le quedan antes del bloqueo
 


📋 Requisitos
 
  • Risus Nova 2.0 instalado y funcionando
  • PHP 8.0+
  • MySQL 5.7+ / MariaDB 10.4+
 


🛠️ Instalación

Paso 1 — Ejecutar el instalador

Sube la carpeta install/ a la raíz del sitio y accede a:
 
Código:
Registrate o inicia tu sesión para ver este contenido

Pulsa Instalar ahora. El instalador creará:
  • w_login_log — registro de todos los intentos de login
  • w_login_bloqueos — bloqueos activos por IP y nick

⚠️ Elimina la carpeta install/ del servidor cuando termine.


Paso 2 — Subir los archivos
 
Código:
inc/class/c.loginlog.php                  →  inc/class/
inc/php/ajax/ajax.loginlog.php            →  inc/php/ajax/
themes/default/css/loginlog.css          →  themes/default/css/
themes/default/templates/modules/
  m.loginlog_admin.tpl                    →  themes/default/templates/modules/

Paso 3 — En ajax.login.php

Abre inc/php/ajax/ajax.login.php y reemplaza el case 'login-user' completo por:

 
Código:
case 'login-user':
            //<---
                $user = $tsCore->setSecure($_POST['nick']);
                $pass = $tsCore->setSecure($_POST['pass']);
                $reme = (($_POST['rem'] ?? '') == 'true') ? true : false;
                //
                if(empty($user) or empty($pass)) echo '0: Faltan datos';
                else echo $tsUser->loginUser($user, $pass, $reme);
            //--->
        break;
 
Cambiar por:
 
Código:
case 'login-user':
    //<---
    $user = $tsCore->setSecure($_POST['nick']);
    $pass = $tsCore->setSecure($_POST['pass']);
    $reme = (($_POST['rem'] ?? '') == 'true') ? true : false;
    $ip   = $tsCore->getIP();

    if (empty($user) || empty($pass)) {
        echo '0: Faltan datos';
        break;
    }

    // ── Protección login ──
    require_once TS_CLASS . 'c.loginlog.php';
    $tsLL = new tsLoginLog();

    $bloqueo = $tsLL->estaBloqueado($user, $ip);
    if ($bloqueo) {
        $tiempo = $tsLL->formatearTiempo($bloqueo['faltan']);
        echo '0: Demasiados intentos fallidos. Inténtalo de nuevo en ' . $tiempo . '.';
        break;
    }

    $resultado = $tsUser->loginUser($user, $pass, $reme);

    if ($resultado === TRUE || is_numeric($resultado)) {
        $tsLL->registrar($user, $ip, true);
        $tsLL->resetear($user, $ip);
        echo $resultado;
    } else {
        $tsLL->registrar($user, $ip, false);
        $info = $tsLL->procesarFallo($user, $ip);
        $restantes = $info['restantes'];
        if ($restantes > 0) {
            echo $resultado . ' (' . $restantes . ' intento' . ($restantes != 1 ? 's' : '') . ' restante' . ($restantes != 1 ? 's' : '') . ')';
        } else {
            echo '0: Cuenta bloqueada temporalmente por seguridad.';
        }
    }
    // ────────────────────
    //--->
break;

Paso 4 — Panel en el admin (opcional)

Para ver el log desde el panel de admin añade en la plantilla t.admin.pl arriba de:

 
Código:
{/if}
 
 
Código:
{elseif $tsAction == 'loginlog'}
                                {include file='admin_mods/m.loginlog_admin.tpl'}

En admin.php buscar:
 
Código PHP:
} elseif($action == 'feed'){ 


Agregar antes:
 
Código:
} elseif($action == 'loginlog'){
    require_once TS_CLASS . 'c.loginlog.php';
    $tsLL = new tsLoginLog();
    $smarty->assign('tsLoginLog', $tsLL->getLog());
    $smarty->assign('tsBloqueos', $tsLL->getBloqueos());


En m.admin_sidemenu.tpl buscar:
 
Código PHP:
<h4>Usuarios</h4>
<
ul class="admin-nav-list">
<
li id="a_users"><a href="{$tsConfig.url}/admin/users"><span class="nav-icon">👤</spanUsuarios</a></li>
<
li id="a_sesiones"><a href="{$tsConfig.url}/admin/sesiones"><span class="nav-icon">🔑</spanSesiones</a></li>
<
li id="a_nicks"><a href="{$tsConfig.url}/admin/nicks"><span class="nav-icon">🆔</spanNicks</a></li>
<
li id="a_rangos"><a href="{$tsConfig.url}/admin/rangos"><span class="nav-icon">💎</spanRangos</a></li>
</
ul


Debajo agregar:
 
Código PHP:
<h4>Seguridad</h4>
<
ul class="admin-nav-list">
<
li id="a_loginlog"><a href="{$tsConfig.url}/admin/loginlog"><span class="nav-icon">🛡️</spanProtección Login</a></li>
</
ul


Paso 5 — Borrar la caché

Borra el contenido de la carpeta /cache/ del sitio.


🗑️ Desinstalar
 
Código:
DROP TABLE IF EXISTS w_login_log;
DROP TABLE IF EXISTS w_login_bloqueos;

Elimina los archivos subidos y restaura el case 'login-user' original en ajax.login.php.

 
Descarga

Mediafire
http://Registrate o inicia tu sesión par... contenido

Google Drive
http://Registrate o inicia tu sesión par... contenido



¿Tienes dudas o encuentras algún problema? Déjalo en los comentarios.

Imprimir


Enviado por: Tronlar
05-27-2026, 04:08 PM
Foro: Terminados
- Sin respuestas

Vídeos y Medios Embebidos v1.0
Nuevo módulo para Risus Nova 2.0 — PHPost


Con este mod basta con pegar una URL en el cuerpo de un post para que se convierta automáticamente en el player embebido correspondiente. Sin etiquetas especiales, sin código — solo la URL en una línea.


▶ Captura
[img]Registrate o inicia tu sesión para ver este contenido[/img]


▶ Plataformas soportadas
 
  • YouTube — youtube.com/watch?v=ID, youtu.be/ID y /shorts/ID
  • Vimeo — vimeo.com/ID
  • Twitter / X — tweets embebidos con el widget oficial
  • Spotify — canciones, álbumes, playlists, podcasts y episodios
  • TikTok — vídeos embebidos con el widget oficial
 


✨ Características
 
  • Sin instalador — no crea tablas ni modifica la base de datos
  • Detección automática de la plataforma por la URL
  • Player responsive adaptado a móvil
  • Carga lazy para no ralentizar la página
  • No modifica los datos guardados en BD, solo el renderizado
  • Spotify adapta la altura según el tipo (track/podcast = compacto, álbum/playlist = expandido)
 


🔒 Seguridad

Cada URL pasa por una cadena de validaciones antes de generar el embed:
 
  • IDs estrictamente validados — YouTube acepta solo exactamente 11 caracteres alfanuméricos. Vimeo solo dígitos. Twitter, TikTok y Spotify tienen sus propios rangos y patrones
  • Lista blanca de tipos en Spotify — solo se permiten track, album, playlist, episode y show. Cualquier otro valor se ignora
  • Sandbox en iframes — todos los iframes tienen el atributo sandbox con los permisos mínimos necesarios para funcionar
  • youtube-nocookie.com — YouTube se carga desde el dominio de privacidad mejorada para no rastrear a los usuarios
  • Vimeo con ?dnt=1 — Do Not Track activado
  • URLs reconstruidas — nunca se usa la URL original del usuario directamente en el src del iframe. Se construye una URL nueva y limpia con el ID validado
  • Si el ID no pasa la validación — se deja la URL original sin tocar en lugar de romper el post
 


📋 Requisitos
 
  • Risus Nova 2.0 instalado y funcionando
  • PHP 8.0+
 


🛠️ Instalación

Paso 1 — Subir los archivos
 
Código:
inc/class/c.embed.php        →  inc/class/
themes/default/css/embed.css →  themes/default/css/


Paso 2 — En c.posts.php

Abre inc/class/c.posts.php y busca dentro de getPost() este bloque:
 
Código:
$postData['post_body'] = preg_replace(
        '/<oembed url="https:\/\/www\.youtube\.com\/watch\?v=([^"]+)"><\/oembed>/s',
        '<iframe width="560" height="315" src="Registrate o inicia tu sesión para ver este contenido" frameborder="0" allowfullscreen></iframe>',
        $postData['post_body']
        );

Justo después añade:
 
Código:
// ── Embeds automáticos ──
require_once TS_CLASS . 'c.embed.php';
$tsEmbed = new tsEmbed();
$postData['post_body'] = $tsEmbed->process($postData['post_body']);
// ────────────────────────

Paso 3 — Borrar la caché

Borra el contenido de la carpeta /cache/ del sitio.


📝 Uso

Al crear un post pega la URL en el cuerpo en una línea aparte:
 
Código:
Mira este vídeo:
Registrate o inicia tu sesión para ver este contenido

Y esta canción:
Registrate o inicia tu sesión para ver este contenido

El mod la detecta y la convierte automáticamente en el player al mostrar el post.


🗑️ Desinstalar
 
  • Elimina inc/class/c.embed.php
  • Elimina themes/default/css/embed.css
  • Quita el hook añadido en c.posts.php
  • Borra la caché
 

 
Descarga

Mediafire
http://Registrate o inicia tu sesión par...0.rar/file

Google Drive
http://Registrate o inicia tu sesión par... contenido


¿Tienes dudas o encuentras algún problema? Déjalo en los comentarios.

Imprimir