<?php
/***
	Esta classe é responsável por disponibilizar métodos utilitários,
	inclusive alguns métodos de validação de dados.
***/

class Utilitarios{
	/* Cria uma máscara */
	static function mascara($val, $mask)
	{
		$maskared = '';
		$k = 0;
		for($i = 0; $i<=strlen($mask)-1; $i++){
			if($mask[$i] == '#'){
				if(isset($val[$k]))
					$maskared .= $val[$k++];
			}
			else{
				if(isset($mask[$i]))
				$maskared .= $mask[$i];
			}
		}
		return $maskared;
	}

	/* Formata o CPF/CNPJ especificado */
	static function formatar_cpf_cnpj($valor){
		if(strlen($valor) == 11){
			return self::mascara(strval($valor), "###.###.###-##");
		}
		else{
			return self::mascara(strval($valor), "##.###.###/####-##");
		}
	}
	
	/* Retorna o primeiro e o último nome */
	static function dividir_nome($name) {
	    $name = trim($name);
	    if(strpos($name, ' ') === false){
	    	$last_name = '';
	    	$first_name = $name;
	    }
	    else{
	    	$names = explode(" ", $name);
	    	$first_name = $names[0];
	    	$last_name = "";
	    	$total = count($names);
	    	for($i = 1; $i < $total;$i++){
	    		$last_name .= $names[$i] . " ";
	    	}
	    	$last_name = trim($last_name);
	    }
	    return array($first_name, $last_name);
	}

	/* Converte o número para real */
	static function formatar_dolar($valor){
		$vl = floatval(intval($valor)) / 100;
		$strvl = '$' . number_format($vl,2,',','.');
		return $strvl;
	}

	/* Aplica hash na string disponibilizada */
	static function hash_str($senha){
		$seed = uniqid(mt_rand(), true);
		$salt = base64_encode($seed);
		$salt = str_replace('+', '.', $salt);
		$salt = substr($salt, 0, 22);
		return crypt($senha, sprintf('$%s$%02d$%s$', '2a', 10, $salt));
	}
	
	/* Compara duas datas */
	static function comparar_datas($data1, $data2){
		$date1 = DateTime::createFromFormat('d/m/Y',$data1);
		$date2 = DateTime::createFromFormat('d/m/Y',$data2);
		return $date1->getTimestamp() - $date2->getTimestamp();
	}

	/* Método utilitário para validação do cpf */
	static function calc_digitos_posicoes( $digitos, $posicoes = 10, $soma_digitos = 0 ) {
        // Faz a soma dos dígitos com a posição
        // Ex. para 10 posições: 
        //   0    2    5    4    6    2    8    8   4
        // x10   x9   x8   x7   x6   x5   x4   x3  x2
        //   0 + 18 + 40 + 28 + 36 + 10 + 32 + 24 + 8 = 196
        for ( $i = 0; $i < strlen( $digitos ); $i++  ) {
            $soma_digitos = $soma_digitos + ( $digitos[$i] * $posicoes );
            $posicoes--;
        }
 
        // Captura o resto da divisão entre $soma_digitos dividido por 11
        // Ex.: 196 % 11 = 9
        $soma_digitos = $soma_digitos % 11;
 
        // Verifica se $soma_digitos é menor que 2
        if ( $soma_digitos < 2 ) {
            // $soma_digitos agora será zero
            $soma_digitos = 0;
        } else {
            // Se for maior que 2, o resultado é 11 menos $soma_digitos
            // Ex.: 11 - 9 = 2
            // Nosso dígito procurado é 2
            $soma_digitos = 11 - $soma_digitos;
        }
 
        // Concatena mais um dígito aos primeiro nove dígitos
        // Ex.: 025462884 + 2 = 0254628842
        $cpf = $digitos . $soma_digitos;
        
        // Retorna
        return $cpf;
    }

    // Verifica se o CPF é válido
	static function cpf_valido( $cpf = false ) {
	    // Exemplo de CPF: 025.462.884-23
	    
	    // Verifica se o CPF foi enviado
	    if ( ! $cpf ) {
	        return false;
	    }
	 
	    // Remove tudo que não é número do CPF
	    // Ex.: 025.462.884-23 = 02546288423
	    $cpf = preg_replace( '/[^0-9]/is', '', $cpf );
	 
	    // Verifica se o CPF tem 11 caracteres
	    // Ex.: 02546288423 = 11 números
	    if ( strlen( $cpf ) != 11 ) {
	        return false;
	    }   
	 
	    // Captura os 9 primeiros dígitos do CPF
	    // Ex.: 02546288423 = 025462884
	    $digitos = substr($cpf, 0, 9);
	    
	    // Faz o cálculo dos 9 primeiros dígitos do CPF para obter o primeiro dígito
	    $novo_cpf = self::calc_digitos_posicoes( $digitos );
	    
	    // Faz o cálculo dos 10 dígitos do CPF para obter o último dígito
	    $novo_cpf = self::calc_digitos_posicoes( $novo_cpf, 11 );
	    
	    // Verifica se o novo CPF gerado é idêntico ao CPF enviado
	    if ( $novo_cpf === $cpf ) {
	        // CPF válido
	        return true;
	    } else {
	        // CPF inválido
	        return false;
	    }
	}

	/* Verifica se o cnpj é válido. */
	static function cnpj_valido($cnpj)
	{
		$cnpj = preg_replace('/[^0-9]/', '', (string) $cnpj);
		if (strlen($cnpj) != 14)
			return false;
		for ($i = 0, $j = 5, $soma = 0; $i < 12; $i++)
		{
			$soma += $cnpj{$i} * $j;
			$j = ($j == 2) ? 9 : $j - 1;
		}
		$resto = $soma % 11;
		if ($cnpj{12} != ($resto < 2 ? 0 : 11 - $resto))
			return false;
		for ($i = 0, $j = 6, $soma = 0; $i < 13; $i++)
		{
			$soma += $cnpj{$i} * $j;
			$j = ($j == 2) ? 9 : $j - 1;
		}
		$resto = $soma % 11;
		return $cnpj{13} == ($resto < 2 ? 0 : 11 - $resto);
	}

	/* Verifica se o CPF/CNPJ é valido */
	static function cpf_cnpj_valido($val){
		if(empty($val)) return false;
		$val = preg_replace( '/[^0-9]/is', '', $val );
		if(strlen($val) == 11)
			return self::cpf_valido($val);
		else
			return self::cnpj_valido($val);
	}

	/* Verifica se a data informada é válida (formato: dd/mm/aa) */
	static function data_valida($data){
		if(empty($data)) return false;
		$test_arr  = explode('/', $data);
		if (count($test_arr) == 3) {
			if (checkdate($test_arr[1], $test_arr[0], $test_arr[2])) {return true;}
			else {return false;}
		}
		else {return false;}
	}

	/* Verifica se o email é válido */
	static function email_valido($email){
		if (!filter_var($email, FILTER_VALIDATE_EMAIL))
			return false;
		else{
			$dominio=explode('@',$email);
			if(!checkdnsrr($dominio[1],'MX')){
				return false;
			}
			else{return true;}
		}
	}

	/* Verifica se a lista de comissões do sistema de indicações está correta. */
	static function bonus_valido($bonus){
		$exploded = explode(',', $bonus);
		if($exploded == false) return false;
		if(count($exploded) == 0) return false;
		foreach($exploded as $comissao){
			$comissao = preg_replace('/\s+/', '', $comissao);
			if(!is_numeric($comissao))
				return false;
		}
		return true;
	}

	/* Verifica se a data informada é válida (formato: padrão) */
	static function data_padrao_valida($data){
		$date = date_parse($data);
		return ($date["error_count"] == 0 && checkdate($date["month"], $date["day"], $date["year"]));
	}

	/* Verifica se a cor é válida */
	static function hex_valido($hex){
		if(preg_match('/^#[a-f0-9]{6}$/i', $hex) || preg_match('/^[a-f0-9]{6}$/i', $hex) || preg_match('/^#[a-f0-9]{3}$/i', $hex) || preg_match('/^[a-f0-9]{3}$/i', $hex))
			return true;
		return false;
	}

	/* */
	static function host_disponivel($host, $port){
		$connection = @fsockopen($host, $port, $errno, $errstr, 1);

	    if (is_resource($connection))
	    {
	        fclose($connection);
	        return true;
	    }
	    else
	    	return false;
	}

	static function gerar_token($tamanho = 8, $maiusculas = true, $numeros = true, $simbolos = false){
	    $lmin = 'abcdefghijklmnopqrstuvwxyz';
	    $lmai = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
	    $num = '1234567890';
	    $simb = '!@#$%*-';
	    $retorno = '';
	    $caracteres = '';

	    $caracteres .= $lmin;
	    if ($maiusculas) $caracteres .= $lmai;
	    if ($numeros) $caracteres .= $num;
	    if ($simbolos) $caracteres .= $simb;

	    $len = strlen($caracteres);
	    for ($n = 1; $n <= $tamanho; $n++) {
	        $rand = mt_rand(1, $len);
	        $retorno .= $caracteres[$rand-1];
	    }
	    return $retorno;
	}
}
