Commit 9d9d876f6da4cd6db3f35e570a0fe0200211ddd1

Authored by Mihail
1 parent 08aff3b4

add xlsx parser iterrator

common/components/parsers/config.php
... ... @@ -13,7 +13,8 @@
13 13 'auto_detect_first_line' => true,
14 14 'converter_conf' => [
15 15 'class' => ' common\components\parsers\CustomConverter',
16   - 'configuration' => ["string" => 'DESCR',
  16 + 'configuration' => ["encode" => 'DESCR',
  17 + "string" => 'DESCR',
17 18 "float" => 'PRICE',
18 19 "brand" => 'BRAND',
19 20 "integer" => ['BOX','ADD_BOX'],
... ... @@ -72,7 +73,9 @@
72 73 'path_for_extract_files' => \Yii::getAlias('@temp_upload') . '/',
73 74 'converter_conf' => [
74 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 64  
65 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 119 $arr_config = $configuration['configuration'];
110 120 unset($configuration['configuration']);
111 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 38  
39 39 public function setup()
40 40 {
41   -
42 41 $this->setupConverter();
43   -
44 42 }
45 43  
46 44 protected function setupConverter()
... ... @@ -50,13 +48,16 @@ abstract class Parser
50 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 63 public abstract function read();
... ... @@ -68,6 +69,7 @@ abstract class Parser
68 69 */
69 70 protected function convert( $arr )
70 71 {
  72 +
71 73 if ($this->converter !== NULL) {
72 74  
73 75 $arr = $this->converter->convertByConfiguration( $arr, $this->converter_conf );
... ...
vendor/yiisoft/multiparser/TableParser.php
... ... @@ -66,13 +66,12 @@ abstract class TableParser extends Parser {
66 66 // прочтем строку из файла
67 67 $this->readRow();
68 68  
69   -
70   -
71 69 if ( $this->isEmptyRow() ) {
72 70 //счетчик пустых строк
73 71 $empty_lines++;
74 72 continue;
75 73 }
  74 +
76 75 // уберем пустые колонки из ряда
77 76 $this->filterRow();
78 77  
... ... @@ -84,7 +83,7 @@ abstract class TableParser extends Parser {
84 83  
85 84 // для первой строки утановим ключи из заголовка
86 85 $this->setKeysFromHeader();
87   -
  86 +
88 87 // если у нас установлен лимит, при его достижении прекращаем парсинг
89 88 if ( $this->isLastLine() )
90 89 break;
... ... @@ -93,12 +92,12 @@ abstract class TableParser extends Parser {
93 92 $empty_lines = 0;
94 93  
95 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 124 */
126 125 protected function adjustRowToSettings( )
127 126 {
  127 +
128 128 // если есть заголовок, то перед конвертацией его нужно назначить
129 129 if ( $this->keys !== NULL ) {
130 130  
... ... @@ -155,11 +155,13 @@ abstract class TableParser extends Parser {
155 155 }
156 156 }
157 157 }
  158 +
158 159 protected function filterRow(){
159 160 $this->row = array_filter( $this->row, function($val){
160 161 return !$this->isEmptyColumn($val);
161 162 });
162 163 }
  164 +
163 165 protected function isLastLine(){
164 166  
165 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 16 * Class XlsxParser
17 17 * @package yii\multiparser
18 18 */
19   -class XlsxParser extends Parser {
  19 +class XlsxParser extends TableParser {
20 20  
21 21 /**
22 22 * @var string - путь куда будут распаковываться файлы, если не указанно - во временный каталог сервера
23 23 */
24 24 public $path_for_extract_files = '';
25   - /** @var bool
26   - имеет ли файл заголовок который будет установлен ключами возвращемого массива*/
27   - public $hasHeaderRow = false;
  25 +
28 26  
29 27 /**
30 28 * @var int - если указано то считывание будет производиться с этого листа, иначе со всех листов
... ... @@ -34,11 +32,15 @@ class XlsxParser extends Parser {
34 32  
35 33 protected $strings_arr = [];
36 34 protected $sheets_arr = [];
37   - protected $result_arr = [];
  35 +
  36 + protected $current_node;
  37 + protected $current_sheet;
38 38  
39 39 public function setup()
40 40 {
  41 +
41 42 parent::setup();
  43 +
42 44 if ( $this->path_for_extract_files == '' ) {
43 45 $this->path_for_extract_files = sys_get_temp_dir();
44 46 }
... ... @@ -52,9 +54,23 @@ class XlsxParser extends Parser {
52 54  
53 55 $this->readSheets();
54 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 74 // return $this->$result_arr;
59 75 }
60 76  
... ... @@ -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 131 $attr = $child->attributes();
134 132  
135 133 if( isset($child->v) ) {
136 134 $value = (string)$child->v;
137 135 }else{
138   - $value = false;
  136 + $value = '';
139 137 }
140 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 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 179 \ No newline at end of file
... ...