Cita:
Iniciado por repara2 ok, pero entonces cuál era el problema? Puedes postear la solución?
Revisando el codigo... de pronto si rebobina el while() tambien jeje ...en fin...
Código PHP:
<?php
namespace FastyPatterns;
interface IComparable
{
/**
* Hace comparacion como
* su homologa en C#
*
* @return int {-1,0,1}
*/
public function compareTo($other);
public function getDiff();
}
abstract class Comparable implements IComparable
{
protected $_diff = array();
/**
* Devuelve diferencias
*
* @return array
*/
public function getDiff ()
{
return $this->_diff;
}
}
/**
* Tag:
* almacena un tag con todas sus propiedades
*/
Class Tag extends Comparable
{
private $_element_name = null; // input-text, input-radio,...etc
private $_prop = array();
public function __construct($element){
$this->_element_name = $element;
return $this;
}
public function getElementName(){
return $this->_element_name;
}
// (objeto)->propiedad = valor (no es encadenable)
public function __set($p,$val)
{
$this->_prop[$p]= $val;
}
public function __get($p)
{
return $this->_prop[$p];
} // end class
// (objeto)->set_propiedad(valor) (si es encadenable)
public function __call($name, $arguments) {
// setting a property
if (substr($name,0,4) == 'set_') {
// get the property name we want to set
$property = substr($name,4);
// assign the value that was passed to this method
// to the class property
$this->_prop[$property] = $arguments[0];
//var_dump($this->_prop);
// adding to an array property
} else if (substr($name,0,4) == 'add_') {
// get the property name we want to add to
$property = substr($name,4);
// add the value
array_push($this->_prop[$property], $arguments[0]);
}
// for method chaining
return $this;
}
public function getAllFormated(){
$out = "Tag: {$this->_element_name} <br/>";
foreach ($this->_prop as $prop => $val){
$out .= "[$prop] => $val <br/>";
}
return $out.'<p/>';
}
public function __ToString()
{
return $this->getAllFormated();
}
// es revelar el estado interno, pero es lo mas facil
public function getProperties(){
return $this->_prop;
}
/**
* Compara Tags: variacion de metodo de C#
*
* @return {-1 ,0 , 1}
*
* si el tipo de elemento es distinto, retorna -1
* si son iguales, retorna 0
* si el primero tiene algo de sobra, retorna 1
*/
public function compareTo ($tag2)
{
$class = __CLASS__;
if (!($tag2 instanceof $class))
throw new Exception ('Debe ser del mismo tipo a comparar');
$this->_diff = null;
// seguro distintos tags y ya
if (strtolower($this->getElementName()) != strtolower($tag2->getElementName()))
return -1;
$p1 = $this->getProperties();
$p2 = $tag2->getProperties();
// seguro son iguales en todo
if ($p1 == $p2)
return 0;
// sera que hay en tag2 elementos que no estan en este ?
$this->_diff = array_diff_assoc ($p2,$p1);
if (count($this->_diff)!=0)
return -1;
// sera que hay en este tag elementos que no estan en tag2 ?
$this->_diff = array_diff_assoc ($p1,$p2);
if (count($this->_diff)!=0)
return 1;
throw new Exception ('Fallo al capturar diferencia de tags');
}
} // end class
/**
* TagSequence:
* almacena una secuencia de tags
*/
Class TagSequence implements Iterator
{
private $_name = null;
private $_tags = array();
private $_optionals = array();
private $_last_search =null;
private $_search_cursor =null;
public function __construct($name=null){
$this->_name = $name;
return $this;
}
public function setName($input)
{
$this->_name=$input;
return $this;
}
public function getName()
{
return $this->_name;
}
public function addTag (tag $tag , $optional=null){
$this->_tags[]=$tag;
$this->_optionals[]=$optional;
return $this;
}
// devuelve si el tag actual en la secuencia esta marcado como opcional o no
public function is_optional(){
return $this->_optionals[$this->key()];
}
public function __ToString ()
{
$out = '<i><b>Secuence:</b> '.$this->_name.'</i><p/>';
foreach ($this->_tags as $tag){
$out .= $tag->getAllFormated();
}
return $out.'<p/>';
}
/* Find: mueve el cursor hasta la primera ocurrencia o hasta el final sino se encuentra devuelve bool
*
* El cursor queda sobre el elemento seleccionado o en NULL si llega al final sin encontrarlo
* Permite buscar varias ocurrencias si se repite la busqueda
*/
public function find(tag $search,$continue=true){
if ($continue and $search==$this->_last_search)
{
while ($this->valid() and $this->key()<=$this->_search_cursor){
$this->next();
}
}
$this->_last_search = $search;
while ($this->valid()){
$current_tag = $this->current();
$this->_search_cursor = $this->key();
if ($current_tag->compareTo($search)>=0){
return true;
}
$this->next();
}
return false;
}
/**
* findFirst : busca la primera ocurrencia
*
* a) Es mas eficiente
* b) Siempre busca *desde el comienzo*
* c) el cursor queda 'pasado' en 1 o o en NULL si llega al final sin encontrarlo
*
* @param tag
* @return bool
*/
public function findFirst(tag $search){
$ret = false;
foreach ($this->_tags as $key=> $current_tag)
{
if ($current_tag->compareTo($search)>=0){
$ret = True;
break;
}
}
return $ret;
}
/* Implemento interface Iterator */
public function rewind()
{
reset($this->_tags );
}
public function current()
{
$tag = current($this->_tags);
return $tag;
}
public function next()
{
$tag = next($this->_tags );
return $tag;
}
public function key()
{
$tag_key = key($this->_tags );
return $tag_key;
}
public function valid()
{
$key = key($this->_tags );
$tag = ($key !== NULL && $key !== FALSE);
return $tag;
}
} // end class
Las pruebas no me entraron.......exceden los 10.000 caracteres
No me pegues, despues de tanta vuelta olvide que fue lo que hice aunque creo que el funcionamiento ya se puede asegurar