<?
function SOAP_import(){ if (!is_object($GLOBALS['SOAP_import'])) $GLOBALS['SOAP_import']=new i_SOAP_import();return($GLOBALS['SOAP_import']);}
include_once(_DIR_EXT.'/esmo_gateway/i_personal_import.php') ;
class i_SOAP_import extends i_personal_import
{
  var $SOAP_XML_content='';
  var $SOAP_current_block_number='';
  var $SOAP_XML_count_rows=0 ;
  var $SOAP_node='ESMO' ;
  var $db_debug=0;
  var $import_begin_time=0;
  var $full_update=0;
  var $error='';

  var $arr_SOURCE_fields=array() ;
  var $arr_SOURCE_DB_fields=array() ;
  var $read_block_stats=array() ;

  var $source_fnames=array('org_name'=>array('code'=>'Organizatsiya'),
                           'otdel_name'=>array('code'=>'PodrazdelenieNaimenovanie'),
                           'work_name'=>array('code'=>'DolzhnostNaimenovanie'),
                           'uid_fl'=>array('code'=>'FizicheskoeLitso'),
                           'uid_so'=>array('code'=>'Sotrudnik'),
                           'vz'=>array('code'=>'VidZanyatosti'),
                           'pol'=>array('code'=>'Pol'),
                           'dr'=>array('code'=>'DataRozhdeniya','is_data'=>1),
                           'du'=>array('code'=>'DataUvolneniya','is_data'=>1),

          ) ;

  // подключается к источнику данных и сохраняет XML контент в  SOAP_XML_content
  function connect_SOURCE($fname="")
  { //damp_array($this,1,-1) ;
     if ($this->read_only) {?><div class="alert">Режим только чтение</div><?}
     if ($fname)
    {
      $this->SOAP_XML_content=file_get_contents($fname) ;
      $this->source_action='XML file, '.hide_server_dir($fname) ;
    }
    else
    {   $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: '.$ReceivedMessageNumber) ;
        // 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);

                // but this will failed
        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') ;
            $this->SOAP_XML_content=$res->return ;
            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 'XML файл сохранен в <a href="/logs/'.str_replace(array('[fname=',']'),'',basename($xml_fname)).'" target=_blank>Источник</a><br>' ;
            $this->source_action='SOAP, '.hide_server_dir($xml_fname) ;
          }
          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');
    }

    define('MAIN_WORK_NAME','ОсновноеМестоРаботы') ;
    $this->defined_vars() ;
  }

  function defined_vars()
  {   define('ORG_NAME',$this->source_fnames['org_name']['code']) ;
      define('OTDEL_NAME',$this->source_fnames['otdel_name']['code']) ;
      define('WORK_NAME',$this->source_fnames['work_name']['code']) ;
      define('UID_FL',$this->source_fnames['uid_fl']['code']) ;
      define('UID_SO',$this->source_fnames['uid_so']['code']) ;
      define('VZ',$this->source_fnames['vz']['code']) ;
      define('DR',$this->source_fnames['dr']['code']) ;
      define('DU',$this->source_fnames['du']['code']) ;
      define('POL',$this->source_fnames['pol']['code']) ;
  }

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

    }

 }

 function parse_source_headers()
 {   $XML=new SimpleXMLElement($this->SOAP_XML_content) ;

     if (is_object($XML))
         {  $this->SOAP_current_block_number=(int)$XML->MessageNumber ;
            foreach($XML->Data->children() as $item) $recs2[]=(array)$item ;
            $this->SOAP_XML_count_rows=sizeof($recs2) ;
            $arr=array() ;
            if (sizeof($recs2)) foreach($recs2 as $rec)
             {   //damp_array($rec) ;
                 $arr['pl'][(string)$rec['Сотрудник']]++ ;
                 $arr['fl'][(string)$rec['ФизическоеЛицо']]++ ;
                 $arr['org'][(string)$rec['Организация']]++ ;
                 $arr['otdel'][(string)$rec['Подразделение']]++ ;
                 $arr['working'][(string)$rec['ДолжностьНаименование']]++ ;
                 // собираем данные по полям XML и размеру данных
                 if (sizeof($rec)) foreach($rec as $fname=>$fvalue)
                 {   $len=strlen($fvalue) ;
                     if (!isset($this->arr_SOURCE_fields[$fname])) $this->arr_SOURCE_fields[$fname]=$len ;
                     else if ($len>$this->arr_SOURCE_fields[$fname])  $this->arr_SOURCE_fields[$fname]=$len ;
                 }
             }
         }

      if (sizeof($this->arr_SOURCE_fields)) foreach($this->arr_SOURCE_fields as $fname=>$len) $this->arr_SOURCE_DB_fields[$fname]=$this->check_db_fields_names($fname) ;
     //damp_array($recs2,1,-1) ;
     // анализируем полученный массив
     //damp_array($arr,1,-1) ;

     $this->read_block_stats=array( 'fname'=>basename($fname),
                                    'Организации'=>sizeof($arr['org']),
                                    'Подразделения'=>sizeof($arr['otdel']),
                                    'Должности'=>sizeof($arr['working']),
                                    'ФизическиеЛица'=>sizeof($arr['fl']),
                                    'СотрудникиОрганизаций'=>sizeof($arr['pl'])
                                    ) ;

     //damp_array($this->arr_SOURCE_fields) ;
     //damp_array($this->arr_SOURCE_DB_fields) ;

 }


 // пересим данные из XML в таблицу soap_xml_block в формате "как есть"
  function parse_SOURCE_to_DB()
  { ?><strong>Переносим данные в таблицу источника</strong><br><?
    $XML=new SimpleXMLElement($this->SOAP_XML_content) ;
    $this->import_begin_time=time() ;
    if (is_object($XML))
    {  $this->SOAP_current_block_number=(int)$XML->MessageNumber ;
	   echo 'current_block_number=<strong>'.$this->SOAP_current_block_number.'</strong><br>' ;

       $j=0 ; $arr=array() ; $i=0 ; $table_fields=implode(',',$this->arr_SOURCE_DB_fields) ;
       foreach($XML->Data->children() as $item)
       {   $rec=(array)$item ;
           $fields=array() ;
           // данные необходимо подготовить для вставки в том же самом порядке, как поля были объявлены в таблице
           if (sizeof($this->arr_SOURCE_fields)) foreach($this->arr_SOURCE_fields as $fname=>$len) $fields[]='"'.addslashes($rec[$fname]).'"' ;
           $arr[]='('.implode(',',$fields).')' ;
           $j++ ; $i++ ;
           if ($j==$GLOBALS['LS_magnit_insert_rows_count'])
           {  $this->insert_arr_to_db($table_fields,$arr) ;
              $j=0 ; $arr=array() ;
              FILE_LOG()->append('parse_SOURCE_to_DB: insert_arr_to_db => +'.$GLOBALS['LS_magnit_insert_rows_count']) ;
           }
       }
       if ($j) $this->insert_arr_to_db($table_fields,$arr) ;
       echo 'Cохранено <strong>'.$i.'</strong> строк</br>' ;
        FILE_LOG()->append('parse_SOURCE_to_DB: save '.$i.' rows') ;

       // имеем две таблицы - одна ФЛ, вторая - сотрудники
       $count=execSQL_update('update '.$this->table_fz.' set obj_name=CONCAT(Familiya," ",Imya," ",Otchestvo)') ;
       $count=execSQL_update('update '.$this->table_fz.' set name1=Familiya') ;
       $count=execSQL_update('update '.$this->table_fz.' set name2=Imya') ;
       $count=execSQL_update('update '.$this->table_fz.' set name3=Otchestvo') ;
       $this->flog_append('update '.$this->table_fz.':obj_name -> '.$count.' rows') ;

       $count=execSQL_update('update '.$this->table_fz.' set dr=DATE_FORMAT('.DR.',"%d.%m.%Y");') ;
       $this->flog_append('update '.$this->table_fz.':dr -> '.$count.' rows') ;

       $count=execSQL_update('update '.$this->table_fz.' set poll=0 where Pol!="Женский"') ;
       $this->flog_append('update '.$this->table_fz.':pol "man" -> '.$count.' rows') ;

       $count=execSQL_update('update '.$this->table_fz.' set poll=1 where Pol="Женский"') ;
       $this->flog_append('update '.$this->table_fz.':pol "woman" -> '.$count.' rows') ;

       $count=execSQL_update('update '.$this->table_so.' set obj_name=CONCAT(Familiya," ",Imya," ",Otchestvo)') ;
       $this->flog_append('update '.$this->table_so.':obj_name -> '.$count.' rows') ;

       $count=execSQL_update('update '.$this->table_so.' set fired_data=UNIX_TIMESTAMP('.DU.') where '.DU.'!=""') ;
       $this->flog_append('update '.$this->table_so.':fired_data -> '.$count.' rows') ;

       $count=execSQL_update('update '.$this->table_so.' set is_main=1 where '.VZ.'="'.MAIN_WORK_NAME.'"') ;
       $this->flog_append('update '.$this->table_so.':is_main -> '.$count.' rows') ;

       $count=execSQL_update('update '.$this->table_so.' set is_second=1 where '.VZ.'!="'.MAIN_WORK_NAME.'"') ;
       $this->flog_append('update '.$this->table_so.':is_second -> '.$count.' rows') ;

       ?><table class="basic fz_small"><th>UID ФЛ</th><th>ФИО</th><th>UID СО</th><th>Организация</th><th>Подразделение</th><th>Должность</th><th>Вид занятости</th><th>Действие</th><?

       $recs=execSQL('select FizicheskoeLitso,count(*) as cnt from '.$this->table_so.' where is_main=1 group by FizicheskoeLitso having cnt>1',0,1) ;
       // удаляем из таблицы все записи по основной должности кроме первой
       if (sizeof($recs))
       { ?><tr><td colspan="8" class="left"><strong>Выполняем проверку по сотрудникам с более чем с одной основной должностью</strong></td></tr><?
         foreach($recs as $rec_fl)
         {  $recs_so=execSQL('select * from '.$this->table_so.' where FizicheskoeLitso="'.$rec_fl['FizicheskoeLitso'].'" and is_main=1 order by is_main desc',0,1) ;
            $this->show_so_tr($recs_so) ;
         }
       }
       $recs=execSQL('select FizicheskoeLitso,count(*) as cnt from '.$this->table_so.' where is_second=1 group by FizicheskoeLitso having cnt>1',0,1) ;
       if (sizeof($recs))
       { ?><tr><td colspan="8" class="left"><strong>Выполняем проверку по сотрудникам с более чем с одной должностью по совмещению</strong></td></tr><?
         foreach($recs as $rec_fl)
         {  $recs_so=execSQL('select * from '.$this->table_so.' where FizicheskoeLitso="'.$rec_fl['FizicheskoeLitso'].'" and is_second=1 order by is_second desc',0,1) ;
            $this->show_so_tr($recs_so) ;
         }
       }
       $recs=execSQL('select FizicheskoeLitso,Organizatsiya,PodrazdelenieNaimenovanie,DolzhnostNaimenovanie,count(*) as cnt from '.$this->table_so.' group by FizicheskoeLitso,Organizatsiya,PodrazdelenieNaimenovanie,DolzhnostNaimenovanie having cnt>1',0,1) ;
       if (sizeof($recs))
       { ?><tr><td colspan="8" class="left"><strong>Выполняем проверку по сотрудникам c одинаковым местом работы в нескольких должностях</strong></td></tr><?
         foreach($recs as $rec_fl)
         {  $recs_so=execSQL('select * from '.$this->table_so.' where FizicheskoeLitso="'.$rec_fl['FizicheskoeLitso'].'" order by is_main desc,is_second desc',0,1) ;
            $this->show_so_tr($recs_so) ;
         }
       }

       ?></table><?

       //execSQL('select * from '.$this->table_so.'',2,1) ;


       // фиксируем в базе номер последнего принятого блока
       $this->fixed_block() ;


    }
    else echo 'Not valid XML structure' ;

  }

  function show_so_tr($recs_so)
  {
       ?><tr><td><?echo $recs_so[0]['FizicheskoeLitso']?></td>
             <td><?echo $recs_so[0]['obj_name']?></td>
             <td><?echo $recs_so[0]['Sotrudnik']?></td>
             <td><?echo $recs_so[0]['Organizatsiya']?></td>
             <td><?echo $recs_so[0]['PodrazdelenieNaimenovanie']?></td>
             <td><?echo $recs_so[0]['DolzhnostNaimenovanie']?></td>
             <td><?echo $recs_so[0]['VidZanyatosti']?></td>
             <td><span class="green">Запись сохранена</span></td>
         </tr><?
       if (sizeof($recs_so)) foreach($recs_so as $i=>$rec_so) if ($i)
       {   ?><tr><td></td>
                  <td></td>
                  <td><?echo $rec_so['Sotrudnik']?></td>
                  <td><?echo $rec_so['Organizatsiya']?></td>
                  <td><?echo $rec_so['PodrazdelenieNaimenovanie']?></td>
                  <td><?echo $rec_so['DolzhnostNaimenovanie']?></td>
                  <td><?echo $rec_so['VidZanyatosti']?></td>
                  <td><span class="red">Запись удалена</span></td>
           </tr><?
           execSQL_update('delete from '.$this->table_so.' where Sotrudnik="'.$rec_so['Sotrudnik'].'"') ;
       }
  }
}

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";
      $xml_fname=LOGS()->reg_file_log('SOAP_XML',$res->return,array('ext'=>'.xml')) ;
    $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;
}
?>
