- Sky
- Blueberry
- Slate
- Blackcurrant
- Watermelon
- Strawberry
- Orange
- Banana
- Apple
- Emerald
- Chocolate
- Charcoal
-
Similar Content
-
By Miguel92
Bueno como ya había mencionado, ya esta la "herramienta" para crear copias de seguridad completa o parcial de la base de datos y podrás restaurar dicho copia, el problema será que no tengas acceso a la administración del sitio y allí necesitarás una herramienta externa pero que funcione dentro del sitio.
Solo tengo que hacerle algunos cambios a la herramienta que ya tengo creada desde hace 1 año.
Capturas:
Antes de comenzar, si tienes Ejecutar SQL desde la administración [Arreglado] tendrás que quitarlo o eliminar archivos
Bueno comencemos con la integración, los archivos para descargar están al final.
1 - Este archivo "c.database.php" y lo agregan a
2 - En inc/php/admin.php buscamos
/** NOTICIAS **/ } elseif($action == 'news'){ arriba agregarán
} elseif($action == 'execute' OR $action == 'backup') { # Incluimos el archivo necesario include("../class/c.database.php"); $tsDataBase = new tsDataBase(); # Todas las opciones de la copia de seguridad if($action == 'backup') { if(empty($act)) { $smarty->assign('tsListBackup', $tsDataBase->listBackup()); # Creamos el backup completo } elseif($act === 'new_backup') { if(!empty($_POST["nombre_copia"])) { if($tsDataBase->createBackUp()[0]) $tsCore->redirectTo($tsCore->settings['url'].'/admin/backup?save=true'); else $smarty->assign("tsError", $tsDataBase->createBackUp()[1]); } # Creamos el backup seleccionando tablas } elseif($act === 'new_backup_select') { $smarty->assign('tsTablas', $tsDataBase->show_tables()); if(!empty($_POST["nombre_copia"])) { if($tsDataBase->seletedTables()[0]) $tsCore->redirectTo($tsCore->settings['url'].'/admin/backup?save=true'); else $smarty->assign("tsError", $tsDataBase->seletedTables()[1]); } # Descargamos el fichero } elseif($act === 'download') { if(isset($_GET["code"])) { $smarty->assign('tsDownload', $tsDataBase->downloader()); } } }
3 - Ahora en inc/php/ajax/ajax.php buscan
'admin-badwords-delete' => array('n' => 4, 'p' => ''), debajo agregan
'admin-eliminar-sql' => array('n' => 4, 'p' => ''), 'admin-restaurar-sql' => array('n' => 4, 'p' => ''), 'admin-ejecutar-sql' => array('n' => 4, 'p' => ''), más abajo buscan
include("../class/c.admin.php"); $tsAdmin = new tsAdmin(); y agregan
if($action === 'admin-eliminar-sql' OR $action === 'admin-restaurar-sql' OR $action === 'admin-ejecutar-sql') { include("../class/c.database.php"); $dbase = new tsDataBase(); } por último buscan
default: die('0: Este archivo no existe.'); break; y arriba agregan
case 'admin-eliminar-sql': echo $dbase->delete_file_sql(); break; case 'admin-restaurar-sql': echo $dbase->restore_file_sql(); break; case 'admin-ejecutar-sql': echo $dbase->executeSQL(); break;
4 - Ahora en tema/templates/t.admin.tpl buscan
{include file='admin_mods/m.admin_rangos.tpl'} y debajo pegan
{elseif $tsAction == 'execute' || $tsAction == 'backup'} {include file='admin_mods/m.admin_database.tpl'}
5 - En tema/templates/admin_mods/m.admin_sidemenu.tpl buscan
<h4>Configuración de PHPost</h4> y arriba agregan
<h4>Seguridad</h4> <ul class="cat-list"> <li id="a_configs"><span class="cat-title"><a href="{$tsConfig.url}/admin/execute">Ejecutar consultas</a></span></li> <li id="a_main"><span class="cat-title"><a href="{$tsConfig.url}/admin/backup">Crear copia</a></span></li> </ul>
6 - Este archivo "m.admin_database.tpl" y lo agregan a tema/templates/admin_mods/
7 - Por último en tema/ja/admin.js al final del archivo agregan
/** * Database * para ejecutar consultas y crear copias */ var database = new function() { this.execute = () => { var SQL = 'sql=' + $("#sql").val(); $.post(global_data.url + '/admin-ejecutar-sql.php', SQL, h => { switch (h.charAt(0)) { case '0': mydialog.alert('Error', h.substring(3), false) break; case '1': mydialog.alert('Bien', h.substring(3), true) break; } }) }, this.delete = (id, file, gew) => { if(!gew) { mydialog.show() mydialog.title('Eliminar') mydialog.body(`Estas seguro que quieres eliminar este archivo: ${file}`) mydialog.buttons(true, true, 'Borrar SQL', `database.delete(${id}, '${file}', true)`, true, false, true, 'Cancelar', 'close', true, true); /*mydialog.buttons([ {mostrar:true,texto:'Borrar SQL',accion:`database.delete(${id}, '${file}', true)`,activo:true}, {mostrar:true,texto:'Cancelar',accion:'cerrar',activo:true} ]); */ mydialog.center() } else { $.post(global_data.url + '/admin-eliminar-sql.php', {id,file}, e => { switch (e.charAt(0)) { case '0': mydialog.alert('Error', e.substring(3)); break; case '1': mydialog.close(); $("#sql" + id).remove(); break; } }) } }, this.restore = (file, gew) => { if(!gew) { mydialog.show() mydialog.title('Restaurar') mydialog.body(`Estas seguro que quieres restaurar esta copia: ${file}`) mydialog.buttons(true, true, 'Restaurar SQL', `database.restore('${file}', true)`, true, false, true, 'Cancelar', 'close', true, true); /*mydialog.buttons([ {mostrar:true,texto:'Restaurar SQL',accion:`database.restore('${file}', true)`,activo:true}, {mostrar:true,texto:'Cancelar',accion:'cerrar',activo:true} ]);*/ mydialog.center() } else { mydialog.procesando_inicio('', "Espere"); mydialog.buttons(false); mydialog.center() $.post(global_data.url + '/admin-restaurar-sql.php', {restore: file}, e => { switch (e.charAt(0)) { case '0': mydialog.procesando_fin(); mydialog.alert('Error', e.substring(3), false); break; case '1': mydialog.procesando_fin(); mydialog.alert('Bien', e.substring(3), false); break; } }) } } }
Descargar los archivos "-#- Justo aquí -#-"
En caso que tengan problemas al querer crear las copias de seguridad, comprueben que se haya creado la carpeta "database" en files/ y que tenga los permisos 0777 aplicados, en caso contrario deberán crearlo y darle los permisos correspondientes
-
By Miguel92
En este caso se usará CDN para que sea mejor
1 - En inc/class/c.admin.php buscamos
function saveOrden() { ... todo ... } y lo reemplazamos por
public function saveOrden() { global $tsCore; # $ordenado = []; # Obtenemos lista con el nuevo orden $nuevo_orden = 1; foreach (explode(',', $_POST["cats"]) as $orden) { db_exec([__FILE__, __LINE__], 'query', "UPDATE p_categorias SET c_orden = ".$nuevo_orden." WHERE cid = ".$orden); array_push($ordenado, $nuevo_orden); $nuevo_orden++; } }
2 - En inc/php/ajax/ajax.admin.php buscan
'admin-badwords-delete' => array('n' => 4, 'p' => ''), y debajo agregan
'admin-ordenar-categorias' => array('n' => 4, 'p' => ''), más abajo buscan
case 'admin-badwords-delete': //<--- echo $tsAdmin->deleteBadWord(); //---> break; y debajo agregan
case 'admin-ordenar-categorias': //<--- echo $tsAdmin->saveOrden(); //---> break;
3 - Luego en tema/templates/admin_mods/m.admin_cats.tpl y buscamos, puedes eliminar jquery.tablednd.js si quieres
<script type="text/javascript" src="{$tsConfig.js}/jquery.tablednd.js"></script> y lo reemplazamos por, se usa la condicional ya que solo es donde se muestra la lista de categorías
{if $tsAct == ''} <script src="https://cdn.jsdelivr.net/npm/[email protected]/Sortable.min.js"></script> {/if} abajo de eso buscamos
<script type="text/javascript"> // {literal} $(function(){ // {/literal} {if $tsAct == ''} {literal} $('#cats_orden').tableDnD({ onDrop: function(table, row) { $.ajax({ type: 'post', url: global_data.url + '/admin/cats?ajax=true&ordenar=true', cache: false, data: $.tableDnD.serialize() }); } }); // {/literal} {/if} {literal} $('#cats_orden').tableDnD({ onDrop: function(table, row) { $.ajax({ type: 'post', url: global_data.url + '/admin/cats?ajax=true&ordenar=true&t=cat', cache: false, data: $.tableDnD.serialize() }); } }); // $('#cat_img').change(function(){ var cssi = $("#cat_img option:selected").css('background'); $('#c_icon').css({"background" : cssi}); }); // }); //{/literal} </script>
y lo reemplazamos por
{if $tsAct == '' || $tsAct == 'editar' || $tsAct == 'nueva'} <script> $(() => { /* {if $tsAct == ''} */ new Sortable(document.getElementById('cats_orden'), { animation: 150, dragClass: "arrastrar", // Clase que puedes modificar selectedClass: "seleccionado", // Clase que puedes modificar store: { // Guardar orden set: sortable => $.post(global_data.url + '/admin-ordenar-categorias.php', 'cats=' + sortable.toArray().join(',')) } }); /* {/if} */ $('#cat_img').on('change', () => { $('#c_icon').css({ "background": $("#cat_img option:selected").css('background') }) }); }) </script> {/if} más abajo buscan y le borran id="cats_orden" de
<table cellpadding="0" cellspacing="0" border="0" width="500" align="center" class="admin_table" id="cats_orden"> un poco más abajo buscan y le añaden id="cats_orden" a
<tbody> abajo buscan
<tr id="{$c.cid}"> y lo reemplazan por
<tr id="{$c.cid}" data-id="{$c.cid}">
Si quieres puedes añadir estas líneas en tema/css/admin.css
.arrastrar { background-color: #EEE; } .seleccionado { background-color: #CCC; }
Si quieres obtener más información sobre el complemento "SortableJS", puedes acceder a la página que contiene la documentación para que puedas hacer los cambios que desees!
-
By Miguel92
En este caso se usará CDN para que sea mejor
1 - En tema/templates/modules/m.cuenta_sidebar.tpl y reemplazamos todo por esto
<div class="sidebar-tabs clearbeta"> <h3>Mi Avatar</h3> <div class="avatar-big-cont"> <div style="display: none" class="avatar-loading"></div> <img width="120" height="120" alt="" src="{$tsConfig.url}/files/avatar/{if $tsPerfil.p_avatar}{$tsPerfil.user_id}_120{else}avatar{/if}.jpg?t={$smarty.now}" class="avatar-big" id="avatar-img"/> </div> <ul class="change-avatar" id="change"> <li class="local-file" id="pc" style="width: 50%;text-align:center;"><span>Local</span></li> <li class="url-file" id="url" style="width: 50%;text-align:center;"><span>Url</span></li> </ul> <div class="clearfix"></div> <a href="javascript:avatar.subir()" class="avatar-next edit" >Editar</a> </div> <div class="clearfix"></div> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/croppr.min.css" integrity="sha256-Bbkel8+0sOmrvX75oDwNElgbmrAP+Pw+XXKKUwoKiVE=" crossorigin="anonymous"> <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/croppr.min.js" integrity="sha256-VPADQYvd0gjLaeduvmP9/UZAdNW3D2sJieeJ3a3PX64=" crossorigin="anonymous"></script> <script src="{$tsConfig.js}/subir-avatar.js?{$smarty.now}"></script>
2 - Creamos un archivo llamado "subir-avatar.js" y lo agregamos en tema/js
const next = $(".avatar-next"); const sizeImg = 120; function cambiarFile(){ const input = $('#file-avatar')[0]; if(input.files && input.files[0]) { let name_file = decodeURIComponent(input.files[0].name); document.querySelector(".drop-message").innerHTML = name_file; next.removeClass('btn-disabled') } } $("#url-avatar").on('keyup', () => { if($("#url-avatar").val().length > 5) next.removeClass('btn-disabled') }) $("#change > li, #change > li span").on('click', event => { const block = $("#change") block.attr('class', '') var tipo = event.target.textContent if(tipo === 'Local') { block.html(`<div id="drop-region"> <input type="file" name="local" id="file-avatar" onchange="return cambiarFile();" class="browse"/> <div class="drop-message"> Arrastra y suelta la imagen o haz clic para subir </div> </div>`) } else { block.html(`<div style="margin: 0 auto 10px auto;"> <input type="text" name="url" autocomplete="off" id="url-avatar" placeholder="Url de la imagen" class="browse form-control"/> </div>`) } }) var avatar = { uid: false, key: false, ext: false, informacion: '', current: false, success: false, subir: async () => { $(".avatar-loading").show().css('display', 'flex'); inputs = [].slice.call(document.querySelectorAll(".browse")) inputs.forEach(input => { const datoUrl = new FormData(); datoUrl.append('url', (input.name == 'url') ? input.value : input.files[0]) if(!empty(input.value)) { fetch(global_data.url + '/upload-avatar.php', { method: 'POST', body: datoUrl }) .then(response => response.json()) .then(blobData => { avatar.subida_exitosa(blobData) }); } }) }, subida_exitosa: rsp => { if (rsp.error == 'success') avatar.success = true; else if (rsp.msg) { avatar.key = rsp.key; avatar.ext = rsp.ext; avatar.cortar(rsp.msg); } else cuenta.enviar_alerta(rsp.error, 0); $(".avatar-loading").hide(); }, cortar: img => { img = img + '?t=' + new Date(); mydialog.show(true); mydialog.title("Cortar avatar"); mydialog.body(`<img class="avatar-cortar" src="${img}" />`); mydialog.buttons(true, true, 'Cortar', "avatar.guardar()", true, false, true, 'Cancelar', 'close', true, true); /*mydialog.buttons([ {mostrar: true, texto: 'Cortar', accion: `avatar.guardar()`, activo: true}, {mostrar: true, texto: 'Cancelar', accion: 'cerrar', activo: true} ]);*/ mydialog.center(); $("#avatar-img, #avatar-menu").attr("src", img).on('load', () => { var croppr = new Croppr('.avatar-cortar', { aspectRatio: 1, // Mantemos el tamanio cuadrado 1:1 maxSize: { width: sizeImg, // Tamano por defecto height: sizeImg // Tamano por defecto }, // Enviamos las coordenadas para cortar la imagen // Tiene la funcion onCropEnd ya que es como va a quedar onCropEnd: data => avatar.informacion = data, }); }); }, recargar: () => $("#avatar-img").attr("src", avatar.current + '?r' + new Date()), guardar: () => { if (empty(avatar.informacion)) cuenta.enviar_alerta('Debes seleccionar una parte de la foto', 0); else { const coordenadas = new FormData(); coordenadas.append('key', avatar.key) coordenadas.append('ext', avatar.ext) coordenadas.append('x', avatar.informacion.x) coordenadas.append('y', avatar.informacion.y) coordenadas.append('w', avatar.informacion.width) coordenadas.append('h', avatar.informacion.height) fetch(global_data.url + '/upload-crop.php', { method: 'POST', body: coordenadas }) .then(response => response.json()) .then(blobData => { if(blobData.error == "success") { mydialog.body("Tu avatar se ha creado correctamente, ahora espera que recargue la página"); setTimeout(() => location.reload(), 1200); mydialog.buttons(false) } }); } } }
3 - Luego en tema/js/cuenta.js buscar¿
var avatar = { ..... y borran todo hasta el final del archivo
4 - Luego van a inc/php/ajax.upload.php y lo reemplazan por esto
<?php if ( ! defined('TS_HEADER')) exit('No se permite el acceso directo al script'); /** * Controlador AJAX * * @name ajax.upload.php * @author PHPost Team */ /**********************************\ * (VARIABLES POR DEFAULT) * \*********************************/ // NIVELES DE ACCESO Y PLANTILLAS DE CADA ACCIÓN $files = array( 'upload-avatar' => array('n' => 2, 'p' => ''), 'upload-crop' => array('n' => 2, 'p' => ''), 'upload-images' => array('n' => 2, 'p' => ''), ); /**********************************\ * (VARIABLES LOCALES ESTE ARCHIVO) * \*********************************/ // REDEFINIR VARIABLES $tsPage = 'php_files/p.upload.'.$files[$action]['p']; $tsLevel = $files[$action]['n']; $tsAjax = empty($files[$action]['p']) ? 1 : 0; /**********************************\ * (INSTRUCCIONES DE CODIGO) * \*********************************/ // DEPENDE EL NIVEL $tsLevelMsg = $tsCore->setLevel($tsLevel, true); if($tsLevelMsg != 1) { echo '0: '.$tsLevelMsg['mensaje']; die();} // CLASE require('../class/c.upload.php'); $tsUpload = new tsUpload(); // CODIGO switch($action){ case 'upload-avatar': // <-- $tsUpload->image_scale = true; $tsUpload->image_size['w'] = 640; $tsUpload->image_size['h'] = 480; // $tsUpload->file_url = $_POST['url']; // $result = $tsUpload->newUpload(3); echo json_encode($result); // --> break; case 'upload-crop': // <-- echo json_encode($tsUpload->cropAvatar($tsUser->uid)); // PARA EL PERFIL db_exec(array(__FILE__, __LINE__), 'query', 'UPDATE u_perfil SET p_avatar = 1 WHERE user_id = ' . $tsUser->uid); // --> break; case 'upload-images': echo json_encode($tsUpload->newUpload(1)); break; }
Eso es todo...
-
By Miguel92
Este "mod" es dual ya que tiene el login y registro, esta realizado de forma que al ingresar a al sitio tengas que registrarte o loguearte de forma obligatoria...
una vista previa de como quedará
Bueno comencemos
1 - En header.php buscamos
define('TS_TEMA', $tsTema);
y debajo agregamos
# El tipo de inicio define('INICIO_DUAL', TRUE); 2 - Buscamos en index.php
// Checamos... if($tsCore->settings['c_allow_portal'] == 1 && $tsUser->is_member == true && $_GET['do'] == 'portal') { // Portal/mi include('inc/php/portal.php'); } else { // Home include('inc/php/posts.php'); } y la reemplazamos por
/** * Dependiendo de la configuración * Solo aplicará el dual si ambos son "TRUE" */ if(INICIO_DUAL AND !$tsUser->is_member) include 'inc/php/dual.php'; else { // Checamos... if(intval($tsCore->settings['c_allow_portal']) == 1 && $tsUser->is_member == true && $_GET['do'] == 'portal') { // Portal/mi include('inc/php/portal.php'); } else { // Home include('inc/php/posts.php'); } }
3 - Descargan los archivos y los ponen en las rutas correspondientes
* dual.php en inc/php/
* dual.css en tema/css/
* dual.js en tema/js/
* t.dual.tpl en tema/templates/
4 - Ir a inc/class/c.registro.php y buscan
$tsData = array( 'user_nick' => $tsCore->parseBadWords($_POST['nick']), 'user_password' => $tsCore->parseBadWords($_POST['password']), 'user_email' => $_POST['email'], 'user_dia' => $_POST['dia'], 'user_mes' => $_POST['mes'], 'user_anio' => $_POST['anio'], 'user_sexo' => $_POST['sexo'] == 'f' ? '0' : 1, 'user_pais' => strtoupper($_POST['pais']), 'user_estado' => $_POST['estado'], 'user_terminos' => $_POST['terminos'], 'user_captcha' => $_POST['g-recaptcha-response'], 'user_registro' => time(), );
y la reemplazan por
$tsData = array( 'user_nick' => $tsCore->parseBadWords($_POST['nick']), 'user_password' => $tsCore->parseBadWords($_POST['password']), 'user_email' => $_POST['email'], 'user_sexo' => $_POST['sexo'] == 'f' ? '0' : 1, 'user_terminos' => $_POST['terminos'], 'user_captcha' => $_POST['response'], 'user_registro' => time(), );
un poco más abajo buscan
/** reCAPTCHA **/ $recaptcha = 'https://www.google.com/recaptcha/api/siteverify?secret=' . $tsCore->settings['skey'] . '&response=' . $tsData['user_captcha'] . '&remoteip=' . $tsCore->getIP(); // Obtener respuesta $response = file_get_contents($recaptcha); // Extraer resultado $ext1 = explode('"success":', $response); $ext2 = explode(',', $ext1[1]); // Comprobar resultado $valid = trim($ext2[0]); // Devolver respuesta si es incorrecta if ($valid == 'false') { return 'recaptcha: No hemos podido validar tu humanidad'; }
y la reemplazan por
/** * Comprobamos el recaptcha v3 */ $response = $tsCore->reCaptcha($tsData['user_captcha']); if (!$response) return 'recaptcha: No hemos podido validar tu humanidad';
más abajo buscamos
// INSERTAMOS EL PERFIL db_exec(array(__FILE__, __LINE__), 'query', 'INSERT INTO `u_perfil` (`user_id`, `user_dia`, `user_mes`, `user_ano`, `user_pais`, `user_estado`, `user_sexo`) VALUES (\''.(int)$tsData['user_id'].'\', \''.(int)$tsData['user_dia'].'\', \''.(int)$tsData['user_mes'].'\', \''.(int)$tsData['user_anio'].'\', \''.$tsCore->setSecure($tsData['user_pais']).'\', \''.$tsCore->setSecure($tsData['user_estado']).'\', \''.(int)$tsData['user_sexo'].'\')'); db_exec(array(__FILE__, __LINE__), 'query', 'INSERT INTO `u_portal` (`user_id`) VALUES (\''.$tsData['user_id'].'\')');
y la reemplazamos por
db_exec([__FILE__, __LINE__], "query", "INSERT INTO u_perfil (user_id, p_avatar, user_sexo) VALUES({$tsData['user_id']}, 1, {$tsData['user_sexo']})"); db_exec([__FILE__, __LINE__], "query", "INSERT INTO u_portal (user_id) VALUES({$tsData['user_id']})"); # Generamos automaticamente un avatar $avatar = "https://ui-avatars.com/api/?name=$1&background=random&size=160&font-size=0.60&bold=true&length=2"; $copy = "../../files/avatar/$2_$3.jpg"; $sizes = [50, 120]; foreach ($sizes as $size) { copy( str_replace('$1', $tsData['user_nick'], $avatar), str_replace(['$2', '$3'], [$tsData['user_id'], $size], $copy) ) } 5 - Luego en inc/class/c.core.php buscamos
/* getIP */ function getIP(){
y arriba agregamos
# Función para comprobar reCaptcha v3 public function reCaptcha(string $publico = '') { $http = http_build_query([ 'secret' => $this->settings["skey"], 'response' => $publico, 'remoteip' => $this->getIP() ]); $init = curl_init(); curl_setopt($init, CURLOPT_URL, "https://www.google.com/recaptcha/api/siteverify"); curl_setopt($init, CURLOPT_POST, 1); curl_setopt($init, CURLOPT_POSTFIELDS, $http); curl_setopt($init, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($init); curl_close($init); return json_decode($response, true); } Y eso sería todo, espero no olvidarme de nada!
Cualquier problema o duda comenten!
-
-
Recently Browsing 0 members
No registered users viewing this page.