Commit 3c5edb9bd8f72114267e9fd71c810cdf78f19121
1 parent
474f35bf
edit createAssocArray function
Showing
20 changed files
with
739 additions
and
92 deletions
Show diff stats
backend/components/parsers/CustomCsvParser.php
| ... | ... | @@ -11,23 +11,20 @@ namespace backend\components\parsers; |
| 11 | 11 | |
| 12 | 12 | class CustomCsvParser extends \yii\multiparser\CsvParser { |
| 13 | 13 | |
| 14 | - //public $last_line = 10; | |
| 14 | + public $last_line = 10; | |
| 15 | 15 | //public $hasHeaderRow = true; |
| 16 | 16 | // public $keys = ['first','second', 'third', 'forth', 'fifth']; |
| 17 | - | |
| 18 | - | |
| 19 | - protected function readRow() | |
| 17 | + public function setupConverter() | |
| 20 | 18 | { |
| 21 | 19 | |
| 22 | - $row = parent::readRow(); | |
| 23 | - | |
| 24 | - if (is_array($row)) { | |
| 25 | - | |
| 26 | - $row = Encoder::encodeArray( Encoder::$in_charset, Encoder::$out_charset, $row ); | |
| 20 | + if ($this->hasHeaderRow) { | |
| 21 | + // если у файла есть заголовок, то в результате имеем ассоциативный массив | |
| 22 | + $this->converter_conf['hasKey'] = 1; | |
| 27 | 23 | } |
| 28 | 24 | |
| 29 | - return $row; | |
| 25 | + $this->converter = \Yii::createObject($this->converter_conf); | |
| 30 | 26 | |
| 31 | 27 | } |
| 32 | 28 | |
| 29 | + | |
| 33 | 30 | } |
| 34 | 31 | \ No newline at end of file | ... | ... |
| 1 | +<?php | |
| 2 | + return [ | |
| 3 | + 'csv' => | |
| 4 | + ['web' => | |
| 5 | + ['class' => 'backend\components\parsers\CustomCsvParser', | |
| 6 | + 'auto_detect_first_line' => true, | |
| 7 | + 'converter_conf' => ['class' => 'yii\multiparser\Converter', | |
| 8 | + 'configuration' => [ | |
| 9 | + "string" => 'DESCR' | |
| 10 | + ] | |
| 11 | + ,]], | |
| 12 | + | |
| 13 | + 'basic_column' => [ | |
| 14 | + Null => 'Пусто', | |
| 15 | + "BRAND" => 'Бренд', | |
| 16 | + "ARTICLE"=> 'Артикул', | |
| 17 | + "PRICE" => 'Цена', | |
| 18 | + "DESCR" => 'Наименование', | |
| 19 | + "BOX" => 'Колво', | |
| 20 | + "ADD_BOX"=> 'В пути', | |
| 21 | + "GROUP" => 'Группа RG' | |
| 22 | + ], | |
| 23 | + ], | |
| 24 | + 'xml' => | |
| 25 | + ['web' => | |
| 26 | + ['class' => 'yii\multiparser\XmlParser', | |
| 27 | + 'node' => 'Товар',], | |
| 28 | + | |
| 29 | + 'basic_column' => [ | |
| 30 | + "BRAND" => 'Производитель', | |
| 31 | + "ARTICLE"=> 'Код', | |
| 32 | + "PRICE" => 'Розница', | |
| 33 | + "DESCR" => 'Наименование', | |
| 34 | + "BOX" => 'Колво', | |
| 35 | + "ADD_BOX"=> 'Ожидаемое', | |
| 36 | + "GROUP" => 'Группа' | |
| 37 | + ], | |
| 38 | + ] | |
| 39 | + ]; | |
| 40 | + | |
| 41 | + | |
| 42 | +//[ | |
| 43 | +// "float" => 'PRICE', | |
| 44 | +// "integer" => ['BOX' , 'ADD_BOX' ], | |
| 45 | +// "prefix" => 'ARTICLE' | |
| 46 | +//] | |
| 0 | 47 | \ No newline at end of file | ... | ... |
backend/config/main.php
| ... | ... | @@ -5,6 +5,7 @@ $params = array_merge( |
| 5 | 5 | require(__DIR__ . '/params.php'), |
| 6 | 6 | require(__DIR__ . '/params-local.php') |
| 7 | 7 | ); |
| 8 | +$mp_configuration = require( __DIR__ . '/../components/parsers/config.php'); | |
| 8 | 9 | |
| 9 | 10 | return [ |
| 10 | 11 | 'id' => 'app-backend', |
| ... | ... | @@ -41,6 +42,7 @@ return [ |
| 41 | 42 | 'multiparser'=>[ |
| 42 | 43 | |
| 43 | 44 | 'class' => 'yii\multiparser\YiiMultiparser', |
| 45 | + 'configuration' => $mp_configuration, | |
| 44 | 46 | |
| 45 | 47 | ], |
| 46 | 48 | ], | ... | ... |
backend/controllers/ParserController.php
| ... | ... | @@ -8,7 +8,7 @@ use yii\filters\VerbFilter; |
| 8 | 8 | use backend\models\UploadFileParsingForm; |
| 9 | 9 | use yii\web\UploadedFile; |
| 10 | 10 | use yii\data\ArrayDataProvider; |
| 11 | -use backend\components\parsers\DynamicFormHelper; | |
| 11 | +use yii\multiparser\DynamicFormHelper; | |
| 12 | 12 | use backend\components\parsers\CustomParserConfigurator; |
| 13 | 13 | |
| 14 | 14 | use common\components\CustomVarDamp; |
| ... | ... | @@ -96,13 +96,14 @@ class ParserController extends BaseController |
| 96 | 96 | ], |
| 97 | 97 | ]); |
| 98 | 98 | |
| 99 | + // CustomVarDamp::dumpAndDie($data); | |
| 99 | 100 | $header_model = DynamicFormHelper::CreateDynamicModel( count( $data[0] ) ); |
| 100 | 101 | |
| 101 | - //CustomVarDamp::dumpAndDie($header_model); | |
| 102 | + // CustomVarDamp::dumpAndDie(Yii::$app->multiparser->getConfiguration('csv','basic_column')); | |
| 102 | 103 | return $this->render('results', |
| 103 | 104 | ['model' => $data, |
| 104 | 105 | 'header_model' => $header_model, |
| 105 | - 'basic_column' => CustomParserConfigurator::$basic_column, | |
| 106 | + 'basic_column' => Yii::$app->multiparser->getConfiguration('csv','basic_column'), | |
| 106 | 107 | 'dataProvider' => $provider]); |
| 107 | 108 | } |
| 108 | 109 | |
| ... | ... | @@ -113,12 +114,15 @@ public function actionWrite() |
| 113 | 114 | $arr_attributes = Yii::$app->request->post()['DynamicModel']; |
| 114 | 115 | $model = DynamicFormHelper::CreateDynamicModel( $arr_attributes ); |
| 115 | 116 | foreach ($arr_attributes as $key => $value) { |
| 116 | - $model->addRule($key, 'in', ['range' => array_keys( CustomParserConfigurator::$basic_column )]); | |
| 117 | + $model->addRule($key, 'in', ['range' => array_keys( Yii::$app->multiparser->getConfiguration('csv','basic_column') )]); | |
| 117 | 118 | } |
| 118 | 119 | |
| 119 | 120 | //CustomVarDamp::dumpAndDie($model); |
| 120 | 121 | if ($model->validate()) { |
| 121 | 122 | $arr = $model->toArray(); |
| 123 | + $data = json_decode( Yii::$app->getCache()->get( 'parser_data' ),true ); | |
| 124 | + | |
| 125 | + // CustomVarDamp::dumpAndDie(DynamicFormHelper::CreateAssocArray($data, $arr)); | |
| 122 | 126 | CustomVarDamp::dumpAndDie($arr); |
| 123 | 127 | } |
| 124 | 128 | ... | ... |
backend/models/UploadFileParsingForm.php
| ... | ... | @@ -52,7 +52,6 @@ class UploadFileParsingForm extends Model |
| 52 | 52 | public function readFile($filePath){ |
| 53 | 53 | |
| 54 | 54 | $data = Yii::$app->multiparser->parse($filePath); |
| 55 | - // \common\components\CustomVarDamp::dumpAndDie($data); | |
| 56 | 55 | if( !is_array($data) ){ |
| 57 | 56 | $data = ['No results']; |
| 58 | 57 | } | ... | ... |
backend/views/parser/results.php
| 1 | 1 | <?php |
| 2 | 2 | |
| 3 | 3 | use yii\helpers\Html; |
| 4 | -use backend\components\parsers\DynamicFormHelper; | |
| 4 | +use yii\multiparser\DynamicFormHelper; | |
| 5 | 5 | use yii\widgets\ActiveForm; |
| 6 | 6 | |
| 7 | 7 | |
| ... | ... | @@ -20,7 +20,7 @@ $this->params['breadcrumbs'][] = $this->title; |
| 20 | 20 | |
| 21 | 21 | $form = ActiveForm::begin(['action' => 'write']); |
| 22 | 22 | ?> |
| 23 | - <?= DynamicFormHelper::CreateDynamicGridViewWithDropDownListHeader( $dataProvider, $form, $header_model, $basic_column )?> | |
| 23 | + <?= DynamicFormHelper::CreateGridWithDropDownListHeader( $dataProvider, $form, $header_model, $basic_column )?> | |
| 24 | 24 | |
| 25 | 25 | <div class="form-group"> |
| 26 | 26 | <?= Html::submitButton(Yii::t('app', 'Записать в БД'), ['class' => 'btn btn-primary']) ?> | ... | ... |
common/components/CustomVarDamp.php
| ... | ... | @@ -17,10 +17,16 @@ class CustomVarDamp extends BaseVarDumper { |
| 17 | 17 | echo "</pre>"; |
| 18 | 18 | die; |
| 19 | 19 | } |
| 20 | - public static function dump($var, $depth = 10, $highlight = false) | |
| 20 | + public static function dump($var, $step = '', $depth = 10, $highlight = false) | |
| 21 | 21 | { |
| 22 | 22 | echo "<pre>"; |
| 23 | + if ($step) { | |
| 24 | + echo "-------------- {$step} -------------"; | |
| 25 | + } | |
| 23 | 26 | echo static::dumpAsString($var, $depth, $highlight); |
| 27 | + if ($step) { | |
| 28 | + echo "-------------- {$step} -------------"; | |
| 29 | + } | |
| 24 | 30 | echo "</pre>"; |
| 25 | 31 | |
| 26 | 32 | } | ... | ... |
| 1 | +<?php | |
| 2 | +/** | |
| 3 | + * Created by PhpStorm. | |
| 4 | + * User: Cibermag | |
| 5 | + * Date: 27.08.2015 | |
| 6 | + * Time: 16:47 | |
| 7 | + */ | |
| 8 | +namespace common\components\debug; | |
| 9 | +use yii\helpers\BaseVarDumper; | |
| 10 | + | |
| 11 | +class CustomVarDamp extends BaseVarDumper { | |
| 12 | + | |
| 13 | + public static function dumpAndDie($var, $depth = 10, $highlight = false) | |
| 14 | + { | |
| 15 | + echo "<pre>"; | |
| 16 | + echo static::dumpAsString($var, $depth, $highlight); | |
| 17 | + echo "</pre>"; | |
| 18 | + die; | |
| 19 | + } | |
| 20 | +} | |
| 0 | 21 | \ No newline at end of file | ... | ... |
framework/core/Convert.php
| ... | ... | @@ -166,63 +166,63 @@ class Convert { |
| 166 | 166 | } |
| 167 | 167 | |
| 168 | 168 | /** |
| 169 | - * Converts an XML string to a PHP array | |
| 170 | - * See http://phpsecurity.readthedocs.org/en/latest/Injection-Attacks.html#xml-external-entity-injection | |
| 171 | - * | |
| 172 | - * @uses recursiveXMLToArray() | |
| 173 | - * @param string $val | |
| 174 | - * @param boolean $disableDoctypes Disables the use of DOCTYPE, and will trigger an error if encountered. | |
| 175 | - * false by default. | |
| 176 | - * @param boolean $disableExternals Disables the loading of external entities. false by default. | |
| 177 | - * @return array | |
| 178 | - */ | |
| 179 | - public static function xml2array($val, $disableDoctypes = false, $disableExternals = false) { | |
| 180 | - // Check doctype | |
| 181 | - if($disableDoctypes && preg_match('/\<\!DOCTYPE.+]\>/', $val)) { | |
| 182 | - throw new InvalidArgumentException('XML Doctype parsing disabled'); | |
| 183 | - } | |
| 169 | + * Converts an XML string to a PHP array | |
| 170 | + * See http://phpsecurity.readthedocs.org/en/latest/Injection-Attacks.html#xml-external-entity-injection | |
| 171 | + * | |
| 172 | + * @uses recursiveXMLToArray() | |
| 173 | + * @param string $val | |
| 174 | + * @param boolean $disableDoctypes Disables the use of DOCTYPE, and will trigger an error if encountered. | |
| 175 | + * false by default. | |
| 176 | + * @param boolean $disableExternals Disables the loading of external entities. false by default. | |
| 177 | + * @return array | |
| 178 | + */ | |
| 179 | + public static function xml2array($val, $disableDoctypes = false, $disableExternals = false) { | |
| 180 | + // Check doctype | |
| 181 | + if($disableDoctypes && preg_match('/\<\!DOCTYPE.+]\>/', $val)) { | |
| 182 | + throw new InvalidArgumentException('XML Doctype parsing disabled'); | |
| 183 | + } | |
| 184 | 184 | |
| 185 | - // Disable external entity loading | |
| 186 | - if($disableExternals) $oldVal = libxml_disable_entity_loader($disableExternals); | |
| 187 | - try { | |
| 188 | - $xml = new SimpleXMLElement($val); | |
| 189 | - $result = self::recursiveXMLToArray($xml); | |
| 190 | - } catch(Exception $ex) { | |
| 191 | - if($disableExternals) libxml_disable_entity_loader($oldVal); | |
| 192 | - throw $ex; | |
| 193 | - } | |
| 194 | - if($disableExternals) libxml_disable_entity_loader($oldVal); | |
| 195 | - return $result; | |
| 196 | - } | |
| 185 | + // Disable external entity loading | |
| 186 | + if($disableExternals) $oldVal = libxml_disable_entity_loader($disableExternals); | |
| 187 | + try { | |
| 188 | + $xml = new SimpleXMLElement($val); | |
| 189 | + $result = self::recursiveXMLToArray($xml); | |
| 190 | + } catch(Exception $ex) { | |
| 191 | + if($disableExternals) libxml_disable_entity_loader($oldVal); | |
| 192 | + throw $ex; | |
| 193 | + } | |
| 194 | + if($disableExternals) libxml_disable_entity_loader($oldVal); | |
| 195 | + return $result; | |
| 196 | + } | |
| 197 | 197 | |
| 198 | - /** | |
| 199 | - * Convert a XML string to a PHP array recursively. Do not | |
| 200 | - * call this function directly, Please use {@link Convert::xml2array()} | |
| 201 | - * | |
| 202 | - * @param SimpleXMLElement | |
| 203 | - * | |
| 204 | - * @return mixed | |
| 205 | - */ | |
| 206 | - protected static function recursiveXMLToArray($xml) { | |
| 207 | - if(is_object($xml) && get_class($xml) == 'SimpleXMLElement') { | |
| 208 | - $attributes = $xml->attributes(); | |
| 209 | - foreach($attributes as $k => $v) { | |
| 210 | - if($v) $a[$k] = (string) $v; | |
| 211 | - } | |
| 212 | - $x = $xml; | |
| 213 | - $xml = get_object_vars($xml); | |
| 214 | - } | |
| 215 | - if(is_array($xml)) { | |
| 216 | - if(count($xml) == 0) return (string) $x; // for CDATA | |
| 217 | - foreach($xml as $key => $value) { | |
| 218 | - $r[$key] = self::recursiveXMLToArray($value); | |
| 219 | - } | |
| 220 | - if(isset($a)) $r['@'] = $a; // Attributes | |
| 221 | - return $r; | |
| 222 | - } | |
| 223 | - | |
| 224 | - return (string) $xml; | |
| 225 | - } | |
| 198 | + /** | |
| 199 | + * Convert a XML string to a PHP array recursively. Do not | |
| 200 | + * call this function directly, Please use {@link Convert::xml2array()} | |
| 201 | + * | |
| 202 | + * @param SimpleXMLElement | |
| 203 | + * | |
| 204 | + * @return mixed | |
| 205 | + */ | |
| 206 | + protected static function recursiveXMLToArray($xml) { | |
| 207 | + if(is_object($xml) && get_class($xml) == 'SimpleXMLElement') { | |
| 208 | + $attributes = $xml->attributes(); | |
| 209 | + foreach($attributes as $k => $v) { | |
| 210 | + if($v) $a[$k] = (string) $v; | |
| 211 | + } | |
| 212 | + $x = $xml; | |
| 213 | + $xml = get_object_vars($xml); | |
| 214 | + } | |
| 215 | + if(is_array($xml)) { | |
| 216 | + if(count($xml) == 0) return (string) $x; // for CDATA | |
| 217 | + foreach($xml as $key => $value) { | |
| 218 | + $r[$key] = self::recursiveXMLToArray($value); | |
| 219 | + } | |
| 220 | + if(isset($a)) $r['@'] = $a; // Attributes | |
| 221 | + return $r; | |
| 222 | + } | |
| 223 | + | |
| 224 | + return (string) $xml; | |
| 225 | + } | |
| 226 | 226 | |
| 227 | 227 | /** |
| 228 | 228 | * Create a link if the string is a valid URL | ... | ... |
| 1 | +<?php | |
| 2 | +/** | |
| 3 | +* Created by PhpStorm. | |
| 4 | + * User: Cibermag | |
| 5 | +* Date: 31.08.2015 | |
| 6 | +* Time: 12:50 | |
| 7 | +*/ | |
| 8 | + | |
| 9 | +namespace yii\multiparser; | |
| 10 | + | |
| 11 | +// класс который содержит преобразователи значений (фильтры) используемые при парсинге | |
| 12 | +class Converter | |
| 13 | +{ | |
| 14 | + | |
| 15 | + const METHOD_PREFIX = 'convertTo'; | |
| 16 | + | |
| 17 | + public $configuration = []; | |
| 18 | + | |
| 19 | + protected static function convertToFloat($value) | |
| 20 | + { | |
| 21 | + | |
| 22 | + if ($value == '') { | |
| 23 | + $value = 0; | |
| 24 | + } | |
| 25 | + $value = trim(str_replace(",", ".", $value)); | |
| 26 | + $value = preg_replace("/[^0-9.]+/", "", strtoupper($value)); | |
| 27 | + | |
| 28 | + if ($value == '') { | |
| 29 | + return ''; | |
| 30 | + } | |
| 31 | + $value = round( (float)$value, 2 ); | |
| 32 | + | |
| 33 | + return $value; | |
| 34 | + } | |
| 35 | + | |
| 36 | + protected static function convertToInteger($value) | |
| 37 | + { | |
| 38 | + if ($value == '') { | |
| 39 | + $value = 0; | |
| 40 | + } | |
| 41 | + $value = trim(str_replace(",", ".", $value)); | |
| 42 | + $value = preg_replace("/[^0-9.]+/", "", strtoupper($value)); | |
| 43 | + if ($value == '') { | |
| 44 | + return ''; | |
| 45 | + } | |
| 46 | + $value = round((int)$value, 2); | |
| 47 | + | |
| 48 | + return $value; | |
| 49 | + } | |
| 50 | + | |
| 51 | + protected static function convertToString($value) | |
| 52 | + { | |
| 53 | + | |
| 54 | + $res = ''; | |
| 55 | + if (is_array($value)) { | |
| 56 | + | |
| 57 | + $res = Encoder::encodeArray($value); | |
| 58 | + | |
| 59 | + }elseif ( is_string($value) ) { | |
| 60 | + | |
| 61 | + $res = Encoder::encodeString($value); | |
| 62 | + | |
| 63 | + } | |
| 64 | + | |
| 65 | + return $res; | |
| 66 | + } | |
| 67 | + | |
| 68 | +// protected static function convertToAssocArray($arr) | |
| 69 | +// { | |
| 70 | +// | |
| 71 | +// $res = ''; | |
| 72 | +// if (is_array($value)) { | |
| 73 | +// | |
| 74 | +// $res = Encoder::encodeArray($value); | |
| 75 | +// | |
| 76 | +// }elseif ( is_string($value) ) { | |
| 77 | +// | |
| 78 | +// $res = Encoder::encodeString($value); | |
| 79 | +// | |
| 80 | +// } | |
| 81 | +// | |
| 82 | +// return $res; | |
| 83 | +// } | |
| 84 | + | |
| 85 | + /** | |
| 86 | + * @param $name - имя метода конвертации | |
| 87 | + * @param $value - значение на конвертацию | |
| 88 | + * @return mixed | |
| 89 | + */ | |
| 90 | + public static function __callStatic( $name, $value ) | |
| 91 | + { | |
| 92 | + $method_name = self::METHOD_PREFIX . $name; | |
| 93 | + if ( method_exists( self::class ,$method_name ) ) { | |
| 94 | + | |
| 95 | + return self::$method_name( $value[0] ); | |
| 96 | + | |
| 97 | + } else{ | |
| 98 | + // если такого метода конвертации не предусмотрено, то возвращаем не конвертируя | |
| 99 | + return $value[0]; | |
| 100 | + | |
| 101 | + } | |
| 102 | + } | |
| 103 | + | |
| 104 | + | |
| 105 | + /** | |
| 106 | + * @param $arr - массив | |
| 107 | + * @return mixed | |
| 108 | + * конвертирует массив по полученным настройкам, вызывая последовательно функции конвертации (указанные в конфигурации) | |
| 109 | + */ | |
| 110 | + public function convertByConfiguration( $arr ) | |
| 111 | + { | |
| 112 | + $result = $arr; | |
| 113 | + | |
| 114 | + $hasKey = isset( $this->configuration['hasKey'] ); | |
| 115 | + foreach ( $this->configuration as $key => $value ) { | |
| 116 | + | |
| 117 | + if ( $hasKey ){ | |
| 118 | + // у нас ассоциативный массив, и мы можем конвертировать каждое значение в отдельности | |
| 119 | + if ( is_array( $value ) ) { | |
| 120 | + foreach ($value as $sub_value) { | |
| 121 | + if (isset($arr[$sub_value])) { | |
| 122 | + // конвертируем только те ячейки которые сопоставлены в прочитанном массиве с колонками в конфигурационном файле | |
| 123 | + $result[$arr[$sub_value]] = self::$key( $arr[$sub_value] ); | |
| 124 | + } | |
| 125 | + | |
| 126 | + } | |
| 127 | + } else { | |
| 128 | + | |
| 129 | + if (isset($arr[$value])) { | |
| 130 | + // конвертируем только те ячейки которые сопоставлены в прочитанном массиве с колонками в конфигурационном файле | |
| 131 | + $result[$arr[$value]] = self::$key( $arr[$value] ); | |
| 132 | + } | |
| 133 | + | |
| 134 | + } | |
| 135 | + | |
| 136 | + } else { | |
| 137 | + // нет заголовка - мы можем конвертировать только строку в целом | |
| 138 | + $result = self::$key( $arr ); | |
| 139 | + } | |
| 140 | + | |
| 141 | + } | |
| 142 | + | |
| 143 | + return $result; | |
| 144 | + } | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | +} | |
| 0 | 149 | \ No newline at end of file | ... | ... |
vendor/yiisoft/multiparser/CsvParser.php
| ... | ... | @@ -45,21 +45,45 @@ class CsvParser implements ParserInterface |
| 45 | 45 | * используется при автоопределении первой строки*/ |
| 46 | 46 | public $min_column_quantity = 5; |
| 47 | 47 | |
| 48 | + /** @var array - конфигурация конвертера значений */ | |
| 49 | + public $converter_conf = []; | |
| 50 | + /** @var array - конвертер созданный по конфигурации */ | |
| 51 | + public $converter = NULL; | |
| 48 | 52 | |
| 49 | 53 | |
| 50 | 54 | /** |
| 51 | - метод устанвливает нужные настройки объекта SplFileObject, для работы с csv | |
| 55 | + * метод устанвливает нужные настройки объекта SplFileObject, для работы с csv | |
| 52 | 56 | */ |
| 53 | 57 | public function setup() |
| 54 | 58 | { |
| 55 | 59 | $this->file->setCsvControl($this->delimiter); |
| 56 | 60 | $this->file->setFlags(\SplFileObject::READ_CSV); |
| 57 | 61 | $this->file->setFlags(\SplFileObject::SKIP_EMPTY); |
| 62 | + | |
| 58 | 63 | if ($this->auto_detect_first_line) { |
| 59 | 64 | $this->shiftToFirstValuableLine(); |
| 60 | 65 | } |
| 66 | + $this->setupConverter(); | |
| 67 | + | |
| 68 | + } | |
| 69 | + | |
| 70 | + /** | |
| 71 | + * устанавливает конвертер значений согласно конфигурационным настройкам | |
| 72 | + */ | |
| 73 | + public function setupConverter() | |
| 74 | + { | |
| 75 | + if (!count($this->converter_conf)) { | |
| 76 | + $this->converter = new Converter(); | |
| 77 | + if ($this->hasHeaderRow) { | |
| 78 | + // если у файла есть заголовок, то в результате имеем ассоциативный массив | |
| 79 | + $this->converter_conf['hasKey'] = 1; | |
| 80 | + } | |
| 81 | + $this->converter->configuration = $this->converter_conf; | |
| 82 | + | |
| 83 | + } | |
| 61 | 84 | } |
| 62 | 85 | |
| 86 | + | |
| 63 | 87 | /** |
| 64 | 88 | * определяет первую значимую строку, |
| 65 | 89 | * считывается файл пока в нем не встретится строка с непустыми колонками |
| ... | ... | @@ -97,6 +121,7 @@ class CsvParser implements ParserInterface |
| 97 | 121 | */ |
| 98 | 122 | public function read() |
| 99 | 123 | { |
| 124 | + | |
| 100 | 125 | $return = []; |
| 101 | 126 | |
| 102 | 127 | $current_line = 0; |
| ... | ... | @@ -104,7 +129,6 @@ class CsvParser implements ParserInterface |
| 104 | 129 | |
| 105 | 130 | while (($row = $this->readRow()) !== FALSE) { |
| 106 | 131 | $current_line++; |
| 107 | - | |
| 108 | 132 | if ($this->hasHeaderRow) { |
| 109 | 133 | if ($this->keys === NULL) { |
| 110 | 134 | $this->keys = array_values($row); |
| ... | ... | @@ -112,14 +136,12 @@ class CsvParser implements ParserInterface |
| 112 | 136 | |
| 113 | 137 | if (count($this->keys) !== count($row)) { |
| 114 | 138 | // |
| 115 | - throw new \ErrorException( "Invalid columns detected on line # {$current_line}", 0, 1, $this->file->getBasename(), $current_line); | |
| 139 | + throw new \ErrorException("Invalid columns detected on line # {$current_line}", 0, 1, $this->file->getBasename(), $current_line); | |
| 116 | 140 | } |
| 117 | 141 | |
| 118 | 142 | $return[] = array_combine($this->keys, $row); |
| 119 | 143 | } |
| 120 | - } | |
| 121 | - else | |
| 122 | - { | |
| 144 | + } else { | |
| 123 | 145 | $return[] = $row; |
| 124 | 146 | } |
| 125 | 147 | // если у нас установлен лимит, при его достижении прекращаем парсинг |
| ... | ... | @@ -134,7 +156,6 @@ class CsvParser implements ParserInterface |
| 134 | 156 | } |
| 135 | 157 | |
| 136 | 158 | |
| 137 | - | |
| 138 | 159 | protected function closeHandler() |
| 139 | 160 | { |
| 140 | 161 | $this->file = NULL; |
| ... | ... | @@ -147,10 +168,16 @@ class CsvParser implements ParserInterface |
| 147 | 168 | { |
| 148 | 169 | |
| 149 | 170 | $row = $this->file->fgetcsv(); |
| 150 | - if (is_array($row) && $this->first_column) { | |
| 171 | + if (is_array($row)) { | |
| 172 | + // попытаемся конвертировать прочитанные занчения согдасно конфигурации котнвертера значений | |
| 173 | + // \common\components\CustomVarDamp::dump($row,1); | |
| 174 | + $row = $this->convert($row); | |
| 175 | + // \common\components\CustomVarDamp::dump($row,2); | |
| 176 | + if ($this->first_column) { | |
| 151 | 177 | |
| 152 | - $row = array_slice($row, $this->first_column); | |
| 178 | + $row = array_slice($row, $this->first_column); | |
| 153 | 179 | |
| 180 | + } | |
| 154 | 181 | } |
| 155 | 182 | if (is_null($row)) |
| 156 | 183 | $row = false; |
| ... | ... | @@ -159,5 +186,25 @@ class CsvParser implements ParserInterface |
| 159 | 186 | |
| 160 | 187 | } |
| 161 | 188 | |
| 189 | + /** | |
| 190 | + * @param $arr | |
| 191 | + * @return mixed | |
| 192 | + * преобразовует значения прочитанного массива в нужные типы, согласно конфигурации конвертера | |
| 193 | + */ | |
| 194 | + protected function convert($arr) | |
| 195 | + { | |
| 196 | + $result = $arr; | |
| 197 | + $converter = $this->converter; | |
| 198 | + | |
| 199 | + if (!is_null($converter)) { | |
| 200 | + | |
| 201 | + $result = $converter->convertByConfiguration( $arr ); | |
| 202 | + | |
| 203 | + } | |
| 204 | + | |
| 205 | + return $result; | |
| 206 | + | |
| 207 | + } | |
| 208 | + | |
| 162 | 209 | |
| 163 | 210 | } |
| 164 | 211 | \ No newline at end of file | ... | ... |
| 1 | +<?php | |
| 2 | +/** | |
| 3 | + * Created by PhpStorm. | |
| 4 | + * User: Cibermag | |
| 5 | + * Date: 08.09.2015 | |
| 6 | + * Time: 14:50 | |
| 7 | + */ | |
| 8 | + | |
| 9 | +namespace yii\multiparser; | |
| 10 | + | |
| 11 | +use yii\base\DynamicModel; | |
| 12 | +use yii\grid\GridView; | |
| 13 | +use yii\grid\SerialColumn; | |
| 14 | +use yii\helpers\ArrayHelper; | |
| 15 | + | |
| 16 | +/** | |
| 17 | + * Class DynamicFormHelper | |
| 18 | + * @package backend\components\parsers | |
| 19 | + * Содержит процедуры генерации компонентов с динамическим количеством аттрибутов | |
| 20 | + */ | |
| 21 | +class DynamicFormHelper | |
| 22 | +{ | |
| 23 | + | |
| 24 | + const KEY_PREFIX = 'attr_'; | |
| 25 | + private static $key_array; | |
| 26 | + | |
| 27 | + /** | |
| 28 | + * @param $source - int or array | |
| 29 | + * если передан массив, то создается модель с атрибутами переданными в массиве, | |
| 30 | + * ключ - имя, значение - значение аттрибута | |
| 31 | + * если передано число, то создается переданное количество аттрибутов с именами - attr_0, attr_1... | |
| 32 | + */ | |
| 33 | + public static function CreateDynamicModel($source) | |
| 34 | + { | |
| 35 | + $arr_keys = []; | |
| 36 | + if (is_array($source)) { | |
| 37 | + $arr_keys = $source; | |
| 38 | + } elseif (is_int($source)) { | |
| 39 | + | |
| 40 | + $i = 0; | |
| 41 | + while ($source > $i) { | |
| 42 | + $arr_keys[] = self::KEY_PREFIX . $i; | |
| 43 | + $i++; | |
| 44 | + } | |
| 45 | + array_flip($arr_keys); | |
| 46 | + | |
| 47 | + } | |
| 48 | + | |
| 49 | + $model = new DynamicModel($arr_keys); | |
| 50 | + | |
| 51 | + return $model; | |
| 52 | + } | |
| 53 | + | |
| 54 | + // @todo add comments | |
| 55 | + public static function CreateGridWithDropDownListHeader( $dataProvider, $form, $header_model, $arr_header_values ) | |
| 56 | + { | |
| 57 | + $columns_config = [['class' => SerialColumn::className()]]; | |
| 58 | + $i = 0; | |
| 59 | + foreach( $header_model as $key => $value ) { | |
| 60 | + | |
| 61 | + $columns_config[] = ['header' => $form->field($header_model, $key, ['inputOptions' => ['label' => '']])->dropDownList($arr_header_values), 'attribute' => $i]; | |
| 62 | + $i++; | |
| 63 | + } | |
| 64 | + $dynamic_grid_view = GridView::widget( ['dataProvider' => $dataProvider, | |
| 65 | + 'columns' => $columns_config ] ); | |
| 66 | + | |
| 67 | + return $dynamic_grid_view; | |
| 68 | + | |
| 69 | + } | |
| 70 | + | |
| 71 | + /** | |
| 72 | + * @param $value_arr - двумерный массив значений, которому нужно присвоить ключи | |
| 73 | + * @param $key_array - ключи для вложенного массива | |
| 74 | + * @return array - таблица с проименованными колонками | |
| 75 | + */ | |
| 76 | + public static function CreateAssocArray ($value_arr, $key_array) | |
| 77 | + { | |
| 78 | + // преобразуем массив ключей (обернем в массив), для передачи его в качестве параметра в анонимную функцию для array_map | |
| 79 | + // для этого увеличим размерность массива, что бы при каждом обходе массива $value_arr , функции был доступен исходный массив ключей | |
| 80 | + $key_array = array_fill( 0, count($value_arr), array_flip($key_array)); | |
| 81 | + | |
| 82 | + $result = array_map( | |
| 83 | + function ($value, $key_array) { | |
| 84 | + $res = $value; | |
| 85 | + foreach ($value as $key => $sub_value) { | |
| 86 | + if (isset($key_array[$key])) { | |
| 87 | + // если такой ключ в базовом массиве (массиве ключей) есть, то заменим новым, иначе просто удалим | |
| 88 | + $new_key = $key_array[$key]; | |
| 89 | + if( !array_key_exists( $new_key , $res ) ){ | |
| 90 | + $res[ $new_key ] = $res[$key]; | |
| 91 | + } | |
| 92 | + } | |
| 93 | + unset( $res[$key] ); | |
| 94 | + } | |
| 95 | + | |
| 96 | + return $res; | |
| 97 | + }, | |
| 98 | + $value_arr, $key_array); | |
| 99 | + return $result; | |
| 100 | + } | |
| 101 | + | |
| 102 | + | |
| 103 | +} | |
| 0 | 104 | \ No newline at end of file | ... | ... |
| 1 | +<?php | |
| 2 | +/** | |
| 3 | + * Created by PhpStorm. | |
| 4 | + * User: Cibermag | |
| 5 | + * Date: 27.08.2015 | |
| 6 | + * Time: 13:36 | |
| 7 | + */ | |
| 8 | + | |
| 9 | +namespace yii\multiparser; | |
| 10 | + | |
| 11 | +// @todo add comments | |
| 12 | +class Encoder | |
| 13 | +{ | |
| 14 | + /** @var out encoding charset */ | |
| 15 | + public static $out_charset = 'UTF-8'; | |
| 16 | + /** @var out encoding charset */ | |
| 17 | + public static $in_charset = 'windows-1251'; | |
| 18 | + | |
| 19 | + public static function encodeFile($in_charset, $out_charset, $filePath) | |
| 20 | + { | |
| 21 | + | |
| 22 | + $old_content = file_get_contents($filePath); | |
| 23 | + $encode_content = self::encodeString( $old_content, $in_charset, $out_charset ); | |
| 24 | + $file = @fopen($filePath, "w"); | |
| 25 | + fwrite($file, $encode_content); | |
| 26 | + @fclose($file); | |
| 27 | + } | |
| 28 | + | |
| 29 | + public static function encodeArray( $array, $in_charset = '', $out_charset = '') | |
| 30 | + { | |
| 31 | + if ($in_charset) | |
| 32 | + self::$in_charset = $in_charset; | |
| 33 | + | |
| 34 | + if ($out_charset) | |
| 35 | + self::$out_charset = $out_charset; | |
| 36 | + | |
| 37 | + $result = array_map( | |
| 38 | + function ($value) { | |
| 39 | + | |
| 40 | + return self::encodeString( $value, self::$in_charset, self::$out_charset ); | |
| 41 | + | |
| 42 | + }, | |
| 43 | + $array); | |
| 44 | + | |
| 45 | + return $result; | |
| 46 | + } | |
| 47 | + | |
| 48 | + public static function encodeString( $source, $in_charset = '', $out_charset = '' ){ | |
| 49 | + | |
| 50 | + if ($in_charset) | |
| 51 | + self::$in_charset = $in_charset; | |
| 52 | + | |
| 53 | + if ($out_charset) | |
| 54 | + self::$out_charset = $out_charset; | |
| 55 | + | |
| 56 | + return iconv( self::$in_charset, self::$out_charset, $source ); | |
| 57 | + | |
| 58 | + } | |
| 59 | +} | |
| 0 | 60 | \ No newline at end of file | ... | ... |
vendor/yiisoft/multiparser/ParserConfigurator.php
| ... | ... | @@ -4,23 +4,29 @@ namespace yii\multiparser; |
| 4 | 4 | class ParserConfigurator |
| 5 | 5 | { |
| 6 | 6 | |
| 7 | - protected static $configuration = [ | |
| 8 | - 'csv' => | |
| 9 | - ['web' => | |
| 10 | - ['class' => 'backend\components\parsers\CustomCsvParser', | |
| 11 | - 'auto_detect_first_line' => true,]]]; | |
| 7 | + protected static $configuration; | |
| 12 | 8 | |
| 13 | - | |
| 14 | - public static function getConfiguration($extension, $mode) | |
| 9 | + public static function getConfiguration($extension, $parameter) | |
| 15 | 10 | { |
| 11 | + self::setConfiguration(); | |
| 12 | + | |
| 16 | 13 | if (!isset( self::$configuration[$extension] )){ |
| 17 | 14 | throw new \ErrorException( "Parser do not maintain file with extension {$extension}"); |
| 18 | 15 | } |
| 19 | - if (!isset( self::$configuration[$extension][$mode] )){ | |
| 20 | - throw new \ErrorException( "Parser configurator do not have settings for {$mode} mode"); | |
| 16 | + if (!isset( self::$configuration[$extension][$parameter] )){ | |
| 17 | + throw new \ErrorException( "Parser configurator do not have settings for {$parameter} parameter"); | |
| 21 | 18 | } |
| 22 | 19 | |
| 23 | - return self::$configuration[$extension][$mode]; | |
| 20 | + return self::$configuration[$extension][$parameter]; | |
| 24 | 21 | } |
| 25 | 22 | |
| 23 | + protected static function setConfiguration() | |
| 24 | + { | |
| 25 | + | |
| 26 | + self::$configuration = require(__DIR__ . '/config.php'); | |
| 27 | + | |
| 28 | + } | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 26 | 32 | } |
| 27 | 33 | \ No newline at end of file | ... | ... |
| 1 | +<?php | |
| 2 | +/** | |
| 3 | + * Created by PhpStorm. | |
| 4 | + * User: Cibermag | |
| 5 | + * Date: 10.09.2015 | |
| 6 | + * Time: 17:47 | |
| 7 | + */ | |
| 8 | + | |
| 9 | +namespace yii\multiparser; | |
| 10 | + | |
| 11 | + | |
| 12 | +class XmlParser implements ParserInterface{ | |
| 13 | + /** @var экземляр SplFileObject читаемого файла */ | |
| 14 | + public $file; | |
| 15 | + public $node; | |
| 16 | + | |
| 17 | + public function read() | |
| 18 | + { | |
| 19 | + $file = $this->file; | |
| 20 | + $result = self::xml2array( $file->getPathname() ); | |
| 21 | + if ( isset($this->node) ) { | |
| 22 | + $result = $result[$this->node]; | |
| 23 | + } | |
| 24 | + | |
| 25 | + //\common\components\CustomVarDamp::dumpAndDie($result); | |
| 26 | + $result = DynamicFormHelper::CreateAssocArray($result, \Yii::$app->multiparser->getConfiguration('xml','basic_column')); | |
| 27 | + \common\components\CustomVarDamp::dumpAndDie($result); | |
| 28 | + } | |
| 29 | + | |
| 30 | + public function setup() | |
| 31 | + { | |
| 32 | + | |
| 33 | + | |
| 34 | + } | |
| 35 | + | |
| 36 | + | |
| 37 | + /** | |
| 38 | + * Converts an XML string to a PHP array | |
| 39 | + * | |
| 40 | + * @uses recursiveXMLToArray() | |
| 41 | + * @param string $file_path | |
| 42 | + * @return array | |
| 43 | + */ | |
| 44 | + protected static function xml2array( $file_path ) { | |
| 45 | + | |
| 46 | + try { | |
| 47 | + $xml = new \SimpleXMLElement( $file_path, 0, true ); | |
| 48 | + //\common\components\CustomVarDamp::dumpAndDie($xml->children()->children()); | |
| 49 | + $result = self::recursiveXMLToArray( $xml ); | |
| 50 | + } catch(Exception $ex) { | |
| 51 | + | |
| 52 | + throw $ex; | |
| 53 | + } | |
| 54 | + | |
| 55 | + return $result; | |
| 56 | + } | |
| 57 | + | |
| 58 | + /** | |
| 59 | + * Convert a XML string to a PHP array recursively. Do not | |
| 60 | + * call this function directly, Please use {@link Convert::xml2array()} | |
| 61 | + * | |
| 62 | + * @param SimpleXMLElement | |
| 63 | + * | |
| 64 | + * @return mixed | |
| 65 | + */ | |
| 66 | + protected static function recursiveXMLToArray($xml) { | |
| 67 | + if(is_object($xml) && get_class($xml) == 'SimpleXMLElement') { | |
| 68 | + $attributes = $xml->attributes(); | |
| 69 | + foreach($attributes as $k => $v) { | |
| 70 | + if($v) $a[$k] = (string) $v; | |
| 71 | + } | |
| 72 | + $x = $xml; | |
| 73 | + $xml = get_object_vars($xml); | |
| 74 | + } | |
| 75 | + | |
| 76 | + //\common\components\CustomVarDamp::dump($xml); | |
| 77 | + if(is_array($xml)) { | |
| 78 | + if(count($xml) == 0) return (string) $x; // for CDATA | |
| 79 | + foreach($xml as $key => $value) { | |
| 80 | + $r[$key] = self::recursiveXMLToArray($value); | |
| 81 | + } | |
| 82 | + if(isset($a)) $r['@'] = $a; // Attributes | |
| 83 | + return $r; | |
| 84 | + } | |
| 85 | + //\common\components\CustomVarDamp::dumpAndDie($xml); | |
| 86 | + return (string) $xml; | |
| 87 | + } | |
| 88 | +} | |
| 0 | 89 | \ No newline at end of file | ... | ... |
vendor/yiisoft/multiparser/YiiMultiparser.php
| ... | ... | @@ -11,8 +11,26 @@ namespace yii\multiparser; |
| 11 | 11 | use yii\base\Component; |
| 12 | 12 | |
| 13 | 13 | |
| 14 | + | |
| 15 | + | |
| 14 | 16 | class YiiMultiparser extends Component{ |
| 15 | 17 | |
| 18 | +public $configuration; | |
| 19 | + | |
| 20 | + public function getConfiguration($extension, $conf_parameter){ | |
| 21 | + | |
| 22 | + if (!isset( $this->configuration[$extension] )){ | |
| 23 | + throw new \ErrorException( "Parser do not maintain file with extension {$extension}"); | |
| 24 | + } | |
| 25 | + if (!isset( $this->configuration[$extension][$conf_parameter] )){ | |
| 26 | + throw new \ErrorException( "Parser configurator do not have settings for {$conf_parameter} parameter"); | |
| 27 | + } | |
| 28 | + | |
| 29 | + return $this->configuration[$extension][$conf_parameter]; | |
| 30 | + | |
| 31 | + } | |
| 32 | + | |
| 33 | + | |
| 16 | 34 | public function parse( $filePath, $options = [] ){ |
| 17 | 35 | |
| 18 | 36 | $parser = new YiiParserHandler( $filePath, $options ); | ... | ... |
vendor/yiisoft/multiparser/YiiParserHandler.php
| ... | ... | @@ -12,4 +12,72 @@ namespace yii\multiparser; |
| 12 | 12 | class YiiParserHandler extends ParserHandler{ |
| 13 | 13 | |
| 14 | 14 | |
| 15 | + /** | |
| 16 | + * @param $filePath | |
| 17 | + * @param array $options | |
| 18 | + * проверяет читабенльность переданного файла, а также наличие настроек парсера в конфигурационном файле для данного типа файла | |
| 19 | + */ | |
| 20 | + public function __construct($filePath, $options = []) | |
| 21 | + { | |
| 22 | + $this->filePath = $filePath; | |
| 23 | + if (isset($options['mode'])) { | |
| 24 | + | |
| 25 | + $this->mode = $options['mode']; | |
| 26 | + unset($options['mode']); | |
| 27 | + | |
| 28 | + } else { | |
| 29 | + | |
| 30 | + $this->mode = self::DEFAULT_MODE; | |
| 31 | + | |
| 32 | + } | |
| 33 | + | |
| 34 | + $this->options = $options; | |
| 35 | + | |
| 36 | + try { | |
| 37 | + $this->fileObject = new \SplFileObject($this->filePath, 'r'); | |
| 38 | + } catch (\ErrorException $e) { | |
| 39 | + // Yii::warning("Ошибка открытия файла {$this->filePath}"); | |
| 40 | + echo "Ошибка открытия файла {$this->filePath}"; | |
| 41 | + return []; | |
| 42 | + } | |
| 43 | + | |
| 44 | + $options['file'] = $this->fileObject; | |
| 45 | + $this->extension = $this->fileObject->getExtension(); | |
| 46 | + | |
| 47 | + try { | |
| 48 | + $this->configuration = \Yii::$app->multiparser->getConfiguration($this->extension, $this->mode); | |
| 49 | + $this->configuration = array_merge($this->configuration, $options); | |
| 50 | + | |
| 51 | + } catch (\ErrorException $e) { | |
| 52 | + echo $e->getMessage(); | |
| 53 | + return []; | |
| 54 | + } | |
| 55 | + | |
| 56 | + } | |
| 57 | + | |
| 58 | + public function run() | |
| 59 | + { | |
| 60 | + | |
| 61 | + $result = []; | |
| 62 | + | |
| 63 | + // \common\components\CustomVarDamp::dumpAndDie($this); | |
| 64 | + if (count($this->configuration)) { | |
| 65 | + $parser = \Yii::createObject($this->configuration); | |
| 66 | + | |
| 67 | + try { | |
| 68 | + | |
| 69 | + $parser->setup(); | |
| 70 | + $result = $parser->read(); | |
| 71 | + | |
| 72 | + } catch (\ErrorException $e) { | |
| 73 | + | |
| 74 | + echo $e->getMessage(); | |
| 75 | + | |
| 76 | + } | |
| 77 | + | |
| 78 | + } | |
| 79 | + | |
| 80 | + return $result; | |
| 81 | + } | |
| 82 | + | |
| 15 | 83 | } |
| 16 | 84 | \ No newline at end of file | ... | ... |
| 1 | +<?php | |
| 2 | +return | |
| 3 | + [ | |
| 4 | + 'csv' => | |
| 5 | + ['web' => | |
| 6 | + ['class' => 'yii\multiparser\CsvParser', | |
| 7 | + 'auto_detect_first_line' => true, | |
| 8 | + 'converter_conf' => [ | |
| 9 | + "float" => 'PRICE', | |
| 10 | + "integer" => 'QUANTITY', | |
| 11 | + "string" => 'DESCR' | |
| 12 | + ]], | |
| 13 | + 'basic_column' => [ | |
| 14 | + "ARTICLE" => 'Артикул', | |
| 15 | + "PRICE" => 'Цена', | |
| 16 | + "DESCR" => 'Наименование', | |
| 17 | + "QUANTITY" => 'Колво' | |
| 18 | + | |
| 19 | + ], | |
| 20 | + ]]; | ... | ... |