Last active
March 7, 2021 23:03
-
-
Save luizvaz/ace093ac3a4323906484b337a0c66df0 to your computer and use it in GitHub Desktop.
Revisions
-
luizvaz revised this gist
Mar 7, 2021 . No changes.There are no files selected for viewing
-
luizvaz renamed this gist
Mar 7, 2021 . 1 changed file with 0 additions and 0 deletions.There are no files selected for viewing
File renamed without changes. -
luizvaz created this gist
Mar 7, 2021 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,565 @@ <?php /** * User: LuizVAz * Date: 22/04/2019 * Time: 21:46 */ namespace Provedores\webService; use DOMDocument; use DOMXPath; use Exception; use Slim\App; use Slim\Http\Request; use Slim\Http\Response; use stdClass; class d2ti_v001 extends \Provedores\webService\webService { private $cnpj; private $dir; private $nfs_dir; private $rps_dir; private $rps_id; private $rps_serie; private $user; public function __construct(Request $request, Response $response, App $app){ parent::__construct($request, $response, $app); //Cabeçalho v 1.00 $this->cabecalho = '<cabecalhoNfseLote xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.ctaconsult.com/nfse">'. '<versao>1.00</versao>'. "<ambiente>%amb%</ambiente>". '</cabecalhoNfseLote>'; $ym = date('Ym'); $this->dir = $dir = getenv('BASE_PATH'); $this->user = $user = str_replace(':', '',$this->request->getUri()->getUserInfo()); $this->cnpj = $cnpj = $request->getAttribute('cnpj'); $this->rps_dir = "$dir/$cnpj/rps/$ym/"; $this->nfs_dir = "$dir/$cnpj/nfse/$ym/"; $this->rps_id = date('Ymd') . str_pad(time() - strtotime("today"), 5, '0'); $this->rps_serie = "ws1"; } public function emitir(stdClass $rps){ $this->rps = $rps; return $this->gerarNfse(); } public function gerarNfse(){ //Retorno $return = new stdClass(); $return->status = 500; $return->data = array("success" => false); $rps_dir = $this->rps_dir; //rps_id ou idExterno $rps_id = (property_exists($this->rps, 'idExterno'))?$this->rps->idExterno:$this->rps_id; if (!$rps_id){ $rps_id = date('Ymd') . str_pad(time() - strtotime("today"), 5, '0'); $this->rps_id = $rps_id; } else $this->rps_id = $rps_id; //Garante que o diretório exista $fname = "${rps_dir}${rps_id}.xml"; if (!file_exists("${rps_dir}")) { mkdir("${rps_dir}", 0777, true); } $envelope = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:wsn=\"http://wsnfselote.ctaconsult.com.br/\">\n". " <soapenv:Header/>". " <soapenv:Body>\n". " <wsn:executar>\n". " <arg0>%CabMsg%</arg0>\n". " <arg1>%DadMsg%</arg1>\n". " </wsn:executar>\n". " </soapenv:Body>\n". "</soapenv:Envelope>"; //Ambiente: 1 = Produção, 2 = Homologação $amb = '1'; if ($this->rps->ambienteEmissao && (strtolower($this->rps->ambienteEmissao) === "homologacao")){ $amb = '2'; } $cab = $this->cabecalho; $cab = str_replace('%amb%', $amb, $cab); //xml $xml = $this->rpsAsXML(); file_put_contents("$fname", $xml); $cab = htmlentities($cab, ENT_XML1 | ENT_NOQUOTES); $xml = htmlentities($xml, ENT_XML1 | ENT_NOQUOTES); $envelope = str_replace('%CabMsg%', $cab, $envelope); $envelope = str_replace('%DadMsg%', $xml, $envelope); file_put_contents("${rps_dir}${rps_id}.soap", $envelope); $headers = array( "Content-type: text/xml;charset=UTF-8", "Accept-Encoding: gzip,deflate", "SOAPAction: \"\"", "Content-length: ".strlen($envelope), ); $url = $this->end_prod; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_TIMEOUT, 300); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $envelope); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); //A prefeitura bloqueia os IPs externos //$proxy = '200.255.122.174:8080'; //$proxy = '200.222.211.54:8080'; //curl_setopt($ch, CURLOPT_PROXY, $proxy); //curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); $live = true; if ($live) { //Live Mode $html = curl_exec($ch); // Converte de UTF-8 para ISO-8859 //$html = utf8_decode(curl_exec($ch)); $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); $return->status = $httpcode; file_put_contents("$fname.ret", $html); } else { //Test Mode curl_close($ch); $httpcode = 200; $return->status = $httpcode; $html = file_get_contents("$fname.ret"); } if ($httpcode!=200){ preg_match_all('/<faultstring>(.*?)<\/faultstring>/s', html_entity_decode($html), $matches); $response = (count($matches)&&count($matches[1])?$matches[1][0]:$html); $return->data['errors'][] = [ "codigo" => $httpcode, "mensagem" => $response, "correcao" => "" ]; return $return; } //Extrai preg_match_all('/<return>(.*?)<\/return>/s', html_entity_decode($html), $matches); $response = (count($matches)&&count($matches[1])?$matches[1][0]:$html); $return = $this->parseGerarNfseResponse($response, $return); return $return; } public function parseGerarNfseResponse($response, $return){ $dom = new DOMDocument(); $dom->preserveWhiteSpace = false; $dom->loadXML($response); $xp = new DOMXPath($dom); $xp->registerNamespace('fake', "http://www.ctaconsult.com/nfse"); // /retornoNfseLote/errors/erro $nodes = $xp->query("/*/*/*[name()='erro']"); if ($nodes->length != 0){ if (!array_key_exists('errors', $return->data)) $return->data['errors'] = []; for ($i = 0; $i<$nodes->length; $i++){ $msg = $nodes->item($i); //Tags $cod = $msg->getElementsByTagName("codigo"); if ($cod->length>0) { $cod = $cod->item(0); $cod = $cod->nodeValue; if (strlen($cod)>5) $cod = "E00"; //Texto redundante } else $cod = "E00"; $txt = $msg->getElementsByTagName("descricao"); if ($txt->length>0) { $txt = $txt->item(0); $txt = $txt->nodeValue; } else $txt = ""; $cor = $msg->getElementsByTagName("ns:correcao"); if ($cor->length>0) { $cor = $cor->item(0); $cor = $cor->nodeValue; } else $cor = ""; //Retorno $return->data['errors'][] = [ "codigo" => $cod, "mensagem" => $txt, "correcao" => $cor ]; } return $return; } //Gerou a Nota Fiscal $nodes = $xp->query("/*[name()='retornoNfseLote']"); if ($nodes->length != 0){ $nfseId = ""; $msg = $nodes->item(0); $id = $msg->getElementsByTagName("protocolo"); $id = ($id->length>0)?$id = $id->item(0)->nodeValue:"0"; $num = $msg->getElementsByTagName("numeroNota"); $num = ($num->length>0)?$num = $num->item(0)->nodeValue:"0"; $cod = $msg->getElementsByTagName("chaveSeguranca"); $cod = ($cod->length>0)?$cod = $cod->item(0)->nodeValue:"0"; $link = $msg->getElementsByTagName("linkPdfNota"); $link = ($link->length>0)?$link = $link->item(0)->nodeValue:"0"; //Garante que o diretório exista $nfs_dir = $this->nfs_dir; $fname = "${nfs_dir}${num}.xml"; if (!file_exists(dirname("$fname"))) { mkdir(dirname("$fname"), 0777, true); } file_put_contents($fname, $msg->ownerDocument->saveXML()); $return->data['nfseId'] = $id; $return->data['numero'] = $num; $return->data['codigoVerificacao'] = $cod; $return->data['url'] = "http://$link"; $return->data['success'] = true; } return $return; } public function rpsAsXML() { //DOM $dom = new DOMDocument('1.0', 'utf-8'); $dom->formatOutput = true; $dom->preserveWhiteSpace = true; //<nfseLote xmlns="http://www.ctaconsult.com/nfse" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> $nfseLote = $dom->createElement("nfseLote"); $nfseLote->setAttribute("xmlns", "http://www.ctaconsult.com/nfse"); $nfseLote->setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance"); $dom->appendChild($nfseLote); //Formato yyyy-mm-dd $dataEmissao = date("'Y-m-d\TH:i:s"); if ($this->rps->dataEmissao) $dataEmissao = $this->rps->dataEmissao; $nfseLote->appendChild($dom->createElement("codigoMunicipio",803)); $nfseLote->appendChild($dom->createElement("dtEmissao", $dataEmissao)); $nfseLote->appendChild($dom->createElement("notaIntermediada", 1)); //1-Sim, 2-Não //Autenticacao $auth = $dom->createElement("autenticacao"); $auth->appendChild($dom->createElement("token", 'SEU_TOKEN')); $nfseLote->appendChild($auth); //prestador $prestador = $dom->createElement("prestador"); $nfseLote->appendChild($prestador); $tipoPessoa = $dom->createElement("tipoPessoa", 2); //1- Pessoa Fisica, 2 - Juridica $prestador->appendChild($tipoPessoa); $cnpj = $dom->createElement("cnpj", $this->conf->cnpj); $prestador->appendChild($cnpj); $im = $dom->createElement("inscricaoMunicipal", $this->conf->inscricaoMunicipal); $prestador->appendChild($im); $razaoSocial = $dom->createElement("razaoSocial", $this->conf->razaoSocial); $prestador->appendChild($razaoSocial); //Endereço $endereco = $dom->createElement("endereco"); $prestador->appendChild($endereco); $endereco->appendChild($dom->createElement("logradouro", 'RUA')); $endereco->appendChild($dom->createElement("complemento", 'COMPLEMENTO')); $endereco->appendChild($dom->createElement("bairro", 'JUCARA')); $endereco->appendChild($dom->createElement("cep", '65919170')); $endereco->appendChild($dom->createElement("codigoMunipio", 803)); $endereco->appendChild($dom->createElement("descricaoMunicipio", 'IMPERATRIZ')); $endereco->appendChild($dom->createElement("codigoEstado", 'MA')); $endereco->appendChild($dom->createElement("descricaoEstado", 'MA')); $prestador->appendChild($dom->createElement("email", 'mail@exemplo.com.br')); $prestador->appendChild($dom->createElement("telefoneDdd", '98')); $prestador->appendChild($dom->createElement("telefoneNumero", '12345678')); //Tomador $tomador = $dom->createElement("tomador"); $tomador->appendChild($dom->createElement("tomadorIdentificado", 1)); //1-Sim, 2-Não if (strlen($this->rps->cliente->cpfCnpj)==11){ $tomador->appendChild($dom->createElement("tipoPessoa", 1)); //1- Pessoa Fisica, 2 - Juridica $tomador->appendChild($dom->createElement("cpf", $this->rps->cliente->cpfCnpj)); } else{ $tomador->appendChild($dom->createElement("tipoPessoa", 2)); $tomador->appendChild($dom->createElement("cnpj", $this->rps->cliente->cpfCnpj)); } if (property_exists($this->rps->cliente, 'inscricaoMunicipal')) if ($this->rps->cliente->inscricaoMunicipal) $tomador->appendChild($dom->createElement("inscricaoMunicipal", $this->rps->cliente->inscricaoMunicipal)); $tomador->appendChild($dom->createElement("razaoSocial", $this->rps->cliente->nome)); //Endereço $cidade = $this->ibgeToTOM($this->rps->cliente->endereco); //Converter de IBGE para TOM $endereco = $dom->createElement("endereco"); $endereco->appendChild($dom->createElement("logradouro", $this->rps->cliente->endereco->logradouro)); $endereco->appendChild($dom->createElement("complemento", $this->rps->cliente->endereco->numero)); $endereco->appendChild($dom->createElement("bairro", $this->rps->cliente->endereco->bairro)); $endereco->appendChild($dom->createElement("cep", $this->rps->cliente->endereco->cep)); if ($cidade->codigoMunicipio){ $endereco->appendChild($dom->createElement("codigoMunipio", $cidade->codigoMunicipio)); $endereco->appendChild($dom->createElement("descricaoMunicipio", $cidade->descricaoMunicipio)); $endereco->appendChild($dom->createElement("codigoEstado", $cidade->codigoEstado)); $endereco->appendChild($dom->createElement("descricaoEstado", $cidade->descricaoEstado)); } $tomador->appendChild($endereco); $nfseLote->appendChild($tomador); //atividadeExecutada $atividadeExecutada = $dom->createElement("atividadeExecutada"); $atividadeExecutada->appendChild($dom->createElement("codigoServico", '0901')); $atividadeExecutada->appendChild($dom->createElement("descricaoServico", 'HOSPEDAGEM DE QUALQUER NATUREZA EM HOTEIS APART SERVICE CONDOMINIAIS FLAT APART HOTEIS HOTEIS RESIDENCIA RESIDENCE SERVICE SUITE SERVICE HOTELARIA MARITIMA MOTEIS PENSOES E CONGENERES; OCUPACAO POR TEMPORADA COM FORNECIMENTO DE SERVICO (O VALOR DA ALIMENTACAO E GORJETA QUANDO INCLUIDO NO PRECO DA DIARIA FICA SUJEITO AO IMPOSTO SOBRE SERVICOS)')); $atividadeExecutada->appendChild($dom->createElement("codigoAtividade", '551080100')); $atividadeExecutada->appendChild($dom->createElement("descricaoAtividade", 'HOTEIS')); $local = $dom->createElement("localPrestacao"); $local->appendChild($dom->createElement("codigoEstado", 'MA')); $local->appendChild($dom->createElement("descricaoEstado", 'MA')); $local->appendChild($dom->createElement("codigoMunipio", 803)); $local->appendChild($dom->createElement("descricaoMunicipio", 'IMPERATRIZ')); $atividadeExecutada->appendChild($local); $atividadeExecutada->appendChild($dom->createElement("tipoTributacao", 4)); //Tipo tributacao 1 - Isento de ISSQN, 2 - IMUNE, 3 - EXIGIBILIDADE SUSPENSA, 4 - TRIBUTÁVEL, 5 - NÃO INCIDENTE NO MUNICÍPIO, 6 - TRIBUTÁVEL S.N., 7 - TRIBUTÁVEL FIXO, 8 - NÃO TRIBUTÁVEL, 9 - TRIBUTÁVEL MEI $atividadeExecutada->appendChild($dom->createElement("tipoRecolhimento", 1)); //Tipo recolhimento 1 - PRÓPRIO, 2 - RETIDO, 3 - ISENTO DE RECOLHIMENTO $aliquotaIss = 0; if (property_exists($this->rps->servico, 'aliquotaIss')) $aliquotaIss = $this->rps->servico->aliquotaIss; if ($aliquotaIss == 0) $aliquotaIss = (0.00+$this->conf->aliquotaIss); if ($aliquotaIss == 0) throw new Exception("Informação aliquotaIss não encontrada."); if ($aliquotaIss >= 1) throw new Exception("Informação aliquotaIss ($aliquotaIss) está fora do padrão."); //Formato da TAG aliquota 5% = 5.00 ao invés de 0.05 $atividadeExecutada->appendChild($dom->createElement("aliquota", $aliquotaIss*100)); $nfseLote->appendChild($atividadeExecutada); //deducoes $deducoes = $dom->createElement("deducoes"); $deducoes->appendChild($dom->createElement("tipo", 1)); //Tipo recolhimento 1 - SEM DEDUÇÃO, 2 - MAPA DE MATERIAIS, 3 - PERCENTUAL, 4 - POR VALOR, 5 - PERCENTUAL / MAPA DE MATERIAIS, 6 - PUBLICIDADE, 7 - MAPA DE DEDUÇÕES PARA INTERMEDIAÇÃO $nfseLote->appendChild($deducoes); //detalhamentoNota $descricao = $this->rps->servico->descricao; $detalhamentoNota = $dom->createElement("detalhamentoNota"); $nfseLote->appendChild($detalhamentoNota); $detalhamentoNota->appendChild($dom->createElement("descricaoNota", $descricao)); $itensServico = $dom->createElement("itensServico"); $detalhamentoNota->appendChild($itensServico); $valorTotal = (0.00+$this->rps->valorTotal); if ($valorTotal == 0) throw new Exception("Informação rps->ValorServicos não encontrada."); $valorIss = round($valorTotal * $aliquotaIss, 3, PHP_ROUND_HALF_EVEN); $item = $dom->createElement("item"); $item->setAttribute("nItem", "1"); $item->appendChild($dom->createElement("tributavel", 1)); $item->appendChild($dom->createElement("descricao", 'SERVIÇOS PRESTADOS')); $item->appendChild($dom->createElement("quantidade", 1)); $item->appendChild($dom->createElement("valorUnitario", $valorTotal)); $item->appendChild($dom->createElement("valorTotal", $valorTotal)); $itensServico->appendChild($item); $totais = $dom->createElement("totais"); $totais->appendChild($dom->createElement("valotTotalNota", $valorTotal)); $totais->appendChild($dom->createElement("valorTotalServico", $valorTotal)); $totais->appendChild($dom->createElement("valorTotalDeducao", 0)); $totais->appendChild($dom->createElement("valorTotalISS", $valorIss)); $totais->appendChild($dom->createElement("valorReducaoBC", 0)); $detalhamentoNota->appendChild($totais); //Retorna o RPS em formato XML sem o XML Declaration return $dom->saveXML($dom->documentElement); } function ibgeToTOM($endereco){ $dir = dirname(dirname(__DIR__)); $cidade = new stdClass(); $cidade->codigoMunicipio = null; $cidade->descricaoMunicipio = null; $cidade->codigoEstado = null; $cidade->descricaoEstado = null; if ($endereco->cidade > 0){ //CoRelacionamento $codigo_IBGE_TOM = []; require_once $dir."/consts/codigoIbgeTom.php"; if (array_key_exists($endereco->cidade, $codigo_IBGE_TOM)){ $tom = $codigo_IBGE_TOM[$endereco->cidade]; $cidade->codigoMunicipio = $tom[0]; $cidade->descricaoMunicipio = $tom[1]; } //CoRelacionamento $codigo_IBGE_UF = []; require_once $dir."/consts/codigoIbgeUf.php"; $id = substr(''.$endereco->cidade, 0, 2)+0; if (array_key_exists($id, $codigo_IBGE_UF)) { $uf = $codigo_IBGE_UF[$id]; $cidade->codigoEstado = $id; $cidade->descricaoEstado = strtoupper($this->remove_accents($uf[0])); } } return $cidade; } function remove_accents($string) { if ( !preg_match('/[\x80-\xff]/', $string) ) return $string; $chars = array( // Decompositions for Latin-1 Supplement chr(195).chr(128) => 'A', chr(195).chr(129) => 'A', chr(195).chr(130) => 'A', chr(195).chr(131) => 'A', chr(195).chr(132) => 'A', chr(195).chr(133) => 'A', chr(195).chr(135) => 'C', chr(195).chr(136) => 'E', chr(195).chr(137) => 'E', chr(195).chr(138) => 'E', chr(195).chr(139) => 'E', chr(195).chr(140) => 'I', chr(195).chr(141) => 'I', chr(195).chr(142) => 'I', chr(195).chr(143) => 'I', chr(195).chr(145) => 'N', chr(195).chr(146) => 'O', chr(195).chr(147) => 'O', chr(195).chr(148) => 'O', chr(195).chr(149) => 'O', chr(195).chr(150) => 'O', chr(195).chr(153) => 'U', chr(195).chr(154) => 'U', chr(195).chr(155) => 'U', chr(195).chr(156) => 'U', chr(195).chr(157) => 'Y', chr(195).chr(159) => 's', chr(195).chr(160) => 'a', chr(195).chr(161) => 'a', chr(195).chr(162) => 'a', chr(195).chr(163) => 'a', chr(195).chr(164) => 'a', chr(195).chr(165) => 'a', chr(195).chr(167) => 'c', chr(195).chr(168) => 'e', chr(195).chr(169) => 'e', chr(195).chr(170) => 'e', chr(195).chr(171) => 'e', chr(195).chr(172) => 'i', chr(195).chr(173) => 'i', chr(195).chr(174) => 'i', chr(195).chr(175) => 'i', chr(195).chr(177) => 'n', chr(195).chr(178) => 'o', chr(195).chr(179) => 'o', chr(195).chr(180) => 'o', chr(195).chr(181) => 'o', chr(195).chr(182) => 'o', chr(195).chr(182) => 'o', chr(195).chr(185) => 'u', chr(195).chr(186) => 'u', chr(195).chr(187) => 'u', chr(195).chr(188) => 'u', chr(195).chr(189) => 'y', chr(195).chr(191) => 'y', // Decompositions for Latin Extended-A chr(196).chr(128) => 'A', chr(196).chr(129) => 'a', chr(196).chr(130) => 'A', chr(196).chr(131) => 'a', chr(196).chr(132) => 'A', chr(196).chr(133) => 'a', chr(196).chr(134) => 'C', chr(196).chr(135) => 'c', chr(196).chr(136) => 'C', chr(196).chr(137) => 'c', chr(196).chr(138) => 'C', chr(196).chr(139) => 'c', chr(196).chr(140) => 'C', chr(196).chr(141) => 'c', chr(196).chr(142) => 'D', chr(196).chr(143) => 'd', chr(196).chr(144) => 'D', chr(196).chr(145) => 'd', chr(196).chr(146) => 'E', chr(196).chr(147) => 'e', chr(196).chr(148) => 'E', chr(196).chr(149) => 'e', chr(196).chr(150) => 'E', chr(196).chr(151) => 'e', chr(196).chr(152) => 'E', chr(196).chr(153) => 'e', chr(196).chr(154) => 'E', chr(196).chr(155) => 'e', chr(196).chr(156) => 'G', chr(196).chr(157) => 'g', chr(196).chr(158) => 'G', chr(196).chr(159) => 'g', chr(196).chr(160) => 'G', chr(196).chr(161) => 'g', chr(196).chr(162) => 'G', chr(196).chr(163) => 'g', chr(196).chr(164) => 'H', chr(196).chr(165) => 'h', chr(196).chr(166) => 'H', chr(196).chr(167) => 'h', chr(196).chr(168) => 'I', chr(196).chr(169) => 'i', chr(196).chr(170) => 'I', chr(196).chr(171) => 'i', chr(196).chr(172) => 'I', chr(196).chr(173) => 'i', chr(196).chr(174) => 'I', chr(196).chr(175) => 'i', chr(196).chr(176) => 'I', chr(196).chr(177) => 'i', chr(196).chr(178) => 'IJ',chr(196).chr(179) => 'ij', chr(196).chr(180) => 'J', chr(196).chr(181) => 'j', chr(196).chr(182) => 'K', chr(196).chr(183) => 'k', chr(196).chr(184) => 'k', chr(196).chr(185) => 'L', chr(196).chr(186) => 'l', chr(196).chr(187) => 'L', chr(196).chr(188) => 'l', chr(196).chr(189) => 'L', chr(196).chr(190) => 'l', chr(196).chr(191) => 'L', chr(197).chr(128) => 'l', chr(197).chr(129) => 'L', chr(197).chr(130) => 'l', chr(197).chr(131) => 'N', chr(197).chr(132) => 'n', chr(197).chr(133) => 'N', chr(197).chr(134) => 'n', chr(197).chr(135) => 'N', chr(197).chr(136) => 'n', chr(197).chr(137) => 'N', chr(197).chr(138) => 'n', chr(197).chr(139) => 'N', chr(197).chr(140) => 'O', chr(197).chr(141) => 'o', chr(197).chr(142) => 'O', chr(197).chr(143) => 'o', chr(197).chr(144) => 'O', chr(197).chr(145) => 'o', chr(197).chr(146) => 'OE',chr(197).chr(147) => 'oe', chr(197).chr(148) => 'R',chr(197).chr(149) => 'r', chr(197).chr(150) => 'R',chr(197).chr(151) => 'r', chr(197).chr(152) => 'R',chr(197).chr(153) => 'r', chr(197).chr(154) => 'S',chr(197).chr(155) => 's', chr(197).chr(156) => 'S',chr(197).chr(157) => 's', chr(197).chr(158) => 'S',chr(197).chr(159) => 's', chr(197).chr(160) => 'S', chr(197).chr(161) => 's', chr(197).chr(162) => 'T', chr(197).chr(163) => 't', chr(197).chr(164) => 'T', chr(197).chr(165) => 't', chr(197).chr(166) => 'T', chr(197).chr(167) => 't', chr(197).chr(168) => 'U', chr(197).chr(169) => 'u', chr(197).chr(170) => 'U', chr(197).chr(171) => 'u', chr(197).chr(172) => 'U', chr(197).chr(173) => 'u', chr(197).chr(174) => 'U', chr(197).chr(175) => 'u', chr(197).chr(176) => 'U', chr(197).chr(177) => 'u', chr(197).chr(178) => 'U', chr(197).chr(179) => 'u', chr(197).chr(180) => 'W', chr(197).chr(181) => 'w', chr(197).chr(182) => 'Y', chr(197).chr(183) => 'y', chr(197).chr(184) => 'Y', chr(197).chr(185) => 'Z', chr(197).chr(186) => 'z', chr(197).chr(187) => 'Z', chr(197).chr(188) => 'z', chr(197).chr(189) => 'Z', chr(197).chr(190) => 'z', chr(197).chr(191) => 's' ); $string = strtr($string, $chars); return $string; } }