O Poder do Ajax

Ontem, pela primeira vez, desenvolvi um sistema em Ajax. Já vinha estudando há pouco mais de uma semana e hoje temos votação do Grêmio Estudantil no Colégio, e achei interessante fazer usando Ajax, e aproveitar algumas coisas como:

  • Todos usam Mozilla Firefox.
  • O servidor fica do lado dos computadores… É rede, não internet!

… para abusar de Ajax, já que eu podia fazer uma coisa que buscasse bastante no servidor e que só funcionasse no Gecko. O resultado ficou bem legal. Embora eu não tenha conseguido fazer um trechinho do script sem um IFRAME que atuliza sem parar, todo o esquema foi feito com JavaScript e aprendi umas coisas bem legais. Além disso, o formuláro ficou muito bonito, posicionado e desenvolvido em CSS. Os botões de radio estão com a propriedade display:none e os labels estão com opacity:0.5; Quando eu clico neles (onclick), eles deixam todos os outros com opacity:0.5 e se dão opacity:1. Quando o visitante clica no submit do formulário, o XmlHttp IMEDIATAMENTE pega os dados do servidor e joga na tela. Ficou uma coisa muito massa. E ainda aproveitei pra usar PNGs transparentes!

Não vou colocar o código aqui agora, ainda queria ajustar algumas coisas porque ontem fiz na pressa, mas confiram um screenshot! (o SS mais legal seria o do “Voto Confirmado”, quando um div com fundo PNG alpha aparece em cima de tudo, mas eu fiz um sistema de segurança para só quem tá dentro do Lab. de Informática poder votar – testando IPs – e agora estou em casa).

Screenshot da votação do Grêmio

Ajax é muito power. Desenvolvendo com ele dá pra fazer umas coisas que antes eu nem imaginava… Agora tô estudando bastante JavaScript, porque com a parte de servidor/PHP não há problemas, mas nunca estudei muito o lado client-side (estudei tableless, mas não DOM/JavaScript!). Já li dois artigos do Elcio, do Tableless.com.br: Um sobre DHTML Crossbrowser e outro que é o conhecido Ajax para quem só ouviu falar. Agora estou acabando o segundo artigo dele sobre Ajax, Ajax: Encarando o Mundo Real. O bom é que a sintaxe das coisas no JavaScript são bem parecidas com as do PHP…


Tenho lido umas coisas desse cara e tô achando muito bom. Sugiro que quem goste de software livre ou quem quer aprender mais sobre ele, leia os artigos também. :)

Troca de Servidor e “Semantic Blog”

Em primeiro lugar, quero pedir desculpa a quem entrou no meu site hoje e teve algum problema. Acontece que acabo de trocar de servidor. Depois de ver uma propaganda no Tableless.com.br, acessei o site da NerdHost e gostei dos preços e da qualidade do serviço. Por causa desses fatos e por eles estarem incentivando os padrões web (dão um mês gratuito pra quem desenvolve em tableless), fechei o contrato com eles no dia em que eu vi. :) Esse servidor usa CPanel, que eu acho bem melhor que o painel de controle da Metaweb e tem vantagens como um SSH que funciona SCP (acreditem! O da Metaweb não funcionava!), subdomínios ilimitados, PHP 5, MySql 4… Foi uma excelente troca! :D E ainda peguei o plano mais barato (limpei o servidor, consegui deixá-lo com 60mb), que custa R$ 5,67 (incrível a precisão do valor… hehehe).

Em segundo lugar: Eu, o Hélio e o Gustavo começamos a desenvolver um sistema de blog, em cima de classes, bastante parecido com o meu mas mais simples que tem como objetivo ser leve e possuir apenas o que é necessário. Ele já vai vir com um Shortstat bem modificado pra dar várias estatísticas (tipo, comentários por visitante, umas paradas assim) e com o GeSHi Highlighter. Os posts vão usar BBCodes e o blog vai ser baseado em templates. Resolvemos dar o nome “Semantic Blog”. Gostou? Deixe um comentário pra eu saber! Não gostou? Deixe um comentário também! :p Hehehe… Se você tiver qualquer sugestão de recurso interessante que ele deve ter, também fique a vontade para postar um comentário!

Mudanças no Site e Código do Blog

Atenção: os códigos desta postagem, além de inúteis, estão com muitos erros de sintaxe. Foram convertidos entre várias plataformas de blog e perderam muita coisa. Estão guardados aqui apenas para registro.

Ultimamente fiz várias alterações no site. Refiz quase que todas as páginas e deixei tudo um pouco mais leve e mais fácil para mudar depois. :D Depois de conhecer a POO, me viciei nela no final de semana e converti meu site inteiro para classes. E agora, que seu script tá um pouco melhor organizado, vou colocar aqui para quem quiser copiar, usar alguma idéia, saber como eu estou indo em POO, ver as besteiras que eu faço enquanto programo, etc. :lol: resolvi disponibilizar todo o código de meu blog aqui.

Já que meu blog tem alguns bugs (known bugs de pouca importância, como o caso de se alguém escreve CHARESPC no meio de um comentário ele deve criar um &;), peço somente que ninguém destrua-o sabendo disso. Se alguém descobrir algum bug, pode me enviar um e-mail que ficarei bastante grato. :)

Já que não passei a sessão de administração para POO não vou publicá-la aqui, mas depois de resolver alguns bugzinhos pretendo disponibilizar o código completo, inclusive com um arquivo de instalação que cria as tabelas no banco de dados, para todos poderem usar um sisteminha de blog simples e prático (só que acho que vai ser algo mais voltado a programadores, porque tem vantagens como o uso do GeSHi, e desvantagens como eu publicar todos os posts escrevendo em HTML – isso mesmo, até os & que eu escrevo são & que são & *e um loop infinito pela frente). Hmmm, aliás, quem quiser me ajudar a fazer parte desse projeto para tornar o meu blog um software livre, sinta-se livre para me mandar um e-mail também. :p

Então, uma última observação é que eu substituí todos os <code (note a ausência do > ) por tag code e todos os por tag /code, porque senão minhas expressões regulares do código dariam bug (quer saber por que? Então leia os códigos!)

Funções e classes “includadas” em todos os arquivos {#funcoeseclasses}

<?php
session_start();

// Syntax Highlight - GeSHi
if (!class_exists(GeSHi)) {
	include("geshi.php");
}

// Objeto de conexão do MySql
class MySql {
	var $host="servidor";
	var $usuario="usuario";
	var $senha="senha";
	var $db="bancodedados";
	var $conexao;

	function conecta() {
		$this->conexao=mysql_connect($this->host, $this->usuario, $this->senha);
		mysql_select_db($this->db);
	}

	function desconecta() {
		mysql_close($this->conexao);
	}
}

// Classe com as funções de expressões regulares
class Regex {
	function Replace($o, $d, $t, $codes=0) {
		for ($i=0; $i<sizeof($o); $i++) {
			$o[$i]=str_replace('(', '(', $o[$i]);
			$o[$i]=str_replace(')', ')', $o[$i]);
			$t=eregi_replace($o[$i], $d[$i], $t);
		}
		if ($codes==1) {
			$t="tag /code".$t."tag code";
		} else if ($codes==2) {
			$t.="tag code";
		} else if ($codes==3) {
			$t="tag /code".$t;
		}
		return $t;
	}

	function Emoticons() {
		$o[0]=":)";
		$d[0]="feliz";
		$o[1]=":(";
		$d[1]="triste";
		$o[2]=":o";
		$d[2]="bocaaberta";
		$o[3]=":p";
		$d[3]="lingua";
		$o[4]=":angry:";
		$d[4]="raiva";
		$o[5]=":s";
		$d[5]="confuso";
		$o[6]=":blink:";
		$d[6]="inacreditavel";
		$o[7]=";)";
		$d[7]="piscando";
		$o[8]=":lol:";
		$d[8]="rindo";
		$o[9]=":d";
		$d[9]="sorriso";
		$o[10]=":unsure:";
		$d[10]="semgraca";

		for ($i=0; $i<sizeof($d); $i++) {
			$d[$i]="<img src="/emoticon/".$d[$i].".gif" alt="".$o[$i]."" />";
		}

		if (!ereg("tag code", $texto)) {
			$this->texto=$this->Replace($o, $d, $this->texto);
		} else {
			preg_match_all("/</code>(.+)tag code/sU", $this->texto, $mat1);
			for ($i=0; $i<sizeof($mat1[1]); $i++) {
				$this->texto=str_replace($mat1[1][$i], $this->Replace($o, $d, $mat1[1][$i]), $this->texto);
			}
			preg_match("/^(.+)tag code/sU", $this->texto, $mat2);
			$texto=str_replace($mat2[1], $this->Replace($o, $d, $mat2[1]), $this->texto);
			$rev=strrev($this->texto); //Tenho medo do PHP5.0.5
			preg_match("/^(.+)>edoc/</sU", $rev, $mat3); //Nossa, que código louco!
			$rev=strrev($mat3[1]); //Repito... Tenho medo do PHP5.0.5
			$this->texto=str_replace($rev, $this->Replace($o, $d, $rev), $this->texto); //Agora fuck PHP5.0.5!
		}
	}

	function GeshiHighlight($codigo, $linguagem) {
		$geshi=new GeSHi($codigo, $linguagem, "./geshi/");
		return $geshi->parse_code();
	}

	function Codigos() {
		preg_match_all("/tag code class=\"(.*)\">(.*)</code>/sU",
			$this->texto,
			$matches);
		for ($i=0; $i<sizeof($matches[1]); $i++) {
			$g=$this->GeshiHighlight($matches[2][$i], $matches[1][$i]);
			if (eregi("MSIE", $_SERVER["HTTP_USER_AGENT"])) {
				$g=ereg_replace("<pre>", "<pre class="alturamaxima">", $g);
			}
			$this->texto=str_replace($matches[0][$i],
				$g,
				$this->texto);
		}
	}

	function QuebraLinha() {
		$this->texto=nl2br($this->texto);
	}
}

// Objeto "Artigo"
class Artigo extends Regex {
	var $id;
	var $data;
	var $permalink;
	var $titulo;
	var $texto;
	var $comentarios;

	function Artigo($identificacao) {
		$this->id=$identificacao;

		$mysql=new MySql();
		$mysql->conecta();

		$query_post=mysql_query("SELECT data, permalink, titulo, texto FROM artigos WHERE id='{$this->id}'");
		$post=mysql_fetch_row($query_post);
		$this->data=date("d/m/Y", $post[0]);
		$this->permalink=$post[1];
		$this->titulo=$post[2];
		$this->texto=$post[3];

		$query_comentarios=mysql_query("SELECT count(id) FROM comentario WHERE idpost='{$this->id}'");
		$comentarios=mysql_fetch_row($query_comentarios);
		$this->comentarios=$comentarios[0];

		$mysql->desconecta();
	}

	function AppendGoogleAds($ads) {
		$this->texto.="nn".$ads;
	}

	function Mostra() {
		echo "<h2><a href=\"/post/{$this-?PHPSESSID=9ec34c96b02b3755051aa682d1e02001>permalink}\">{$this->titulo}</a></h2>\n";
		echo $this->texto."\n";
		echo "<h5>{$this->data} ";
    echo "<a href=\"/post/{$this-?PHPSESSID=9ec34c96b02b3755051aa682d1e02001>permalink}\" class=\"permalink\">permalink</a> ";
    echo "<a href=\"/post/{$this-?PHPSESSID=9ec34c96b02b3755051aa682d1e02001>permalink}#comentarios\" class=\"comentarios\">";
    echo "{$this->comentarios} comentário(s)</a></h5>\n";
	}

	function MostraComentarios() {
		if ($_POST["comenta"]&&(!$_SESSION["comentario"]||time()-30>$_SESSION["comentario"])) {
			$_SESSION["comentario"]=time();
			EscreveComentario($_POST["nome"], $_POST["email"], $_POST["texto"], $this->id);
		}
		$comentarios=new Comentarios($this->id);
		$comentarios->Mostra();
	}
}

// Objeto Artigos (serve para pegar vários artigos sem eu precisar fazer nada nas outras páginas)
class Artigos {
	var $id;
	var $titulo;
	var $texto;
	var $permalink;
	var $data;
	var $comentarios;

	function Artigos($n=20, $start=0, $emoticons=0, $codigos=0, $mostrar=0, $comentarios=0) {
		$mysql=new MySql();
		$mysql->conecta();
		$query=mysql_query("SELECT id FROM artigos ORDER BY data DESC, id DESC LIMIT $start,$n");
		$mysql->desconecta();
		for ($i=0; $array=mysql_fetch_array($query); $i++) {
			$artigo=new Artigo($array["id"]);
			if ($emoticons) {
				$artigo->Emoticons();
			}
			if ($codigos) {
				$artigo->Codigos();
			}
			if ($mostrar) {
				$artigo->Mostra();
			}
			if ($comentarios) {
				$artigo->MostraComentarios();
			}
			$this->id[$i]=$array["id"];
			$this->titulo[$i]=$artigo->titulo;
			$this->texto[$i]=$artigo->texto;
			$this->permalink[$i]=$artigo->permalink;
			$this->comentarios[$i]=$artigo->comentarios;
			$this->data[$i]=$artigo->data;
		}
	}
}

// Objeto Comentário
class Comentario extends Regex {
	var $id;
	var $data;
	var $nome;
	var $email;
	var $ip;
	var $useragent;
	var $texto;
	var $numero;

	function Comentario($identificacao, $numero) {
		$this->id=$identificacao;
		$this->numero=$numero;

		$mysql=new MySql();
		$mysql->conecta();

		$query=mysql_query("SELECT data, nome, email, ip, useragent, texto FROM comentario WHERE id='{$this->id}'");
		$comentario=mysql_fetch_row($query);

		$this->data=date("d/m/Y", $comentario[0]);
		$this->nome=$comentario[1];
		if ($_SESSION["tiagomadeira"]) {
			$this->email="</small> <span style=\"font-size:10px;\"><br />";
			if ($comentario[2]) $this->email.="<strong>E-mail:</strong> ".$comentario[2]."<br />n";
			if ($comentario[3]) $this->ip="<strong>IP:</strong> ".$comentario[3]."<br />n";
			if ($comentario[4]) $this->useragent="<strong>User Agent:</strong> ".$comentario[4];
			$this->useragent.="</span>";
		} else {
			$this->email="</small>";
		}
		$this->texto=$comentario[5];

		$mysql->desconecta();
	}

	function CharEspc($pos) {
		if ($pos==1) {
			$this->texto=preg_replace("/&([^;]+);/sU", "CHARESPC\1/CHARESPC", $this->texto);
		} else if ($pos==2) {
			$this->texto=preg_replace("/CHARESPC(.+)/CHARESPC/sU", "&\1;", $this->texto);
		}
	}

	function Mostra() {
		echo "<div class=\"comentario\" id=\"com{$this->id}\">\n";
    echo "\t <h4><a href=\"?PHPSESSID=9ec34c96b02b3755051aa682d1e02001#com{$this->id}\">#{$this->numero}</a> | ";
    echo "{$this->nome} ";
    echo "<small>{$this->data}{$this->email}{$this->ip}{$this->useragent}</h4>\n";
    echo "<p>{$this->texto}</p>";
    echo "</div>\n";
  }
}

// Objeto Comentários
class Comentarios {
  var $idpost;
  var $ids;
  var $tamanho;

  function Comentarios($idpost) {
    $this->idpost=$idpost;

    $mysql=new MySql();
    $mysql->conecta();

    $query=mysql_query("SELECT id FROM comentario WHERE idpost='{$this->idpost}' ORDER BY data ASC, id ASC");
    for ($i=1; $array=mysql_fetch_array($query); $i++) {
      $this->ids[$i]=$array["id"];
    }

    $this->tamanho=$i;
    $mysql->desconecta();
  }

  function Mostra() {
    echo "<h3 id="comentarios">Comentários</h3>\n";
    for ($i=1; $i<$this->tamanho; $i++) {
      $comentario=new Comentario($this->ids[$i], $i);
      $comentario->CharEspc(1);
      $comentario->Emoticons();
      $comentario->CharEspc(2);
      $comentario->QuebraLinha();
      $comentario->Mostra();
    }

    if ($this->tamanho <= 1) {
      echo "<p>Nenhum comentário cadastrado.</p>\n";
    }

    FormularioComentario($this->idpost);
  }
}

// Função para descobrir IP do visitante
function PegaIP() {
  if (getenv("HTTP_CLIENT_IP") && strcasecmp(getenv("HTTP_CLIENT_IP"), "desconhecido")) {
    $ip=getenv("HTTP_CLIENT_IP");
  } else if (getenv("HTTP_X_FORWARDED_FOR") && strcasecmp(getenv("HTTP_X_FORWARDED_FOR"), "desconhecido")) {
    $ip=getenv("HTTP_X_FORWARDED_FOR");
  } else if (getenv("REMOTE_ADDR") && strcasecmp(getenv("REMOTE_ADDR"), "desconhecido")) {
    $ip=getenv("REMOTE_ADDR");
  } else if (isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], "desconhecido")) {
    $ip=$_SERVER['REMOTE_ADDR'];
  } else {
    $ip="desconhecido";
  }

  return($ip);
}

// Função que escreve o formulário para envio de comentário
function FormularioComentario($idpost) {
  $mysql=new MySql();
  $mysql->conecta();
  $query=mysql_query("SELECT permalink FROM artigos WHERE id='$idpost'");
  $row=mysql_fetch_row($query);
  $permalink=$row[0];
  $mysql->desconecta();
?>

<h3>
  Escreva um comentário
</h3>

<?php
}

// Função que cadastra um comentário
function EscreveComentario($nome, $email, $texto, $idpost) {
$ip=PegaIP();
$useragent=$_SERVER["HTTP_USER_AGENT"];
$nome=purifica($nome);
$email=purifica($email);
$texto=purifica($texto);
$data=time();
$mysql=new MySql();
$mysql->conecta();
  mysql_query("INSERT INTO comentario (id, idpost, nome, email, texto, data, ip, useragent) VALUES
    ('', '$idpost', '$nome', '$email', '$texto', '$data', '$ip', '$useragent')") or die(mysql_error());
  $mysql->desconecta();
  $email=($email)?$email:"contato@tiagomadeira.net";
  $mensagem="No post de id $idpost, o $nome ($email) comentou em ".date("d/m/Y", $time)." dizendo:";
  $mensagem.="nn";
  $mensagem.="$texto";
  mail("contato@tiagomadeira.net", "[tiagomadeira.net] Novo Comentário!", "$mensagem", "From: $nome <$email>");
}

// Função que cria escreve o título das seções
function titulo($titulo) {
  $tit="$titulo [tiagomadeira.net]";
  echo "n";
}

// Função para purificar os comentários depois do envio
function purifica($texto) {
  $t=ereg_replace("&", "&", $texto);
  $t=ereg_replace("%", "%", $t);
  $t=ereg_replace("<", "<", $t);
  $t=ereg_replace(">", ">", $t);
  $t=ereg_replace("[", "[", $t);
  $t=ereg_replace("]", "]", $t);
  $t=ereg_replace(""", """, $t);
  return $t;
}

// Função para editar artigos
function pra_textarea($texto) {
  $texto=ereg_replace("&", "&", $texto);
  $texto=ereg_replace("<", "<", $texto);
  $texto=ereg_replace(">", ">", $texto);
  $texto=ereg_replace(""", """, $texto);
  return $texto;
}
?>

E os arquivos que usam essas funções e classes…

/artigos (ou /blog)

<?php
  $artigosporpagina=10; //Artigos Por Página
  $p=($_GET["pg"])?$_GET["pg"]:1; //Página Atual

  $mysql=new MySql();
  $mysql->conecta();
  $query=mysql_query("SELECT count(id) FROM artigos");
  $row=mysql_fetch_row($query);
  $np=ceil($row[0]/$artigosporpagina);
  $mysql->desconecta();

  $paginacao="";
  for ($i=1; $i<=$np; $i++) {
    $paginacao.="<a href="/artigos/$i"";
    if ($i==$p) $paginacao.=" style="font-weight:bold; color:#c00;"";
    $paginacao.=">$i</a> ";
  }
  $paginacao="\n\n<p style=\"text-align:center;\"><span style=\"color:#aaa; font-size:11px;\">";
  $paginacao.="Ir para página:</span> $paginacao</p>\n\n";

  echo $paginacao;

  $artigos=new Artigos($artigosporpagina, ($p-1)*$artigosporpagina);
  echo " <ul>\n";
  for ($i=0; $i<count($artigos->id); $i++) {
      echo "<li><a href=\"{$artigos->permalink[$i]}\">{$artigos->titulo[$i]}</a><br />";
      echo "<small>{$artigos->data[$i]} ";
      echo "<a class=\"comentarios\" href=\"/post/{$artigos->permalink[$i]}#comentarios\">{$artigos->comentarios[$i]} comentário(s)</a>";
      if ($_SESSION["tiagomadeira"]) {
        echo " <a href="/admin-edita&id={$artigos->id[$i]}">[editar]</a>";
        echo " <a href="/admin-exclui&id={$artigos->id[$i]}">[excluir]</a>";
      }
      echo "</small></li>\n";
  }
  echo "</ul>n";
  echo $paginacao;
?>

/ (ou /ultimos)

<?php
	$artigos=new Artigos(5, 0, 1, 1, 1);
?>

Para finalizar… .htaccess

RewriteEngine On

#Diretórios
RewriteRule ^link/?$ http://tableless.tiagomadeira.net
RewriteRule ^post/?$ http://tableless.tiagomadeira.net/blog
RewriteRule ^script/?$ http://tableless.tiagomadeira.net/scripts
RewriteRule ^downloadscript/?$ http://tableless.tiagomadeira.net/scripts

#Blog: A grande excessão
RewriteRule ^blog/([0-9]+)$ http://tableless.tiagomadeira.net/index.php?l=blog&pg=$1
RewriteRule ^/link/blog/([0-9]+)$ http://tableless.tiagomadeira.net/index.php?l=blog&pg=$1
RewriteRule ^artigos/([0-9]+)$ http://tableless.tiagomadeira.net/index.php?l=blog&pg=$1
RewriteRule ^/link/artigos/([0-9]+)$ http://tableless.tiagomadeira.net/index.php?l=blog&pg=$1

#Links
RewriteRule ^link/(.+)$ http://tableless.tiagomadeira.net/index.php?l=$1
RewriteRule ^([^/.]+)$ http://tableless.tiagomadeira.net/index.php?l=$1

#Posts
RewriteRule ^post/([0-9]+)$ http://tableless.tiagomadeira.net/index.php?l=artigo&id=$1
RewriteRule ^post/(.+)$ http://tableless.tiagomadeira.net/index.php?l=artigo&permalink=$1

#Scripts
RewriteRule ^script/(.+)$ http://tableless.tiagomadeira.net/index.php?l=script&script=$1
RewriteRule ^downloadscript/(.+)$ http://tableless.tiagomadeira.net/downloadscript.php?script=$1

#Feeds
RewriteRule ^feed.rss$ http://tableless.tiagomadeira.net/rss.php
RewriteRule ^rss.xml$ http://tableless.tiagomadeira.net/rss.php
RewriteRule ^index.rss$ http://tableless.tiagomadeira.net/rss.php
RewriteRule ^sitemap.xml$ http://tableless.tiagomadeira.net/sitemap.php

Novo site do Colégio!

Publiquei hoje o novo site do Colégio Salesiano Itajaí, um site totalmente administrável (até o título pode ser mudado via formulários) que usa a linguagem PHP e o banco de dados MySql. O site também segue os padrões web, mesmo com formulários rich text que às vezes deixam o site pouco semântico (é que os monitores do Colégio devem poder atualizar) e está disponível em: salesianoitajai.g12.br.

A notícia de estréia da página está disponível aqui e conta com um lindo screenshot do meu Fluxbox com Mrxvt e o Vim com três splits. Embora o site já esteja publicado, ainda tenho que arrumar alguns detalhes como por exemplo o Sitemap que eu cito nesta notícia.

Uma coisa bem legal que eu coloquei no site foi um JavaScript, usando a função addGlobalStyle do Dive into Greasemonkey, que nos Mozillas (ereg(“Gecko/”, $\SERVER[“HTTP_USER_AGENT”]))_ faz o site ficar maior se o usuário usar uma resolução igual ou maior a 1024×768. Dá pra fazer pra todos os navegadores, mas eu sou meio newbie em JavaScript e por isso só usei esse código do Greasemonkey, que só funciona nos Mozillas mesmo… Mas o resultado ficou ótimo! :)

Ontem o Sr. Paulo Matias me ensinou como trabalhar com operadores bit-a-bit no C. Achei muito massa! Agora comecei até a economizar fazendo:

numero = outronumero << 1;

… ao invés de simplesmente:

numero = outronumero * 2;

… para meus programas serem mais rápidos! Hehehe :D Fiz uma função que converte de decimal para binário, e depois vou postar aqui.

Observação: Tenho que descobrir porque os emoticons não funcionam quando tem código... Quer dizer, descobrir eu já descobri, mas preciso ver como eu faço pra resolver de forma boa essas expressões regulares...

Editado!

Corrigi o problema… Confira abaixo o novo trecho de ERs da função de emoticons, onde $o é o vetor de origem (com as carinhas originais), $d é o vetor de desgino (com o <img src…) e replace() é uma função que eu criei para substituir os emoticons:

<?php
if (!ereg("<code", $texto)) {
	$texto=replace($o, $d, $texto);
} else {
	preg_match_all("/</code>(.+)<code/sU", $texto, $mat1);
	for ($i=0; $i<sizeof($mat1[1]); $i++) {
		$texto=str_replace($mat1[1][$i], replace($o, $d, $mat1[1][$i]), $texto);
	}
	preg_match("/^(.+)<code/sU", $texto, $mat2);
	$texto=str_replace($mat2[1], replace($o, $d, $mat2[1]), $texto);
	$rev=strrev($texto); //Tenho medo do PHP5.0.5
	preg_match("/^(.+)>edoc/</sU", $rev, $mat3); //Nossa, que código louco!
	$rev=strrev($mat3[1]); //Repito... Tenho medo do PHP5.0.5
	$texto=str_replace($rev, replace($o, $d, $rev), $texto);
}
?>

Ficou feio, né? Não consegui pensar em outra coisa mais fácil que usar o strrev() ali… :blink:

MRxvt e Controle Anti-flood

Formatei minha partição Linux e instalei o novo Slackware 10.2 para ver quais eram as novidades…

Ainda estou configurando o sistema, mas ele já está bastante estável, com Kernel 2.6, Grub, XDirectFB em desenvolvimento e hoje testei um programa que merece um post especial aqui no blog chamado MRxvt. É um terminal que abre na velocidade do Xterm, mas tem os recursos do Konsole do KDE! Hehehe… :D Abas, transparências, entre outras coisas de uma forma leve que eu nunca tinha visto. Eu descobri o programa quando eu e o Thotypous estávamos pensando em baixar o source do Gnome-Terminal e tentar modificar para deixar bem levinho e só com abas, ou pegar o xterm e implementar abas… :) Mas esse programa é simplesmente fabuloso. Acabou com nossos problemas… Baixem aqui!

O Hélio (a.k.a. hlegius) me deu uma idéia bastante útil que é um controle anti-flood para os comentários do meu site… Já implementei usando sessões… Valeu Hélio!

Bom… Por enquanto é só! ;) Resolvi agora postar mais aqui, e fazer posts menores. Fiz várias mudanças aí no lado direito do site nos últimos dias (e no meio também), deixando o site mais semântico além de mais atualizado e “correto”. Também atualizei a minha biografia (colocando até o MRxvt) e acho que vou dar uma reformulada no sistema de BBCode (ER) do meu blog, porque quando eu coloco um código depois não funciona mais os emoticons embaixo dele.

© 2005–2020 Tiago Madeira