<?
// класс для импорта данных из файла XLS во временную таблицу
// данные переносятся как есть, заголовки таблицы будут использованы как названия столбцов
class i_xls_to_db_import
{
  public $XLS_fname ;
  public $table ;
  public $row_header ;


  var $db_debug=0;
  var $import_begin_time=0;

  var $arr_XLS_cols_names=array() ;   // массив - столбец XLS => заголовок
  var $arr_XLS_cols_DB=array() ;         // массив - столбец XLS => столбец БД
  var $aSheet ;
  var $objPHPExcel ;
  var $append_row_count=500 ;
  var $row_import=0 ;
  var $session_uid=0 ;
  var $import_result=array() ;
  var $import_error=array() ;
  var $use_only_column_letter=0 ; //  в таблице использовать в качестве названий столбцов буквы A B C D

  var $def_field_size=256 ;
  var $result=array() ;

  function __construct($options=array())
  {   $this->session_uid=($options['uid'])? $options['uid']:$_GET['uid'] ;
      if (!$this->session_uid) $this->session_uid=ENGINE()->generate_UID() ;
      $this->table=($options['use_table_name'])? $options['use_table_name']:'temp_import_'.$this->session_uid ;
  }

  function delete_temp_tables()
  {
     execSQL_update('drop table if exists '.$this->table) ;
  }

  function import($fname_source='')
  {   set_include_path(_DIR_TO_ADDONS.'/PHPExcel/');
      if (!file_exists(_DIR_TO_ADDONS.'/PHPExcel/')) $this->import_error[]='Расширение PHPExcel не установлено' ;

      if (!$fname_source) $fname_source=$this->XLS_fname ;
      $check_file=$fname_source ;
      if ($fname_source and file_exists(_DIR_TO_ROOT.$check_file) and is_file(_DIR_TO_ROOT.$check_file)) echo 'Будет использован файл <strong>'.$check_file.'</strong><br>' ;
      else $this->import_error[]='Не найден файл для импорта "'.$check_file.'"' ;

      $this->connect_SOURCE() ;
      $this->parse_XLS_headers() ;
      $this->create_temp_tables_xls() ;
      $this->parse_xls_to_temp_table() ;

      $this->result=(_sizeof($this->import_error))? array('status'=>'error','error'=>implode('<br>',$this->import_error)):array('success'=>1,'status'=>'success');

      return($this->result) ;
  }



  // подключается к источнику данных и сохраняет XML контент в  SOAP_XML_content
  function connect_SOURCE()
    {   if (_sizeof($this->import_error)) return ;
        set_time_limit(0) ;
        include_once 'PHPExcel/IOFactory.php';
        $this->flog_append('PHPExcel_IOFactory будет загружен файл '.$this->XLS_fname) ;
        $this->objPHPExcel = PHPExcel_IOFactory::load(_DIR_TO_ROOT.$this->XLS_fname);
        $this->flog_append('PHPExcel_IOFactory файл загружен, открываем 1-у страницу') ;
        $this->objPHPExcel->setActiveSheetIndex(0);
        $this->aSheet = $this->objPHPExcel->getActiveSheet();
        if (!is_object($this->aSheet)) $this->import_error[]='Не удалось открыть объект страницы таблицы XLS' ;
        else $this->flog_append('PHPExcel_IOFactory готов к чтению данных') ;
    }

    // получаем заголовки XLS файла и сохраняем в массив
    function parse_XLS_headers()
    {  if (_sizeof($this->import_error)) return ;

       $rowIterator = $this->objPHPExcel->getActiveSheet()->getRowIterator();
            $this->flog_append('PHPExcel_IOFactory начинаем читать заголовки страницы') ;
            foreach($rowIterator as $row)
            { $cellIterator = $row->getCellIterator();
              $cur_row=$row->getRowIndex() ;
              $cellIterator->setIterateOnlyExistingCells(false); // Loop all cells, even if it is not set
              if ($cur_row==$this->row_header)
              { echo 'Разбираем строку заголовка: <strong>'.$this->row_header.'</strong><br>' ;
                foreach ($cellIterator as $cell)
                { $value=trim(str_replace("\n",'',$cell->getValue()));
                  $fname=($this->use_only_column_letter)? strtoupper($cell->getColumn()):$cell->getColumn().'_'.substr($this->check_db_fields_names($value),0,16) ;
                  if ($value!="")
                  { $this->arr_XLS_cols_names[$cell->getColumn()]=$value ;  // первая строка - заголовки
                    $this->arr_XLS_cols_DB[$cell->getColumn()]=$fname ;  // первая строка - заголовки
                  }
                }
                echo 'Найдено столбцов: <strong>'._sizeof($this->arr_XLS_cols_DB).'</strong><br>' ;
              }
              if ($cur_row>$this->row_header) break ;
            }
            $this->flog_append('PHPExcel_IOFactory заголовки страницы прочитаны') ;

        //damp_array($this->arr_XLS_cols_names) ;
        //damp_array($this->arr_XLS_cols_DB) ;
        $this->flog_append('parse_XLS_headers') ;
    }

    // создаем временную таблицу на основе данных из xls файла - как есть
   function create_temp_tables_xls()
   {   if (_sizeof($this->import_error)) return ;

       execSQL_update('DROP TABLE  IF EXISTS '.$this->table) ;
       $arr_fields=array() ;
       if (_sizeof($this->arr_XLS_cols_DB)) foreach($this->arr_XLS_cols_DB as $fname) $arr_fields[]=$fname.' text NULL' ;
       if (_sizeof($arr_fields))
       { $sql='CREATE TABLE  '.$this->table.' (ai_key int(11) auto_increment,primary key (ai_key),'.implode(',',$arr_fields).') ENGINE = InnoDB DEFAULT CHARSET=utf8' ;
       execSQL_update($sql,array('debug'=>0)) ;
       echo 'Создана временная таблица для размещения данных из XLS файла<br>' ;
   }
       else
       {  echo '<div class="red">Не удалось получить список полей XLS файла</div>' ;

       }
   }

   // переносим данные из ИСТОЧНИКА в таблицу soap_xml_block в формате "как есть"
   function parse_xls_to_temp_table()
   {   if (_sizeof($this->import_error)) return ;

       $this->flog_append('parse_xls_to_temp_table start') ;
       ?>Переносим данные в во временную таблицу<br><?
       $cnt_space=0 ; $cnt_data=0 ; 
       if (is_object($this->aSheet))
       {   $rowIterator = $this->objPHPExcel->getActiveSheet()->getRowIterator();
           $this->flog_append('PHPExcel_IOFactory начинаем читать данные страницы') ;
           $lastRow = $this->aSheet->getHighestRow();

           foreach($rowIterator as $row) if ($row->getRowIndex()>$this->row_header)
           { $line=$row->getRowIndex() ;
             $cellIterator = $row->getCellIterator();
             $cellIterator->setIterateOnlyExistingCells(false); // Loop all cells, even if it is not set

             $rec=array() ;

             foreach ($cellIterator as $cell)
             {   $value=$cell->getValue(); // если в ячейке формула getFormattedValue будет выдавать ошибку
//                 if (substr($value,0,1)=='=') $value= 'formula' ;
                 if (substr($value,0,1)=='=') {
                     $value= $cell->getCalculatedValue();
                     if (substr($value,0,1)=='#') $value = '';
                 }
                 else $value=$cell->getFormattedValue(); // только так корректно считывается дата, через getFormattedValue
                 $col=$cell->getColumn() ;
                 if (isset($this->arr_XLS_cols_DB[$col])) $rec[$this->arr_XLS_cols_DB[$col]]=trim($value);
             }

             $cnt_data++ ;
             //$recs[]=$rec ;
             multiSQL_insert($this->table)->append($rec) ;

             $this->flog_append('прочитана строка '.$line.' из '.$lastRow) ;

             if ($cnt_space>10) break ;
           }
           multiSQL_insert($this->table)->flush() ;
           //print_2x_arr($recs) ;

           echo 'Прочитано строк файла XLS: <strong>'.$line.'</strong><br>' ;
           echo 'Cохранено строк с данными: <strong>'.$cnt_data.'</strong></br>' ;
           $this->row_import=$cnt_data ;

           $this->flog_append('all read line: '.$line) ;
       }
       else $this->flog_append('Не удалось прочитать XLS файл') ;
       $this->flog_append('parse_xls_to_temp_table end') ;
    }

    function insert_arr_to_db_temp($table_fields,$arr)
    {   $sql='REPLACE INTO '.$this->table.' ('.$table_fields.') VALUES '.implode(', ',$arr).';' ;
        execSQL_update($sql,array('debug'=>0)) ;
    }

    function check_db_fields_names($text)
    {  $text=trim($text) ;
       $text=stripslashes($text) ;
       $text=strip_tags($text) ;
       $text=translit($text) ;
       //$text=iconv('utf-8','ASCII//TRANSLIT',$text) ;
       // удаляем вредные символы
    
       $text=str_replace(array("\\",'/','"',"'",'`',',','.','+','?','&','#','%','<','>','-','(',')','=','!','[',']',':'),'',$text) ;
       $text=trim($text) ;
       // заменяем подряд следующие пробелы ( в том числе переносы строк и табуляторы) на символ-заменитель пробела
       $text=preg_replace('/\s+/','_',$text) ;
       $text=preg_replace('/\-+/','_',$text) ;
       //echo  $text.'<br>' ;
    
       return($text) ;
    }


    function flog_append($text)
    {
      FILE_LOG()->append($text);
    }
  
}

?>
