Commit 90ff40df3f4c57aea54440ee58572c4fdbbf16e8
1 parent
df1a5df8
fixed issue with xml parser - redid in universul manner
Showing
7 changed files
with
104 additions
and
49 deletions
Show diff stats
backend/controllers/ParserController.php
... | ... | @@ -52,6 +52,8 @@ class ParserController extends BaseController |
52 | 52 | |
53 | 53 | public function actionIndex($mode = 0) |
54 | 54 | { |
55 | +// $path = 'common\components\parsers\CustomConverter'; | |
56 | +// CustomVarDamp::dumpAndDie(new $path()); | |
55 | 57 | $model = new UploadFileParsingForm(); |
56 | 58 | // установим режим, 0 - ручная загрузка, 1 - автозагрузка |
57 | 59 | $model->mode = $mode; |
... | ... | @@ -81,7 +83,6 @@ class ParserController extends BaseController |
81 | 83 | try { |
82 | 84 | $files_model->save(); |
83 | 85 | } catch (ErrorException $e) { |
84 | - // CustomVarDamp::dump($e->getMessage()); | |
85 | 86 | throw $e; |
86 | 87 | } |
87 | 88 | // получим id только что записанной записи - его запишем в название файла | ... | ... |
backend/models/UploadFileParsingForm.php
... | ... | @@ -71,12 +71,14 @@ class UploadFileParsingForm extends Model |
71 | 71 | public function readFile( $options = [] ){ |
72 | 72 | |
73 | 73 | $data = Yii::$app->multiparser->parse( $this->file_path, $options ); |
74 | - if( !is_array( $data ) ){ | |
74 | + CustomVarDamp::dumpAndDie($data); | |
75 | + if( !is_array( $data ) || count($data) == 0 ){ | |
75 | 76 | throw new ErrorException("Ошибка чтения из файла прайса {$this->file_path}"); |
76 | 77 | } |
77 | 78 | // файл больше не нужен - данные прочитаны и сохранены в кеш |
78 | -// if( file_exists($this->file_path) ) | |
79 | -// unlink($this->file_path); | |
79 | + if( file_exists($this->file_path) ) | |
80 | + //@ todo - перестало работать - нет доступа на удалениев этом сеансе, в следующем - файл удаляется - разобраться | |
81 | + //unlink( $this->file_path ); | |
80 | 82 | |
81 | 83 | return $data; |
82 | 84 | } | ... | ... |
common/components/parsers/config.php
... | ... | @@ -14,7 +14,6 @@ |
14 | 14 | 'hasHeaderRow' => true, |
15 | 15 | 'converter_conf' => [ |
16 | 16 | 'class' => ' common\components\parsers\CustomConverter', |
17 | - 'hasKey' => 1, | |
18 | 17 | 'configuration' => ["string" => 'DESCR', |
19 | 18 | "float" => 'PRICE', |
20 | 19 | "brand" => 'BRAND', |
... | ... | @@ -54,21 +53,40 @@ |
54 | 53 | ['console' => |
55 | 54 | ['class' => 'yii\multiparser\XmlParser', |
56 | 55 | 'node' => 'Товар', |
56 | + 'hasHeaderRow' => true, | |
57 | + 'keys' => [ | |
58 | + "BRAND" => 'Производитель', | |
59 | + "ARTICLE"=> 'Код', | |
60 | + "PRICE" => 'Розница', | |
61 | + "DESCR" => 'Наименование', | |
62 | + "BOX" => 'Колво', | |
63 | + "ADD_BOX"=> 'Ожидаемое', | |
64 | + "GROUP" => 'Группа' | |
65 | + ], | |
57 | 66 | 'converter_conf' => [ |
58 | - 'class' => ' common\components\parsers\CustomConverter', | |
59 | - 'hasKey' => 1, | |
67 | + 'class' => 'common\components\parsers\CustomConverter', | |
60 | 68 | 'configuration' => ["details" => [] |
61 | 69 | ],], |
62 | 70 | ], |
63 | - 'basic_column' => [ | |
64 | - "BRAND" => 'Производитель', | |
65 | - "ARTICLE"=> 'Код', | |
66 | - "PRICE" => 'Розница', | |
67 | - "DESCR" => 'Наименование', | |
68 | - "BOX" => 'Колво', | |
69 | - "ADD_BOX"=> 'Ожидаемое', | |
70 | - "GROUP" => 'Группа' | |
71 | - ], | |
71 | + 'web' => | |
72 | + ['class' => 'yii\multiparser\XmlParser', | |
73 | + 'node' => 'Товар', | |
74 | + 'hasHeaderRow' => true, | |
75 | + 'keys' => [ | |
76 | + "BRAND" => 'Производитель', | |
77 | + "ARTICLE"=> 'Код', | |
78 | + "PRICE" => 'Розница', | |
79 | + "DESCR" => 'Наименование', | |
80 | + "BOX" => 'Колво', | |
81 | + "ADD_BOX"=> 'Ожидаемое', | |
82 | + "GROUP" => 'Группа' | |
83 | + ], | |
84 | + 'converter_conf' => [ | |
85 | + 'class' => 'common\components\parsers\CustomConverter', | |
86 | + 'configuration' => ["details" => [] | |
87 | + ],], | |
88 | + ], | |
72 | 89 | ], |
90 | + | |
73 | 91 | ]; |
74 | 92 | ... | ... |
vendor/yiisoft/multiparser/CsvParser.php
... | ... | @@ -18,7 +18,7 @@ class CsvParser extends Parser |
18 | 18 | public $hasHeaderRow = false; |
19 | 19 | /** @var array - массив с заголовком, |
20 | 20 | * если не указан и установлено свойство $hasHeaderRow - будет определен автоматически */ |
21 | - public $keys; | |
21 | + // public $keys; - определен в родительском классе | |
22 | 22 | |
23 | 23 | /** @var экземляр SplFileObject читаемого файла */ |
24 | 24 | public $file; |
... | ... | @@ -66,11 +66,6 @@ class CsvParser extends Parser |
66 | 66 | $this->shiftToFirstValuableLine(); |
67 | 67 | } |
68 | 68 | |
69 | - if ($this->hasHeaderRow) { | |
70 | - // если у файла есть заголовок, то в результате имеем ассоциативный массив | |
71 | - $this->converter_conf['hasKey'] = 1; | |
72 | - } | |
73 | - | |
74 | 69 | parent::setup(); |
75 | 70 | |
76 | 71 | } | ... | ... |
vendor/yiisoft/multiparser/ObjectCreator.php
... | ... | @@ -14,7 +14,7 @@ use common\components\CustomVarDamp; |
14 | 14 | class ObjectCreator { |
15 | 15 | public static function build( array $configuration ){ |
16 | 16 | if ( isset( $configuration['class'] ) ) { |
17 | - $class = $configuration['class']; | |
17 | + $class = trim( $configuration['class'] ); | |
18 | 18 | unset( $configuration['class'] ); |
19 | 19 | } else{ |
20 | 20 | throw new \ErrorException('Error configuration - undefined class'); | ... | ... |
vendor/yiisoft/multiparser/Parser.php
... | ... | @@ -13,6 +13,11 @@ abstract class Parser |
13 | 13 | public $converter_conf = []; |
14 | 14 | protected $converter = NULL; |
15 | 15 | |
16 | + /** @var array - массив с заголовком, | |
17 | + * */ | |
18 | + public $keys = NULL; | |
19 | + public $hasHeaderRow = false; | |
20 | + | |
16 | 21 | public function setup() |
17 | 22 | { |
18 | 23 | $this->setupConverter(); |
... | ... | @@ -20,6 +25,11 @@ abstract class Parser |
20 | 25 | |
21 | 26 | protected function setupConverter() |
22 | 27 | { |
28 | + if ($this->hasHeaderRow) { | |
29 | + // если у файла есть заголовок, то в результате имеем ассоциативный массив | |
30 | + $this->converter_conf['hasKey'] = 1; | |
31 | + } | |
32 | + | |
23 | 33 | $converter = ObjectCreator::build( $this->converter_conf ); |
24 | 34 | if ( $converter instanceof ConverterInterface ) { |
25 | 35 | ... | ... |
vendor/yiisoft/multiparser/XmlParser.php
... | ... | @@ -9,6 +9,9 @@ |
9 | 9 | namespace yii\multiparser; |
10 | 10 | |
11 | 11 | |
12 | +use common\components\CustomVarDamp; | |
13 | +use common\components\CustomArrayHelper; | |
14 | + | |
12 | 15 | class XmlParser extends Parser{ |
13 | 16 | /** @var экземляр SplFileObject читаемого файла */ |
14 | 17 | public $file; |
... | ... | @@ -17,21 +20,13 @@ class XmlParser extends Parser{ |
17 | 20 | public function read() |
18 | 21 | { |
19 | 22 | $file = $this->file; |
20 | - $result = self::xmlToArray( $file->getPathname() ); | |
23 | + $result = $this->xmlToArray( $file->getPathname() ); | |
24 | + | |
21 | 25 | if ( isset($this->node) ) { |
22 | - $result = $result[$this->node]; | |
23 | - } | |
24 | 26 | |
25 | - //@todo переделать на универсальный способ, а для фрейма создать отдельный класс | |
26 | -// $key_column = \Yii::$app->multiparser->getConfiguration('xml','basic_column'); | |
27 | -// $key_column = array_flip($key_column); | |
28 | -// | |
29 | -// $result = \Yii::$app->multiparser->convertToAssocArray($result, $key_column); | |
30 | -// foreach ( $result as &$value ) { | |
31 | -// if (is_array($value)) { | |
32 | -// $value = \Yii::$app->multiparser->convertByConfiguration( $value, $this->converter_conf ); | |
33 | -// } | |
34 | -// } | |
27 | + $result = $result[ $this->node ]; | |
28 | + | |
29 | + } | |
35 | 30 | |
36 | 31 | return $result; |
37 | 32 | } |
... | ... | @@ -44,12 +39,12 @@ class XmlParser extends Parser{ |
44 | 39 | * @param string $file_path |
45 | 40 | * @return array |
46 | 41 | */ |
47 | - protected static function xmlToArray( $file_path ) { | |
42 | + protected function xmlToArray( $file_path ) { | |
48 | 43 | |
49 | 44 | try { |
50 | 45 | $xml = new \SimpleXMLElement( $file_path, 0, true ); |
51 | 46 | //\common\components\CustomVarDamp::dumpAndDie($xml->children()->children()); |
52 | - $result = self::recursiveXMLToArray( $xml ); | |
47 | + $result = $this->recursiveXMLToArray( $xml ); | |
53 | 48 | } catch(Exception $ex) { |
54 | 49 | |
55 | 50 | throw $ex; |
... | ... | @@ -66,26 +61,60 @@ class XmlParser extends Parser{ |
66 | 61 | * |
67 | 62 | * @return mixed |
68 | 63 | */ |
69 | - protected static function recursiveXMLToArray($xml) { | |
70 | - if(is_object($xml) && get_class($xml) == 'SimpleXMLElement') { | |
64 | + protected function recursiveXMLToArray($xml) { | |
65 | + if( $xml instanceof \SimpleXMLElement ) { | |
71 | 66 | $attributes = $xml->attributes(); |
72 | - foreach($attributes as $k => $v) { | |
73 | - if($v) $a[$k] = (string) $v; | |
67 | + | |
68 | + foreach( $attributes as $key => $value ) { | |
69 | + if( $value ) { | |
70 | + $attribute_array[$key] = (string) $value; | |
71 | + } | |
74 | 72 | } |
75 | - $x = $xml; | |
73 | + $previous_xml = $xml; | |
76 | 74 | $xml = get_object_vars($xml); |
77 | 75 | } |
78 | 76 | |
79 | - //\common\components\CustomVarDamp::dump($xml); | |
80 | 77 | if(is_array($xml)) { |
81 | - if(count($xml) == 0) return (string) $x; // for CDATA | |
78 | + | |
79 | + if( count($xml) == 0 ) | |
80 | + return (string) $previous_xml; // for CDATA | |
81 | + | |
82 | 82 | foreach($xml as $key => $value) { |
83 | - $r[$key] = self::recursiveXMLToArray($value); | |
83 | + $row[$key] = $this->recursiveXMLToArray($value); | |
84 | + } | |
85 | + if ( is_string($value) ) { | |
86 | + // дошли до конца рекурсии | |
87 | + // преобразуем ряд согласно конфигурации | |
88 | + if ( $this->keys !== NULL ) { | |
89 | + | |
90 | + // назначим ключи из конфигурации, согласно массиву $keys | |
91 | + $row = $this->compareArrayWithKeys( $row ); | |
92 | + } | |
93 | + $row = $this->convert( $row ); | |
94 | + | |
84 | 95 | } |
85 | - if(isset($a)) $r['@'] = $a; // Attributes | |
86 | - return $r; | |
96 | + | |
97 | + | |
98 | + if( isset( $attribute_array ) ) | |
99 | + $row['@'] = $attribute_array; // Attributes | |
100 | + | |
101 | + return $row; | |
87 | 102 | } |
88 | - //\common\components\CustomVarDamp::dumpAndDie($xml); | |
89 | 103 | return (string) $xml; |
90 | 104 | } |
105 | + | |
106 | + /** | |
107 | + * @param array $value_arr - текущий ряд, массив, которому нужно назначить конфигурационные ключи ($keys) | |
108 | + * @return array | |
109 | + */ | |
110 | + protected function compareArrayWithKeys( array $value_arr ){ | |
111 | + $res = $this->keys; | |
112 | + foreach ( $this->keys as $key => $value ) { | |
113 | + if ( array_key_exists( $value, $value_arr ) ) { | |
114 | + $res[$key] = $value_arr[$value]; | |
115 | + } | |
116 | + } | |
117 | + return $res; | |
118 | + } | |
119 | + | |
91 | 120 | } |
92 | 121 | \ No newline at end of file | ... | ... |