Commit 6215a30d57d62a68a21a5e2a485581e923701b0d

Authored by Mihail
1 parent f02e1203

add converter interface, object creator, abstract class Parser

backend/controllers/ParserController.php
@@ -15,6 +15,7 @@ use backend\models\Importers; @@ -15,6 +15,7 @@ use backend\models\Importers;
15 use yii\base\ErrorException; 15 use yii\base\ErrorException;
16 use common\components\PriceWriter; 16 use common\components\PriceWriter;
17 use common\components\CustomVarDamp; 17 use common\components\CustomVarDamp;
  18 +use common\components\CustomArrayHelper;
18 19
19 /** 20 /**
20 * Parser controller 21 * Parser controller
@@ -54,7 +55,6 @@ class ParserController extends BaseController @@ -54,7 +55,6 @@ class ParserController extends BaseController
54 $model = new UploadFileParsingForm(); 55 $model = new UploadFileParsingForm();
55 // установим режим, 0 - ручная загрузка, 1 - автозагрузка 56 // установим режим, 0 - ручная загрузка, 1 - автозагрузка
56 $model->mode = $mode; 57 $model->mode = $mode;
57 - //CustomVarDamp::dumpAndDie(phpinfo());  
58 return $this->render('index', ['model' => $model]); 58 return $this->render('index', ['model' => $model]);
59 } 59 }
60 60
@@ -186,7 +186,7 @@ class ParserController extends BaseController @@ -186,7 +186,7 @@ class ParserController extends BaseController
186 186
187 // соотнесем отпарсенные данные с соответсивем полученным от пользователя 187 // соотнесем отпарсенные данные с соответсивем полученным от пользователя
188 // для этого преобразуем массив отпарсенных данных - назначим ключи согласно соответствию 188 // для этого преобразуем массив отпарсенных данных - назначим ключи согласно соответствию
189 - $data = \Yii::$app->multiparser->convertToAssocArray($data, $arr , 'attr_'); 189 + $data = CustomArrayHelper::createAssocArray( $data, $arr , 'attr_' );
190 190
191 // запустим специальный класс который запишет данные в таблицы связанные с прайсами 191 // запустим специальный класс который запишет данные в таблицы связанные с прайсами
192 $writer = new PriceWriter(); 192 $writer = new PriceWriter();
backend/models/UploadFileParsingForm.php
@@ -75,8 +75,8 @@ class UploadFileParsingForm extends Model @@ -75,8 +75,8 @@ class UploadFileParsingForm extends Model
75 throw new ErrorException("Ошибка чтения из файла прайса {$this->file_path}"); 75 throw new ErrorException("Ошибка чтения из файла прайса {$this->file_path}");
76 } 76 }
77 // файл больше не нужен - данные прочитаны и сохранены в кеш 77 // файл больше не нужен - данные прочитаны и сохранены в кеш
78 - if( file_exists($this->file_path) )  
79 - unlink($this->file_path); 78 +// if( file_exists($this->file_path) )
  79 +// unlink($this->file_path);
80 80
81 return $data; 81 return $data;
82 } 82 }
common/components/CustomArrayHelper.php 0 → 100644
  1 +<?php
  2 +/**
  3 + * Created by PhpStorm.
  4 + * User: Tsurkanov
  5 + * Date: 20.10.2015
  6 + * Time: 14:42
  7 + */
  8 +
  9 +namespace common\components;
  10 +
  11 +
  12 +class CustomArrayHelper extends \yii\helpers\ArrayHelper {
  13 +
  14 + /**
  15 + * @param $value_arr - двумерный массив значений, которому нужно присвоить ключи
  16 + * @param $key_array - ключи для вложенного массива
  17 + * @return array - таблица с проименованными колонками
  18 + */
  19 +
  20 + public static function createAssocArray(array $value_arr, array $key_array, $key_prefix = '')
  21 + {
  22 + // очистка служебного префикса в массиве заголовков
  23 + if ($key_prefix) {
  24 + // @todo оптимизировать - два переворота массива - избыточно
  25 + $key_array = array_flip($key_array);
  26 +
  27 + array_walk($key_array, function (&$value, $key, $key_prefix) {
  28 + $value = str_replace($key_prefix, '', $value);
  29 + }, $key_prefix);
  30 +
  31 + $key_array = array_flip($key_array);
  32 + //уберем пустые элементы
  33 + $key_array = array_filter($key_array, function ($value) {
  34 + return $value !== '';
  35 + });
  36 + }
  37 +
  38 + array_walk($value_arr,
  39 + function (&$value, $key, $key_array) {
  40 + $res = $value;
  41 + foreach ($res as $sub_key => $sub_value) {
  42 + if (isset($key_array[$sub_key])) {
  43 + // если такой ключ в базовом массиве (массиве ключей) есть, то заменим новым, иначе просто удалим
  44 + $new_key = $key_array[$sub_key];
  45 + if (!array_key_exists($new_key, $res)) {
  46 + $res[$new_key] = $value[$sub_key];
  47 + }
  48 + }
  49 + unset($res[$sub_key]);
  50 + $value = $res;
  51 + }
  52 +
  53 + },
  54 + $key_array);
  55 +
  56 + return $value_arr;
  57 + }
  58 +
  59 + /**
  60 + * @param $value_arr - двумерный массив к которому нужно добавить колонки
  61 + * @param $add_array - массив с колонками (ключи) и значениями колонок
  62 + * @return mixed
  63 + */
  64 + public static function addColumns(array $value_arr, array $add_array)
  65 + {
  66 + $i = 0;
  67 + while ($i < count($value_arr)) {
  68 + foreach ($add_array as $add_key => $add_value) {
  69 + $value_arr[$i][$add_key] = $add_value;
  70 + }
  71 + $i++;
  72 + }
  73 + return $value_arr;
  74 + }
  75 +}
0 \ No newline at end of file 76 \ No newline at end of file
common/components/PriceWriter.php
@@ -62,20 +62,20 @@ class PriceWriter @@ -62,20 +62,20 @@ class PriceWriter
62 // преобразуем числовые значения 62 // преобразуем числовые значения
63 foreach ($this->data as &$row) { 63 foreach ($this->data as &$row) {
64 64
65 - $row['PRICE'] = \Yii::$app->multiparser->convertToFloat($row['PRICE']);  
66 - $row['BOX'] = \Yii::$app->multiparser->convertToInteger($row['BOX']); 65 + $row['PRICE'] = \Yii::$app->converter->convertTo('float',$row['PRICE']);
  66 + $row['BOX'] = \Yii::$app->converter->convertTo('integer',$row['BOX']);
67 // присвоим полный артикул 67 // присвоим полный артикул
68 68
69 $row['FULL_ARTICLE'] = $row['ARTICLE']; 69 $row['FULL_ARTICLE'] = $row['ARTICLE'];
70 if ((int)$this->configuration['delete_prefix']) { 70 if ((int)$this->configuration['delete_prefix']) {
71 - $row = \Yii::$app->multiparser->convertToArticle( $row, $this->configuration['importer_id'] ); 71 + $row = \Yii::$app->converter->convertTo( 'Article', $row, ['importer_id' => $this->configuration['importer_id']] );
72 } else { 72 } else {
73 - $row['ARTICLE'] = \Yii::$app->multiparser->convertToArticle( $row['ARTICLE'] ); 73 + $row['ARTICLE'] = \Yii::$app->converter->convertTo( 'Article', $row['ARTICLE'] );
74 } 74 }
75 75
76 76
77 if (isset($row['ADD_BOX'])) 77 if (isset($row['ADD_BOX']))
78 - $row['ADD_BOX'] = \Yii::$app->multiparser->convertToInteger($row['ADD_BOX']); 78 + $row['ADD_BOX'] = \Yii::$app->converter->convertTo( 'integer', $row['ADD_BOX'] );
79 79
80 // проверим все ли обязательные колонки были указаны пользователем 80 // проверим все ли обязательные колонки были указаны пользователем
81 $details_model->load(['Details' => $row]); 81 $details_model->load(['Details' => $row]);
@@ -87,7 +87,7 @@ class PriceWriter @@ -87,7 +87,7 @@ class PriceWriter
87 } 87 }
88 88
89 // дополним данные значением импортера и даты обновления цены 89 // дополним данные значением импортера и даты обновления цены
90 - $this->data = \Yii::$app->multiparser->addColumns($this->data, ['IMPORT_ID' => $this->configuration['importer_id'], 'timestamp' => $update_date]); 90 + $this->data = CustomArrayHelper::addColumns( $this->data, ['IMPORT_ID' => $this->configuration['importer_id'], 'timestamp' => $update_date] );
91 try { 91 try {
92 //@todo add transaction 92 //@todo add transaction
93 93
common/components/parsers/CustomConverter.php
@@ -10,71 +10,11 @@ use backend\models\ImportersPrefix; @@ -10,71 +10,11 @@ use backend\models\ImportersPrefix;
10 class CustomConverter extends Converter 10 class CustomConverter extends Converter
11 { 11 {
12 12
13 - /**  
14 - * @param $value_arr - двумерный массив значений, которому нужно присвоить ключи  
15 - * @param $key_array - ключи для вложенного массива  
16 - * @return array - таблица с проименованными колонками  
17 - */  
18 public static $sign; 13 public static $sign;
19 public static $multiplier; 14 public static $multiplier;
20 public static $importer_id; 15 public static $importer_id;
21 public static $brand; 16 public static $brand;
22 17
23 - public static function convertToAssocArray(array $value_arr, array $key_array, $key_prefix = '')  
24 - {  
25 - // очистка служебного префикса в массиве заголовков  
26 - if ($key_prefix) {  
27 - // @todo оптимизировать - два переворота массива - избыточно  
28 - $key_array = array_flip($key_array);  
29 -  
30 - array_walk($key_array, function (&$value, $key, $key_prefix) {  
31 - $value = str_replace($key_prefix, '', $value);  
32 - }, $key_prefix);  
33 -  
34 - $key_array = array_flip($key_array);  
35 - //уберем пустые элементы  
36 - $key_array = array_filter($key_array, function ($value) {  
37 - return $value !== '';  
38 - });  
39 - }  
40 -  
41 - array_walk($value_arr,  
42 - function (&$value, $key, $key_array) {  
43 - $res = $value;  
44 - foreach ($res as $sub_key => $sub_value) {  
45 - if (isset($key_array[$sub_key])) {  
46 - // если такой ключ в базовом массиве (массиве ключей) есть, то заменим новым, иначе просто удалим  
47 - $new_key = $key_array[$sub_key];  
48 - if (!array_key_exists($new_key, $res)) {  
49 - $res[$new_key] = $value[$sub_key];  
50 - }  
51 - }  
52 - unset($res[$sub_key]);  
53 - $value = $res;  
54 - }  
55 -  
56 - },  
57 - $key_array);  
58 -  
59 - return $value_arr;  
60 - }  
61 -  
62 - /**  
63 - * @param $value_arr - двумерный массив к которому нужно добавить колонки  
64 - * @param $add_array - массив с колонками (ключи) и значениями колонок  
65 - * @return mixed  
66 - */  
67 - public function addColumns(array $value_arr, array $add_array)  
68 - {  
69 - $i = 0;  
70 - while ($i < count($value_arr)) {  
71 - foreach ($add_array as $add_key => $add_value) {  
72 - $value_arr[$i][$add_key] = $add_value;  
73 - }  
74 - $i++;  
75 - }  
76 - return $value_arr;  
77 - }  
78 18
79 public static function convertToDetails(array $row) 19 public static function convertToDetails(array $row)
80 { 20 {
@@ -143,11 +83,8 @@ class CustomConverter extends Converter @@ -143,11 +83,8 @@ class CustomConverter extends Converter
143 83
144 } 84 }
145 85
146 - public static function convertToArticle( $value, $importer_id = '' ) 86 + public static function convertToArticle( $value )
147 { 87 {
148 - if(isset( $importer_id )){  
149 - self::$importer_id = $importer_id;  
150 - }  
151 88
152 if (is_array($value)) { 89 if (is_array($value)) {
153 90
@@ -189,7 +126,7 @@ class CustomConverter extends Converter @@ -189,7 +126,7 @@ class CustomConverter extends Converter
189 126
190 public static function convertToBrand($value) 127 public static function convertToBrand($value)
191 { 128 {
192 - $res = parent::convertToEncode($value);; 129 + $res = self::convertToEncode($value);;
193 $res = trim(strtoupper($res)); 130 $res = trim(strtoupper($res));
194 $res = str_replace("Ä", "A", str_replace("Ö", "O", str_replace("Ü", "U", str_replace("Ë", "E", str_replace("Ò", "O", $res))))); 131 $res = str_replace("Ä", "A", str_replace("Ö", "O", str_replace("Ü", "U", str_replace("Ë", "E", str_replace("Ò", "O", $res)))));
195 $res = str_replace(array('@', '#', '~', '"', "'", "?", "!"), '', $res); 132 $res = str_replace(array('@', '#', '~', '"', "'", "?", "!"), '', $res);
@@ -197,12 +134,5 @@ class CustomConverter extends Converter @@ -197,12 +134,5 @@ class CustomConverter extends Converter
197 return $res; 134 return $res;
198 } 135 }
199 136
200 - public static function convertToString($value)  
201 - {  
202 - $value = parent::convertToEncode($value);  
203 -  
204 - return str_replace(array('!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', '=', '-', '~', '`', '"', "'", ' ', '№', '%', ';', ':', '[', ']', '{', '}', '*', '?', '/', '\'', '|', '.', ',', '<', '>', '\\'), '', $value);  
205 - }  
206 -  
207 137
208 } 138 }
209 \ No newline at end of file 139 \ No newline at end of file
common/components/parsers/CustomCsvParser.php
@@ -19,31 +19,19 @@ class CustomCsvParser extends \yii\multiparser\CsvParser { @@ -19,31 +19,19 @@ class CustomCsvParser extends \yii\multiparser\CsvParser {
19 public $last_line = 100; 19 public $last_line = 100;
20 //public $hasHeaderRow = true; 20 //public $hasHeaderRow = true;
21 // public $keys = ['first','second', 'third', 'forth', 'fifth']; 21 // public $keys = ['first','second', 'third', 'forth', 'fifth'];
22 - public function setupConverter()  
23 - {  
24 - if (!count($this->converter_conf)) {  
25 - if ($this->hasHeaderRow) {  
26 - // если у файла есть заголовок, то в результате имеем ассоциативный массив  
27 - $this->converter_conf['hasKey'] = 1;  
28 -  
29 - }  
30 -  
31 - }  
32 -// $this->converter = \Yii::createObject( $this->converter_conf );  
33 -// CustomVarDamp::dumpAndDie($this->converter);  
34 - }  
35 -  
36 - /**  
37 - * @param $arr  
38 - * @return mixed  
39 - * преобразовует значения прочитанного массива в нужные типы, согласно конфигурации конвертера  
40 - */  
41 - protected function convert($arr)  
42 - {  
43 - $arr = \Yii::$app->multiparser->convertByConfiguration( $arr, $this->converter_conf );  
44 -  
45 - return $arr;  
46 -  
47 - } 22 +// public function setupConverter()
  23 +// {
  24 +// if (!count($this->converter_conf)) {
  25 +// if ($this->hasHeaderRow) {
  26 +// // если у файла есть заголовок, то в результате имеем ассоциативный массив
  27 +// $this->converter_conf['hasKey'] = 1;
  28 +//
  29 +// }
  30 +//
  31 +// }
  32 +//// $this->converter = \Yii::createObject( $this->converter_conf );
  33 +// }
  34 +
  35 +
48 36
49 } 37 }
50 \ No newline at end of file 38 \ No newline at end of file
common/components/parsers/config.php
@@ -5,7 +5,7 @@ @@ -5,7 +5,7 @@
5 ['class' => 'common\components\parsers\CustomCsvParser', 5 ['class' => 'common\components\parsers\CustomCsvParser',
6 'auto_detect_first_line' => true, 6 'auto_detect_first_line' => true,
7 'converter_conf' => [ 7 'converter_conf' => [
8 - //'class' => ' common\components\parsers\CustomConverter', // @todo переделать на компонент 8 + 'class' => 'common\components\parsers\CustomConverter',
9 'configuration' => ["encode" => 'DESCR'],] 9 'configuration' => ["encode" => 'DESCR'],]
10 ], 10 ],
11 'console' => 11 'console' =>
@@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@
13 'auto_detect_first_line' => true, 13 'auto_detect_first_line' => true,
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, 17 'hasKey' => 1,
18 'configuration' => ["string" => 'DESCR', 18 'configuration' => ["string" => 'DESCR',
19 "float" => 'PRICE', 19 "float" => 'PRICE',
@@ -42,7 +42,7 @@ @@ -42,7 +42,7 @@
42 'hasHeaderRow' => true, 42 'hasHeaderRow' => true,
43 'keys' =>['ARTICLE', 'CROSS_ARTICLE', 'BRAND', 'CROSS_BRAND'], 43 'keys' =>['ARTICLE', 'CROSS_ARTICLE', 'BRAND', 'CROSS_BRAND'],
44 'converter_conf' => [ 44 'converter_conf' => [
45 - //'class' => ' common\components\parsers\CustomConverter', 45 + 'class' => ' common\components\parsers\CustomConverter',
46 'hasKey' => 1, 46 'hasKey' => 1,
47 'configuration' => [ 47 'configuration' => [
48 "brand" => ['BRAND', 'CROSS_BRAND'], 48 "brand" => ['BRAND', 'CROSS_BRAND'],
@@ -55,7 +55,7 @@ @@ -55,7 +55,7 @@
55 ['class' => 'yii\multiparser\XmlParser', 55 ['class' => 'yii\multiparser\XmlParser',
56 'node' => 'Товар', 56 'node' => 'Товар',
57 'converter_conf' => [ 57 'converter_conf' => [
58 - //'class' => ' common\components\parsers\CustomConverter', 58 + 'class' => ' common\components\parsers\CustomConverter',
59 'hasKey' => 1, 59 'hasKey' => 1,
60 'configuration' => ["details" => [] 60 'configuration' => ["details" => []
61 ],], 61 ],],
common/config/main.php
@@ -15,14 +15,15 @@ return [ @@ -15,14 +15,15 @@ return [
15 ] 15 ]
16 ], 16 ],
17 'multiparser'=>[ 17 'multiparser'=>[
18 -  
19 'class' => 'yii\multiparser\YiiMultiparser', 18 'class' => 'yii\multiparser\YiiMultiparser',
20 'configuration' => $mp_configuration, 19 'configuration' => $mp_configuration,
21 - 'as behavior' => [  
22 - 'class' => 'common\components\parsers\CustomConverter', 20 + ],
  21 + 'converter'=>[
  22 + 'class' => 'yii\multiparser\YiiConverter',
  23 + 'configuration' => [
  24 + 'class' => 'common\components\parsers\CustomConverter'
  25 + ],
23 ], 26 ],
24 27
25 ], 28 ],
26 - ],  
27 -  
28 ]; 29 ];
common/models/DetailsCurrency.php
@@ -6,7 +6,7 @@ use Yii; @@ -6,7 +6,7 @@ use Yii;
6 6
7 /** 7 /**
8 * This is the model class for table "{{%details_currency}}". 8 * This is the model class for table "{{%details_currency}}".
9 - * 9 + * w_details_currency - СПЕЦИАЛЬНО СОЗАДННАЯ ВЬЮШКА ДЛЯ ДОСТУПА К СПИСКУ ТОВАРОВ С ВАЛЮТАМИ И ИХ КУРСАМИ
10 * @property string $ID 10 * @property string $ID
11 * @property string $IMPORT_ID 11 * @property string $IMPORT_ID
12 * @property string $BRAND 12 * @property string $BRAND
vendor/yiisoft/multiparser/Converter.php
1 <?php 1 <?php
2 /** 2 /**
3 -* Created by PhpStorm. 3 + * Created by PhpStorm.
4 * User: Cibermag 4 * User: Cibermag
5 -* Date: 31.08.2015  
6 -* Time: 12:50  
7 -*/ 5 + * Date: 31.08.2015
  6 + * Time: 12:50
  7 + */
8 8
9 namespace yii\multiparser; 9 namespace yii\multiparser;
10 -use common\components\CustomVarDamp;  
11 -use yii\base\Behavior;  
12 -use yii\base\ErrorException;  
13 10
14 // класс который содержит преобразователи значений (фильтры) используемые при парсинге 11 // класс который содержит преобразователи значений (фильтры) используемые при парсинге
15 -class Converter extends Behavior 12 +class Converter implements ConverterInterface
16 { 13 {
17 14
18 const METHOD_PREFIX = 'convertTo'; 15 const METHOD_PREFIX = 'convertTo';
@@ -30,7 +27,7 @@ class Converter extends Behavior @@ -30,7 +27,7 @@ class Converter extends Behavior
30 if ($value == '') { 27 if ($value == '') {
31 return ''; 28 return '';
32 } 29 }
33 - $value = round( (float)$value, 2 ); 30 + $value = round((float)$value, 2);
34 31
35 return $value; 32 return $value;
36 } 33 }
@@ -57,7 +54,7 @@ class Converter extends Behavior @@ -57,7 +54,7 @@ class Converter extends Behavior
57 54
58 $res = Encoder::encodeArray($value); 55 $res = Encoder::encodeArray($value);
59 56
60 - }elseif ( is_string($value) ) { 57 + } elseif (is_string($value)) {
61 58
62 $res = Encoder::encodeString($value); 59 $res = Encoder::encodeString($value);
63 60
@@ -65,20 +62,26 @@ class Converter extends Behavior @@ -65,20 +62,26 @@ class Converter extends Behavior
65 return $res; 62 return $res;
66 } 63 }
67 64
  65 + public static function convertToString($value)
  66 + {
  67 + $value = self::convertToEncode($value);
  68 +
  69 + return str_replace(array('!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', '=', '-', '~', '`', '"', "'", ' ', '№', '%', ';', ':', '[', ']', '{', '}', '*', '?', '/', '\'', '|', '.', ',', '<', '>', '\\'), '', $value);
  70 + }
68 71
69 /** 72 /**
70 * @param $name - имя метода конвертации 73 * @param $name - имя метода конвертации
71 * @param $value - значение на конвертацию 74 * @param $value - значение на конвертацию
72 * @return mixed 75 * @return mixed
73 */ 76 */
74 - public static function __callStatic( $name, $value ) 77 + public static function __callStatic($name, $value)
75 { 78 {
76 - $method_name = self::METHOD_PREFIX . $name; 79 + $method_name = self::METHOD_PREFIX . $name;
77 80
78 - if ( method_exists( static::class, $method_name ) ) {  
79 - return static::$method_name( $value[0] ); 81 + if (method_exists(static::class, $method_name)) {
  82 + return static::$method_name($value[0]);
80 83
81 - } else{ 84 + } else {
82 // если такого метода конвертации не предусмотрено, то возвращаем не конвертируя 85 // если такого метода конвертации не предусмотрено, то возвращаем не конвертируя
83 return $value[0]; 86 return $value[0];
84 87
@@ -87,7 +90,7 @@ class Converter extends Behavior @@ -87,7 +90,7 @@ class Converter extends Behavior
87 90
88 public function __call($name, $params) 91 public function __call($name, $params)
89 { 92 {
90 - return self::__callStatic( $name, $params ); 93 + return self::__callStatic($name, $params);
91 } 94 }
92 95
93 96
@@ -97,39 +100,36 @@ class Converter extends Behavior @@ -97,39 +100,36 @@ class Converter extends Behavior
97 * @return mixed 100 * @return mixed
98 * конвертирует массив по полученным настройкам, вызывая последовательно функции конвертации (указанные в конфигурации) 101 * конвертирует массив по полученным настройкам, вызывая последовательно функции конвертации (указанные в конфигурации)
99 */ 102 */
100 - public static function convertByConfiguration( $arr, $configuration ) 103 + public static function convertByConfiguration($arr, $configuration)
101 { 104 {
102 - if( $hasKey = isset( $configuration['hasKey'] ) )  
103 - unset( $configuration['hasKey'] ); 105 + if ($hasKey = isset($configuration['hasKey']))
  106 + unset($configuration['hasKey']);
104 107
105 - if ( isset( $configuration['configuration'] ) ) { 108 + if (isset($configuration['configuration'])) {
106 $arr_config = $configuration['configuration']; 109 $arr_config = $configuration['configuration'];
107 - unset( $configuration['configuration'] );  
108 - } else{  
109 - throw new ErrorException('Не указан обязательный параметр конфигурационного файла - converter_conf[configuration]'); 110 + unset($configuration['configuration']);
  111 + } else {
  112 + throw new \ErrorException('Не указан обязательный параметр конфигурационного файла - converter_conf[configuration]');
110 } 113 }
111 114
112 - // проставим аттрибуды из конфига{}{}  
113 - foreach ($configuration as $key_setting => $setting) {  
114 - if( property_exists( static::class, $key_setting ) )  
115 - static::$$key_setting = $setting;  
116 - } 115 + // проставим аттрибуты из конфига{}{}
  116 + self::setAttributes($configuration);
117 117
118 - foreach ( $arr_config as $key => $value ) {  
119 - if ( $hasKey ){ 118 + foreach ($arr_config as $key => $value) {
  119 + if ($hasKey) {
120 // у нас ассоциативный массив, и мы можем конвертировать каждое значение в отдельности 120 // у нас ассоциативный массив, и мы можем конвертировать каждое значение в отдельности
121 - if ( is_array( $value ) ) { 121 + if (is_array($value)) {
122 //если пустой массив то конвертируем всю строку 122 //если пустой массив то конвертируем всю строку
123 - if (count( $value ) === 0 ){ 123 + if (count($value) === 0) {
124 124
125 - $arr = self::$key( $arr ); 125 + $arr = self::$key($arr);
126 continue; 126 continue;
127 } 127 }
128 // иначе конвертируем каждую ячейку в отдельности 128 // иначе конвертируем каждую ячейку в отдельности
129 foreach ($value as $sub_value) { 129 foreach ($value as $sub_value) {
130 if (isset($arr[$sub_value])) { 130 if (isset($arr[$sub_value])) {
131 // конвертируем только те ячейки которые сопоставлены в прочитанном массиве с колонками в конфигурационном файле 131 // конвертируем только те ячейки которые сопоставлены в прочитанном массиве с колонками в конфигурационном файле
132 - $arr[$sub_value] = self::$key( $arr[$sub_value] ); 132 + $arr[$sub_value] = self::$key($arr[$sub_value]);
133 } 133 }
134 134
135 } 135 }
@@ -137,15 +137,15 @@ class Converter extends Behavior @@ -137,15 +137,15 @@ class Converter extends Behavior
137 137
138 if (isset($arr[$value])) { 138 if (isset($arr[$value])) {
139 // конвертируем только те ячейки которые сопоставлены в прочитанном массиве с колонками в конфигурационном файле 139 // конвертируем только те ячейки которые сопоставлены в прочитанном массиве с колонками в конфигурационном файле
140 - $arr[$value] = self::$key( $arr[$value] );  
141 - // CustomVarDamp::dump($result); 140 + $arr[$value] = self::$key($arr[$value]);
  141 + // CustomVarDamp::dump($result);
142 } 142 }
143 143
144 } 144 }
145 145
146 } else { 146 } else {
147 // нет заголовка - мы можем конвертировать только строку в целом 147 // нет заголовка - мы можем конвертировать только строку в целом
148 - $arr = self::$key( $arr ); 148 + $arr = self::$key($arr);
149 } 149 }
150 150
151 } 151 }
@@ -153,6 +153,14 @@ class Converter extends Behavior @@ -153,6 +153,14 @@ class Converter extends Behavior
153 return $arr; 153 return $arr;
154 } 154 }
155 155
  156 + public static function setAttributes($configuration)
  157 + {
  158 + foreach ($configuration as $key_setting => $setting) {
  159 + if (property_exists(static::class, $key_setting))
  160 + static::$$key_setting = $setting;
  161 + }
  162 +
  163 + }
156 164
157 165
158 } 166 }
159 \ No newline at end of file 167 \ No newline at end of file
vendor/yiisoft/multiparser/ParserInterface.php renamed to vendor/yiisoft/multiparser/ConverterInterface.php
1 <?php 1 <?php
2 /** 2 /**
3 * Created by PhpStorm. 3 * Created by PhpStorm.
4 - * User: Cibermag  
5 - * Date: 04.09.2015  
6 - * Time: 18:25 4 + * User: Tsurkanov
  5 + * Date: 20.10.2015
  6 + * Time: 13:38
7 */ 7 */
8 8
9 namespace yii\multiparser; 9 namespace yii\multiparser;
10 10
11 11
12 -interface ParserInterface {  
13 -  
14 - public function setup();  
15 -  
16 - public function read(); 12 +interface ConverterInterface {
17 13
  14 + public static function convertByConfiguration( $arr_values_to_convert, $configuration );
18 15
19 } 16 }
20 \ No newline at end of file 17 \ No newline at end of file
vendor/yiisoft/multiparser/CsvParser.php
@@ -9,11 +9,10 @@ use common\components\CustomVarDamp; @@ -9,11 +9,10 @@ use common\components\CustomVarDamp;
9 /** 9 /**
10 * Class CsvParser 10 * Class CsvParser
11 * @package yii\multiparser 11 * @package yii\multiparser
  12 + * @todo - перевести на анг. яз.
12 */ 13 */
13 -class CsvParser implements ParserInterface 14 +class CsvParser extends Parser
14 { 15 {
15 -  
16 -  
17 /** @var bool 16 /** @var bool
18 имеет ли файл заголовок который будет установлен ключами возвращемого массива*/ 17 имеет ли файл заголовок который будет установлен ключами возвращемого массива*/
19 public $hasHeaderRow = false; 18 public $hasHeaderRow = false;
@@ -46,10 +45,10 @@ class CsvParser implements ParserInterface @@ -46,10 +45,10 @@ class CsvParser implements ParserInterface
46 * используется при автоопределении первой строки*/ 45 * используется при автоопределении первой строки*/
47 public $min_column_quantity = 5; 46 public $min_column_quantity = 5;
48 47
49 - /** @var array - конфигурация конвертера значений */  
50 - public $converter_conf = [];  
51 - /** @var array - конвертер созданный по конфигурации */  
52 - public $converter = NULL; 48 +// /** @var array - конфигурация конвертера значений */
  49 +// public $converter_conf = [];
  50 +// /** @var array - конвертер созданный по конфигурации */
  51 +// public $converter = NULL;
53 /** @var int - текущая строка */ 52 /** @var int - текущая строка */
54 private $current_line = 0; 53 private $current_line = 0;
55 54
@@ -66,27 +65,15 @@ class CsvParser implements ParserInterface @@ -66,27 +65,15 @@ class CsvParser implements ParserInterface
66 if ($this->auto_detect_first_line) { 65 if ($this->auto_detect_first_line) {
67 $this->shiftToFirstValuableLine(); 66 $this->shiftToFirstValuableLine();
68 } 67 }
69 - $this->setupConverter();  
70 -  
71 - }  
72 -  
73 - /**  
74 - * устанавливает конвертер значений согласно конфигурационным настройкам  
75 - */  
76 - public function setupConverter()  
77 - {  
78 - if (!count($this->converter_conf)) {  
79 - $this->converter = new Converter();  
80 - if ($this->hasHeaderRow) {  
81 - // если у файла есть заголовок, то в результате имеем ассоциативный массив  
82 - $this->converter_conf['hasKey'] = 1;  
83 - }  
84 - //$this->converter->configuration = $this->converter_conf;  
85 68
  69 + if ($this->hasHeaderRow) {
  70 + // если у файла есть заголовок, то в результате имеем ассоциативный массив
  71 + $this->converter_conf['hasKey'] = 1;
86 } 72 }
87 - }  
88 73
  74 + parent::setup();
89 75
  76 + }
90 /** 77 /**
91 * определяет первую значимую строку, 78 * определяет первую значимую строку,
92 * считывается файл пока в нем не встретится строка с непустыми колонками 79 * считывается файл пока в нем не встретится строка с непустыми колонками
@@ -208,25 +195,5 @@ class CsvParser implements ParserInterface @@ -208,25 +195,5 @@ class CsvParser implements ParserInterface
208 195
209 } 196 }
210 197
211 - /**  
212 - * @param $arr  
213 - * @return mixed  
214 - * преобразовует значения прочитанного массива в нужные типы, согласно конфигурации конвертера  
215 - */  
216 - protected function convert($arr)  
217 - {  
218 - $result = $arr;  
219 - $converter = $this->converter;  
220 -  
221 - if (!is_null($converter)) {  
222 -  
223 - $result = $converter->convertByConfiguration( $arr, $this->converter_conf );  
224 -  
225 - }  
226 -  
227 - return $result;  
228 -  
229 - }  
230 -  
231 198
232 } 199 }
233 \ No newline at end of file 200 \ No newline at end of file
vendor/yiisoft/multiparser/ObjectCreator.php 0 → 100644
  1 +<?php
  2 +/**
  3 + * Created by PhpStorm.
  4 + * User: Tsurkanov
  5 + * Date: 20.10.2015
  6 + * Time: 16:24
  7 + */
  8 +
  9 +namespace yii\multiparser;
  10 +
  11 +
  12 +use common\components\CustomVarDamp;
  13 +
  14 +class ObjectCreator {
  15 + public static function build( array $configuration ){
  16 + if ( isset( $configuration['class'] ) ) {
  17 + $class = $configuration['class'];
  18 + unset( $configuration['class'] );
  19 + } else{
  20 + throw new \ErrorException('Error configuration - undefined class');
  21 + }
  22 +
  23 + $object = new $class();
  24 + foreach ($configuration as $name => $value) {
  25 + $object->$name = $value;
  26 + }
  27 +
  28 + return $object;
  29 + }
  30 +}
0 \ No newline at end of file 31 \ No newline at end of file
vendor/yiisoft/multiparser/Parser.php 0 → 100644
  1 +<?php
  2 +/**
  3 + * Created by PhpStorm.
  4 + * User: Cibermag
  5 + * Date: 04.09.2015
  6 + * Time: 18:25
  7 + */
  8 +
  9 +namespace yii\multiparser;
  10 +
  11 +abstract class Parser
  12 +{
  13 + public $converter_conf = [];
  14 + protected $converter = NULL;
  15 +
  16 + public function setup()
  17 + {
  18 + $this->setupConverter();
  19 + }
  20 +
  21 + protected function setupConverter()
  22 + {
  23 + $converter = ObjectCreator::build( $this->converter_conf );
  24 + if ( $converter instanceof ConverterInterface ) {
  25 +
  26 + $this->converter = $converter;
  27 +
  28 + }
  29 +
  30 + }
  31 +
  32 + public abstract function read();
  33 +
  34 + /**
  35 + * @param $arr
  36 + * @return mixed
  37 + * преобразовует значения прочитанного массива в нужные типы, согласно конфигурации конвертера
  38 + */
  39 + protected function convert( $arr )
  40 + {
  41 + if ($this->converter !== NULL) {
  42 +
  43 + $arr = $this->converter->convertByConfiguration( $arr, $this->converter_conf );
  44 +
  45 + }
  46 +
  47 +
  48 + return $arr;
  49 +
  50 + }
  51 +}
0 \ No newline at end of file 52 \ No newline at end of file
vendor/yiisoft/multiparser/ParserConfigurator.php deleted
1 -<?php  
2 -namespace yii\multiparser;  
3 -  
4 -class ParserConfigurator  
5 -{  
6 -  
7 - protected static $configuration;  
8 -  
9 - public static function getConfiguration($extension, $parameter)  
10 - {  
11 - self::setConfiguration();  
12 -  
13 - if (!isset( self::$configuration[$extension] )){  
14 - throw new \ErrorException( "Parser do not maintain file with extension {$extension}");  
15 - }  
16 - if (!isset( self::$configuration[$extension][$parameter] )){  
17 - throw new \ErrorException( "Parser configurator do not have settings for {$parameter} parameter");  
18 - }  
19 -  
20 - return self::$configuration[$extension][$parameter];  
21 - }  
22 -  
23 - protected static function setConfiguration()  
24 - {  
25 -  
26 - self::$configuration = require(__DIR__ . '/config.php');  
27 -  
28 - }  
29 -  
30 -  
31 -  
32 -}  
33 \ No newline at end of file 0 \ No newline at end of file
vendor/yiisoft/multiparser/ParserHandler.php
@@ -2,17 +2,21 @@ @@ -2,17 +2,21 @@
2 2
3 namespace yii\multiparser; 3 namespace yii\multiparser;
4 4
5 -use Yii; 5 +use common\components\CustomVarDamp;
6 6
7 class ParserHandler 7 class ParserHandler
8 { 8 {
9 - 9 + //@todo - добавить комменты на анг язе (ошибки выкидывать тоже на англ яз.)
  10 + //@todo - сделать универсальную обработку ошибок
  11 + //@todo - возможно отказаться от YiiParserHandler
10 const DEFAULT_MODE = 'web'; 12 const DEFAULT_MODE = 'web';
11 /** @var string */ 13 /** @var string */
12 protected $filePath; 14 protected $filePath;
13 15
14 /** @var string */ 16 /** @var string */
15 - protected $configuration; 17 + protected $configuration = [];
  18 + /** @var string */
  19 + protected $custom_configuration = [];
16 20
17 /** @var instance of SplFileObject */ 21 /** @var instance of SplFileObject */
18 protected $fileObject; 22 protected $fileObject;
@@ -20,16 +24,16 @@ class ParserHandler @@ -20,16 +24,16 @@ class ParserHandler
20 /** @var string - extension of file $filePath */ 24 /** @var string - extension of file $filePath */
21 protected $extension; 25 protected $extension;
22 26
23 - /** @var string - extension of file $filePath */ 27 + /** @var string - */
24 protected $mode; 28 protected $mode;
25 29
26 - /** @var string - extension of file $filePath */ 30 + /** @var string - */
27 protected $options; 31 protected $options;
28 32
29 /** 33 /**
30 * @param string first line in file for parsing 34 * @param string first line in file for parsing
31 */ 35 */
32 - public function __construct($filePath, $options = []) 36 + public function setup($filePath, $options = [])
33 { 37 {
34 $this->filePath = $filePath; 38 $this->filePath = $filePath;
35 if (isset($options['mode'])) { 39 if (isset($options['mode'])) {
@@ -45,36 +49,22 @@ class ParserHandler @@ -45,36 +49,22 @@ class ParserHandler
45 49
46 $this->options = $options; 50 $this->options = $options;
47 51
48 - try {  
49 - $this->fileObject = new \SplFileObject($this->filePath, 'r');  
50 - } catch (\ErrorException $e) {  
51 - // Yii::warning("Ошибка открытия файла {$this->filePath}");  
52 - echo "Ошибка открытия файла {$this->filePath}";  
53 - return [];  
54 - } 52 + $this->fileObject = new \SplFileObject($this->filePath, 'r');
55 53
56 $options['file'] = $this->fileObject; 54 $options['file'] = $this->fileObject;
57 $this->extension = $this->fileObject->getExtension(); 55 $this->extension = $this->fileObject->getExtension();
58 56
59 - try {  
60 - $this->configuration = ParserConfigurator::getConfiguration($this->extension, $this->mode);  
61 - $this->configuration = array_merge($this->configuration, $options);  
62 -  
63 - } catch (\ErrorException $e) {  
64 - echo $e->getMessage();  
65 - return [];  
66 - } 57 + $this->custom_configuration = $this->getCustomConfiguration($this->extension, $this->mode);
  58 + $this->custom_configuration = array_merge_recursive($this->custom_configuration, $options);
67 59
68 } 60 }
69 61
70 public function run() 62 public function run()
71 { 63 {
72 -  
73 $result = []; 64 $result = [];
74 - // @todo - rewrite to universal manner  
75 - // \common\components\CustomVarDamp::dumpAndDie($this);  
76 - if (count($this->configuration)) {  
77 - $parser = Yii::createObject($this->configuration); 65 + if (count($this->custom_configuration)) {
  66 +
  67 + $parser = $this->createObjectByConfiguration($this->custom_configuration);
78 68
79 try { 69 try {
80 70
@@ -91,5 +81,32 @@ class ParserHandler @@ -91,5 +81,32 @@ class ParserHandler
91 81
92 return $result; 82 return $result;
93 } 83 }
  84 +
  85 + public function getCustomConfiguration($extension, $parameter)
  86 + {
  87 + if (!count($this->configuration)) {
  88 + $this->setConfiguration(require(__DIR__ . '/config.php'));
  89 + }
  90 +
  91 + if (!isset($this->configuration[$extension])) {
  92 + throw new \ErrorException("Parser do not maintain file with extension {$extension}");
  93 + }
  94 + if (!isset($this->configuration[$extension][$parameter])) {
  95 + throw new \ErrorException("Parser configurator do not have settings for {$parameter} parameter");
  96 + }
  97 +
  98 + return $this->configuration[$extension][$parameter];
  99 + }
  100 +
  101 + public function setConfiguration($configuration)
  102 + {
  103 + $this->configuration = $configuration;
  104 + }
  105 +
  106 + protected function createObjectByConfiguration($configuration)
  107 + {
  108 + return ObjectCreator::build($configuration);
  109 + }
94 } 110 }
95 111
  112 +
vendor/yiisoft/multiparser/XmlParser.php
@@ -9,7 +9,7 @@ @@ -9,7 +9,7 @@
9 namespace yii\multiparser; 9 namespace yii\multiparser;
10 10
11 11
12 -class XmlParser implements ParserInterface{ 12 +class XmlParser extends Parser{
13 /** @var экземляр SplFileObject читаемого файла */ 13 /** @var экземляр SplFileObject читаемого файла */
14 public $file; 14 public $file;
15 public $node; 15 public $node;
vendor/yiisoft/multiparser/YiiConverter.php 0 → 100644
  1 +<?php
  2 +/**
  3 + * Created by PhpStorm.
  4 + * User: Cibermag
  5 + * Date: 07.09.2015
  6 + * Time: 15:56
  7 + */
  8 +
  9 +namespace yii\multiparser;
  10 +
  11 +use common\components\CustomVarDamp;
  12 +use yii\base\Component;
  13 +use yii\base\ErrorException;
  14 +
  15 +
  16 +class YiiConverter extends Component{
  17 +
  18 +public $configuration;
  19 +public $converter;
  20 +
  21 + public function init()
  22 + {
  23 + parent::init();
  24 + $converter = \Yii::createObject( $this->configuration );
  25 + if ( $converter instanceof ConverterInterface ) {
  26 +
  27 + $this->converter = $converter;
  28 + }else{
  29 + throw new ErrorException('Wrong type of converter');
  30 + }
  31 +
  32 +
  33 + }
  34 +
  35 + public function convertTo( $method, $value, $attributes = [] ){
  36 +
  37 + if ( $attributes ) {
  38 + $this->converter->setAttributes($attributes);
  39 + }
  40 + return $this->converter->$method( $value );
  41 +
  42 + }
  43 +
  44 + public function convertByConfiguration( $value, $configuration ){
  45 +
  46 + return $this->converter->convertByConfiguration( $value, $configuration );
  47 +
  48 + }
  49 +
  50 +
  51 +}
0 \ No newline at end of file 52 \ No newline at end of file
vendor/yiisoft/multiparser/YiiMultiparser.php
@@ -17,27 +17,29 @@ use yii\base\Component; @@ -17,27 +17,29 @@ use yii\base\Component;
17 class YiiMultiparser extends Component{ 17 class YiiMultiparser extends Component{
18 18
19 public $configuration; 19 public $configuration;
  20 +public $parserHandler;
20 21
21 - public function getConfiguration($extension, $conf_parameter){  
22 -  
23 - if (!isset( $this->configuration[$extension] )){  
24 - throw new \ErrorException( "Parser do not maintain file with extension {$extension}");  
25 - }  
26 - if (!isset( $this->configuration[$extension][$conf_parameter] )){  
27 - throw new \ErrorException( "Parser configurator do not have settings for {$conf_parameter} parameter");  
28 - }  
29 -  
30 - return $this->configuration[$extension][$conf_parameter]; 22 + public function init()
  23 + {
  24 + parent::init();
  25 + $this->parserHandler = new YiiParserHandler( );
  26 + $this->parserHandler->setConfiguration( $this->configuration );
31 27
32 } 28 }
33 29
34 30
35 public function parse( $filePath, $options = [] ){ 31 public function parse( $filePath, $options = [] ){
36 32
37 - $parser = new YiiParserHandler( $filePath, $options );  
38 - return $parser->run(); 33 + $this->parserHandler->setup( $filePath, $options );
  34 +
  35 + return $this->parserHandler->run();
39 36
40 } 37 }
41 38
  39 + public function getConfiguration( $extension, $parameter ){
  40 +
  41 + return $this->parserHandler->getCustomConfiguration( $extension, $parameter );
  42 +
  43 + }
42 44
43 } 45 }
44 \ No newline at end of file 46 \ No newline at end of file
vendor/yiisoft/multiparser/YiiParserHandler.php
@@ -17,68 +17,74 @@ class YiiParserHandler extends ParserHandler{ @@ -17,68 +17,74 @@ class YiiParserHandler extends ParserHandler{
17 /** 17 /**
18 * @param $filePath 18 * @param $filePath
19 * @param array $options 19 * @param array $options
20 - * проверяет читабенльность переданного файла, а также наличие настроек парсера в конфигурационном файле для данного типа файла 20 + * проверяет читабельность переданного файла, а также наличие настроек парсера в конфигурационном файле для данного типа файла
21 */ 21 */
22 - public function __construct($filePath, $options = []) 22 +// public function setup($filePath, $options = [])
  23 +// {
  24 +// $this->filePath = $filePath;
  25 +// if (isset($options['mode'])) {
  26 +//
  27 +// $this->mode = $options['mode'];
  28 +// unset($options['mode']);
  29 +//
  30 +// } else {
  31 +//
  32 +// $this->mode = self::DEFAULT_MODE;
  33 +//
  34 +// }
  35 +//
  36 +// $this->options = $options;
  37 +//
  38 +// try {
  39 +// $this->fileObject = new \SplFileObject($this->filePath, 'r');
  40 +// } catch (\ErrorException $e) {
  41 +// // Yii::warning("Ошибка открытия файла {$this->filePath}");
  42 +// echo "Ошибка открытия файла {$this->filePath}";
  43 +// return [];
  44 +// }
  45 +//
  46 +// $options['file'] = $this->fileObject;
  47 +// $this->extension = $this->fileObject->getExtension();
  48 +//
  49 +// try {
  50 +//
  51 +// $this->configuration = array_merge_recursive ($this->configuration, $options);
  52 +//
  53 +// } catch (\ErrorException $e) {
  54 +// echo $e->getMessage();
  55 +// return [];
  56 +// }
  57 +//
  58 +// }
  59 +//
  60 +// public function run()
  61 +// {
  62 +//
  63 +// $result = [];
  64 +//
  65 +// // \common\components\CustomVarDamp::dumpAndDie($this);
  66 +// if (count($this->configuration)) {
  67 +// $parser = \Yii::createObject($this->configuration);
  68 +//
  69 +// try {
  70 +//
  71 +// $parser->setup();
  72 +// $result = $parser->read();
  73 +//
  74 +// } catch (\ErrorException $e) {
  75 +//
  76 +// echo $e->getMessage();
  77 +//
  78 +// }
  79 +//
  80 +// }
  81 +//
  82 +// return $result;
  83 +// }
  84 + protected function createObjectByConfiguration($configuration)
23 { 85 {
24 - $this->filePath = $filePath;  
25 - if (isset($options['mode'])) {  
26 -  
27 - $this->mode = $options['mode'];  
28 - unset($options['mode']);  
29 -  
30 - } else {  
31 -  
32 - $this->mode = self::DEFAULT_MODE;  
33 -  
34 - }  
35 -  
36 - $this->options = $options;  
37 -  
38 - try {  
39 - $this->fileObject = new \SplFileObject($this->filePath, 'r');  
40 - } catch (\ErrorException $e) {  
41 - // Yii::warning("Ошибка открытия файла {$this->filePath}");  
42 - echo "Ошибка открытия файла {$this->filePath}";  
43 - return [];  
44 - }  
45 -  
46 - $options['file'] = $this->fileObject;  
47 - $this->extension = $this->fileObject->getExtension();  
48 -  
49 - try {  
50 - $this->configuration = \Yii::$app->multiparser->getConfiguration($this->extension, $this->mode);  
51 - $this->configuration = array_merge_recursive ($this->configuration, $options);  
52 - } catch (\ErrorException $e) {  
53 - echo $e->getMessage();  
54 - return [];  
55 - }  
56 - 86 + return \Yii::createObject($configuration);
57 } 87 }
58 88
59 - public function run()  
60 - {  
61 -  
62 - $result = [];  
63 -  
64 - // \common\components\CustomVarDamp::dumpAndDie($this);  
65 - if (count($this->configuration)) {  
66 - $parser = \Yii::createObject($this->configuration);  
67 -  
68 - try {  
69 -  
70 - $parser->setup();  
71 - $result = $parser->read();  
72 -  
73 - } catch (\ErrorException $e) {  
74 -  
75 - echo $e->getMessage();  
76 -  
77 - }  
78 -  
79 - }  
80 -  
81 - return $result;  
82 - }  
83 89
84 } 90 }
85 \ No newline at end of file 91 \ No newline at end of file