Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Mensajes - Alex

#341
Código: php

<?php
    include ('start_connection.php');
    $query = 'SELECT id, mes, dia, categoria, titulo from noticias';
    $result = mysql_query($query);
    while($row = mysql_fetch_array($result))
    {
echo '<article class="slide">
         <time datetime="2013-02-04">'.$row['mes'].'<span>'.$row['dia'].'</span></time>
<div class="holder">
<h2 class="text-green">'.$row['categoria'].'</h2>
<p><a class="ejemplo_4" href="noticias.php?id='.$row['id'].'">'.$row['titulo'].'</a></p>
</div>
</article>';
    }
    include ('close_connection.php');
?>


suponiendo que el campo se llama id, ahí puse en el link noticias.php?id={$id}, también hice varias otras cosas
1º quité el *, y lo cambié por los campos que vas a usar, usar el * está totalmente desaconcejado.
di vueltas las comillas dobles y los apostrofes porque estaban mal utilizados.
Si bien el include es un constructor del lenguaje, por lo cual no es necesario poner los parentesis, se aconceja utilizarlos para mejor lectura.

saludos!
#342
pon el link a noticias.php?id=NUMERO_DE_NOTICIA_SACADO_DE_LA_BASE_DE_DATOS

y luego en tu código noticias.php pones

<?php

$idnoticia = (int) $_GET['id'];

aquí haces la consulta sql poniendo WHERE id_noticia = $idnoticia
para que saque solo el registro que tenga ese id

listo fin del problema xD
#343
aquí entran conceptos muy muy importantes, que son dificiles de captar.

Verás la W3C es el consorcio de empresas que se agruparon y diseñaron la normativa, los protocolos, diseñaron html, y crearon la mayoría de las cosas que nosotros conocemos en la web (HTML1 2 3 4 5, CSS1, 2, 3) ellos ponen "las reglas", osea los estándares, es importante que los códigos estén basados en los estándares, porque los estándares no se crean porque la gente tiene tiempo de sobra, en realidad resulta que, había en un momento mucha gente que hacía cada uno las cosas a su gusto, y despues no andaban bien en todos los navegadores, entonces se decidió hacer algo fijo que diga "las cosas son así".
El validador de la W3C está diseñado para decirte si tu página web cumple con los estándares, en otras palabras, si tu página web está bien hecha, hacer las cosas mal no te sirven, por lo que en mi opinión es importante cumplir con la validación de la W3C.

No se si se entienden los motivos, pero es como decirte que la W3C establece los pasos para armar una torta, lo que se debe hacer y lo que no, si tu no sigues las reglas, lo más probable es que las cosas salgan mal.

saludos!

PD: World Wide Web Consortium = W3C
#344
Es importante Rampe, que empiezes a hacer las cosas bien, en la programación hay dos caminos, el camino fácil y el camino dificil, en realidad no es tan así, el camino dificil no es que sea dificil sino más bien que te llevará un poco más de tiempo y siempre está el camino fácil que te atrae.

Es importante que empiezes a pensar en separar cosas como el html del código php, en archivos diferentes, ¿por qué? porque si tienes las cosas separadas y ordenadas tu código será más limpio y ordenado.
Además es necesario que empiezes a indentar por ejemplo, para que tu código sea más entendible.

Lo malo de php es que hay mucha gente que dice saber mucho y hace cosas horrorosas.

Y como decía en un libro, en la programación no hay balas de plata (que maten a los vampiros chupasangres, que son esos códigos horrorosos jajaja)

El hecho es que tienes dos cosas que aprender por paralelo (que en realidad van por la misma linea)

Primero a hacer un buen código, con buena estructura, ordenado y limpio.

Segundo a aprender a programar.

Volviendo al tema del post, la función mail anda bien, quizá no en localhost si no lo configuras bien, pero en servidores la gran mayoría si.

saludos!
#345
la funcion mail anda y no es muy complicada fijate busca ejemplos simples o en el link q te pase, en lo q respecta a configuracion es muy parecido xampp a wampp.

saludos
#346
sigo acá abajo, porque no me deja poner más nada en el comentario de arriba jajajjaja

Como decía, permite crear salas, poner moderadores, es parecido a un IRC.
Aunque no me baso en ningún protocolo como xmpp o IRC, por lo que no aconcejo el uso de éste código.

es simplemente demostrativo.

dejo el HTML que conecta con el servidor de arriba.

Código: HTML5
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Abrir un WebSocket</title>
</head>
<body>

<h1>Chat de prueba</h1>

<script type="text/javascript">


        function escribir(texto){
                valor = document.getElementById("caja").value;
                document.getElementById("caja").value = texto + "\n" + valor;
        }       

        var mysocket = new WebSocket("ws://localhost:778");

        mysocket.onopen = function (evt){
                escribir("Conectado al chat...");
               
        };

        mysocket.onmessage = function (evt){
                escribir(evt.data);
               
        };

        mysocket.onclose = function (evt){
                 escribir("Desconectado del chat...");
        };

        mysocket.onerror = function (evt) {
                escribir("ERROR: " + evt.data);
        }

        function enviar(texto) {
                mysocket.send(texto);
                escribir("Yo: " + texto);
        }

        function desconectar(){         
                mysocket.close();
        }

       
</script>


<textarea id="caja" cols="100" rows="20"></textarea><br/>
<input id="mensaje" type="text" size="105"></input>
<button onClick="enviar(document.getElementById('mensaje').value);">Enviar</button>


<br><br>
<hr>


</body>
</html>


no es de mi autoría pero lo googlee asique no se de quien es jajajaj, si alguien encuentra fuente por favor la agrega.

saludos!
#347
Seguridad Wireless / Re:airoscript-ng
Octubre 07, 2013, 06:24:14 PM
You are not allowed to view links. You are not allowed to view links. Register or Login or You are not allowed to view links. Register or Login
gracias n,n antrax uso adobe photoshop cs6

eres bastante bueno en photoshop.

muy pero muy buen aporte, desde ya se agradece.

saludos!
#348
Zona Webmaster / Re:Sobre robots.txt
Octubre 07, 2013, 06:23:11 PM
You are not allowed to view links. You are not allowed to view links. Register or Login or You are not allowed to view links. Register or Login
Cabe resaltar que aun indicando a Robots.txt algunos directorios que no sean indexados por los buscadores lo hacen hay metatags como tambien cabezeras para subsanar pero como el caso de google se tiene que cubrir por todo lado !

Regards,
Snifer

nunca faltas snifer no?

muchas gracias un amportazo Mr. Foster :)

saludoS!
#349
genial chicos, para los que son nuevos :P

aportes básicos que terminan siendo útiles a muchos :)

saludos!
#350
You are not allowed to view links. You are not allowed to view links. Register or Login or You are not allowed to view links. Register or Login
No, son los 20 y 21. Debes contarlos comenzando desde la mueca y dando un giro anti horario

como cualquier integrado xD

saludos!
#351
You are not allowed to view links. You are not allowed to view links. Register or Login or You are not allowed to view links. Register or Login
You are not allowed to view links. You are not allowed to view links. Register or Login or You are not allowed to view links. Register or Login
tienes que habilitar SMTP en tu servidor local así: You are not allowed to view links. You are not allowed to view links. Register or Login or You are not allowed to view links. Register or Login

espero sea eso, avísame cualquier cosa

saludos!

Muchas gracias :D me servirá mucho :)

You are not allowed to view links. You are not allowed to view links. Register or Login or You are not allowed to view links. Register or Login
¿Estás corriendo el script en tu servidor local, en algún Hosting o un VPS?. Todo varia dependiendo y a continuación de explico un poco:

Si lo estas corriendo desde localhost y no te envia los correos es probable {como ya te comento jx4nk00} que no tengas ó instalado un servidor SMTP ó éste mal configurado; para ésto te recomiendo la clase PHPMailer la cual a base de credenciales de un correo (en éste caso gmail generalmente) te envía correctamente, lo único que deberás hacer es modificar el archivo php.ini y cambiar ;extension=php_openssl.dll por extension=php_openssl.dll.

Si lo estas corriendo desde un hosting o un vps, checa que SMTP igual, que no este en black list o saturado; de igual manera PHPMailer es una buena alternativa.

Con poca información al respecto, por mi parte es todo.

Saludos,
Xt3mP.

Lo ando corriendo en localhost, lo de PHPMailer lo probé pero nunca pude configurarlo correctamente :( por eso lo deje supongo lo tengo que volver a tocar...

Sin embargo evaluándolo un poco seguro en hosting gratuitos no funcionara, así que debería pensar en configurarlo en uno pago... en ese caso ¿Cómo debería ponerlo en código?como debería ponerlo (teniendo ya los datos del STMP)

SMTP server: You are not allowed to view links. You are not allowed to view links. Register or Login or You are not allowed to view links. Register or Login
SMTP port: 465
SMTP username: You are not allowed to view links. You are not allowed to view links. Register or Login or You are not allowed to view links. Register or Login <-- reemplazalo con tu cuenta de gmail y la password.

Investigando un poco conseguí estos datos, ¿Cómo debería usarlos?... Lo de php.ini ya lo revisare hablando de los mismo al activar lo de las url´s cuando lo dejo y vuelvo abrirlo me aparece error :S ¿Que debería cambiar exactamente para no me pase esto? o ¿Debido a que me pasa?

Saludos!

PD: Muchas gracias por las ayudas :) me sirven un montón aunque me falta aprender mas aun :/

tu código actual, es un desastre, desconozco de donde lo haz sacado pero tendrás que usar otro.

usa funciones que están obsoletas tales como eregi You are not allowed to view links. You are not allowed to view links. Register or Login or You are not allowed to view links. Register or Login

también revisas que el mail esté bien en una variable vacía, cosa que siempre dará mal.

y esto para empezar jejeje, no te lo tomes a mal, pero busca otro código

Respecto a tu problema, si usas xampp sobre windows no te funcionará nunca la función mail (por lo menos no con la configuración por default)

La documentación oficial sobre la función Mail:
You are not allowed to view links. You are not allowed to view links. Register or Login or You are not allowed to view links. Register or Login

de todos modos, deberías probar como dice xtemp con la clase PHPMailer, no vi mucha gente que tenga problemas con ella.

SMTP server: You are not allowed to view links. You are not allowed to view links. Register or Login or You are not allowed to view links. Register or Login
SMTP port: 465
SMTP username: You are not allowed to view links. You are not allowed to view links. Register or Login or You are not allowed to view links. Register or Login <-- reemplazalo con tu cuenta de gmail y la password.

eso es el servidor de google, si usaras SMTP, no obstante tu usas directamente mail, por lo que eso no te sirve, si usaras phpmailer si te sirve xD

un saludo, y no te tomes a mal mi coment, va con toda la buena onda y para que mejores :)
#352
You are not allowed to view links. You are not allowed to view links. Register or Login or You are not allowed to view links. Register or Login
Java y C como ves en la tabla de Crazy, pero si lo preguntas por que quieres aprenderlo empieza por el que mas te guste, no por el que mas se use.

Saludos;).

si bien pekador tiene toda la razón, hay que pensar que para alguien que no conoce los lenguajes, obviamente se le complicará decidir cual le gusta más jajaja.

asique te voy a decir lo siguiente

¿Queres programar apps para tu celular o el de tus amigos?
-> Java sin duda alguna
¿Querés programar para web?
-> Ni pienses en ASP ve directo a PHP en mi opinión te gustará más :)
¿Querés programar industrialmente, en un lenguaje que soporte todo de la manera correcta y que sea digamos el más amplio?
-> C++

¿querés aprender otros lenguajes no los antes mencionados?
Empieza por python, es hoy en día un lenguaje popular y a mucha gente le gusta mucho, hay varios en el foro que son amantes de python.

¿lenguajes no recomendados?
VisualBasic, razón: obviamente hay muchos que defienden a muerte visual basic, cada uno programa y defiende el lenguaje en el que programa por su propio gusto, asique esta recomendación le sonará fea a muchos, pero en mi opinión (y sepan que fue mi primer lenguaje), es un lenguaje que si bien te permite hacer bastantes cosas y de manera fácil, cuanta con dependencias importantes (empezando por netframework), las versiones viejas tienen incompatibilidades grandes, por lo que no te recomiendo hoy en día empezar a aprender programación o gastar el tiempo aprendiendo vb.
Además vb cuenta con muchos errores de conceptos importantes, algunos dicen que está orientado a eventos, y otro a objetos, en cualquiera de ambos casos, podemos inferir que el lenguaje está mal orientado, porque si está orientado a objetos lo está de forma erronea (no como debería) y si está a eventos pues ni hablar xD, su facilidad le da muchas limitaciones, algunos dicen "yo en vb puedo hacer cualquier cosa" quizá lo hagan, pero en ese momento, el tema de la facilidad desaparece, y la estructura del código empieza a complicarse. Obviamente hay que aclarar que no da soporte para muchos de los criterios de calidad, y a los que si da, lo hace de forma "light"

En javascript por ejemplo puedes hacer complementos para navegadores, y la parte importante del lado del cliente para páginas webs.

Hay muchos lenguajes, no hablaré de todos porque no tengo mucho tiempo, en fin, puedes chuzmear en google, y ver las utilidades y que lenguajes hay.

saludos!

PD: no es mi intención fastidiar a nadie, ni buscar polémica, y desde ya pido disculpas si ofendí a alguien.

#353
Buenas, ayer un amigo me comentó su necesidad de hacer un chat con Websockets (ya había intentado hacer un chat con AJAX y es el desmadre de consumo jajaja, aunque me lo imaginaba tenía que verlo con mis propios hojos), asique busqué un ejemplo y estube varias horas tratando de entender por que no andaba, hasta que me di cuenta que el protocolo había cambiado y ahora se usaba una clave de encriptación basada en XOR con dígitos de control. Me puse a trabajar y mientras buscaba algunas ayudas en internet me encontré con un repositorio y lo que yo llamo "la clase perfecta" si bien le falta pulir mucho para que sea la perfecta clase que mensiono, era la solución para no romperme más la cabeza, y para probar su funcionamiento en unas horas hice un sistema de chat basado en esa clase y ajustando un par de cosas.

Clase Original You are not allowed to view links. You are not allowed to view links. Register or Login or You are not allowed to view links. Register or Login

ahora mis disculpas ¿por que? por que el código que voy a poner a continuación es un azco, realmente un desorden, por lo que en mi defensa diré simplemente que quería probar la clase, y no reparé en la estructura del código, y en criterio de calidad alguno. De hecho si se fijan no eh tenido tiempo ni de implementar las interfaces, igual primero debería revisar la estructura de la clase.
Probablemente en unos días les presentaré la versión refinada (como hice en el código de bbc)

Ahora que ya saben que se tienen que esperar un azco de código mezclado y sin estructura aparente, les dejo mi desastroso pero funcional código.

Código: php
<?php

/** WebSocketServer
*  @original code: https://github.com/ghedipunk/PHP-Websockets/blob/master/users.php
*  @redesign: Alexander171294
*  @Proyect Name: PHSP: phSocketPlus
*  @contact: [email protected]
*  @Status: Prototype
*  @Date: 07/10/13 
*/           

interface iphSocketPlus
{

}

interface iSocketPlusUser
{

}

trait Property // mi hermosa clase property
{
    // llamando a funciones setters
    Public function __set($property, $value)
    {
            return call_user_func(array($this, 'set_'.$property), $value);
    }
   
    // llamando a funciones getters
    Public function __get($property)
    {
        if(is_callable(array($this, 'get_'.$property)))
            return call_user_func(array($this, 'get_'.$property));
        elseif(is_callable(array(parent, 'get_'.$property)))
            return call_user_func(array(parent, 'get_'.$property));
        else
        // no hay funcion getter para este atributo (o no existe el atributo)
            throw new exception('The atribute $'.$property.' not exist in get'); 
    }
}

abstract class AbstractWebSocketUser {
  private $socket;
  private $id;
  private $headers = array();
  private $handshake = false;

  private $handlingPartialPacket = false;
  private $partialBuffer = "";

  private $sendingContinuous = false;
  private $partialMessage = "";

  private $hasSentClose = false;
 
  private $RequestedResource = null;

  public function __construct($id,$socket)
  {
    $this->id = $id;
    $this->socket = $socket;
  }
 
  public function get_socket()
  {
    return $this->socket;
  }
 
  public function get_id()
  {
    return $this->id;
  }
 
  public function get_headers()
  {
    return $this->headers;
  }
 
  public function get_handshake()
  {
    return $this->handshake;
  }
 
  public function get_handlingPartialPacket()
  {
    return $this->handlingPartialPacket;
  }
 
  public function get_partialBuffer()
  {
    return $this->partialBuffer;
  }
 
  public function get_sendingContinuous()
  {
    return $this->sendingContinuous;
  }
 
  public function get_partialMessage()
  {
    return $this->partialMessage;
  }
 
  public function get_hasSentClose()
  {
    return $this->hasSentClose;
  }
 
  public function get_RequestedResource()
  {
    return $this->RequestedResource;
  }
 
  public function set_RequestedResource($value)
  {
    $this->RequestedResource = $value;
  }
 
  public function set_socket($value)
  {
    $this->socket = $value;
  }
 
  public function set_id($value)
  {
    $this->id = $value;
  }
 
  public function set_headers($value)
  {
    $this->headers = $value;
  }
 
  public function set_handshake($value)
  {
    $this->handshake = $value;
  }
 
  public function set_handlingPartialPacket($value)
  {
    $this->handlingPartialPacket = $value;
  }
 
  public function set_partialBuffer($value)
  {
    $this->partialBuffer = $value;
  }
 
  public function set_sendingContinuous($value)
  {
    $this->sendingContinuous = $value;
  }
 
  public function set_partialMessage($value)
  {
    $this->partialMessage = $value;
  }
 
  public function set_hasSentClose($value)
  {
    $this->hasSentClose = $value;
  }
}

class SocketPlusUser extends AbstractWebSocketUser implements iSocketPlusUser
{
use Property;

    private $accedio = false; // si accedió
    private $name = null; // nombre de usuario
    private $channel = null;
    private $founder = false;
    private $moderator = false;
    static $users = array();
    static $channels = array(); // array complejo
    static $uonlines = array();
   
    // acceder
    public function acceder($user, $pass)
    {
        if(isset(self::$users[$user]) && self::$users[$user]==$pass)
        {
            $this->accedio = true;
            $this->name = $user;
            return true;
        } else {return false;}
    }
   
    public function registrarse($user, $pass)
    {
        if(strlen($user)<3 || strlen($pass)<3) return false;
        if(!isset(self::$users[$user]))
        {
            self::$users[$user] = $pass;
            return true;
        } else {return false;}
    }
   
    public function crear_canal($name, $desc)
    {
        if(strlen($name)<3 || strlen($desc)<3) return false;
        if(!isset(self::$channels[$name]))
        {
            self::$channels[$name]['name'] = $desc;
            self::$channels[$name]['userlist'] = array();
            self::$channels[$name]['founder'] = $this->name;
            self::$channels[$name]['specialusers'] = array();
            return true;
        } else {return false;}
    }
   
    public function ir_canal($user, $canal)
    {
        if(isset(self::$channels[$canal]))
        {
            // si estás banneado
            if(isset(self::$channels[$canal]['specialusers'][$this->name]) && self::$channels[$canal]['specialusers'][$this->name] == 'B' && self::$channels[$canal]['founder'] != $this->name)
            { $this->channel = null; return false; }
            $this->channel = $canal;
            self::$channels[$canal]['userlist'][] = $user;
              if(self::$channels[$canal]['founder'] == $this->name)
                  $this->founder=true;
              else
                  $this->founder=false;
              if(isset(self::$channels[$canal]['specialusers'][$this->name]) && self::$channels[$canal]['specialusers'][$this->name] == 'M')  // si somos moderadores
                  $this->moderator=true;
              else
                  $this->moderator=false;
            return true;
        } else { return false; }
    }
   
    public function cambiar_pass($user, $pass, $pass2)
    {
        if(strlen($pass2)<3) return false;
        if(isset(self::$users[$user]) && self::$users[$user]==$pass)
        {
            self::$users[$user]=$pass2;
            return true;
        } else {return false;}
    }
   
    public function get_accedio()
    {
      return $this->accedio;
    }
   
    public function get_name()
    {
      return $this->name;
    }
   
    public function get_channel()
    {
      return $this->channel;
    }
   
    public function set_channel($value)
    {
      $this->channel = $value;
    }
   
    public function get_founder()
    {
      return $this->founder;
    }
   
    public function get_moderator()
    {
      return $this->moderator;
    }

}

// Original Class
abstract class WebSocketServer {

protected $userClass = 'WebSocketUser'; // redefine this if you want a custom user class.  The custom user class should inherit from WebSocketUser.
protected $maxBufferSize;       
protected $master;
protected $sockets                              = array();
protected $users                                = array();
protected $interactive                          = true;
protected $headerOriginRequired                 = false;
protected $headerSecWebSocketProtocolRequired   = false;
protected $headerSecWebSocketExtensionsRequired = false;

function __construct($addr, $port, $userClass=null , $bufferLength = 2048) {
$this->maxBufferSize = $bufferLength;
    if(!empty($userClass)) $this->userClass = $userClass;
$this->master = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)  or die("Failed: socket_create()");
socket_set_option($this->master, SOL_SOCKET, SO_REUSEADDR, 1) or die("Failed: socket_option()");
socket_bind($this->master, $addr, $port)                      or die("Failed: socket_bind()");
socket_listen($this->master,20)                               or die("Failed: socket_listen()");
$this->sockets[] = $this->master;
    $this->stdout('###### WEBCHAT SERVER ###### v1.0');
$this->stdout("Server started\nListening on: $addr:$port\nMaster socket: ".$this->master);

while(true) {
if (empty($this->sockets)) {
$this->sockets[] = $master;
}
$read = $this->sockets;
$write = $except = null;
@socket_select($read,$write,$except,null);
foreach ($read as $socket) {
if ($socket == $this->master) {
$client = socket_accept($socket);
if ($client < 0) {
$this->stderr("Failed: socket_accept()");
continue;
} else {
$this->connect($client);
}
} else {
$numBytes = @socket_recv($socket,$buffer,$this->maxBufferSize,0); // todo: if($numBytes === false) { error handling } elseif ($numBytes === 0) { remote client disconected }
if ($numBytes == 0) {
$this->disconnect($socket);
} else {
$user = $this->getUserBySocket($socket);
if (!$user->handshake) {
$this->doHandshake($user,$buffer);
} else {
              if ($message = $this->deframe($buffer, $user)) {
                $this->process($user, utf8_encode($message));
                if($user->hasSentClose) {
                  $this->disconnect($user->socket);
                }
              } else {
do {
$numByte = @socket_recv($socket,$buffer,$this->maxBufferSize,MSG_PEEK);
if ($numByte > 0) {
$numByte = @socket_recv($socket,$buffer,$this->maxBufferSize,0);
if ($message = $this->deframe($buffer,$user)) {
$this->process($user,$message);
                      if($user->hasSentClose) {
                        $this->disconnect($user->socket);
                      }
}
}
} while($numByte > 0);
}
}
}
}
}
}
}

abstract protected function process($user,$message); // Calked immediately when the data is recieved.
abstract protected function connected($user);        // Called after the handshake response is sent to the client.
abstract protected function closed($user);           // Called after the connection is closed.

protected function connecting($user) {
    // Override to handle a connecting user, after the instance of the User is created, but before
    // the handshake has completed.
  }
 
  protected function send($user,$message) {
//$this->stdout("> $message");
$message = $this->frame($message,$user);
socket_write($user->socket,$message,strlen($message));
}

protected function connect($socket) {
$user = new $this->userClass(uniqid(),$socket);
array_push($this->users,$user);
array_push($this->sockets,$socket);
$this->connecting($user);
}

protected function disconnect($socket,$triggerClosed=true) {
$foundUser = null;
$foundSocket = null;
foreach ($this->users as $key => $user) {
if ($user->socket == $socket) {
$foundUser = $key;
$disconnectedUser = $user;
break;
}
}
if ($foundUser !== null) {
unset($this->users[$foundUser]);
$this->users = array_values($this->users);
}
foreach ($this->sockets as $key => $sock) {
if ($sock == $socket) {
$foundSocket = $key;
break;
}
}
if ($foundSocket !== null) {
unset($this->sockets[$foundSocket]);
$this->sockets = array_values($this->sockets);
}
if ($triggerClosed) {
$this->closed($disconnectedUser);
}
}

protected function doHandshake($user, $buffer) {
$magicGUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
$headers = array();
$lines = explode("\n",$buffer);
foreach ($lines as $line) {
if (strpos($line,":") !== false) {
$header = explode(":",$line,2);
$headers[strtolower(trim($header[0]))] = trim($header[1]);
} else if (stripos($line,"get ") !== false) {
preg_match("/GET (.*) HTTP/i", $buffer, $reqResource);
$headers['get'] = trim($reqResource[1]);
}
}
if (isset($headers['get'])) {
$user->requestedResource = $headers['get'];
} else {
// todo: fail the connection
$handshakeResponse = "HTTP/1.1 405 Method Not Allowed\r\n\r\n";
}
if (!isset($headers['host']) || !$this->checkHost($headers['host'])) {
$handshakeResponse = "HTTP/1.1 400 Bad Request";
}
if (!isset($headers['upgrade']) || strtolower($headers['upgrade']) != 'websocket') {
$handshakeResponse = "HTTP/1.1 400 Bad Request";
}
if (!isset($headers['connection']) || strpos(strtolower($headers['connection']), 'upgrade') === FALSE) {
$handshakeResponse = "HTTP/1.1 400 Bad Request";
}
if (!isset($headers['sec-websocket-key'])) {
$handshakeResponse = "HTTP/1.1 400 Bad Request";
} else {

}
if (!isset($headers['sec-websocket-version']) || strtolower($headers['sec-websocket-version']) != 13) {
$handshakeResponse = "HTTP/1.1 426 Upgrade Required\r\nSec-WebSocketVersion: 13";
}
if (($this->headerOriginRequired && !isset($headers['origin']) ) || ($this->headerOriginRequired && !$this->checkOrigin($headers['origin']))) {
$handshakeResponse = "HTTP/1.1 403 Forbidden";
}
if (($this->headerSecWebSocketProtocolRequired && !isset($headers['sec-websocket-protocol'])) || ($this->headerSecWebSocketProtocolRequired && !$this->checkWebsocProtocol($header['sec-websocket-protocol']))) {
$handshakeResponse = "HTTP/1.1 400 Bad Request";
}
if (($this->headerSecWebSocketExtensionsRequired && !isset($headers['sec-websocket-extensions'])) || ($this->headerSecWebSocketExtensionsRequired && !$this->checkWebsocExtensions($header['sec-websocket-extensions']))) {
$handshakeResponse = "HTTP/1.1 400 Bad Request";
}

// Done verifying the _required_ headers and optionally required headers.

if (isset($handshakeResponse)) {
socket_write($user->socket,$handshakeResponse,strlen($handshakeResponse));
$this->disconnect($user->socket);
return false;
}

$user->headers = $headers;
$user->handshake = $buffer;

$webSocketKeyHash = sha1($headers['sec-websocket-key'] . $magicGUID);

$rawToken = "";
for ($i = 0; $i < 20; $i++) {
$rawToken .= chr(hexdec(substr($webSocketKeyHash,$i*2, 2)));
}
$handshakeToken = base64_encode($rawToken) . "\r\n";

$subProtocol = (isset($headers['sec-websocket-protocol'])) ? $this->processProtocol($headers['sec-websocket-protocol']) : "";
$extensions = (isset($headers['sec-websocket-extensions'])) ? $this->processExtensions($headers['sec-websocket-extensions']) : "";

$handshakeResponse = "HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: $handshakeToken$subProtocol$extensions\r\n";
socket_write($user->socket,$handshakeResponse,strlen($handshakeResponse));
    $this->connected($user);
}

protected function checkHost($hostName) {
return true; // Override and return false if the host is not one that you would expect.
     // Ex: You only want to accept hosts from the my-domain.com domain,
// but you receive a host from malicious-site.com instead.
}

protected function checkOrigin($origin) {
return true; // Override and return false if the origin is not one that you would expect.
}

protected function checkWebsocProtocol($protocol) {
return true; // Override and return false if a protocol is not found that you would expect.
}

protected function checkWebsocExtensions($extensions) {
return true; // Override and return false if an extension is not found that you would expect.
}

protected function processProtocol($protocol) {
return ""; // return either "Sec-WebSocket-Protocol: SelectedProtocolFromClientList\r\n" or return an empty string. 
   // The carriage return/newline combo must appear at the end of a non-empty string, and must not
   // appear at the beginning of the string nor in an otherwise empty string, or it will be considered part of
   // the response body, which will trigger an error in the client as it will not be formatted correctly.
}

protected function processExtensions($extensions) {
return ""; // return either "Sec-WebSocket-Extensions: SelectedExtensions\r\n" or return an empty string.
}

protected function getUserBySocket($socket) {
foreach ($this->users as $user) {
if ($user->socket == $socket) {
return $user;
}
}
return null;
}

  // no la protegemos para que pueda ser reescrita si se cambia
  // el método de salida cuando se hereda la clase
private function stdout($message) {
if ($this->interactive) {
echo "$message\n";
}
}

  // no la protegemos para que pueda ser reescrita si se cambia
  // el método de salida cuando se hereda la clase
private function stderr($message) {
if ($this->interactive) {
echo "$message\n";
}
}

protected function frame($message, $user, $messageType='text', $messageContinues=false) {
switch ($messageType) {
case 'continuous':
$b1 = 0;
break;
case 'text':
$b1 = ($user->sendingContinuous) ? 0 : 1;
break;
case 'binary':
$b1 = ($user->sendingContinuous) ? 0 : 2;
break;
case 'close':
$b1 = 8;
break;
case 'ping':
$b1 = 9;
break;
case 'pong':
$b1 = 10;
break;
}
if ($messageContinues) {
$user->sendingContinuous = true;
} else {
$b1 += 128;
$user->sendingContinuous = false;
}

$length = strlen($message);
$lengthField = "";
if ($length < 126) {
$b2 = $length;
} elseif ($length <= 65536) {
$b2 = 126;
$hexLength = dechex($length);
//$this->stdout("Hex Length: $hexLength");
if (strlen($hexLength)%2 == 1) {
$hexLength = '0' . $hexLength;
}
$n = strlen($hexLength) - 2;

for ($i = $n; $i >= 0; $i=$i-2) {
$lengthField = chr(hexdec(substr($hexLength, $i, 2))) . $lengthField;
}
while (strlen($lengthField) < 2) {
$lengthField = chr(0) . $lengthField;
}
} else {
$b2 = 127;
$hexLength = dechex($length);
if (strlen($hexLength)%2 == 1) {
$hexLength = '0' . $hexLength;
}
$n = strlen($hexLength) - 2;

for ($i = $n; $i >= 0; $i=$i-2) {
$lengthField = chr(hexdec(substr($hexLength, $i, 2))) . $lengthField;
}
while (strlen($lengthField) < 8) {
$lengthField = chr(0) . $lengthField;
}
}

return chr($b1) . chr($b2) . $lengthField . $message;
}

protected function deframe($message, $user) {
//echo $this->strtohex($message);
$headers = $this->extractHeaders($message);
$pongReply = false;
$willClose = false;
switch($headers['opcode']) {
case 0:
case 1:
case 2:
break;
case 8:
// todo: close the connection
$user->hasSentClose = true;
return "";
case 9:
$pongReply = true;
case 10:
break;
default:
//$this->disconnect($user); // todo: fail connection
$willClose = true;
break;
}

if ($user->handlingPartialPacket) {
$message = $user->partialBuffer . $message;
$user->handlingPartialPacket = false;
return $this->deframe($message, $user);
}

if ($this->checkRSVBits($headers,$user)) {
return false;
}

if ($willClose) {
// todo: fail the connection
return false;
}

$payload = $user->partialMessage . $this->extractPayload($message,$headers);

if ($pongReply) {
$reply = $this->frame($payload,$user,'pong');
socket_write($user->socket,$reply,strlen($reply));
return false;
}
if (extension_loaded('mbstring')) {
if ($headers['length'] > mb_strlen($payload)) {
$user->handlingPartialPacket = true;
$user->partialBuffer = $message;
return false;
}
} else {
if ($headers['length'] > strlen($payload)) {
$user->handlingPartialPacket = true;
$user->partialBuffer = $message;
return false;
}
}

$payload = $this->applyMask($headers,$payload);

if ($headers['fin']) {
$user->partialMessage = "";
return $payload;
}
$user->partialMessage = $payload;
return false;
}

protected function extractHeaders($message) {
$header = array('fin'     => $message[0] & chr(128),
'rsv1'    => $message[0] & chr(64),
'rsv2'    => $message[0] & chr(32),
'rsv3'    => $message[0] & chr(16),
'opcode'  => ord($message[0]) & 15,
'hasmask' => $message[1] & chr(128),
'length'  => 0,
'mask'    => "");
$header['length'] = (ord($message[1]) >= 128) ? ord($message[1]) - 128 : ord($message[1]);

if ($header['length'] == 126) {
if ($header['hasmask']) {
$header['mask'] = $message[4] . $message[5] . $message[6] . $message[7];
}
$header['length'] = ord($message[2]) * 256
  + ord($message[3]);
} elseif ($header['length'] == 127) {
if ($header['hasmask']) {
$header['mask'] = $message[10] . $message[11] . $message[12] . $message[13];
}
$header['length'] = ord($message[2]) * 65536 * 65536 * 65536 * 256
  + ord($message[3]) * 65536 * 65536 * 65536
  + ord($message[4]) * 65536 * 65536 * 256
  + ord($message[5]) * 65536 * 65536
  + ord($message[6]) * 65536 * 256
  + ord($message[7]) * 65536
  + ord($message[8]) * 256
  + ord($message[9]);
} elseif ($header['hasmask']) {
$header['mask'] = $message[2] . $message[3] . $message[4] . $message[5];
}
//echo $this->strtohex($message);
//$this->printHeaders($header);
return $header;
}

protected function extractPayload($message,$headers) {
$offset = 2;
if ($headers['hasmask']) {
$offset += 4;
}
if ($headers['length'] > 65535) {
$offset += 8;
} elseif ($headers['length'] > 125) {
$offset += 2;
}
return substr($message,$offset);
}

protected function applyMask($headers,$payload) {
$effectiveMask = "";
if ($headers['hasmask']) {
$mask = $headers['mask'];
} else {
return $payload;
}

while (strlen($effectiveMask) < strlen($payload)) {
$effectiveMask .= $mask;
}
while (strlen($effectiveMask) > strlen($payload)) {
$effectiveMask = substr($effectiveMask,0,-1);
}
return $effectiveMask ^ $payload;
}
protected function checkRSVBits($headers,$user) { // override this method if you are using an extension where the RSV bits are used.
if (ord($headers['rsv1']) + ord($headers['rsv2']) + ord($headers['rsv3']) > 0) {
//$this->disconnect($user); // todo: fail connection
return true;
}
return false;
}

protected function strtohex($str) {
$strout = "";
for ($i = 0; $i < strlen($str); $i++) {
$strout .= (ord($str[$i])<16) ? "0" . dechex(ord($str[$i])) : dechex(ord($str[$i]));
$strout .= " ";
if ($i%32 == 7) {
$strout .= ": ";
}
if ($i%32 == 15) {
$strout .= ": ";
}
if ($i%32 == 23) {
$strout .= ": ";
}
if ($i%32 == 31) {
$strout .= "\n";
}
}
return $strout . "\n";
}

protected function printHeaders($headers) {
echo "Array\n(\n";
foreach ($headers as $key => $value) {
if ($key == 'length' || $key == 'opcode') {
echo "\t[$key] => $value\n\n";
} else {
echo "\t[$key] => ".$this->strtohex($value)."\n";

}

}
echo ")\n";
}
}

class phSocketPlus extends WebSocketServer implements iphSocketPlus
{
  use Property;
 
    public function __construct($addr, $port=722, $userClass='SocketPlusUser')
    {
      parent::__construct($addr, $port, $userClass);
    }

  protected function process($user,$message) // Calked immediately when the data is recieved.
  {
      // procesar
      #parent::send($user,$mensaje);
      // obtenemos el mensaje y vemos que comando es
      $command = null;
      for($i=0; $i<3; $i++)
      {
        $command .= $message[$i];
      }
      $params = null;
      for($i=4; $i<strlen($message); $i++)
      {
        $params .= $message[$i];
      }
      switch($command)
      {
          case 'AUT':
            if(!$user->accedio)
            {
              $this->HEout('AUTentificate command');
              if($this->autenticate($user, $params))
              {
                  $this->MEout('Welcome '.$user->name.'...');
                  parent::send($user,'#SERVER: Welcome '.htmlentities($user->name).'...');
              } else { parent::send($user,'#SERVER: Access Deneid...'); }
            } else { parent::send($user,'#SERVER: @'.$user->name); }
          break;
          case 'NEW':
            if(!$user->accedio)
            {
              $this->HEout('New Account command - '.$params);
              if($this->registrate($user, $params))
              {
                  $this->MEout('New Account '.htmlentities($params).'...');
                  parent::send($user,'#SERVER: new account create success...');
              } else { parent::send($user,'#SERVER: Isn\'t possible register your account...'); }
            } else { parent::send($user,'#SERVER: @'.htmlentities($user->name)); }
          break;
          case 'CHN':
            if($user->accedio)
            {
              $this->HEout('Join Channel command');
              // si ya tenía canal
              if($user->channel!=null) $this->killchannel($user);
              if($this->ir_canal($user, $params))
              {
                  $this->MEout('Join to channel '.$params.'...');
                  $this->meunicanal($user);
                  parent::send($user,'#SERVER: Welcome to channel: '.SocketPlusUser::$channels[$params]['name']);
              } else { parent::send($user,'#SERVER: the channel '.htmlentities($params).' not exist...'); $user->channel = null;}
            } else { parent::send($user,'#SERVER: Authentication is required, type HLP for help'); }
          break;
          case 'PWD':
            if($user->accedio)
            {
              $this->HEout('Change password command');
              if($this->cambiar_pass($user, $params))
              {
                  $this->MEout('Change Password '.$params.'...');
                  parent::send($user,'#SERVER: Change Password Success');
              } else { parent::send($user,'#SERVER: isn\'t possible change password...'); }
            } else { parent::send($user,'#SERVER: Authentication is required, type HLP for help'); }
          break;
          case 'ULT':
            if($user->accedio)
            {
              $this->HEout('User List command');
              if($user->channel!=null)
              {
                parent::send($user,'#SERVER: Users in this channel:');
                $this->obtener_usuarios($user);
                $this->MEout('User List...');
              }
              else { parent::send($user,'#SERVER: Join Channel is required, type HLP for help'); }
            } else { parent::send($user,'#SERVER: Authentication is required, type HLP for help'); }
          break;
          case 'NEC':
              if($user->accedio)
              {
                $this->HEout('New Chanel command');
                if($this->crear_canal($user, $params))
                {
                    parent::send($user,'#SERVER: Channel Create Success');
                    $this->MEout('New Channel Create Success...');
                } else { parent::send($user,'#SERVER: Channel isn\'t create, type HLP for help'); }
               
              }
              else { parent::send($user,'#SERVER: Authentication is required, type HLP for help'); }
          break;
          case 'MOD':
            if($user->accedio)
            {
              $this->HEout('Add Moderator command');
              if($user->channel!=null)
              {
                if($user->founder==true)
                {
                    $this->addmod($user, $params);
                    parent::send($user,'#SERVER: Add Moderator :)');
                    $this->MEout('Add Moderator To Channel...');
                } else { parent::send($user,'#SERVER: You aren\'t founder, type HLP for help'); }
              }
              else { parent::send($user,'#SERVER: Join Channel is required, type HLP for help'); }
            } else { parent::send($user,'#SERVER: Authentication is required, type HLP for help'); }
          break;
          case 'USR':
            if($user->accedio)
            {
              $this->HEout('Delete Moderator command');
              if($user->channel!=null)
              {
                if($user->founder==true)
                {
                    $this->quitmod($user, $params);
                    parent::send($user,'#SERVER: Delete Moderator');
                    $this->MEout('Delete Moderator of the Channel...');
                } else { parent::send($user,'#SERVER: You aren\'t founder, type HLP for help'); }
              }
              else { parent::send($user,'#SERVER: Join Channel is required, type HLP for help'); }
            } else { parent::send($user,'#SERVER: Authentication is required, type HLP for help'); }
          break;
          case 'BAN':
            if($user->accedio)
            {
              $this->HEout('REQUEST BAN USER command');
              if($user->channel!=null)
              {
                if($user->founder==true || $user->moderator==true)
                {
                    $this->ban($user, $params);
                    parent::send($user,'#SERVER: Ban user success');
                    $this->MEout('Ban Aproved...');
                } else { parent::send($user,'#SERVER: You aren\'t Founder or Moderator, type HLP for help'); }
              }
              else { parent::send($user,'#SERVER: Join Channel is required, type HLP for help'); }
            } else { parent::send($user,'#SERVER: Authentication is required, type HLP for help'); }
          break;
          case 'KIK':
            if($user->accedio)
            {
              $this->HEout('REQUEST KIK USER command');
              if($user->channel!=null)
              {
                if($user->founder==true || $user->moderator==true)
                {
                    $this->kik($user, $params);
                    parent::send($user,'#SERVER: Kik user success');
                    $this->MEout('Kik Aproved...');
                } else { parent::send($user,'#SERVER: You aren\'t Founder or Moderator, type HLP for help'); }
              }
              else { parent::send($user,'#SERVER: Join Channel is required, type HLP for help'); }
            } else { parent::send($user,'#SERVER: Authentication is required, type HLP for help'); }
          break;
          case 'DEL':
            if($user->accedio)
            {
              $this->HEout('REQUEST DELETE CHANEL command');
              if($user->channel!=null)
              {
                if($user->founder==true || $user->moderator==true)
                {
                    //$this->channeldelete($user, $params);  <---- Falta Hacer
                    parent::send($user,'#SERVER: Delete chanel deneid by SERVER');
                    $this->MEout('Delete channel Deneid...');
                } else { parent::send($user,'#SERVER: You aren\'t Founder or Moderator, type HLP for help'); }
              }
              else { parent::send($user,'#SERVER: Join Channel is required, type HLP for help'); }
            } else { parent::send($user,'#SERVER: Authentication is required, type HLP for help'); }
          break;
          case 'GRD':
            if($user->accedio)
            {
              $this->HEout('REQUEST GRADE USER command');
              if($user->channel!=null)
              {
                    parent::send($user,'#SERVER: '.$this->getGrade($user));
                    $this->MEout('Grade sent');
              }
              else { parent::send($user,'#SERVER: Join Channel is required, type HLP for help'); }
            } else { parent::send($user,'#SERVER: Authentication is required, type HLP for help'); }
          break;
          case 'HLP':
               $this->HEout('help command');
               $this->MEout('Show Help...');
               parent::send($user,'#SERVER: Help Command');
               parent::send($user,'*Acces your account use: AUT user@pass');
               parent::send($user,'*View Help use: HLP');
               parent::send($user,'*Register an account use: NEW user@pass');
               parent::send($user,'*Change your password use: PWD user@oldpass@newpass');
               parent::send($user,'*Access to channel: CHN ChannelName'); 
               parent::send($user,'*List of users in channel: ULT');
               parent::send($user,'*New channel: NEC ChannelName@Channel Welcome');
               parent::send($user,'*Kik User: KIK user');
               parent::send($user,'*Ban user: BAN user');
               parent::send($user,'*Moderator Add: MOD user');
               parent::send($user,'*Moderator Delete: USR user');
               parent::send($user,'*Get Grade (is mod, is founder or is user): GRD');
               parent::send($user,'*Destroy Channel: DEL mypassword');            //TODO
               parent::send($user,'*[M]userName: hello <-- is a moderator');
               parent::send($user,'*[F]userName: hello <-- is a founder');
          break;
          default:
            if($user->accedio)
            {
              if($user->channel!=null)
              {
                $this->HEout('MSG command');
                $this->resend($user, $message);
                $this->MEout('New Message... Resending to terminals');
              }
              else { parent::send($user,'#SERVER: Join Channel is required, type HLP for help'); }
            } else { parent::send($user,'#SERVER: Authentication is required, type HLP for help'); }
          break;
      }
  }
 
  private function autenticate($user, $params)
  {
    $user_init = strpos($params,'@');
    $usr = null;
    if($user_init===false) return false;
    for($i = 0; $i<$user_init; $i++)
      $usr.=$params[$i];
    $pss = null;
    for($i = $user_init+1; $i<strlen($params); $i++)
      $pss.=$params[$i];
    return $user->acceder($usr, $pss);
  }
 
  private function crear_canal($user, $params)
  {
    $user_init = strpos($params,'@');
    $name = null;
    if($user_init===false) return false;
    for($i = 0; $i<$user_init; $i++)
      $name.=$params[$i];
    $name = trim($name);
    $desc = null;
    for($i = $user_init+1; $i<strlen($params); $i++)
      $desc.=$params[$i];
    return $user->crear_canal($name, $desc);
  }
 
  private function getGrade($user)
  {
      if($user->founder)
          return 'You Are a Founder of the channel';
      elseif($user->moderator)
          return 'You Are a Moderator of the channel';
      else
          return 'You Are a User in the channel';
  }
 
  private function cambiar_pass($user, $params)
  {
    $user_init = strpos($params,'@');
    $usr = null;
    if($user_init===false) return false;
    for($i = 0; $i<$user_init; $i++)
      $usr.=$params[$i];
    $passs = null;
    for($i = $user_init+1; $i<strlen($params); $i++)
      $passs.=$params[$i];
    $pass_init = strpos($passs,'@');
    if($pass_init===false) return false;
    $pss1 = null;
    for($i = 0; $i<$pass_init; $i++)
      $pss1.=$passs[$i];
    $pss2 = null;
    for($i = $pass_init+1; $i<strlen($passs); $i++)
      $pss2.=$passs[$i];
    return $user->cambiar_pass($usr, $pss1, $pss2);
  }
 
  private function registrate($user, $params)
  {
    $user_init = strpos($params,'@');
    $usr = null;
    if($user_init===false) return false;
    for($i = 0; $i<$user_init; $i++)
      $usr.=$params[$i];
    $pss = null;
    for($i = $user_init+1; $i<strlen($params); $i++)
      $pss.=$params[$i];
    return $user->registrarse($usr, $pss);
  }
 
  private function obtener_usuarios($user)
  {
     
      $userlist = SocketPlusUser::$channels[$user->channel]['userlist'];
      for($i=0; $i<count($userlist); $i++)
      {
          $rango = '@';
          if($userlist[$i]->founder == true) $rango = '[F]';
          if($user->moderator == true) $rango = '[M]';
          parent::send($user, $rango.$userlist[$i]->name);
      }
  }
 
  private function resend($user, $message)
  {
      $rango = '@';
      if($user->founder == true) $rango = '[F]';
      if($user->moderator == true) $rango = '[M]';
      $userlist = SocketPlusUser::$channels[$user->channel]['userlist'];
      for($i=0; $i<count($userlist); $i++)
      {
          if($userlist[$i]->name != $user->name) // no nos enviamos a nosotros mismos
              parent::send($userlist[$i], $rango.$user->name.': '.$message);
      }
  }
 
  private function addmod($me, $user)
  {
    SocketPlusUser::$channels[$me->channel]['specialusers'][$user]='M';
  }
 
  private function quitmod($me, $user)
  {
    unset(SocketPlusUser::$channels[$me->channel]['specialusers'][$user]);
  }
 
  private function ban($me, $user)
  {
    SocketPlusUser::$channels[$me->channel]['specialusers'][$user]='B';
  }
 
  private function kik($user, $objetivo) // el user se fue del canal
  {
      $userlist = SocketPlusUser::$channels[$user->channel]['userlist'];
      for($i=0; $i<count($userlist); $i++)
      {
          if($userlist[$i]->founder != true)
            {
              $userlist[$i]->channel = null;
              unset(SocketPlusUser::$channels[$user->channel]['userlist'][$i]);
              SocketPlusUser::$channels[$user->channel]['userlist'] = array_values(SocketPlusUser::$channels[$user->channel]['userlist']);
              parent::send($userlist[$i], '#SERVER You Forced Disconnected from the channel');
            }
      }
  }
 
  private function killchannel($user) // el user se fue del canal
  {
      $rango = '@';
      if($user->founder == true) $rango = '[F]';
      if($user->moderator == true) $rango = '[M]';
      $userlist = SocketPlusUser::$channels[$user->channel]['userlist'];
      for($i=0; $i<count($userlist); $i++)
      {
          if($userlist[$i]->name != $user->name) // no nos enviamos a nosotros mismos
              parent::send($userlist[$i], '***Lost Connection: '.$rango.$user->name);
          else
           {
                unset(SocketPlusUser::$channels[$user->channel]['userlist'][$i]); //lo quitamos de la lista de usuarios
                SocketPlusUser::$channels[$user->channel]['userlist'] = array_values(SocketPlusUser::$channels[$user->channel]['userlist']);
           }
      }
  }
 
  private function meunicanal($user) // el user se fue del canal
  {
      $rango = '@';
      if($user->founder == true) $rango = '[F]';
      if($user->moderator == true) $rango = '[M]';
      $userlist = SocketPlusUser::$channels[$user->channel]['userlist'];
      for($i=0; $i<count($userlist); $i++)
      {
          if($userlist[$i]->name != $user->name) // no nos enviamos a nosotros mismos
              parent::send($userlist[$i], '***JOIN A CHANEL: '.$rango.$user->name);
      }
  }
 
  private function ir_canal($user, $params)
  {
    return $user->ir_canal($user, $params);
  }
 
  private function stdout($message)
  {
      echo '-----<>'.$message."\r\n";
  }
 
  private function MEout($message)
  {
      echo '<<-----'.$message."\r\n";
  }
 
  private function HEout($message)
  {
      echo '----->>'.$message."\r\n";
  }
 
  private function stderr($message)
  {
      echo '-----**'.$message."\r\n";
  }
 
protected function connected($user)        // Called after the handshake response is sent to the client.
  {
      echo '-----<> Connected Success #'.$user->id."\r\n";
  }
 
protected function closed($user)           // Called after the connection is closed.
  {
      // borrar de la lista donde estaba dicho user
      $this->killchannel($user);
      // nos vimos!
      echo '-----<> CLOSE: #'.$user->id."\r\n";
  }
 
}

// definimos los usuarios:
SocketPlusUser::$users = array('alex' => '1234',
                               'prueba' => '1234');

SocketPlusUser::$channels[1]['name'] = 'Canal de ejemplo';
SocketPlusUser::$channels[1]['userlist'] = null;

SocketPlusUser::$channels['alex']['name'] = 'El Canal de alex';
SocketPlusUser::$channels['alex']['userlist'] = null;

// iniciamos el servidor
$socket = new phSocketPlus('localhost','778');


estube a punto de implementar hilos (threads) pero, se me acabó el tiempo asique lo publico así.

este código permite crear varias salas, poner moderadores, et
#354
Back-end / Re:Property en PHP
Octubre 07, 2013, 05:41:23 PM
You are not allowed to view links. You are not allowed to view links. Register or Login or You are not allowed to view links. Register or Login
Excelente manera de utilizar los famosos Traits; hace ya mas de unos tres meses cuando los leí por primera vez con la nueva versión de PHP me di cuenta que para mi y seguro para muchos fue la salvación para lo que es POO.

P.D. Ya que tu complemento es bueno y a más de uno le servira, dejo a continuación el siguiente link para que comprendan un poco más sobre el tema: You are not allowed to view links. You are not allowed to view links. Register or Login or You are not allowed to view links. Register or Login

Saludos,
Xt3mP.

jajaja, yo cuando lo vi dije "oh dios, lo amo, y aún no lo usé por primera vez" jajaja, la verdad que si es muy útil, además buen ejemplo con la implementación de singleton en trait, no se me había ocurrido jajaja.

saludos!
#355
Back-end / BBCODE en PHP Clase BBParser 1.1.0
Octubre 06, 2013, 07:22:25 PM
Buenas tardes, dejaré el trabajo del día de hoy, tomando mi clase anterior para controlar bbcode You are not allowed to view links. You are not allowed to view links. Register or Login or You are not allowed to view links. Register or Login le hize un poco de refinamiento e implementé algunas mejoras, asique hoy traigo mi BBParser 1.1.0 con mejoras que mensionaré ahora mismo:


  • Agregado soporte para emoticonos
  • Implementada interfaces
  • Agregado el Property que diseñé You are not allowed to view links. You are not allowed to view links. Register or Login or You are not allowed to view links. Register or Login
  • Agregado soporte toString para los objetos
  • Agregadas los final function

Voy a detallar las mejoras:
el soporte para emoticonos implementa una nueva clase de tipo smiley (así le llamé) y una función para crear emoticonos que se puedan usar por si no manejan objetos. (bbp_generate_bbcode_smiley();)

A partir de ahora para usar el BBParser tienen que incluir unicamente bbcode_interface.php
La interface les permitirá ver las funciones publicas que pueden utilizar y sus parametros sin tener que ver todo el código.
Si una interfaz se llama Ibbcode es la que se usa en la clase bbcode (por lo que sus funciones son las que están en los objetos instanciados de esa clase)
Si una interfaz dice Iejemplo extend Ibbcode por ejemplo, quiere decir que la interfaz Iejemplo tendrá todas las funciones de Ibbcode además de las que se describen en Iejemplo.

El property les permite acceder a los atributos privados de las clases, por ejemplo ver el id de un bbcode poniendo
Código: text
echo $objetobbcode->id;

donde objetobbcode es el objeto de una de las clases e id es un atributo privado.

El soporte tostring les permite dependiendo de la clase a la que pertenezca un objeto hacer:
$objeto = new bbcode();
echo $objeto;
y mostrará dependiendo de la clase algo de relevancia de la misma clase.

Internamente es útil el final function por si alguien realiza ediciones al modulo BBParser que no pueda realizar ciertos cambios sin que genere errores, lo que asegura el correcto funcionamiento del código aún cuando se quiera sobreescribir ciertas cosas que no se deberían sobreescribir.

Dejando las explicaciones de lado les dejo el código para descargar You are not allowed to view links. You are not allowed to view links. Register or Login or You are not allowed to view links. Register or Login.

el ejemplo de uso también está adjuntado pero es éste:

Código: php

<?php

// EXAMPLE OF USE

// incluimos el parseador
include('bbcode_interface.php');

// creamos la lista de los distintos bbc que usaremos
$lista = array();

$lista[] = bbp_generate_bbcode_simple('hr', '<hr>'); // [hr] -> <hr>
$lista[] = bbp_generate_bbcode_simple('br', '<br />'); // [br] -> <br />

$lista[] = bbp_generate_bbcode_double('b', '<b>', '</b>'); // [b]?[/b] -> <b>?</b>
$lista[] = bbp_generate_bbcode_double('s', '<s>', '</s>'); // [b]?[/b] -> <b>?</b>

$lista[] = bbp_generate_bbcode_smiley(':)', '<img src="http://png.findicons.com/files/icons/1577/danish_royalty_free/32/smiley.png">'); // emoticono :)

$lista[] = bbp_generate_bbcode_double_params('url', '<a href="?">', '</a>'); // [url=google.com]example[/url] -> <a href="google.com">example</a>

$example = '[br]Hola, soy [b]alexander[/b][br] esto es una prueba :) [s]FEOS![/s] [br][hr][br] [url=http://basecode.org]BaseCode[/url][br] Voy a probar ahora, que pasa si dejo una etiqueta abierta como [b]esta[br][br]';
$errors = null;

echo $lista[3]; // mostramos el bbcode [s] para probar que se puede hacer un echo directamente al objeto

// vemos el texto parseado
echo bbp_parse($lista, $example, $errors);

var_dump($errors);


y se ve así:



como verán en la imagen hay ciertas cosas que funcionan mejor en mi código que por ejemplo en SMF, ya que si en smf dejan una etiqueta abierta, como la de negrita, todo el texto desde donde empieza hasta donde termina el texto queda en negrita, en mi código si no tiene la etiqueta de cierre se muestra sin ser parseado, lo que evita que se vea feo xD.

saludos para todos! espero que les guste!
#356
Back-end / Property en PHP
Octubre 06, 2013, 05:51:03 PM
Haciendo mi segunda versión de la clase BBParser (que publiqué anteriormente la versión 1), mientras refinaba el código que había escrito, miraba la documentación de php. Hace unos días había oído que php era una basura como lenguaje, y uno de los argumentos del expositor de dicho mensaje, era que php no daba soporte al famoso y muy útil property.
Todos sabemos que si nos basamos en los principios de encapsulamiento no podemos tener atributos públicos que sean accesibles directamente desde fuera de las clase, por lo que la solución a éste problema era simple, crear funciones públicas que cambien los valores y/o los obtengan, de aquellos atributos privados. Para lo cual surgen las funciones getter y setters, no obstante, si uno hacía un módulo, tendría que explicarle a los que lo usaran (si no eran muy experimentados) que habían funciones para setear valores, y funciones para obtenerlos, y posiblemente se le haría una confusión porque, para setear un valor a una variable simplemente uno pone $variable = $valor; pero para setear valores de esta forma tenemos que usar una función setear_variable($valor); lo cual es muy diferente y le podría dar confusión, para solucionar esto, y quitar este peso absolutamente innecesario, se creó el property, que son unas pocas lineas de código que especifican que cuando alguien quiere acceder a una propiedad privada, se llama a una función que manipule la propiedad y devuelva el resultado, dando entonces que a una clase que tiene un atributo privado como la que pondré más abajo, se pueda acceder "directamente" o eso parecería, aunque internamente pasa por funciones que manipulan el atributo.
Para mala suerte de la persona que dijo que el property no era posible en php porque el lenguaje no lo soportaba, estaba equivocado, y con un par de funciones mágicas pude hacer un property, que lo puse en un trait para que pueda ser usado en cualquier clase cuantas veces sea necesario (según la cantidad de clases).

aquí les dejo el property que lo verán en la nueva versión de mi clase controladora de bbcodes.

Código: php



    /** Property para php
     *  ésto fué escrito por alexander171294 - [H]arkonnen
     *  como parte del módulo BBParser 1.1.0
     *  @ Contact: [email protected]
     */ 
    trait MyProperty // mi hermoso trait property
    {
        // llamando a funciones setters
        Public function __set($property, $value)
        {
            if(is_callable(array($this, 'set_'.$property), $value))
                return call_user_func(array($this, 'set_'.$property), $value);
            else
            // no hay funcion setter para este atributo (o no existe el atributo)
                return false;
        }
       
        // llamando a funciones getters
        Public function __get($property)
        {
            if(is_callable(array($this, 'get_'.$property)))
                return call_user_func(array($this, 'get_'.$property));
            else
            // no hay funcion getter para este atributo (o no existe el atributo)
                return false;
        }
    }
     
    /* implementación de ejemplo: */
     
    Class prueba
    {
    use MyProperty;
            private $ejemplo = 0; // variable privada a la que accederemos
     
            // getter
            private get_ejemplo()
            {
                    return $ejemplo;
            }
           
            // setter
            private set_ejemplo($value)
            {
                    $this->ejemplo = $value;
            }
    }
     
    $example = new prueba();
     
    $example->ejemplo = 2;
    echo $example->ejemplo;
     
    // como verán, se puede acceder al atributo privado aparentemente "directamente" no obstante, previamente el código llama a las funciones getters y setters para los atributos privados a los que queremos acceder, por lo tanto no viola los principios de encapsulamiento :)


también lo pueden ver desde pastebin You are not allowed to view links. You are not allowed to view links. Register or Login or You are not allowed to view links. Register or Login

saludos!
#357
Galería / Re:Mi Firma - (Estilo Cmd)
Octubre 06, 2013, 02:08:52 PM
que buena idea que me haz dado jajjaja

genial!

saludos!

Edito:

así me quedó a mi :P

#358
Seguridad web y en servidores / Re:ParameterFuzz v1.7
Octubre 05, 2013, 04:46:06 PM
genial, se agradece :)

saludos!
#359
Bugs y Exploits / Re:CSRF Twitter
Octubre 05, 2013, 04:23:28 PM
You are not allowed to view links. You are not allowed to view links. Register or Login or You are not allowed to view links. Register or Login
Buenas indagando por todas las redes sociales grandes buscando diversas vulnerabilidades, me encontre con este CSRF en el registro, no es mucha cosa ya que solo registra una cuenta nueva la persona que entra pero quiero compartirla.

Url: You are not allowed to view links. You are not allowed to view links. Register or Login or You are not allowed to view links. Register or Login

CSRF: You are not allowed to view links. You are not allowed to view links. Register or Login or You are not allowed to view links. Register or Login

Fue reportado por un mensaje a la cuenta oficial de twitter ayer por la noche, desconozco si ya fue arreglada.



El texto fue redactado en el traductor ya que no se ingles, supongo que habra algunas burradas  ;D

Salu2;)

algunas burradas? con solo leer la primera linea dice exactamente:

Hola, mi nombre es y yo trabajo en el pekador mundo informático. xD

dejando el gracioso mensaje en inglés de lado, muy interesante lo que encontraste.

un saludo! :)
#360
Back-end / [CLASS] BBParser (clase para manejar bbcode)
Octubre 05, 2013, 03:43:40 PM
Buenas tardes, estaba trabajando en mi proyecto personal, y me surguió el problema de tener que trabajar mensajes con formato pero sin permitirle al usuario que pueda ingresar html, porque todos sabemos los problemas que implica eso, por lo que tomé la idea del BBCODE de smf, y diseñé una clase para manipular textos parseando el bbcode y transformarlo a html a la hora de ver el mensaje.

Para esto creé una clase modelo de lo que era un bbcode, luego creé otras tres clases que la extienden para diferenciar tres tipos de BBCODE el simple (una etiqueta sola, como el [hr]), luego el bbcode doble, (lo que sería por ejemplo [b][/b]), y luego una etiqueta doble con parámetros (lo que sería por ejemplo [url=algo.com]algo[/url]) teniendo estos tres tipos de objetos bbc, también creé una clase que parsee todos los objetos de un listado. por último para los que no tienen muy claro el funcionamiento de programación orientada a objetos, hize lo que podría llamarse una interfaz, con funciones simples que les permiten a los usuarios menos experimentados utilizar la clase sin utilizarla directamente sino en base a un conjunto de funciones, y para finalizar realizé un ejemplo de uso que prueba mi clase.

Quiero aclarar que mi clase está en fase prototipo, lo que quiere decir que puede contener errores, y no está pulida, es un inicio.

Sin más dejo el archivo bbcode_parser.php (la "librería" que tiene todo el parser)

Código: php


<?php

/** BBCODE PARSER CLASS
*  @ Project Name: BBParser Alias BBP
*  @ Author: Alexander171294 - [H]arkonnen
*  @ Date: 05/10/13
*  @ Contact: [email protected]
*  @ Status: Prototype
*  @ Comment-Lang: es-AR
*  @ PHP-Version: >=5.1
*  @ Class-Version: 1.0.0
*/ 

/* Ésta clase está orientada al tratamiento efectivo de bbcode
   Para lo cual cuenta con varias clases, la principal para parsear los textos
   y clases secundarias que corresponden a bbcode en específico
*/

/* Clase que define a un objeto BBCODE
    Es una clase básicamente declaratoria
*/

abstract class bbcode
{
    /*
        identificador del bbcode
        @obj_id (string)
    */
    private $obj_id = null;
    /*
        su identidad en html
        @obj_html (string)
    */
    private $obj_html = null;
    /*
        cantidad de coincidencias
        @obj_html (int)
    */
    private $obj_cc = 0;
    /*
        delimitador inicial del bbcode (con que se inicia el bbcode)
        @delimiter_initial (string)
    */
    private $delimiter_initial = '[';
    /*
        delimitador final del bbcode (con que se finaliza el bbcode)
        @delimiter_final (string)
    */
    private $delimiter_final = ']';
    /*
        variable que contiene el estado de errores
        @error (bool) false: sin errores; true: ocurrio un problema
    */
    private $error = false;
    /*
        variable que contiene el posible mensaje de error
        @error_detail (string)
    */
    private $error_detail = null;
   
    /*
        función constructora que asigna el id o clave del bbcode
        @obj_id (string) identificador del bbcode
        @obj_html (string) identidad en html
        @delimiter_initial (char) OPTIONAL caracter inicial del bbcode
        @delimiter_final (char) OPTIONAL caracter final del bbcode
    */
    public function __construct( $obj_id, $obj_html, $delimiter_initial = null, $delimiter_final = null)
    {
        $obj_id = (string) $obj_id; $obj_html = (string) $obj_html; $delimiter_initial = (string) $delimiter_initial; $delimiter_final = (string) $delimiter_final;
        try
        {
            $obj_id = trim($obj_id);
            if(strlen($obj_id)<1 || empty($obj_id)) throw new exception ('INVALID PARAM @OBJ_ID');
            $this->obj_id = $obj_id;
            $obj_html = trim($obj_html);
            if(strlen($obj_html)<1 || empty($obj_html)) throw new exception ('INVALID PARAM @OBJ_HTML');
            $this->obj_html = $obj_html;
            $this->delimiter_initial = empty($delimiter_initial) ? $this->delimiter_initial : $delimiter_initial;
            $this->delimiter_final = empty($delimiter_final) ? $this->delimiter_final : $delimiter_final;
           
        } catch (Exception $e)
        {
            $this->error_detail = $e->getMessage();
            $this->error = true;
        }
    }
   
    ///////////////////////////////////////////////////////////
    // Funciones Setters (para cambio luego del constructor) //
    ///////////////////////////////////////////////////////////
   
    // steamos el nuevo id del objeto
    public function set_obj_id($new_obj_id)
    {
        $new_obj_id = (string) $new_obj_id;
        try
        {
            $obj_id = trim($obj_id);
            if(strlen($obj_id)<1 || empty($obj_id)) throw new exception ('INVALID PARAM @OBJ_ID');
            $this->obj_id = $new_obj_id;
            return true;
        } catch (Exception $e)
        {
            $this->error_detail = $e->getMessage();
            $this->error = true;
            return false;
        }
    }
   
    // seteamos el nuevo html para este bbcode
    public function set_obj_html($new_obj_html)
    {
        $new_obj_html = (string) $new_obj_html;
        try
        {
            $obj_html = trim($obj_html);
            if(strlen($obj_html)<1 || empty($obj_html)) throw new exception ('INVALID PARAM @OBJ_HTML');
            $this->obj_html = $new_obj_html;
            return true;
        } catch (Exception $e)
        {
            $this->error_detail = $e->getMessage();
            $this->error = true;
            return false;
        }
    }
   
    // seteamos los nuevos delimitadores para este bbcode
    public function set_delimiters($delimiter_initial, $delimiter_final)
    {
        $delimiter_initial = (string) $delimiter_initial; $delimiter_final = (string) $delimiter_final;
        try
        {
            $delimiter_initial = trim($delimiter_initial);
            if(strlen($delimiter_initial)<1 || empty($delimiter_initial)) throw new exception ('INVALID PARAM @delimiter_initial');
            $this->delimiter_initial = $delimiter_initial;
            $delimiter_final = trim($delimiter_final);
            if(strlen($delimiter_final)<1 || empty($delimiter_final)) throw new exception ('INVALID PARAM @delimiter_final');
            $this->delimiter_final = $delimiter_final;
            return true;
        } catch (Exception $e)
        {
            $this->error_detail = $e->getMessage();
            $this->error = true;
            return false;
        }
    }
   
    ///////////////////////////////////////////////////////////
    // Funciones Getters (para obtener atributos)            //
    ///////////////////////////////////////////////////////////
   
    // obtener el id de este bbcode
    public function get_obj_id()
    {
        return $this->obj_id;
    }
   
    // obtener el html de este bbcode
    public function get_obj_html()
    {
        return $this->obj_html;
    }
   
    // obtener los delimitadores de este bbcode
    public function get_delimiter_initial()
    {
        return $this->delimiter_initial;
    }
   
    // obtener los delimitadores de este bbcode
    public function get_delimiter_final()
    {
        return $this->delimiter_final;
    }
   
    // obtener si hay error
    public function get_error()
    {
        return $this->error;
    }
   
    // obtener detalles del error
    public function get_error_detail()
    {
        return $this->error_detail;
    }
}

class bbc_basic extends bbcode
{
    /*
        función que parsea el texto para bbcodes básicos
    */
    public function parser($text)
    {
        $text = (string) $text;
        $text = trim($text);
        if(!empty($text))
            return str_replace(parent::get_delimiter_initial().parent::get_obj_id().parent::get_delimiter_final(),parent::get_obj_html(),$text);
        else
            return false;
    }
}

class bbcode_double extends bbcode
{
    /*
        identificador de cierre de bbcode (dado por delimitador inicial + identificador de cierre + id + delimitador final)
        @obj_close_id (string)
    */
    private $obj_close_id = '/';
    /*
        identificador de cierre de html (por ejemplo </a>)
        @html_close (string)
    */
    private $html_close = null;
   
    /*
        función que parsea el texto para bbcodes dobles
    */
    public function parser($text)
    {
        $text = (string) $text;
        $text = trim($text);
        if(!empty($text))
        {
            $key = parent::get_delimiter_initial().parent::get_obj_id().parent::get_delimiter_final().'?'.parent::get_delimiter_initial().$this->obj_close_id.parent::get_obj_id().parent::get_delimiter_final();
            $item = parent::get_obj_html().'$1'.$this->html_close;
            return preg_replace('#'.str_replace(array('[',']'),array('\[','\]'),str_replace('?','(.+)',$key)).'#i', $item, $text);
        }
        else
        {
            $this->error = true;
            $this->error_detail = 'Class bbcode_double ERROR: function parser :: Param $text is invalid';
            return false;
        }
    }
   
    ///////////////////////////////////////////////////////////
    // Funciones Setters (para cambio luego del constructor) //
    ///////////////////////////////////////////////////////////
   
    /*
        función para setear el cierre del bbcode (por ejemplo /)
    */
    public function set_obj_close_id($id)
    {
        $id = (string) $id;
        $id = trim($id);
        if(!empty($id))
        {
            $this->obj_close_id = $id;
            return true;
        } else {
            $this->error = true;
            $this->error_detail = 'Class bbcode_double ERROR: function set_obj_close_id :: Param $id is invalid';
            return false;
        }
    }
   
    /*
        función para setear el cierre de html (por ejemplo </a>)
    */
    public function set_html_close($html)
    {
        $html = (string) $html;
        $html = trim($html);
        if(!empty($html))
        {
            $this->html_close = $html;
            return true;
        } else {
            $this->error = true;
            $this->error_detail = 'Class bbcode_double ERROR: function set_html_close :: Param $html is invalid';
            return false;
        }
       
    }
   
    ///////////////////////////////////////////////////////////
    // Funciones Getters (para obtener atributos)            //
    ///////////////////////////////////////////////////////////
   
    public function get_obj_close_id()
    {
        return $this->obj_close_id;
    }
   
    public function get_html_close()
    {
        return $this->html_close;
    }
}

class bbcode_double_params extends bbcode
{
    /*
        identificador de cierre de bbcode (dado por delimitador inicial + identificador de cierre + id + delimitador final)
        @obj_close_id (string)
    */
    private $obj_close_id = '/';
    /*
        identificador de cierre de html (por ejemplo </a>)
        @html_close (string)
    */
    private $html_close = null;
   
    /*
        función que parsea el texto para bbcodes dobles con parametros
    */
    public function parser($text)
    {
        $text = (string) $text;
        $text = trim($text);
        if(!empty($text))
        {
            $key = parent::get_delimiter_initial().parent::get_obj_id().'=?'.parent::get_delimiter_final().'?'.parent::get_delimiter_initial().$this->obj_close_id.parent::get_obj_id().parent::get_delimiter_final();
            $item = str_replace('?','$1',parent::get_obj_html()).'$2'.$this->html_close;
            return preg_replace('#'.str_replace(array('[',']'),array('\[','\]'),str_replace('?','(.+)',$key)).'#i', $item, $text);
        }
        else
        {
            $this->error = true;
            $this->error_detail = 'Class bbcode_double_params ERROR: function parser :: Param $text is invalid';
            return false;
        }
    }
   
        /*
        función para setear el cierre de html (por ejemplo </a>)
    */
    public function set_html_close($html)
    {
        $html = (string) $html;
        $html = trim($html);
        if(!empty($html))
        {
            $this->html_close = $html;
            return true;
        } else {
            $this->error = true;
            $this->error_detail = 'Class bbcode_double ERROR: function set_html_close :: Param $html is invalid';
            return false;
        }
       
    }
   
    ///////////////////////////////////////////////////////////
    // Funciones Getters (para obtener atributos)            //
    ///////////////////////////////////////////////////////////
   
    public function get_obj_close_id()
    {
        return $this->obj_close_id;
    }
   
    public function get_html_close()
    {
        return $this->html_close;
    }

}

//////////////////////////////////////
//         CLASE PARSEADORA         //
//////////////////////////////////////

// clase que parsea los bbcode
class BBParser
{
    // arreglo de errores
    private $errors = array();
    // cantidad de errores
    private $errors_count = 0;
    // cantidad de bbcode simples
    private $simple_count = 0;
    // cantidad de bbcode dobles
    private $double_count = 0;
    // cantidad de bbcode doble con parametros
    private $double_params_count = 0;
    // listado de bbcodes disponibles
    private $bbcode = null;
    // texto a parsear
    private $text = null;
   
    // función constructora
    public function __construct( $bbcode_list, $text )
    {
        $text = (string) $text;
        try
        {
            if(!is_array($bbcode_list)) throw new exception ('Class bbcode_parser INSTANCE ERROR: the param $bbcode_list is invalid type');
            if(count($bbcode_list)<1) throw new exception ('Class bbcode_parser INSTANCE ERROR: the param $bbcode_list is invalid array');
            $text = trim($text);
            if(empty($text)) throw new exception ('Class bbcode_parser INSTANCE ERROR: empty param $text');
            $this->bbcode = $bbcode_list;
            $this->text = $text;
        } catch (Exception $e)
        {
            $this->errors[$this->errors_count] = $e->getMessage();
            $this->errors_count++;
        }
    }
   
    // función para parsear
    public function parser()
    {
        if(empty($this->bbcode))
        {
            $this->errors[$this->errors_count] = 'Class bbcode_parser Function parser(); NOT VALID BBCODE_LIST';
            $this->errors_count++;
            return false;
        }
        for($i = 0; $i<count($this->bbcode); $i++)
        {
            if($this->bbcode[$i] instanceof bbc_basic)
                $this->text = $this->parser_bbc_basic($this->bbcode[$i]);
            elseif($this->bbcode[$i] instanceof bbcode_double)
                $this->text = $this->parser_bbc_double($this->bbcode[$i]);
            elseif($this->bbcode[$i] instanceof bbcode_double_params)
                $this->text = $this->parser_bbc_double_params($this->bbcode[$i]);
            else
            {
                $this->errors[$this->errors_count] = 'Class bbcode_parser Function parser(); The item #' . $i . ' of array $bbcode_list is not a bbc valid class';
                $this->errors_count++;
            }
        }
        return true;
    }
   
    // parse bbcode_basic
    private function parser_bbc_basic( bbc_basic $bbc )
    {
        $bbc = (object) $bbc;
        $this->simple_count++;
        if($result = $bbc->parser($this->text))
            return $result;
        else
        {
            $this->errors[$this->errors_count] =  $bbc->get_error_detail();
            $this->errors_count++;
            return false;
        }
    }
   
    // parse bbcode_double
    private function parser_bbc_double( bbcode_double $bbc )
    {
        $bbc = (object) $bbc;
        $this->double_count++;
        if($result = $bbc->parser($this->text))
            return $result;
        else
        {
            $this->errors[$this->errors_count] =  $bbc->get_error_detail();
            $this->errors_count++;
            return false;
        }
    }
   
    // parse bbcode_double_params
    private function parser_bbc_double_params( bbcode_double_params $bbc )
    {
        $bbc = (object) $bbc;
        $this->double_params_count++;
        if($result = $bbc->parser($this->text))
            return $result;
        else
        {
            $this->errors[$this->errors_count] =  $bbc->get_error_detail();
            $this->errors_count++;
            return false;
        }
    }
   
    // GETTERS
    public function get_errors()
    {
        return $this->errors;
    }
    public function get_errors_count()
    {
        return $this->errors_count;
    }
    public function get_simple_count()
    {
        return $this->simple_count;
    }
    public function get_double_count()
    {
        return $this->double_count;
    }
    public function get_double_params_count()
    {
        return $this->double_params_count;
    }
    public function get_text()
    {
        return $this->text;
    }
}

//*********************************//
//*          INTERFACE            *//
//*********************************//

// crear objeto bbcode simple
function bbp_generate_bbcode_simple($obj_id, $obj_html, $delimiter_initial = null, $delimiter_final = null)
{
    if(empty($delimiter_initial))
    {
        $obj_id = (string)$obj_id;
        $obj_html = (string)$obj_html;
        //die(gettype($obj_id));
        return new bbc_basic($obj_id, $obj_html);
    } else {
        return new bbc_basic((string)$obj_id, (string)$obj_html, (string)$delimiter_initial, (string)$delimiter_final);
    }
}

// crear objeto bbcode doble
function bbp_generate_bbcode_double($obj_id, $obj_html, $html_close, $delimiter_initial = null, $delimiter_final = null)
{
    if(empty($delimiter_initial))
    {
        $bbc = new bbcode_double((string)$obj_id, (string)$obj_html);
        $bbc->set_html_close((string) $html_close);
        return $bbc;
    } else {
        $bbc = new bbcode_double((string)$obj_id, (string)$obj_html, (string)$delimiter_initial, (string)$delimiter_final);
        $bbc->set_html_close((string) $html_close);
        return $bbc;
    }
}

// crear objeto bbcode doble con parametros
function bbp_generate_bbcode_double_params($obj_id, $obj_html, $html_close, $delimiter_initial = null, $delimiter_final = null)
{
    if(empty($delimiter_initial))
    {
        $bbc = new bbcode_double_params((string)$obj_id, (string)$obj_html);
        $bbc->set_html_close((string) $html_close);
        return $bbc;
    } else {
        $bbc = new bbcode_double_params((string)$obj_id, (string)$obj_html, (string)$delimiter_initial, (string)$delimiter_final);
        $bbc->set_html_close((string) $html_close);
        return $bbc;
    }
}

// parsear un texto usando una lista de codigos bbc
function bbp_parse($list_bbcode, $text_parse, &$error_array)
{
    $bbp = new BBParser( (array) $list_bbcode, (string) $text_parse );
    $error_array = $bbp->get_errors();
    $bbp->parser();
    return $bbp->get_text();
}



y para mostrarles el funcionamiento les dejo un script de ejemplo:

Código: php


<?php

// EXAMPLE OF USE

// incluimos el parseador
include('bbcode_parser.php');

// creamos la lista de los distintos bbc que usaremos
$lista = array();

$lista[] = bbp_generate_bbcode_simple('hr', '<hr>'); // [hr] -> <hr>
$lista[] = bbp_generate_bbcode_simple('br', '<br />'); // [br] -> <br />

$lista[] = bbp_generate_bbcode_double('b', '<b>', '</b>'); // [b]?[/b] -> <b>?</b>
$lista[] = bbp_generate_bbcode_double('s', '<s>', '</s>'); // [b]?[/b] -> <b>?</b>

$lista[] = bbp_generate_bbcode_double_params('url', '<a href="?">', '</a>'); // [url=google.com]example[/url] -> <a href="google.com">example</a>

$example = 'Hola, soy [b]alexander[/b][br] esto es una prueba :) [s]FEOS[/s] [br][hr][br] [url=http://basecode.org]BaseCode[/url][br] ';
$errors = null;

// vemos el texto parseado
echo bbp_parse($lista, $example, $errors);

// lista de errores
var_dump($errors);



esto se vería así:



bueno como verán el funcionamiento es sencillo, se crea la lista de bbcodes disponibles (hasta podríamos hacer un archivo a parte que los cree) y luego parseamos un texto de ejemplo de una variable de ejemplo.

el bbcode_simple también podría ser usado para emoticonos, ya que la clase es bastante manipulable (no tanto así el conjunto de funciones) se puede hasta cambiar los delimitadores del bbc, y de pronto en vez de poner [b] poner {b} o -b* por poner un ejemplo, o quitarle los delimitadores.

pueden descargar mi ejemplo clase You are not allowed to view links. You are not allowed to view links. Register or Login or You are not allowed to view links. Register or Login

un saludo para todos!