<?php
// входной скрипт для URL https://dev.kvzrm.ru/services/esmo_gateway/upload_persons/
// внимание! по умолчанию сервис возвращает структурированный ответ по выполенными операциям
// для просмотра лога импорта надо либо передать опцию show_log, либо после приема сервиса достать лог из файла _DIR_TO_ROOT.'/logs/import_trace_'.$arr_result['session_uid'].'.html'
// класс создан для получения из SOAP XML-файла, дальнейшая обработка происходит в c_services_esmo_gateway_upload_persons_1c
include_once('c_services_esmo_gateway_upload_persons_1c.php');
class c_services_esmo_gateway_upload_persons_SOAP extends c_services_esmo_gateway_upload_persons_1c
{
  var $SOAP_node;

  // подключается к источнику данных и сохраняет XML контент в  SOAP_XML_content
  function connect_SOURCE()
  { $xml_fname=parent::connect_SOURCE() ;
    //damp_array($this) ;
    $this->SOAP_node=($this->setting['update_mode']=='full')? $GLOBALS['LS_magnit_import_personal_from_SOAP_node_update']:$GLOBALS['LS_magnit_import_personal_from_SOAP_node_full'] ;  //'ESMOCHG' ; // только изменения
    if (!$xml_fname) // если данные не загружены стандартными способами - получаем данные через SOAP
    {   $ReceivedMessageNumber=($this->SOAP_node=='ESMOCHG')? $GLOBALS['LS_magnit_import_SOAP_block_number_update']:$GLOBALS['LS_magnit_import_SOAP_block_number_full'] ;
        $url = $GLOBALS['LS_magnit_import_personal_from_SOAP_server'];
        echo 'connect to SOAP server url: <strong>'.$url.'</strong><br>' ;
        echo 'node: <strong>'.$this->SOAP_node.'</strong><br>' ;
        echo 'ReceivedMessageNumber: <strong>'.$ReceivedMessageNumber.'</strong><br>' ;
        FILE_LOG()->append('SOAP server url: '.$url) ;
        FILE_LOG()->append('SOAP server node: '.$this->SOAP_node) ;
        FILE_LOG()->append('SOAP server ReceivedMessageNumber: '.$this->SOAP_node) ;
        // we unregister the current HTTP wrapper

        define('LS_magnit_import_personal_from_SOAP_login',$GLOBALS['LS_magnit_import_personal_from_SOAP_login']) ;
        define('LS_magnit_import_personal_from_SOAP_password',$GLOBALS['LS_magnit_import_personal_from_SOAP_password']) ;

        stream_wrapper_unregister('https');
        stream_wrapper_register('https', 'MyServiceProviderNTLMStream') or die("Failed to register protocol");

        // so now all request to a http page will be done by MyServiceProviderNTLMStream.
        // ok now, let's request the wsdl file
        // if everything works fine, you should see the content of the wsdl file
        ini_set('default_socket_timeout',1000) ;
        $options=array('trace'=>1,'exeptions'=>1,'connection_timeout'=>1000) ;
        $client = new SoapClient($url, $options);
        try
          {
            $params=new stdClass() ;
            $params->NodeCode=$this->SOAP_node ;

            $params->ReceivedMessageNumber=$ReceivedMessageNumber ; // номер последнего принятого блока
            FILE_LOG()->append('use node SOAP: '.$this->SOAP_node) ;
            FILE_LOG()->append('BeginExchange') ;
            $res=$client->BeginExchange($params);
            FILE_LOG()->append('connect to SOAP is OK') ;
            FILE_LOG()->append('response data: '.show_size(strlen($res->return))) ;
            $xml_fname=LOGS()->reg_file_log('SOAP_XML',$res->return,array('ext'=>'.xml')) ;
            FILE_LOG()->append('save data to '.hide_server_dir($xml_fname)) ;
            echo 'Получение данных из SOAP: XML файл сохранен в <a href="/logs/'.str_replace(array('[fname=',']'),'',basename($xml_fname)).'" target=_blank>Источник</a><br>' ;
          }
          catch(SoapFault $e)
          { $this->flog_append('ERROR: '.$e->getMessage()) ;
            echo '<div class=alert>error: '.$e->getMessage()."</div>" ;
            //$this->error=$e->getMessage() ;

          }
        // restore the original http protocole
        stream_wrapper_restore('https');
    }

    return(hide_server_dir($xml_fname)) ;

  }

  function fixed_block($block_number)
  {	if ($block_number)
    {   if ($this->SOAP_node=='ESMOCHG') update_site_setting('LS_magnit_import_SOAP_block_number_update',$block_number) ;
        else                             update_site_setting('LS_magnit_import_SOAP_block_number_full',$block_number) ;
    }
  }

}


class NTLMStream
{
  private $path;
  private $mode;
  private $options;
  private $opened_path;
  private $buffer;
  private $pos;

  /**
   * Open the stream
   *
   * @param unknown_type $path
   * @param unknown_type $mode
   * @param unknown_type $options
   * @param unknown_type $opened_path
   * @return unknown
   */
  public function stream_open($path, $mode, $options, $opened_path) {
    echo "[NTLMStream::stream_open] $path , mode=$mode \n";
    $this->path = $path;
    $this->mode = $mode;
    $this->options = $options;
    $this->opened_path = $opened_path;

    $this->createBuffer($path);

    return true;
  }

  /**
   * Close the stream
   *
   */
  public function stream_close() {
    echo "[NTLMStream::stream_close] \n";
    curl_close($this->ch);
  }

  /**
   * Read the stream
   *
   * @param int $count number of bytes to read
   * @return content from pos to count
   */
  public function stream_read($count) {
    echo "[NTLMStream::stream_read] $count \n";
    if(strlen($this->buffer) == 0) {
      return false;
    }

    $read = substr($this->buffer,$this->pos, $count);

    $this->pos += $count;

    return $read;
  }
  /**
   * write the stream
   *
   * @param int $count number of bytes to read
   * @return content from pos to count
   */
  public function stream_write($data) {
    echo "[NTLMStream::stream_write] \n";
    if(strlen($this->buffer) == 0) {
      return false;
    }
    return true;
  }


  /**
   *
   * @return true if eof else false
   */
  public function stream_eof() {
    echo "[NTLMStream::stream_eof] ";

    if($this->pos > strlen($this->buffer)) {
      echo "true \n";
      return true;
    }

    echo "false \n";
    return false;
  }

  /**
   * @return int the position of the current read pointer
   */
  public function stream_tell() {
    echo "[NTLMStream::stream_tell] \n";
    return $this->pos;
  }

  /**
   * Flush stream data
   */
  public function stream_flush()
  { echo "[NTLMStream::stream_flush] \n";
    $this->buffer = null;
    $this->pos = null;
  }

  /**
   * Stat the file, return only the size of the buffer
   *
   * @return array stat information
   */
  public function stream_stat() {
    echo "[NTLMStream::stream_stat] \n";

    $this->createBuffer($this->path);
    $stat = array(
      'size' => strlen($this->buffer),
    );

    return $stat;
  }
  /**
   * Stat the url, return only the size of the buffer
   *
   * @return array stat information
   */
  public function url_stat($path, $flags) {
    echo "[NTLMStream::url_stat] \n";
    $this->createBuffer($path);
    $stat = array(
      'size' => strlen($this->buffer),
    );

    return $stat;
  }

  /**
   * Create the buffer by requesting the url through cURL
   *
   * @param unknown_type $path
   */
  private function createBuffer($path) {
    if($this->buffer) {
      return;
    }

    echo "[NTLMStream::createBuffer] create buffer from : $path\n";
    $this->ch = curl_init($path);
    curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($this->ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
    curl_setopt($this->ch, CURLOPT_HTTPAUTH, CURLAUTH_NTLM);
    curl_setopt($this->ch, CURLOPT_USERPWD, $this->user.':'.$this->password);
    echo $this->buffer = curl_exec($this->ch);
    echo "[NTLMStream::createBuffer] buffer size : ".strlen($this->buffer)."bytes\n";
    $this->pos = 0;

  }
}

class MyServiceProviderNTLMStream extends NTLMStream {
  protected $user = LS_magnit_import_personal_from_SOAP_login ;
  protected $password = LS_magnit_import_personal_from_SOAP_password;
}


?>