Commit 90ff40df3f4c57aea54440ee58572c4fdbbf16e8

Authored by Mihail
1 parent df1a5df8

fixed issue with xml parser - redid in universul manner

backend/controllers/ParserController.php
@@ -52,6 +52,8 @@ class ParserController extends BaseController @@ -52,6 +52,8 @@ class ParserController extends BaseController
52 52
53 public function actionIndex($mode = 0) 53 public function actionIndex($mode = 0)
54 { 54 {
  55 +// $path = 'common\components\parsers\CustomConverter';
  56 +// CustomVarDamp::dumpAndDie(new $path());
55 $model = new UploadFileParsingForm(); 57 $model = new UploadFileParsingForm();
56 // установим режим, 0 - ручная загрузка, 1 - автозагрузка 58 // установим режим, 0 - ручная загрузка, 1 - автозагрузка
57 $model->mode = $mode; 59 $model->mode = $mode;
@@ -81,7 +83,6 @@ class ParserController extends BaseController @@ -81,7 +83,6 @@ class ParserController extends BaseController
81 try { 83 try {
82 $files_model->save(); 84 $files_model->save();
83 } catch (ErrorException $e) { 85 } catch (ErrorException $e) {
84 - // CustomVarDamp::dump($e->getMessage());  
85 throw $e; 86 throw $e;
86 } 87 }
87 // получим id только что записанной записи - его запишем в название файла 88 // получим id только что записанной записи - его запишем в название файла
backend/models/UploadFileParsingForm.php
@@ -71,12 +71,14 @@ class UploadFileParsingForm extends Model @@ -71,12 +71,14 @@ class UploadFileParsingForm extends Model
71 public function readFile( $options = [] ){ 71 public function readFile( $options = [] ){
72 72
73 $data = Yii::$app->multiparser->parse( $this->file_path, $options ); 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 throw new ErrorException("Ошибка чтения из файла прайса {$this->file_path}"); 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 return $data; 83 return $data;
82 } 84 }
common/components/parsers/config.php
@@ -14,7 +14,6 @@ @@ -14,7 +14,6 @@
14 'hasHeaderRow' => true, 14 'hasHeaderRow' => true,
15 'converter_conf' => [ 15 'converter_conf' => [
16 'class' => ' common\components\parsers\CustomConverter', 16 'class' => ' common\components\parsers\CustomConverter',
17 - 'hasKey' => 1,  
18 'configuration' => ["string" => 'DESCR', 17 'configuration' => ["string" => 'DESCR',
19 "float" => 'PRICE', 18 "float" => 'PRICE',
20 "brand" => 'BRAND', 19 "brand" => 'BRAND',
@@ -54,21 +53,40 @@ @@ -54,21 +53,40 @@
54 ['console' => 53 ['console' =>
55 ['class' => 'yii\multiparser\XmlParser', 54 ['class' => 'yii\multiparser\XmlParser',
56 'node' => 'Товар', 55 'node' => 'Товар',
  56 + 'hasHeaderRow' => true,
  57 + 'keys' => [
  58 + "BRAND" => 'Производитель',
  59 + "ARTICLE"=> 'Код',
  60 + "PRICE" => 'Розница',
  61 + "DESCR" => 'Наименование',
  62 + "BOX" => 'Колво',
  63 + "ADD_BOX"=> 'Ожидаемое',
  64 + "GROUP" => 'Группа'
  65 + ],
57 'converter_conf' => [ 66 'converter_conf' => [
58 - 'class' => ' common\components\parsers\CustomConverter',  
59 - 'hasKey' => 1, 67 + 'class' => 'common\components\parsers\CustomConverter',
60 'configuration' => ["details" => [] 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,7 +18,7 @@ class CsvParser extends Parser
18 public $hasHeaderRow = false; 18 public $hasHeaderRow = false;
19 /** @var array - массив с заголовком, 19 /** @var array - массив с заголовком,
20 * если не указан и установлено свойство $hasHeaderRow - будет определен автоматически */ 20 * если не указан и установлено свойство $hasHeaderRow - будет определен автоматически */
21 - public $keys; 21 + // public $keys; - определен в родительском классе
22 22
23 /** @var экземляр SplFileObject читаемого файла */ 23 /** @var экземляр SplFileObject читаемого файла */
24 public $file; 24 public $file;
@@ -66,11 +66,6 @@ class CsvParser extends Parser @@ -66,11 +66,6 @@ class CsvParser extends Parser
66 $this->shiftToFirstValuableLine(); 66 $this->shiftToFirstValuableLine();
67 } 67 }
68 68
69 - if ($this->hasHeaderRow) {  
70 - // если у файла есть заголовок, то в результате имеем ассоциативный массив  
71 - $this->converter_conf['hasKey'] = 1;  
72 - }  
73 -  
74 parent::setup(); 69 parent::setup();
75 70
76 } 71 }
vendor/yiisoft/multiparser/ObjectCreator.php
@@ -14,7 +14,7 @@ use common\components\CustomVarDamp; @@ -14,7 +14,7 @@ use common\components\CustomVarDamp;
14 class ObjectCreator { 14 class ObjectCreator {
15 public static function build( array $configuration ){ 15 public static function build( array $configuration ){
16 if ( isset( $configuration['class'] ) ) { 16 if ( isset( $configuration['class'] ) ) {
17 - $class = $configuration['class']; 17 + $class = trim( $configuration['class'] );
18 unset( $configuration['class'] ); 18 unset( $configuration['class'] );
19 } else{ 19 } else{
20 throw new \ErrorException('Error configuration - undefined class'); 20 throw new \ErrorException('Error configuration - undefined class');
vendor/yiisoft/multiparser/Parser.php
@@ -13,6 +13,11 @@ abstract class Parser @@ -13,6 +13,11 @@ abstract class Parser
13 public $converter_conf = []; 13 public $converter_conf = [];
14 protected $converter = NULL; 14 protected $converter = NULL;
15 15
  16 + /** @var array - массив с заголовком,
  17 + * */
  18 + public $keys = NULL;
  19 + public $hasHeaderRow = false;
  20 +
16 public function setup() 21 public function setup()
17 { 22 {
18 $this->setupConverter(); 23 $this->setupConverter();
@@ -20,6 +25,11 @@ abstract class Parser @@ -20,6 +25,11 @@ abstract class Parser
20 25
21 protected function setupConverter() 26 protected function setupConverter()
22 { 27 {
  28 + if ($this->hasHeaderRow) {
  29 + // если у файла есть заголовок, то в результате имеем ассоциативный массив
  30 + $this->converter_conf['hasKey'] = 1;
  31 + }
  32 +
23 $converter = ObjectCreator::build( $this->converter_conf ); 33 $converter = ObjectCreator::build( $this->converter_conf );
24 if ( $converter instanceof ConverterInterface ) { 34 if ( $converter instanceof ConverterInterface ) {
25 35
vendor/yiisoft/multiparser/XmlParser.php
@@ -9,6 +9,9 @@ @@ -9,6 +9,9 @@
9 namespace yii\multiparser; 9 namespace yii\multiparser;
10 10
11 11
  12 +use common\components\CustomVarDamp;
  13 +use common\components\CustomArrayHelper;
  14 +
12 class XmlParser extends Parser{ 15 class XmlParser extends Parser{
13 /** @var экземляр SplFileObject читаемого файла */ 16 /** @var экземляр SplFileObject читаемого файла */
14 public $file; 17 public $file;
@@ -17,21 +20,13 @@ class XmlParser extends Parser{ @@ -17,21 +20,13 @@ class XmlParser extends Parser{
17 public function read() 20 public function read()
18 { 21 {
19 $file = $this->file; 22 $file = $this->file;
20 - $result = self::xmlToArray( $file->getPathname() ); 23 + $result = $this->xmlToArray( $file->getPathname() );
  24 +
21 if ( isset($this->node) ) { 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 return $result; 31 return $result;
37 } 32 }
@@ -44,12 +39,12 @@ class XmlParser extends Parser{ @@ -44,12 +39,12 @@ class XmlParser extends Parser{
44 * @param string $file_path 39 * @param string $file_path
45 * @return array 40 * @return array
46 */ 41 */
47 - protected static function xmlToArray( $file_path ) { 42 + protected function xmlToArray( $file_path ) {
48 43
49 try { 44 try {
50 $xml = new \SimpleXMLElement( $file_path, 0, true ); 45 $xml = new \SimpleXMLElement( $file_path, 0, true );
51 //\common\components\CustomVarDamp::dumpAndDie($xml->children()->children()); 46 //\common\components\CustomVarDamp::dumpAndDie($xml->children()->children());
52 - $result = self::recursiveXMLToArray( $xml ); 47 + $result = $this->recursiveXMLToArray( $xml );
53 } catch(Exception $ex) { 48 } catch(Exception $ex) {
54 49
55 throw $ex; 50 throw $ex;
@@ -66,26 +61,60 @@ class XmlParser extends Parser{ @@ -66,26 +61,60 @@ class XmlParser extends Parser{
66 * 61 *
67 * @return mixed 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 $attributes = $xml->attributes(); 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 $xml = get_object_vars($xml); 74 $xml = get_object_vars($xml);
77 } 75 }
78 76
79 - //\common\components\CustomVarDamp::dump($xml);  
80 if(is_array($xml)) { 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 foreach($xml as $key => $value) { 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 return (string) $xml; 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 \ No newline at end of file 121 \ No newline at end of file