domingo, 31 de julho de 2011

Valor por extenso com PHP

Nesta postagem quero compartilhar uma classe bem interessante, "Monetary",  simplesmente ela formata um valor monetário por extenso. Logo abaixo segue o código da classe e um exemplo de como utilizar.

<?php
class Monetary {
    private static $unidades = array("um", "dois", "três", "quatro", "cinco", "seis", "sete", "oito", "nove", "dez", "onze", "doze",
                                     "treze", "quatorze", "quinze", "dezesseis", "dezessete", "dezoito", "dezenove");
    private static $dezenas = array("dez", "vinte", "trinta", "quarenta","cinqüenta", "sessenta", "setenta", "oitenta", "noventa");
    private static $centenas = array("cem", "duzentos", "trezentos", "quatrocentos", "quinhentos", 
                                     "seiscentos", "setecentos", "oitocentos", "novecentos");
    private static $milhares = array(
        array("text" => "mil", "start" => 1000, "end" => 999999, "div" => 1000),
        array("text" => "milhão", "start" =>  1000000, "end" => 1999999, "div" => 1000000),
        array("text" => "milhões", "start" => 2000000, "end" => 999999999, "div" => 1000000),
        array("text" => "bilhão", "start" => 1000000000, "end" => 1999999999, "div" => 1000000000),
        array("text" => "bilhões", "start" => 2000000000, "end" => 2147483647, "div" => 1000000000)        
    );
    const MIN = 0.01;
    const MAX = 2147483647.99;
    const MOEDA = " real ";
    const MOEDAS = " reais ";
    const CENTAVO = " centavo ";
    const CENTAVOS = " centavos ";    
    
    static function numberToExt($number, $moeda = true) {
        if ($number >= self::MIN && $number <= self::MAX) {
            $value = self::conversionR((int)$number);       
            if ($moeda) {
                if (floor($number) == 1) {
                    $value .= self::MOEDA;
                }
                else if (floor($number) > 1) $value .= self::MOEDAS;
            }

            $decimals = self::extractDecimals($number);            
            if ($decimals > 0.00) {
                $decimals = round($decimals * 100);
                $value .= " e ".self::conversionR($decimals);
                if ($moeda) {
                    if ($decimals == 1) {
                        $value .= self::CENTAVO;
                    }   
                    else if ($decimals > 1) $value .= self::CENTAVOS;
                }
            }
        }
        return trim($value);
    }
    
    private static function extractDecimals($number) {
        return $number - floor($number);
    }
    
    static function conversionR($number) {
        if (in_array($number, range(1, 19))) {
            $value = self::$unidades[$number-1];
        }
        else if (in_array($number, range(20, 90, 10))) {
             $value = self::$dezenas[floor($number / 10)-1]." ";           
        }     
        else if (in_array($number, range(21, 99))) {
             $value = self::$dezenas[floor($number / 10)-1]." e ".self::conversionR($number % 10);           
        }     
        else if (in_array($number, range(100, 900, 100))) {
             $value = self::$centenas[floor($number / 100)-1]." ";           
        }          
        else if (in_array($number, range(101, 199))) {
             $value = ' cento e '.self::conversionR($number % 100);         
        }   
        else if (in_array($number, range(201, 999))) {
             $value = self::$centenas[floor($number / 100)-1]." e ".self::conversionR($number % 100);        
        }  
        else {
            foreach (self::$milhares as $item) {
                if ($number >= $item['start'] && $number <= $item['end']) {
                    $value = self::conversionR(floor($number / $item['div']))." ".$item['text']." ".self::conversionR($number % $item['div']);
                    break;
                }
            }
        }        
        return $value;
    }
}

// exemplo de como utilizar
echo Monetary::numberToExt(4526.89);
// o exemplo acima ira imprimir: quatro mil quinhentos e vinte e seis reais e oitenta e nove centavos
?>

sábado, 30 de julho de 2011

Setar posição do cursor com JavaScript

Neste post, quero compartilhar uma função que pode ser bem útil, trata-se de uma solução de como setar o cursor em um determinado ponto de um input text ou textarea. Esta função foi testada no Firefox, IE 7 e Chrome.

function setPosCursor(element, pos) {
    element.focus();
    if (typeof(element.setSelectionRange) != "undefined") {
        element.setSelectionRange(pos, pos);
    }
    else if (element.createTextRange) {
        var breaks = element.value.slice(0, pos).match(/\n/g);
        var endPoint = 0;
        if (breaks instanceof Array) {
            endPoint = -breaks.length;
        }
        var range = element.createTextRange(); 
        range.collapse(true); 
        range.moveStart("character", pos); 
        range.moveEnd("character", endPoint); 
        range.select(); 
    }
} 

Pegar posição do cursor com JavaScript

Em algumas situações precisamos pegar a posição do cursor em um campo de texto (aquele que fica piscando), abaixo tenho uma solução bem prática eu testei no Firefox, IE 7 e Chrome. Para utilizar, você deve passar o elemento input text ou textarea como parâmetro o retorno será um inteiro com o índice da posição.

function getPosCursor(element) {
    var value = 0;
    if (typeof(element.selectionStart) != "undefined") {
        value = element.selectionStart;
    }
    else if (document.selection) {
        var range = document.selection.createRange();
        var storedRange = range.duplicate();
        storedRange.moveToElementText(element);
        storedRange.setEndPoint("EndToEnd", range);
        value = storedRange.text.length - range.text.length;
    }
    return value;
}

sexta-feira, 29 de julho de 2011

Envio de e-mail com PHP por Socket

Para o envio de e-mail o PHP nos possibilita o uso da função mail, porém para utilizá-la é preciso efetuar algumas configurações no php.ini e esta função é bem limitada quanto a servidores SMTP que requerem autenticação com usuário e senha. Neste tutorial estarei ensinando como enviar e-mail por Socket utilizando a função fsockopen.

Abaixo tem a função com o exemplo de utilização, espero que vocês gostem e qualquer dúvida é só comentar.

<?php
function enviar_email($destinatario, $remetente, $assunto, $mensagem) {
    // dominio do servidor SMTP, para servidores HTTPS coloque o prefixo ssl://
    $servidor = "smtp.meuservidor.com";
    // usuario do servidor SMTP
    $usuario = "usuario";
    // senha do servidor SMTP
    $senha = "senha";
    // numero da porta do servidor SMTP
    $success = true;
        
    // abro uma conexao por socket com o servidor
    $socket = @fsockopen($servidor, 25, $errno, $errstr, 10);
    if ($socket) {
        $ln = "\r\n"; 
        // pego o texto de retorno do servidor e verifico o codigo da resposta se for 220 ok
        $response = fgets($socket, 256);
        if (!preg_match("/^220/", $response)) $success = false;

        // envio um comando HELO e verifico o codigo da resposta se for 250 ok
        fwrite($socket, "HELO $servidor".$ln);
        $response = fgets($socket, 256);
        if (!preg_match("/^250/", $response)) $success = false;
       
        // envio um comando AUTH LOGIN para iniciar a autenticacao
        fwrite($socket, "AUTH LOGIN".$ln);
        fgets($socket, 256);
        // envio o nome de usuario
        fwrite($socket, base64_encode($usuario).$ln);
        fgets($socket, 256);
        // envio senha do servidor
        fwrite($socket, base64_encode($senha).$ln);
        // verifico o codigo da resposta se for 235 a autenticacao ocorreu com sucesso
        $response = fgets($socket, 256);
        if (!preg_match("/^235/", $response)) $success = false;

        // envio um comando MAIL FROM e verifico o codigo da resposta se for 250 ok      
        fwrite($socket, "MAIL FROM:$remetente".$ln);
        $response = fgets($socket, 256); 
        if (!preg_match("/^250/", $response)) $success = false;
        
        // envio um comando RCPT TO e verifico o codigo da resposta se for 250 ok 
        fwrite($socket, "RCPT TO:$destinatario".$ln);
        $response = fgets($socket, 256);
        if (!preg_match("/^250/", $response)) $success = false;

        // envio um comando DATA e verifico o codigo da resposta se for 354 ok 
        fwrite($socket, "DATA".$ln);
        $response = fgets($socket, 256);
        if (!preg_match("/^354/", $response)) $success = false;
        
        // definicao dos cabecalhos da mensagem 
        $headers = "Message-Id: <".time().".".md5(microtime())."@".$_SERVER['SERVER_ADDR'].">".$ln;
        $headers .= "Date: ".date("r").$ln;
        $headers .= "X-Priority: 3".$ln;
        $headers .= "Content-Type: text/plain; charset=\"UTF-8\"".$ln;
        $headers .= "Subject: $assunto".$ln;
        $headers .= "To: $destinatario".$ln;       
        $headers .= "From: $remetente".$ln.$ln;
        $headers .= $mensagem.$ln.".".$ln;
        fwrite($socket, $headers);
        $response = fgets($socket, 256);
        if (!preg_match("/^250/", $response)) $success = false;
 
         // envio um comando QUIT e verifico o codigo da resposta se for 221 ok        
        fwrite($socket, "QUIT".$ln);
        $response = fgets($socket, 256);
        if (!preg_match("/^221/", $response)) $success = false;
        
        // fecho a conexao com o servidor
        fclose($socket);
        return $success;
    }
    else return false;
}

$result = enviar_email("destinatario@email.com", "remetente@email.com", "Meu Assunto", "Minha Mensagem");
if ($result) {
    echo "E-mail enviado com sucesso!";
}
else echo "Ocorreu um erro ao tentar enviar o e-mail!";
?>