Ir para conteúdo

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Giovani Silva

PHP NFSe com SOAP envio de XML RPS para Betha Fly-enota

Recommended Posts

Boa noite, estou tentando enviar com PHP SOAP o XML de um lote RPS assinado para o Web Service da Betha também conhecido como Fly e-nota. 

No entanto, não tenho tido nenhum retorno quanto a se deu algum erro ou algo do tipo.

 

Documentação https://e-gov.betha.com.br/e-nota-test/ambienteteste.faces 

 

Ambiente Teste Webservice 

https://e-gov.betha.com.br/e-nota-contribuinte-test-ws/recepcionarLoteRps?wsdl

https://e-gov.betha.com.br/e-nota-contribuinte-test-ws/consultarLoteRps?wsdl 

 

Layout https://e-gov.betha.com.br/e-nota/manuais/layout.pdf 
Modelo Conceitual http://www.abrasf.org.br/arquivos/files/NFSE-NACIONAL_Modelo_Conceitual versao 2-02.pdf

Manual de Integração ABRASF http://www.abrasf.org.br/arquivos/files/NFSE-NACIONAL_Manual_De_Integracao versao 2-02.pdf 

 

Tem uma opção na área administrativa Fly e-nota para solicitar a prefeitura autorização para impressão de RPS tanto manual como eletrônica.
Não sei se isso é obrigatório ou se é necessário para o meu objetivo.

  

Parte do código para o envio:

------------------------------

function transmiteRps($xmlAssinado,$certificadoPem,$senha){
    $wsdl            = 'https://e-gov.betha.com.br/e-nota-contribuinte-test-ws/recepcionarLoteRps?wsdl';
    $endpoint        = 'https://e-gov.betha.com.br/e-nota-contribuinte-test-ws/recepcionarLoteRps';
    $certificate    = $certificadoPem;
    $password        = $senha;
    
    $options = array(
        'location'        => $endpoint,
        'keep_alive'    => true,
        'trace'            => true,
        'local_cert'    => $certificate,
        'passphrase'    => $password,
        'cache_wsdl'    => WSDL_CACHE_NONE
    );
    
    try {
        
        $client = new SoapClient($wsdl, $options);



        $function = 'EnviarLoteRpsEnvio';
        $arguments = ['EnviarLoteRpsEnvio' => ['xml'=>$xmlAssinado]];
        
        $options = [];
        $result = $client -> __soapCall($function, $arguments, $options);



    } catch(Exception $e){
        $result = false;
    }
      
    if($result!==false){
        return xml2array($result->return);
    }else{
        return false;
    }
    
}//transmiteRps





----------------------------------------------------------


function xml2array($xmlstring){
    $xml = simplexml_load_string($xmlstring);
    $json = json_encode($xml);
    $array = json_decode($json, TRUE);
    return $array;
    
}



-----------------------------------------------



function consultaRps($cnpj, $inscricao, $protocolo, $certificadoPem, $senha){
    
    $wsdl            = 'https://e-gov.betha.com.br/e-nota-contribuinte-test-ws/consultarLoteRps?wsdl';
    $endpoint        = 'https://e-gov.betha.com.br/e-nota-contribuinte-test-ws/consultarLoteRps';
    $certificate    = $certificadoPem;
    $password        = $senha;

    

$xml = '<?xml version="1.0" encoding="utf-8"?>
    <ConsultarLoteRpsEnvio xmlns="http://www.betha.com.br/e-nota-contribuinte-test-ws">
    <Prestador>
        <CpfCnpj>
            <Cnpj>'.$cnpj.'</Cnpj>
        </CpfCnpj>
        <InscricaoMunicipal>'.$inscricao.'</InscricaoMunicipal>
    </Prestador>
    <Protocolo>'.$protocolo.'</Protocolo>
    </ConsultarLoteRpsEnvio>';
    
    
    $options = array(
        'location'        => $endpoint,
        'keep_alive'    => true,
        'trace'            => true,
        'local_cert'    => $certificate,
        'passphrase'    => $password,
        'cache_wsdl'    => WSDL_CACHE_NONE
    );
    
    try {
        
        $client = new SoapClient($wsdl, $options);
        $function = 'consultarLoteRps';
        $arguments = ['consultarLoteRps' => ['xml'=>$xml]];
        
        $options = [];
        $result = $client -> __soapCall($function, $arguments, $options);
    } catch(Exception $e){
        $result = false;
    }
    
    if($result!==false){
        return $result->return;
    }else{
        return false;
    }
    
} //consultaRps



--------------------------------



$certificadoPem=dirname(__FILE__).'/certificado.pem';
$senha='xxxxx'; //senha do certificado



----------------------------------



//assina RPS
$xmlAssinado=assinaRps(dirname(__FILE__).'/only_rps.xml'); //usei para assinar só a RPS



file_put_contents(dirname(__FILE__).'/rps_temp/rps1.xml','<?xml version="1.0" encoding="utf-8"?>
<EnviarLoteRpsEnvio xmlns="https://e-gov.betha.com.br/e-nota-contribuinte-test-ws"><LoteRps Id="LOTE1"><NumeroLote>1</NumeroLote><Cnpj>xxxxxxxxxxxxxx</Cnpj><InscricaoMunicipal>xxxx</InscricaoMunicipal><QuantidadeRps>1</QuantidadeRps>
<ListaRps>'.str_replace('<?xml version="1.0" encoding="utf-8"?>','',$xmlAssinado).'</ListaRps></LoteRps></EnviarLoteRpsEnvio>');

$_SESSION['nome_uri']='LOTE1';



$xmlAssinado=assinaRps(dirname(__FILE__).'/rps_temp/rps1.xml'); //usei para assinar o Lote RPS






$resultado=transmiteRps($xmlAssinado,
                       $certificadoPem,
                       $senha);


if(!empty($resultado["Protocolo"])){//se tem protocolo e sucesso
    //$resultado["NumeroLote"]
    //$resultado["Protocolo"]
    //consulta lote e pega nfse
    
    $nfseResposta = consultaRps('xxxxxxxxxxxxx', //cnpj
                               'xxxx', //inscrição municipal
                               $resultado["Protocolo"],
                               $certificadoPem,
                               $senha);
    
    if($nfseResposta!==false){
        echo '<textarea cols="120" rows="70">';
        echo $nfseResposta;
        echo '</textarea>';
    }else{
        echo 'Erro ao consultar RPS';
    }
    
}else{
    echo "erro no envio";
}


 

Vídeo Tutorial do código NFSe acima porém para outro webservice que não é da Betha.

https://www.youtube.com/watch?v=v1rByVX1_FY

 

Desde já agradeço a atenção e colaboração dos colegas.
Funcionando postarei aqui a solução com o código completo para quem precisar.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Um dos pontos que analizei, é que você está enviando os dados de forma errada. Apesar do WSDL definir os tipos como um XML, não é um XML que deve ser enviado. Você deve criar um objeto que corresponda ao tipo definido na mensageria.

 

Veja o seguinte XML:

<ConsultarLoteRpsEnvio xmlns="http://www.betha.com.br/e-nota-contribuinte-test-ws">
    <Prestador>
        <CpfCnpj>
            <Cnpj>?</Cnpj>
        </CpfCnpj>
        <InscricaoMunicipal>?</InscricaoMunicipal>
    </Prestador>
    <Protocolo>?</Protocolo>
</ConsultarLoteRpsEnvio>

Sendo ConsultarLoteRpsEnvio o nome do método, o que está abaixo são as propriedades.

 

Com anos de experiência, eu compreendi que o Soap trabalha melhor quando lhe é enviado um objeto do tipo stdClass ao invés de um array. Logo, quando for montar o objeto, ele deve ser similar a este:

//Cria o objeto nó raiz
$consultarLoteRpsEnvio = new stdClass();

//cria o objeto do nó Prestador
$prestador = new stdClass();

//Cria o objeto do nó CpfCnpj
$cpfCnpj = new stdClass();
$cpfCnpj->Cnpj = 'xxxxxxxxxxxx';

//Adiciona o nó CpfCnpj ao nó Prestador
$prestador->CpfCnpj = $cpfCnpj;
$prestador->InstricaoMunicipal = 'xxxxxx';

//Adiciona o nó Prestador ao nó Raiz
$consultarLoteRpsEnvio->Prestador = $crestador;
$consultarLoteRpsEnvio->Protocolo = 'xxxxx';

E, na hora de enviar, utilize apenas o objeto:

$result = $client->ConsultarLoteRpsEnvio($consultarLoteRpsEnvio);

Você pode encontrar outro exemplo aqui:

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Bom dia Gabriel, muito obrigado pela dica.
Gostei do conceito de criar e enviar o objeto.

 

Vou tentar fazer como você mencionou.

 

Bem, pelo que entendi o mesmo conceito deve ser aplicado a função transmiteRps.

 

Mas a parte que diz no manual que tanto a RPS como o Lote devem ser Assinados
a assinatura também deve ser colocada no objeto da forma que mencionasse?
Em nenhuma parte enviarei um arquivo XML do Lote RPS, apenas o objeto? quanto a senha, assinatura,... e outras coisas para ter um minimo de segurança?

 

O certificado eu converti para .pem Nesse caso o processo de assinar o objeto seria o mesmo praticamente que eu havia usado?

 

Só lembrando a parte que receberá o RPS https://e-gov.betha.com.br/e-nota-contribuinte-test-ws/recepcionarLoteRps?wsdl 

 

Obs. No caso que fiz eu gravei o XML assinado, mas na hora de enviar não tive o Protocolo para a parte da consulta. Ou seja, algo errado mas também não tive resposta de erro do webservice.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Quanto a essas situações do certificado, terei de pesquisar, nunca precisei enviar nada assinado digitalmente via SOAP.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Obrigado, vou dar uma olhada.

Aproveitando, você sabe interpretar o WSDL? 
https://e-gov.betha.com.br/e-nota-contribuinte-test-ws/recepcionarLoteRps?wsdl 
é que na chamada
__soapCall($function, $arguments, $options); 

 

Tenho duvida quanto a função e os argumentos usados para o envio dos dados.
         $function = 'EnviarLoteRpsEnvio';
        $arguments = ['EnviarLoteRpsEnvio' => ['xml'=>$xmlAssinado]];

 

--- Dúvida: EnviarLoteRpsEnvioResponse ou EnviarLoteRpsEnvio em ambos os casos (função e nos argumentos) ?

 

Outra questão: ao usar stdClass na real não estaria criando a mesma estrutura do XML manualmente e salvando em um objeto para enviá-la ao webservice?

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Caso você não conheça todas as partes do WSDL, use o SoapUI para interpretar o WSDL, ele lhe ajudar bastante.

 

6 minutos atrás, didio20ss disse:

[...] ao usar stdClass na real não estaria criando a mesma estrutura do XML manualmente e salvando em um objeto para enviá-la ao webservice?

 

 

Sim e não. A ideia é criar exatamente a estrutura do XML, entretanto, a sua estrutura de XML é apenas uma string, por isso elas possuem comportamentos diferentes.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Oi, tive mais uma dúvida, tenho dois modelos de lote RPS onde um baixei da Betha e outro fornecido por uma empresa de automação que usa o sistema da Betha.
No cabeçalho dessa outra empresa tem o "e:" e no na Betha não.

Empresa Midia
<e:EnviarLoteRpsEnvio xmlns:e="http://www.betha.com.br/e-nota-contribuinte-ws">
Betha 
<EnviarLoteRpsEnvio xmlns = "http://www.betha.com.br/e-nota-contribuinte-ws">

Esse "e:" ou as vezes já notei outras expressões no lugar,
como se chama e para que serve? 
Faz diferença usar ?

 

----------------
Outra dúvida

Nos exemplos da Betha tem:
envioSoapUi.xml que tem o comentário "Quando utilizar, por exemplo, o Soap-UI para envio do XML deve ser utilizada a estrutura abaixo" que teria um cabeçalho <soapenv 
E tem exemplos sem isso. 
Na hora de montar a estrutura do XML devo usar isso no meu código php ou não?

Outros exemplos que tem:
RecepcionarLoteRps.xml

RecepcionarLoteRpsSincrono.xml
GerarNfse.xml <GerarNfseEnvio xmlns = "http://www.betha.com.br/e-nota-contribuinte-ws">

 

Qual a diferença do Sincrono e do outro? Qual a melhor opção?

 

E eu estava a usar o RecepcionarLoteRps.
Me passaram a informação que gerando e enviando o XML do lote RPS para o Webservice da Betha, 
o sistema deles gera a DANFE e até envia a NFSe para o e-mail do cliente se o mesmo for informado no XML
.

 

Então devo continuar a usar apenas o RecepecionarLoteRps ou também devo usar o GerarNfse?

 

Obrigado mais uma vez

Compartilhar este post


Link para o post
Compartilhar em outros sites
2 horas atrás, didio20ss disse:

Esse "e:" ou as vezes já notei outras expressões no lugar,
como se chama e para que serve? 
Faz diferença usar ?

 

É um prefixo de namespace. Quando não utilizado, tudo que é global, cai no namespace sem prefixo. Já, caso você utilizar, você pode usar o prefixo para informar o namespace utilizado.

 

Para saber mais, de uma olhada aqui: https://msdn.microsoft.com/en-us/library/aa468565.aspx

 

2 horas atrás, didio20ss disse:

Nos exemplos da Betha tem:
envioSoapUi.xml que tem o comentário "Quando utilizar, por exemplo, o Soap-UI para envio do XML deve ser utilizada a estrutura abaixo" que teria um cabeçalho <soapenv 
E tem exemplos sem isso. 
Na hora de montar a estrutura do XML devo usar isso no meu código php ou não?

 

essa estrutura deve ser usada quando você quiser manipular completamente a chamada do SOAP (cabeçalho e corpo da requisição). Isso normalmente acontece quando utiliza-se a biblioteca cURL. Com a biblioteca SOAP do PHP, ele já faz isso por ti.

 

2 horas atrás, didio20ss disse:

Outros exemplos que tem:
RecepcionarLoteRps.xml

RecepcionarLoteRpsSincrono.xml
GerarNfse.xml <GerarNfseEnvio xmlns = "http://www.betha.com.br/e-nota-contribuinte-ws">

 

Qual a diferença do Sincrono e do outro? Qual a melhor opção?

 

Sincrono será feita a requisição e o sistema irá esperar o retorno dessa requisição. Assíncrono é o contrário, a requisição é efetuada, o script não esperar o retorno e continua executando. Qual é melhor? Nenhum. Cada um tem seu propósito.

 

2 horas atrás, didio20ss disse:

E eu estava a usar o RecepcionarLoteRps.
Me passaram a informação que gerando e enviando o XML do lote RPS para o Webservice da Betha, 
o sistema deles gera a DANFE e até envia a NFSe para o e-mail do cliente se o mesmo for informado no XML
.

 

Então devo continuar a usar apenas o RecepecionarLoteRps ou também devo usar o GerarNfse?

 

Não sei, isso foge da área de programação e entra na área de negócio da empresa Betha. Entre em contato com eles e verifique o que for melhor.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Agradeço a ajuda do Gabriel Heming e outras fontes sobre o assunto.

Para quem precisar assinar e enviar lote RPS para a Betha emitindo assim a NFSe seguem algumas dicas que me ajudaram a resolver o problema:

 

1º - Ao gerar o XML da RPS, deve-se assinar primeiro a RPS e depois o Lote.
2º - para assinar o XML converte-se o arquivo .pfx do certificado para .pem para assim poder trabalhar com assinatura no servidor PHP

Para a conversão basta procurar na internet por "convert pfx to pem" e terá como exemplo https://www.sslshopper.com/ssl-converter.html 

O meu certificado baixei da Betha e ao converter o arquivo continua contendo tanto a chave privada quanto a publica.
Por isso, após a conversão para "pem" deve-se abrir o arquivo com Bloco de Notas, Notepad++ ou outro, 
Verá vários blocos de código. O primeiro é a chave primaria. Deve-se copiar o segundo bloco que é a chave publica e salvar em um novo arquivo chavepublica.pem 
Irá precisar dos dois arquivos .pem para a assinatura, o completo e o com apenas a chave pública.

 

Biblioteca para assinar o XML https://github.com/robrichards/xmlseclibs 

Vídeo bem útil do Bill Barsch da Geranet https://www.youtube.com/watch?v=v1rByVX1_FY

Usei apenas a parte para assinar o documento.

 

* Importante: Usar o "force_uri". Não sei se porque usei o certificado da Betha no meu caso o atributo URI não apareceu no XML como no exemplo do vídeo, mas teve efeito na assinatura. Sem essa opção ela não é válida.

 

3º - Para o envio usei o cURL adicionando o cabeçalho SOAP por ele.
Segundo algumas fontes, usando o somente o SOAP pode ocorre de não trazer retorno em caso de erros e ai você não sabe o que fazer. Já com o cURL você recebe sempre as mensagens. Quanto usei só o SOAP tinha erro mas a página ficava em branco, de mogo que eu não sabia o que estava acontecendo.


Agradeço ao POST do Luiz Paulo Franz aqui do fórum sobre o envio por cURL.

 

* Tive que fazer algumas modificações no código dele pois tava dando erro de assinatura inválida.

Tirei toda a parte do código dele que fazia alterações no XML, onde ele usava str_replace
Motivo: após você assinar um documento, ele não deve ser alterado, pois assim a assinatura se tornaria inválida.

 

Observações finais:

Fazer os testes no ambiente de homologação.

cuidar de acentos ou caracteres especiais no XML.
Também é bom remover os espaços em branco e quebras de linha antes de se assinar o documento.

Nunca repetir o número do lote e usar em sequência.

 

Espero que estas informações possam ajudar a outros.

 

Um forte abraço a todos
Giovani Silva
Virthuz Anunciante Virtual

Compartilhar este post


Link para o post
Compartilhar em outros sites

Boa tarde Josemir Costa,  você conseguiu resolver sua questão? 
Chegou a olhar os links que mencionei? 

Biblioteca para assinar o XML https://github.com/robrichards/xmlseclibs 

Vídeo bem útil do Bill Barsch da Geranet https://www.youtube.com/watch?v=v1rByVX1_FY 

 

Para assinar individual, colocamos a primeira parte do XML em uma string e então chamamos a função de assinar enviando o código. Após pegamos o retorno e concatenamos com o restante do XML de deveria estar antes e após a primeira string já assinada. Daí chamamos novamente a função de assinar passando a segunda string (XML completo) a ser assinada.

 

Não sei se ficou claro.

 

O único cuidado que tem que ter é não modificar nada no primeiro bloco após assinado, pois remover espaços após a assinatura por exemplo, a invalidaria.

 

Att.

Giovani Silva
Virthuz Anunciante Virtual

Compartilhar este post


Link para o post
Compartilhar em outros sites
4 minutos atrás, Giovani Silva disse:

Boa tarde Josemir Costa,  você conseguiu resolver sua questão? 
Chegou a olhar os links que mencionei? 

Biblioteca para assinar o XML https://github.com/robrichards/xmlseclibs 

Vídeo bem útil do Bill Barsch da Geranet https://www.youtube.com/watch?v=v1rByVX1_FY 

 

Para assinar individual, colocamos a primeira parte do XML em uma string e então chamamos a função de assinar enviando o código. Após pegamos o retorno e concatenamos com o restante do XML de deveria estar antes e após a primeira string já assinada. Daí chamamos novamente a função de assinar passando a segunda string (XML completo) a ser assinada.

 

Não sei se ficou claro.

 

O único cuidado que tem que ter é não modificar nada no primeiro bloco após assinado, pois remover espaços após a assinatura por exemplo, a invalidaria.

 

Att.

Giovani Silva
Virthuz Anunciante Virtual

Então! A questão é que quando assino o xml usando a biblioteca ele só assina a primeira tag, como faço p assinar a tag correta? tipo assinar a tag <rps> depois a tag <LoteRps> que são as que devem conter os ids e serem assinadas. Deu pra entender?

Compartilhar este post


Link para o post
Compartilhar em outros sites

$rps="<Rps><InfRps Id="rps1"> ... </InfRps></Rps";

$RpsAssinado=assinaRps($rps,$chave_publica);

 

$Lote='<e:EnviarLoteRpsEnvio xmlns:e="http://www.betha.com.br/e-nota-contribuinte-ws"><LoteRps Id="LOTE1'"><NumeroLote>1</NumeroLote><Cnpj>xxxxxxx</Cnpj><InscricaoMunicipal>xxxx</InscricaoMunicipal><QuantidadeRps>1</QuantidadeRps><ListaRps>'.$RpsAssinado.'</ListaRps></LoteRps></e:EnviarLoteRpsEnvio>';

$LoteAssinado=assinaRps($Lote , $chave_publica);

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Mais um detalhe Josemir, na função assinaRps não sei se você estava enviando um arquivo com o XML.
Caso era um arquivo, na função teria a opção $doc -> load($arquivo)

Nessa caso tem que substituir por 
$doc -> loadXML($arquivo) 

para funcionar com a string 
$rps="<Rps><InfRps Id="rps1"> ... </InfRps></Rps";

Compartilhar este post


Link para o post
Compartilhar em outros sites

Veja meu xml:

<Rps>
 <InfDeclaracaoPrestacaoServico>
  <Rps Id="1">
   <IdentificacaoRps>
    <Numero>254122</Numero>
    <Serie>serie</Serie>
    <Tipo>1</Tipo>
   </IdentificacaoRps>
   <DataEmissao>2018-04-10</DataEmissao>
   <Status>1</Status>
  </Rps>
  <Competencia>2018-04-10</Competencia>
  <Servico>
   <Valores>
    <ValorServicos>400.00</ValorServicos>
    <ValorIss>8.00</ValorIss>
    <Aliquota>0.0200</Aliquota>
   </Valores>
   <IssRetido>1</IssRetido>
   <ItemListaServico>1401</ItemListaServico>
   <Discriminacao>Descriminação do serviço</Discriminacao>
   <CodigoMunicipio>3100401</CodigoMunicipio>
   <ExigibilidadeISS>3</ExigibilidadeISS>
  </Servico>
  <Prestador>
   <CpfCnpj>
    <Cnpj>01139388000179</Cnpj>
   </CpfCnpj>
   <InscricaoMunicipal>1234</InscricaoMunicipal>
  </Prestador>
  <Tomador>
   <IdentificacaoTomador>
    <CpfCnpj>
     <Cnpj>12345678912345</Cnpj>
    </CpfCnpj>
    <InscricaoMunicipal>1234</InscricaoMunicipal>
   </IdentificacaoTomador>
   <RazaoSocial>TOMADOR</RazaoSocial>
   <Endereco>
    <Endereco>teste</Endereco>
    <Numero>123</Numero>
    <Bairro>teste</Bairro>
    <CodigoMunicipio>1234</CodigoMunicipio>
    <Uf>SE</Uf>
    <Cep>35438000</Cep>
   </Endereco>
   <Contato>
    <Telefone>32554411</Telefone>
    <Email>teste@dominiodoemail.com</Email>
   </Contato>
  </Tomador>
  <RegimeEspecialTributacao>1</RegimeEspecialTributacao>
  <OptanteSimplesNacional>2</OptanteSimplesNacional>
  <IncentivoFiscal>2</IncentivoFiscal>
 </InfDeclaracaoPrestacaoServico>
</Rps>';

quando eu coloco a opção do force_uri não aparece na assinatura, na verdade aparece um código aleatório, quando coloco o id na tag pai <rps> aí sim aparece mas na estrutura correta o id aparece na tag rps filho. Não consegui chegar a uma solução ainda. 

 

Muito obrigado pela atenção e pasciência!

Compartilhar este post


Link para o post
Compartilhar em outros sites

Boa noite, em nossos testes não lembro se tentamos colocar um ID na tag Rps e sim na InfRps.

Conforme havia comentado na solução aqui neste post, é necessário deixar o force_uri como true mesmo que aparentemente não apareça na estrutura do seu xml ou que fique em branco. Funciona dessa maneira mesmo. Agora se desativar o force_uri da erro na assinatura.

 

Então mesmo que não apareça o uri na assinatura de seu xml, ele fez alguma coisa nela tornando-a válida.

Compartilhar este post


Link para o post
Compartilhar em outros sites

  • Conteúdo Similar

    • Por ILR master
      Fala galera, tudo bem?
       
      Tenho o seguinte codigo:
       
       class Data {
      public static function ExibirTempoDecorrido($date)
      {
          if(empty($date))
          {
              return "Informe a data";
          }
          $periodos = array("segundo", "minuto", "hora", "dia", "semana", "mês", "ano", "década");
          $duracao = array("60","60","24","7","4.35","12","10");
          $agora = time();
          $unix_data = strtotime($date);
          // check validity of date
          if(empty($unix_data))
          {  
              return "Bad date";
          }
          // is it future date or past date
          if($agora > $unix_data) 
          {  
              $diferenca     = $agora - $unix_data;
              $tempo         = "atrás";
          } 
          else 
          {
              $diferenca     = $unix_data - $agora;
              $tempo         = "agora";
          }
          for($j = 0; $diferenca >= $duracao[$j] && $j < count($duracao)-1; $j++) 
          {
              $diferenca /= $duracao[$j];
          }
          $diferenca = round($diferenca);
          if($diferenca != 1) 
          {
              $periodos[$j].= "s";
          }
          return "$diferenca $periodos[$j] {$tempo}";
      }
      }
       
      Funciona redondinho se o valor retornado for de algumas horas, mas...
      Quando passa de dois meses, ele retorna a palavra mess. Deve ser por conta dessa linha
      if($diferenca != 1) 
          {
              $periodos[$j].= "s";
          }
       
      Quero que modre:
       
      2 meses atrás
      e não
      2 mess atrás.
       
      Espero que tenham entendido.
       
      Valeu
    • Por Carlos Web Soluções Web
      Olá...
      Estou tentando fazer o seguinte !!
      Listando dados em tabela !!
      Gostaria que....se na listagem houver 4 linhas...indepedente de seu número de ID, faça a listagem em ID ser em ordem 1 2 3 4 !!
      Exemplo...se tiver uma listagem de dados que está em ID 1 3 3...faça ficar 1 2 3 !!

       
      echo "<table class='tabela_dados' border='1'> <tr> <td>ID</td> <td>Nome Empresa</td> <td>Responsável</td> <td>Telefone 1</td> <td>Telefone 2</td> <td>E-mail 1</td> <td>E-mail 2</td> <td>Endereço</td> <td>CEP</td> <td>Bairro</td> <td>AÇÃO 1</td> <td>AÇÃO 2</td> </tr> "; $sql = "SELECT ID FROM usuarios_dados WHERE Usuario='$usuario'"; $result = $conn->query($sql); $num_rows = $result->num_rows; $Novo_ID = 1; for ($i = 0; $i < $num_rows; $i++) { $registro = $result -> fetch_row(); $sql2 = "UPDATE usuarios_dados SET ID='$Novo_ID' WHERE ID='$Novo_ID'"; $result2 = $conn->query($sql2); $Novo_ID++; } $sql = "SELECT * FROM usuarios_dados"; $result = $conn->query($sql); if ($result->num_rows > 0) { // output data of each row while($row = $result->fetch_assoc()) { echo "<tr> <td>$row[ID]</td> <td>$row[Nome_Empresa]</td> <td>$row[Responsavel]</td> <td>$row[Telefone_1]</td> <td>$row[Telefone_2]</td> <td>$row[Email_1]</td> <td>$row[Email_2]</td> <td>$row[Endereço]</td> <td>$row[CEP]</td> <td>$row[Bairro]</td> <td> <form method='post' action='Editar_Dados.php'> <input type='hidden' name='usuario' value='$usuario'> <input type='hidden' name='senha' value='$senha'> <input type='hidden' name='ID' value='$row[ID]'> <input type='submit' style='padding: 10px;' value='EDITAR'> </form> </td> <td> <form method='post' action='Deletar_Dados.php'> <input type='hidden' name='usuario' value='$usuario'> <input type='hidden' name='senha' value='$senha'> <input type='hidden' name='ID' value='$row[ID]'> <input type='submit' style='padding: 10px;' value='DELETAR'> </form> </td> </tr> "; } } else { echo "0 results"; } $conn->close();  
    • Por ILR master
      Boa tarde pessoal, tudo bem ?
       
      Eu uso o tinymce para cadastro de textos no meu siite, porém, quero fazer um sistema para que os colunistas possam fazer o próprio post.
      O problema do tinymce, é que ele mantém a formatação do texto copiado, como tamanho de fonts, negritos, etc... Quero que o usuário cole o texto e a própria textarea limpe a formatação para que ele formate como quiser.
       
      A pergunta é:
       
      O tinymce tem uma opção para desabilitar a formatação quando um texto é colocado?
      Tem alguma função via java ou php para retirar a formatação assim que o texto é colado?
      Ou é melhor usar um outro editor?
       
      Agradeço deste já.
    • Por Giovanird
      Olá a todos!
      Tenho uma pagina que possui uma DIV onde coloquei uma pagina PHP.
      Uso a função setInterval para atualizar a pagina inclusa dentro da DIV.
      O problema é que ao acessar o site , a DIV só me mostra a pagina inclusa somente quando completo o primeiro minuto.
      Preciso que a pagina inclusa já inicie carregada
       
      Meu código JavaScript e a DIV com a pagina PHP
       
      <script> function atualiza(){ var url = 'direita.php'; $.get(url, function(dataReturn) { $('#direita').html(dataReturn); }); } setInterval("atualiza()",60000); </script> <div> <span id="direita"></span> </div>  
    • Por ILR master
      Fala pessoal.
       
      Seguinte:
       
      Quero selecionar duas tabelas e mostrar com resultados intercalados. Abaixo segue um código explicando para vcs terem uma ideia.
       
      $consulta = "SELECT A.*, B.* FROM tabela1 A, tabela2 B'";
      $resultado = mysqli_query($conexao, $consulta) or die ("erro");
      while($busca = mysqli_fetch_array($resultado)){
       
      print $busca['cod_evento']; --> traz o código da tabela1 
      print $busca['titulo_evento']; -->  traz o titulo da tabela1
      print $busca['cod_noticia']; --> traz o código da tabela2
      print $busca['titulo_noticia']; --> traz o tituloda tabela2
       
      }
       
      Espero que entendam. Grato
       
×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.