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 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
... ...