Commit 9d9d876f6da4cd6db3f35e570a0fe0200211ddd1

Authored by Mihail
1 parent 08aff3b4

add xlsx parser iterrator

common/components/parsers/config.php
@@ -13,7 +13,8 @@ @@ -13,7 +13,8 @@
13 'auto_detect_first_line' => true, 13 'auto_detect_first_line' => true,
14 'converter_conf' => [ 14 'converter_conf' => [
15 'class' => ' common\components\parsers\CustomConverter', 15 'class' => ' common\components\parsers\CustomConverter',
16 - 'configuration' => ["string" => 'DESCR', 16 + 'configuration' => ["encode" => 'DESCR',
  17 + "string" => 'DESCR',
17 "float" => 'PRICE', 18 "float" => 'PRICE',
18 "brand" => 'BRAND', 19 "brand" => 'BRAND',
19 "integer" => ['BOX','ADD_BOX'], 20 "integer" => ['BOX','ADD_BOX'],
@@ -72,7 +73,9 @@ @@ -72,7 +73,9 @@
72 'path_for_extract_files' => \Yii::getAlias('@temp_upload') . '/', 73 'path_for_extract_files' => \Yii::getAlias('@temp_upload') . '/',
73 'converter_conf' => [ 74 'converter_conf' => [
74 'class' => 'common\components\parsers\CustomConverter', 75 'class' => 'common\components\parsers\CustomConverter',
75 - 'configuration' => ["encode" => 'DESCR'],] 76 + 'hasHeaderRow' => true,
  77 + 'configuration' => ["string" => []],
  78 + ]
76 ], 79 ],
77 ] 80 ]
78 ]; 81 ];
vendor/yiisoft/multiparser/Converter.php
@@ -64,9 +64,19 @@ class Converter implements ConverterInterface @@ -64,9 +64,19 @@ class Converter implements ConverterInterface
64 64
65 public static function convertToString($value) 65 public static function convertToString($value)
66 { 66 {
67 - $value = self::convertToEncode($value); 67 + $convert_func = function ($value_to_convert) {
  68 + return str_replace(array('!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', '=', '-', '~', '`', '"', "'", ' ', '№', '%', ';', ':', '[', ']', '{', '}', '*', '?', '/', '\'', '|', '.', ',', '<', '>', '\\'), '', $value_to_convert);
  69 + };
68 70
69 - return str_replace(array('!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', '=', '-', '~', '`', '"', "'", ' ', '№', '%', ';', ':', '[', ']', '{', '}', '*', '?', '/', '\'', '|', '.', ',', '<', '>', '\\'), '', $value); 71 + if( is_string( $value ) ){
  72 + $value = $convert_func( $value );
  73 + }
  74 +
  75 + if( is_array( $value ) ){
  76 + array_walk( $value, $convert_func );
  77 + }
  78 +
  79 + return $value;
70 } 80 }
71 81
72 /** 82 /**
@@ -109,7 +119,7 @@ class Converter implements ConverterInterface @@ -109,7 +119,7 @@ class Converter implements ConverterInterface
109 $arr_config = $configuration['configuration']; 119 $arr_config = $configuration['configuration'];
110 unset($configuration['configuration']); 120 unset($configuration['configuration']);
111 } else { 121 } else {
112 - throw new \ErrorException('Не указан обязательный параметр конфигурационного файла - converter_conf[configuration]'); 122 + throw new \Exception('Не указан обязательный параметр конфигурационного файла - converter_conf[configuration]');
113 } 123 }
114 124
115 // проставим аттрибуты из конфига{}{} 125 // проставим аттрибуты из конфига{}{}
vendor/yiisoft/multiparser/Parser.php
@@ -38,9 +38,7 @@ abstract class Parser @@ -38,9 +38,7 @@ abstract class Parser
38 38
39 public function setup() 39 public function setup()
40 { 40 {
41 -  
42 $this->setupConverter(); 41 $this->setupConverter();
43 -  
44 } 42 }
45 43
46 protected function setupConverter() 44 protected function setupConverter()
@@ -50,13 +48,16 @@ abstract class Parser @@ -50,13 +48,16 @@ abstract class Parser
50 $this->converter_conf['hasKey'] = 1; 48 $this->converter_conf['hasKey'] = 1;
51 } 49 }
52 50
53 - $converter = ObjectCreator::build( $this->converter_conf );  
54 - if ( $converter instanceof ConverterInterface ) { 51 + if ( $this->converter_conf ) {
  52 + $converter = ObjectCreator::build( $this->converter_conf );
  53 + if ( $converter instanceof ConverterInterface ) {
55 54
56 - $this->converter = $converter; 55 + $this->converter = $converter;
57 56
  57 + }
58 } 58 }
59 59
  60 +
60 } 61 }
61 62
62 public abstract function read(); 63 public abstract function read();
@@ -68,6 +69,7 @@ abstract class Parser @@ -68,6 +69,7 @@ abstract class Parser
68 */ 69 */
69 protected function convert( $arr ) 70 protected function convert( $arr )
70 { 71 {
  72 +
71 if ($this->converter !== NULL) { 73 if ($this->converter !== NULL) {
72 74
73 $arr = $this->converter->convertByConfiguration( $arr, $this->converter_conf ); 75 $arr = $this->converter->convertByConfiguration( $arr, $this->converter_conf );
vendor/yiisoft/multiparser/TableParser.php
@@ -66,13 +66,12 @@ abstract class TableParser extends Parser { @@ -66,13 +66,12 @@ abstract class TableParser extends Parser {
66 // прочтем строку из файла 66 // прочтем строку из файла
67 $this->readRow(); 67 $this->readRow();
68 68
69 -  
70 -  
71 if ( $this->isEmptyRow() ) { 69 if ( $this->isEmptyRow() ) {
72 //счетчик пустых строк 70 //счетчик пустых строк
73 $empty_lines++; 71 $empty_lines++;
74 continue; 72 continue;
75 } 73 }
  74 +
76 // уберем пустые колонки из ряда 75 // уберем пустые колонки из ряда
77 $this->filterRow(); 76 $this->filterRow();
78 77
@@ -84,7 +83,7 @@ abstract class TableParser extends Parser { @@ -84,7 +83,7 @@ abstract class TableParser extends Parser {
84 83
85 // для первой строки утановим ключи из заголовка 84 // для первой строки утановим ключи из заголовка
86 $this->setKeysFromHeader(); 85 $this->setKeysFromHeader();
87 - 86 +
88 // если у нас установлен лимит, при его достижении прекращаем парсинг 87 // если у нас установлен лимит, при его достижении прекращаем парсинг
89 if ( $this->isLastLine() ) 88 if ( $this->isLastLine() )
90 break; 89 break;
@@ -93,12 +92,12 @@ abstract class TableParser extends Parser { @@ -93,12 +92,12 @@ abstract class TableParser extends Parser {
93 $empty_lines = 0; 92 $empty_lines = 0;
94 93
95 $this->result[] = $this->row; 94 $this->result[] = $this->row;
  95 + $this->row = [];
  96 +
96 } 97 }
97 98
98 99
99 } 100 }
100 -  
101 -  
102 /** 101 /**
103 * определяет первую значимую строку, 102 * определяет первую значимую строку,
104 * считывается файл пока в нем не встретится строка с непустыми колонками 103 * считывается файл пока в нем не встретится строка с непустыми колонками
@@ -125,6 +124,7 @@ abstract class TableParser extends Parser { @@ -125,6 +124,7 @@ abstract class TableParser extends Parser {
125 */ 124 */
126 protected function adjustRowToSettings( ) 125 protected function adjustRowToSettings( )
127 { 126 {
  127 +
128 // если есть заголовок, то перед конвертацией его нужно назначить 128 // если есть заголовок, то перед конвертацией его нужно назначить
129 if ( $this->keys !== NULL ) { 129 if ( $this->keys !== NULL ) {
130 130
@@ -155,11 +155,13 @@ abstract class TableParser extends Parser { @@ -155,11 +155,13 @@ abstract class TableParser extends Parser {
155 } 155 }
156 } 156 }
157 } 157 }
  158 +
158 protected function filterRow(){ 159 protected function filterRow(){
159 $this->row = array_filter( $this->row, function($val){ 160 $this->row = array_filter( $this->row, function($val){
160 return !$this->isEmptyColumn($val); 161 return !$this->isEmptyColumn($val);
161 }); 162 });
162 } 163 }
  164 +
163 protected function isLastLine(){ 165 protected function isLastLine(){
164 166
165 if ( ( $this->last_line ) && ( $this->current_row_number > $this->last_line ) ) { 167 if ( ( $this->last_line ) && ( $this->current_row_number > $this->last_line ) ) {
vendor/yiisoft/multiparser/XlsxParser.php
@@ -16,15 +16,13 @@ use common\components\CustomVarDamp; @@ -16,15 +16,13 @@ use common\components\CustomVarDamp;
16 * Class XlsxParser 16 * Class XlsxParser
17 * @package yii\multiparser 17 * @package yii\multiparser
18 */ 18 */
19 -class XlsxParser extends Parser { 19 +class XlsxParser extends TableParser {
20 20
21 /** 21 /**
22 * @var string - путь куда будут распаковываться файлы, если не указанно - во временный каталог сервера 22 * @var string - путь куда будут распаковываться файлы, если не указанно - во временный каталог сервера
23 */ 23 */
24 public $path_for_extract_files = ''; 24 public $path_for_extract_files = '';
25 - /** @var bool  
26 - имеет ли файл заголовок который будет установлен ключами возвращемого массива*/  
27 - public $hasHeaderRow = false; 25 +
28 26
29 /** 27 /**
30 * @var int - если указано то считывание будет производиться с этого листа, иначе со всех листов 28 * @var int - если указано то считывание будет производиться с этого листа, иначе со всех листов
@@ -34,11 +32,15 @@ class XlsxParser extends Parser { @@ -34,11 +32,15 @@ class XlsxParser extends Parser {
34 32
35 protected $strings_arr = []; 33 protected $strings_arr = [];
36 protected $sheets_arr = []; 34 protected $sheets_arr = [];
37 - protected $result_arr = []; 35 +
  36 + protected $current_node;
  37 + protected $current_sheet;
38 38
39 public function setup() 39 public function setup()
40 { 40 {
  41 +
41 parent::setup(); 42 parent::setup();
  43 +
42 if ( $this->path_for_extract_files == '' ) { 44 if ( $this->path_for_extract_files == '' ) {
43 $this->path_for_extract_files = sys_get_temp_dir(); 45 $this->path_for_extract_files = sys_get_temp_dir();
44 } 46 }
@@ -52,9 +54,23 @@ class XlsxParser extends Parser { @@ -52,9 +54,23 @@ class XlsxParser extends Parser {
52 54
53 $this->readSheets(); 55 $this->readSheets();
54 $this->readStrings(); 56 $this->readStrings();
55 - $this->readValues();  
56 57
57 - CustomVarDamp::dumpAndDie($this->result_arr); 58 + foreach ( $this->sheets_arr as $sheet ) {
  59 + //проходим по всем файлам из директории /xl/worksheets/
  60 +
  61 + $sheet_path = $this->path_for_extract_files . '/xl/worksheets/' . $sheet . '.xml';
  62 + if ( file_exists( $sheet_path ) && is_readable( $sheet_path ) ) {
  63 +
  64 + $xml = simplexml_load_file( $sheet_path, "SimpleXMLIterator" );
  65 + $this->current_node = $xml->sheetData->row;
  66 + $this->current_node->rewind();
  67 +
  68 + parent::read();
  69 +
  70 + }
  71 +
  72 + }
  73 +CustomVarDamp::dumpAndDie($this->$result);
58 // return $this->$result_arr; 74 // return $this->$result_arr;
59 } 75 }
60 76
@@ -104,46 +120,59 @@ class XlsxParser extends Parser { @@ -104,46 +120,59 @@ class XlsxParser extends Parser {
104 } 120 }
105 } 121 }
106 122
107 - protected function readValues ()  
108 - {  
109 - //foreach ( glob($this->path_for_extract_files . '/xl/worksheets/*.xml' ) as $sheet ) {  
110 - foreach ( $this->sheets_arr as $sheet ) {  
111 - //проходим по всем файлам из директории /xl/worksheets/  
112 - //CustomVarDamp::dumpAndDie($sheet);  
113 - $sheet_path = $this->path_for_extract_files . '/xl/worksheets/' . $sheet . '.xml';  
114 - if ( file_exists( $sheet_path ) && is_readable( $sheet_path ) ) {  
115 - $xml = simplexml_load_file( $sheet_path );  
116 - //по каждой строке  
117 - $current_row = 0;  
118 -  
119 - foreach ( $xml->sheetData->row as $row_values ) {  
120 - $this->readRowValues( $row_values, $sheet , $current_row );  
121 - $current_row++;  
122 - }  
123 - }  
124 - }  
125 - }  
126 123
127 - protected function readRowValues ( $item, $sheet , $current_row ) 124 +
  125 + // protected function readRow ( $item, $sheet , $current_row )
  126 + protected function readRow ( )
128 { 127 {
129 - $this->result_arr[$sheet][$current_row] = array();  
130 - //по каждой ячейке строки  
131 - $cell = 0;  
132 - foreach ( $item as $child ) { 128 + $node = $this->current_node->getChildren();
  129 +
  130 + foreach ( $node as $child ) {
133 $attr = $child->attributes(); 131 $attr = $child->attributes();
134 132
135 if( isset($child->v) ) { 133 if( isset($child->v) ) {
136 $value = (string)$child->v; 134 $value = (string)$child->v;
137 }else{ 135 }else{
138 - $value = false; 136 + $value = '';
139 } 137 }
140 if ( isset( $attr['t'] ) ) { 138 if ( isset( $attr['t'] ) ) {
141 - $this->result_arr[$sheet][$current_row][$cell] = $this->strings_arr[ $value ]; 139 + // $this->result_arr[$sheet][$current_row][$cell] = $this->strings_arr[ $value ];
  140 + $this->row[] = $this->strings_arr[ $value ];
142 }else{ 141 }else{
143 - $this->result_arr[$sheet][$current_row][$cell] = $value; 142 + // $this->result_arr[$sheet][$current_row][$cell] = $value;
  143 + $this->row[] = $value;
144 } 144 }
145 - $cell++; 145 +
146 } 146 }
  147 + $this->current_node->next();
  148 + CustomVarDamp::dump($this->row);
  149 + }
  150 +
  151 + protected function isEmptyRow(){
  152 +
  153 + $is_empty = false;
  154 +
  155 + if ( !count( $this->row ) || !$this->current_node->valid() ) {
  156 + return true;
  157 + }
  158 +
  159 + $j = 0;
  160 + for ($i = 1; $i <= count( $this->row ); $i++) {
  161 +
  162 + if ( $this->isEmptyColumn( $this->row[$i - 1] ) ) {
  163 + $j++;
  164 + }
  165 +
  166 + if ( $j >= $this->min_column_quantity ) {
  167 + $is_empty = true;
  168 + break;
  169 + }
  170 + }
  171 +
  172 + return $is_empty;
  173 + }
147 174
  175 + protected function isEmptyColumn( $val ){
  176 + return $val == '';
148 } 177 }
149 } 178 }
150 \ No newline at end of file 179 \ No newline at end of file