Skip to Content

Nesse documento tem como objetivo explicar, de forma simples e objetiva, como realizar de forma simples uma conexão usando RFCs/Webservices (WSDL) com uma aplicação PHP, utilizando a classe SoapClient. A motivação para criar esse documento em português vem da falta de artigos desse tipo na nossa língua.

O documento será dividido em duas partes:

  1. Configurar o lado SAP, criandos as RFCs e gerando os Webservices.
  2. Criar os arquivos PHP para consumir os Webservices.

Iremos utilizar como exemplo uma situação em que uma aplicação PHP tem as seguintes necessidades de integração com o SAP:

  • Acessar os dados básicos de um usuário do SAP, como nome, validade, endereços, roles, etc.
  • Copiar um usuário
  • Recuperar a senha e desbloquar um usuário

Parte 1: Configurar o lado SAP

Para realizar essa tarefa, vamos dividir nosso exemplo em três partes, sendo cada uma a resolução de cada uma das nossas três necessidades. Algumas

Tarefa 1: Acessar os dados básicos de um usuário do SAP

Para isso, vamos criar um webservice baseado em uma RFC já pronta, a função BAPI_USER_GET_DETAIL.

/wp-content/uploads/2014/01/ws_bapi_get_user_detail_362614.pngFigura 1: Caminho para criação de Web Service

gerando ws - tela1.png

Figura 2: Criando Web Service – Tela 1 (nome e descrição do Web Service)

gerando ws - tela2.png

Figura 3: Criando Web Service – Tela 2 (opção para mapear o nome da função p/ gerar a operação)

gerando ws - tela3.png

Figura 4: Criando Web Service – Tela 3 (menos seguro, para simplificar nosso exemplo)

gerando ws - tela4.png

Figura 5: Criando Web Service – Tela 4 (meu pacote local $SDN)

gerando ws - tela5.png

Figura 6: Criando Web Service – Tela 5 (confirmação)

Após esses 5 telas, o Web Service está basicamente criado. Irá ser aberta uma tela de definição do serviço, que deveremos somente ativar e utilizar como base no futuro para verificar os parâmetros de entrada e saída.

gerando ws - tela6.png

Figura 7: Criando Web Service – Tela 6 (Definição do Serviço)

Nesse momento, para finalizar só precisamos pegar a URL do nosso WSDL, para utilizarmos nas nossas classes PHP. Para isso, iremos acessar os detalhes do Web Service na transação SOAMANAGER (necessita que o básico de Webdynpro esteja configurado no ambiente) e entrar nas configurações simplificadas, onde é conseguiremos acessar a URl de maneira bem simples:

/wp-content/uploads/2014/01/soamanager_1_362677.png

Figura 8: SOAMANAGER – Tela 1

/wp-content/uploads/2014/01/soamanager_2_362696.png

Figura 9: SOAMANAGER – Tela 2 (Não esquecer de marcar o checkbox ‘User Name/Password (Basic)’ e salvar, para gerar uma configuração válida)


Nesse momento, para finalizamos a tarefa 1! Vamos para a próxima tarefa.


Tarefa 2: Copiar um usuário

Para essa tarefa, vamos optar por desenvolver nosso próprio módulo de função e criar nossos Web Service.


Código-fonte do módulo de função:


FUNCTION zrw_user_copy.

*”———————————————————————-

*”*”Local Interface:

*”  IMPORTING

*”     VALUE(USER_REFERENCE) LIKE  USR02-BNAME

*”     VALUE(NEW_USER) LIKE  USR02-BNAME

*”     VALUE(PASSWORD) TYPE  SUID_ST_NODE_PASSWORD-PASSWORD OPTIONAL

*”     VALUE(WITH_ADDRESS) TYPE  CHAR01 DEFAULT ‘X’

*”     VALUE(WITH_PARAMETERS) TYPE  CHAR01 DEFAULT ‘X’

*”     VALUE(WITH_REFUSER) TYPE  CHAR01 DEFAULT ‘X’

*”     VALUE(WITH_DEFAULTS) TYPE  CHAR01 DEFAULT ‘X’

*”     VALUE(WITH_UCLASS) TYPE  CHAR01 DEFAULT ‘X’

*”  EXPORTING

*”     VALUE(NEW_PASS) TYPE  SUID_ST_NODE_PASSWORD

*”  EXCEPTIONS

*”      INTERNAL_ERROR

*”———————————————————————-

   DATA: lv_new_user TYPE suid_st_node_root,

         ls_password TYPE suid_st_node_password.

   TRY.

       CALL METHOD cl_identity=>copy

         EXPORTING

           iv_id_source             = user_reference

           iv_id_destination        = new_user

           iv_copy_address          = with_address

           iv_copy_defaults         = with_defaults

           iv_copy_parameters       = with_parameters

           iv_copy_refuser          = with_refuser

           iv_copy_roles            = abap_true

           iv_copy_profiles         = abap_true

           iv_copy_groups           = abap_true

           iv_copy_personalization  = abap_true

           iv_copy_uclass           = with_uclass

           iv_copy_easy_access      = abap_true

         IMPORTING

           ev_node_root_destination = lv_new_user.

       IF lv_new_useridref IS INITIAL.

         RAISE internal_error.

       ENDIF.

       IF password IS INITIAL.

         CALL METHOD lv_new_useridref->if_identity_password~password_generate

           EXPORTING

             iv_return_pwd_only    = space

             iv_downward_comp      = abap_true

           IMPORTING

             ev_generated_password = new_pass.

       ELSE.

         ls_passwordpassword = password.

         lv_new_useridref->if_identity_password~set_password( ls_password ).

       ENDIF.

       lv_new_useridref->if_identity_password~set_password_to_initial( ).

       cl_identity=>do_save( ).

       COMMIT WORK.

     CATCH cx_suid_identity .

       RAISE internal_error.

   ENDTRY.

ENDFUNCTION.


Essa função utiliza como base a classe CL_IDENTITY para realizar as operações de cópia e geração de senha. Não vou entrar em detalhes mas caso tenham dúvidas sobre o funcionamento da função, fiquem a vontade nos comentários. Repitam o procedimento de criação do Web Service da tarefa 1 e anotem a URL do WSDL.


Tarefa 3: Recuperar a senha e desbloquar um usuário

Vamos utilizar a mesma base da tarefa anterior, porém acessando alguns métodos diferentes:


FUNCTION zrw_user_reset_password.

*”———————————————————————-

*”*”Local Interface:

*”  IMPORTING

*”     REFERENCE(IV_USER) TYPE  USR02-BNAME

*”     REFERENCE(IV_NEW_PASSWORD) TYPE  SUID_ST_NODE_PASSWORD-PASSWORD

  *”       OPTIONAL

*”  EXPORTING

*”     REFERENCE(EV_PASSWORD) TYPE  SUID_ST_NODE_PASSWORD-PASSWORD

*”  EXCEPTIONS

*”      INVALID_USER

*”———————————————————————-

   DATA: lo_user     TYPE REF TO cl_identity,

         lt_users    TYPE suid_tt_node_root,

         lt_bnames   TYPE suid_tt_bname,

         ls_user     LIKE LINE OF lt_users,

         ls_bname    LIKE LINE OF lt_bnames,

         ls_password TYPE suid_st_node_password,

         lv_locked   TYPE boolean.

   TRY.

       ls_bnamebname = iv_user.

       APPEND ls_bname TO lt_bnames.

       CALL METHOD cl_identity=>retrieve_for_update

         EXPORTING

           it_bname     = lt_bnames

         IMPORTING

           et_node_root = lt_users.

       READ TABLE lt_users INTO ls_user INDEX 1.

       IF sysubrc IS NOT INITIAL.

         RAISE invalid_user.

       ENDIF.

       IF iv_new_password IS INITIAL.

         CALL METHOD ls_useridref->if_identity_password~password_generate

           EXPORTING

             iv_return_pwd_only    = space

             iv_downward_comp      = abap_true

           IMPORTING

             ev_generated_password = ls_password.

         ev_password = ls_passwordpassword.

       ELSE.

         ev_password = ls_passwordpassword = iv_new_password.

         ls_useridref->if_identity_password~set_password( ls_password ).

       ENDIF.

       CALL METHOD ls_useridref->get_lockstatus

         IMPORTING

           ev_locked_by_failed_logon = lv_locked.

       IF lv_locked EQ abap_true.

         ls_useridref->action_unlock( ).

       ENDIF.

       ls_useridref->if_identity_password~set_password_to_initial( ).

       cl_identity=>do_save( ).

       COMMIT WORK.

     CATCH cx_suid_identity .

   ENDTRY.

ENDFUNCTION.

Novamente não vou entrar em detalhes mas caso tenham dúvidas sobre o funcionamento da função, fiquem a vontade nos comentários. Repitam o procedimento de criação do Web Service da tarefa 1 e anotem a URL do WSDL.

Parte 2: Criar Arquivos PHP para consumir os Web Services criados

No nosso exemplo vamos usar como mdelo uma classe que iremos concentrar todos os webservices e um arquivo consumidor que irá instanciar um objeto dessa classe e utilizar as operações

Classe dos Webservices:


<?php
/**
*
* @author Renan
*     
*/
class SAPWebServices {
  const SERVER = 'http://localhost:8000';
  //WSDL paths
  const ZRW_WS_GET_USER_DETAIL  = '/sap/bc/srt/wsdl/bndg_005056C000081ED39DC1E10DA9C97287/soap11/wsdl11/allinone/standard/document?sap-client=800';
  const ZRW_WS_RESET_PASS = '/sap/bc/srt/wsdl/bndg_005056C000081ED39DCE159B661ABBB1/soap11/wsdl11/allinone/standard/document?sap-client=800';
  const ZRW_WS_COPY_USER   = '/sap/bc/srt/wsdl/bndg_005056C000081ED39DDE16E7906E7BB1/soap11/wsdl11/allinone/standard/document?sap-client=800';
  //default values
  const INITIAL_PASS = 'inicial123';
  const ABAP_TRUE = 'X';
  const ABAP_FALSE = '';
  /**
  *
  * @var array SAP Logon Details
  */
  private $SOAP_OPTS;
  /**
  *
  * @var SoapClient Soap Object
  */
  private $client;
  function __construct() {
  $this->SOAP_OPTS = array (
  'login' => 'RENAN',
  'password' => 'mypassword',
  'features' => SOAP_SINGLE_ELEMENT_ARRAYS
  );
  }
  /**
  * Call websevice ZRW_WS_GET_USER_DETAIL (BAPI_USER_GET_DETAIL)
  *
  * @param string $user_name     
  *
  */
  public function get_user_detail($user_name) {
  $this->client = new SoapClient ( SAPWebServices::SERVER . SAPWebServices::ZWEB_USER_DETAIL, $this->SOAP_OPTS );
  $params = array (
  'Username' => "$user_name",
  'Return' => ''
  );
  try {
  return $this->client->UserGetDetail ( $params );
  } catch ( SoapFault $e ) {
  throw $e;
  }
  }
  /**
  * Call websevice ZRW_WS_RESET_PASS
  *
  * @param string $user_name     
  * @param string $initial_password   
  */
  public function reset_password($user_name, $initial_password = NULL) {
  $this->client = new SoapClient ( SAPWebServices::SERVER . SAPWebServices::ZRW_WS_RESET_PASS, $this->SOAP_OPTS );
  $params = array (
  'Username'  => $user_name,
  'NewPassword' => $initial_password,
  'EvPassword'  => '',
  );
  try {
  return $this->client->ResetPassword ( $params );
  } catch ( SoapFault $e ) {
  throw $e;
  }
  }
  /**
  * Call websevice ZRW_WS_COPY_USER
  *
  * @param string $user_name     
  * @param string $user_reference     
  */
  public function clone_user($user, $user_reference, $initial_password = null) {
  $this->client = new SoapClient ( SAPWebServices::SERVER . SAPWebServices::ZRW_WS_COPY_USER, $this->SOAP_OPTS );
  $params = array (
  'UserReference' => $user_reference,
  'NewUser'       => $user,
  'Password'      => $initial_password,
  'NewPass'       => array('Password' => ''),
  'WithAddress'   => SAPWebServices::ABAP_FALSE,
  );
  try {
  return $this->client->UserCopy ( $params );
  } catch ( SoapFault $e ) {
  throw $e;
  }
  }
}
?>

Arquivo que usará a classe para consumir os Web Services:


<?php
require_once 'sap/SAPWebServices.php';
try {
  $sap = new SAPWebServices ();
  $result = $sap->get_user_detail('RENAN');
  $result = $sap->clone_user('TESTE_USER' , 'RW_TEMPLATE');
  $result = $sap->reset_password('TESTE_USER');
}
catch ( SoapFault $exception ) {
  print "***Caught Exception***<br />";
  echo '<pre>';
  print_r ( $exception );
  echo '</pre>';
  print "***END Exception***<br />";
  die ();
}
print "***Success***<br />";
echo '<pre>';
print_r ( $result );
echo '</pre>';
?>

Pronto! Se você seguiu todos os passos, você terá o seus arquivos PHP acessandos as RFCs do SAP via WebServices/Soap de maneira fácil e rápida, sem integradores de terceiros ou classes customizadas, tudo 100% nativo.

To report this post you need to login first.

6 Comments

You must be Logged on to comment or reply to a post.

  1. Eduardo Chagas

    Parabéns Renan!

    Curiosidade… aqui você deu um exemplo de como acessar os dados básicos de um usuário; o que tipo de processo/informações você tem mais usado com esse tipo de aplicação?

    Abraço

    Eduardo Chagas

    (0) 
    1. Renan William Alves de Oliveira Post author

      Obrigado Eduardo!

      Exemplos de aplicação:

      • Portal/Intranet, com opção de Reset de Senha de forma automática – Nesse caso eu pegaria os detalhes do usuário pra exibir o nome completo, empresa, data de validade do usuário, etc.
      • Portal/Intranet para administração de usuários (time de security) – Grid com os usuários do sistema e ao clicar em algum usuário da lista, exibir os detalhes de logon na web
      • Integração com algum sistema de RH web para exibição de alguns detalhes do usuário SAP do funcionário

      No meu caso especificamente eu estou fazendo um portal paa os meus alunos de treinamentos onde eles podem ver os dados cadastrados no SAP e resetar a senha/desbloquear os usuários (coisa bem comum durante treinamento).

      (0) 

Leave a Reply