RgGrupController.php 8.83 KB
<?php
/**
 * Created by PhpStorm.
 * User: Tsurkanov
 * Date: 27.10.2015
 * Time: 15:22
 */

namespace backend\controllers;

use backend\components\base\BaseController;
use backend\models\UploadFileRgForm;
use common\components\exceptions\RgParsingException;
use common\components\ModelArrayValidator;
use common\components\parsers\MailAttachmentsSaver;
use common\models\Margins;
use common\models\MarginsGroups;
use yii\filters\AccessControl;
use Yii;
use yii\web\UploadedFile;
use yii\data\ArrayDataProvider;
use common\components\parsers\DynamicFormHelper;
use common\components\CustomArrayHelper;
use backend\components\traits\ParserTrait;

class RgGrupController extends BaseController
{
    use ParserTrait;
    public $layout = "/column";

    /**
     * @inheritdoc
     */
    public function behaviors()
    {
        return [
            'access' => [
                'class' => AccessControl::className(),
                'rules' => [
                    [
                        'allow' => true,
                        'roles' => ['@'],
                    ],
                ],
            ],
//            'verbs' => [
//                'class' => VerbFilter::className(),
//                'actions' => [
//                    'logout' => ['post'],
//                ],
//            ],
        ];
    }

    public function actionIndex()
    {
        $model = new UploadFileRgForm();

        return $this->render('index', ['model' => $model]);
    }

    public function actionResults()
    {
        $model = new UploadFileRgForm();
        $data = [];

        if ($model->load(Yii::$app->request->post())) {
            $model->file = UploadedFile::getInstance($model, 'file');
            // первый проход - валидируем, сохраняем файл, ложим в кеш  отпарсенные данные и параметры модели (потом при записи в базу данных они пригодятся)
            if ($model->validate()) {
                $model->file_path = Yii::getAlias('@manual_upload') . '/' . $model->file->name;
                $model->file->saveAs($model->file_path);
                //запускаем парсинг
                $options['mode'] = 'rg';
                $data = $model->readFile($options);
                // сохраняем в кеш отпарсенные даные
                $this->parserCacheHandler(1, $data, $model);
            } else {
                // не прошла валидация форма загрузки файлов
                $this->throwStringErrorException($model, 'common\components\exceptions\RgParsingException');
            }
            // листаем пагинатором, или повторно вызываем - считываем из кеша отпрасенные данные
        } else if (Yii::$app->getCache()->get('parser_data')) {

            $data = json_decode(Yii::$app->getCache()->get('parser_data'), true);

        }
        // сборка динамической модели и её рендеринг
        return $this->renderResultView($data);
    }

    public function actionWrite()
    {
        //получим колонки которые выбрал пользователь
        $arr_attributes = Yii::$app->request->post()['DynamicModel'];
        $margin_model = new MarginsGroups();
        //соберем модель по полученным данным
        $model = DynamicFormHelper::CreateDynamicModel($arr_attributes);
        //добавим правила валидации (колонки должны быть те что в модели)
        foreach ($arr_attributes as $key => $value) {
            $model->addRule($key, 'in', ['range' => array_keys(Margins::getHeader())]);
        }
        // установим режим проверки обязательных полей
        $margin_model->setScenario('form_upload_validation');
        $model_validator = new ModelArrayValidator($margin_model);
        // провалидируем выбранные колонки
        if ($model->validate() && $model_validator->validateRow($this->getAttributesForValidate($arr_attributes))) {

            // валидация успешна у нас есть соответсвие колонок, преобразуем в массив данное соответсвие для дальнейшей работы
            $arr = $model->toArray();

            // получим данные из кеша
            $this->parserCacheHandler(0, $data, $configuration);

            array_walk($arr, function (&$val) {
                $val = '!' . $val;
            });

            // соотнесем отпарсенные данные с соответсивем полученным от пользователя
            // для этого преобразуем массив отпарсенных данных - назначим ключи согласно соответствию
            $data = CustomArrayHelper::createAssocArray($data, $arr, 'attr_');

            // в первой строке у нас заголовки - уберем
            unset($data[0]); //- закоментировать если в конфиге парсера указано о наличии заголовка
            // подготовим данные для записи в таблицу w_margins_groups
            $data = $this->convertDataByConfiguration($data, $configuration);

            // валидируем отпарсенные данные моделью в которую будем записывать
            $margin_model->setScenario('default');
            $data = $model_validator->validate($data);
            $msg = $model_validator->getMassage();
            $type_msg = $model_validator->hasError() ? 'warning' : 'success';
            $model_validator->close();
            // сохраним подготовленные данные
            if (!empty($data)) {
                if (MarginsGroups::ManualInsertWithUpdate($data, ['group', 'importer_id', 'margin_id'])) {
                    // все прошло успешно - очищаем кеш
                    $this->parserCacheHandler(2);

                    if (file_exists($configuration['file_path']))
                        unlink($configuration['file_path']);
                }

            }
            Yii::$app->session->setFlash($type_msg, $msg);
            return $this->render('index', ['model' => $configuration]);

        } else {
            // не прошла валидация формы загрузки файлов
            $errors_str = "Ошибка валидации формы загрузки файлов. ";
            $this->throwStringErrorException($margin_model, 'common\components\exceptions\RgParsingException', $errors_str);
        }
    }

    protected function convertDataByConfiguration($data, $configuration)
    {
        $arr_values = [];
        $group = '';
        $importer_id = $configuration['importer_id'];
        foreach ($data as $row_data) {

            if (isset($row_data['!group'])) {
                $group = $row_data['!group'];
                unset($row_data['!group']);
            }
            if (isset($row_data['!_null'])) {
                unset($row_data['!_null']);
            }

            foreach ($row_data as $key => $value) {
                if ($group)
                    $row['group'] = trim($group);

                $row['importer_id'] = trim($importer_id);
                $row['margin_id'] = ltrim($key, '!');
                $row['koef'] = \Yii::$app->converter->convertTo('float', $value, ['precision' => 6]);

                $arr_values[] = $row;
            }
        }
        return $arr_values;
    }

    protected function getBasicColumns()
    {
        return Margins::getHeader();
    }

    // подготавливает массив для валидирования моделью - MarginsGroups
    // для этого меняем выбранные значения именем поля - margin_id
    protected function getAttributesForValidate($arr)
    {
        $base_columns_arr = Margins::find()->select('id')->asArray()->all();
        $base_columns_arr = array_column($base_columns_arr,'id');

        array_walk( $arr, function (&$value, $key, $base_columns_arr) {
            if (in_array( $value, $base_columns_arr )){
                $value = 'margin_id';
            }
        }, $base_columns_arr );

        return array_flip( $arr );
    }

//    public function actionMail()
//    {
//        $mail_saver = new MailAttachmentsSaver('{imap.gmail.com:993/imap/ssl/novalidate-cert}', 'tsurkanovm@gmail.com', 'Wtvr@2000');
//        //$mail_saver = new MailAttachmentsSaver('{imap.gmail.com:993/imap/ssl/novalidate-cert}', 'price@italauto.com.ua', '67853562');
//        $mail_saver->saveAttachmentsTo();
//    }

}