Commit ddc5878206349d0410f48f43a91e80c00734fb96

Authored by Administrator
2 parents 9c2b01c6 6d07a535

Merge remote-tracking branch 'origin/master'

1 -.idea  
2 /uploads 1 /uploads
  2 +/.idea
3 /vendor 3 /vendor
4 /storage 4 /storage
5 tests/_output/* 5 tests/_output/*
backend/controllers/LogController.php 0 → 100644
  1 +<?php
  2 +
  3 +namespace backend\controllers;
  4 +
  5 +use Yii;
  6 +use backend\models\Log;
  7 +use backend\models\LogSearch;
  8 +use backend\components\base\BaseController;
  9 +use yii\web\NotFoundHttpException;
  10 +use yii\filters\VerbFilter;
  11 +
  12 +/**
  13 + * LogController implements the CRUD actions for Log model.
  14 + */
  15 +class LogController extends BaseController
  16 +{
  17 + public $layout = "/column";
  18 +
  19 + public function behaviors()
  20 + {
  21 + return [
  22 + 'verbs' => [
  23 + 'class' => VerbFilter::className(),
  24 + 'actions' => [
  25 + 'delete' => ['post'],
  26 + ],
  27 + ],
  28 + ];
  29 + }
  30 +
  31 + /**
  32 + * Lists all Log models.
  33 + * @return mixed
  34 + */
  35 + public function actionIndex()
  36 + {
  37 + $searchModel = new LogSearch();
  38 + $dataProvider = $searchModel->search(Yii::$app->request->queryParams);
  39 +
  40 + return $this->render('index', [
  41 + 'searchModel' => $searchModel,
  42 + 'dataProvider' => $dataProvider,
  43 + ]);
  44 + }
  45 +
  46 + /**
  47 + * Displays a single Log model.
  48 + * @param string $id
  49 + * @return mixed
  50 + */
  51 + public function actionView($id)
  52 + {
  53 + return $this->render('view', [
  54 + 'model' => $this->findModel($id),
  55 + ]);
  56 + }
  57 +
  58 + /**
  59 + * Creates a new Log model.
  60 + * If creation is successful, the browser will be redirected to the 'view' page.
  61 + * @return mixed
  62 + */
  63 + public function actionCreate()
  64 + {
  65 + $model = new Log();
  66 +
  67 + if ($model->load(Yii::$app->request->post()) && $model->save()) {
  68 + return $this->redirect(['view', 'id' => $model->id]);
  69 + } else {
  70 + return $this->render('create', [
  71 + 'model' => $model,
  72 + ]);
  73 + }
  74 + }
  75 +
  76 + /**
  77 + * Updates an existing Log model.
  78 + * If update is successful, the browser will be redirected to the 'view' page.
  79 + * @param string $id
  80 + * @return mixed
  81 + */
  82 + public function actionUpdate($id)
  83 + {
  84 + $model = $this->findModel($id);
  85 +
  86 + if ($model->load(Yii::$app->request->post()) && $model->save()) {
  87 + return $this->redirect(['view', 'id' => $model->id]);
  88 + } else {
  89 + return $this->render('update', [
  90 + 'model' => $model,
  91 + ]);
  92 + }
  93 + }
  94 +
  95 + /**
  96 + * Deletes an existing Log model.
  97 + * If deletion is successful, the browser will be redirected to the 'index' page.
  98 + * @param string $id
  99 + * @return mixed
  100 + */
  101 + public function actionDelete($id)
  102 + {
  103 + $this->findModel($id)->delete();
  104 +
  105 + return $this->redirect(['index']);
  106 + }
  107 +
  108 + /**
  109 + * Finds the Log model based on its primary key value.
  110 + * If the model is not found, a 404 HTTP exception will be thrown.
  111 + * @param string $id
  112 + * @return Log the loaded model
  113 + * @throws NotFoundHttpException if the model cannot be found
  114 + */
  115 + protected function findModel($id)
  116 + {
  117 + if (($model = Log::findOne($id)) !== null) {
  118 + return $model;
  119 + } else {
  120 + throw new NotFoundHttpException('The requested page does not exist.');
  121 + }
  122 + }
  123 +}
backend/controllers/ParserController.php
@@ -237,11 +237,12 @@ class ParserController extends BaseController @@ -237,11 +237,12 @@ class ParserController extends BaseController
237 237
238 } 238 }
239 239
  240 + $controller = new \console\controllers\ParserController( 'parse-prices', $this->module );
  241 + $controller->actionSaveMailAttachments();
  242 + $controller->actionParsePrices();
  243 +
240 Yii::$app->session->setFlash( 'server-files', 'Файл успешно загружен' ); 244 Yii::$app->session->setFlash( 'server-files', 'Файл успешно загружен' );
241 $this->redirect('server-files'); 245 $this->redirect('server-files');
242 -  
243 -// $csv = new \console\controllers\ParserController( 'parse-csv', $this->module );  
244 -// $csv->actionParseCsv();  
245 } 246 }
246 247
247 248
backend/models/Log.php 0 → 100644
  1 +<?php
  2 +
  3 +namespace backend\models;
  4 +
  5 +use Yii;
  6 +
  7 +/**
  8 + * This is the model class for table "w_log".
  9 + *
  10 + * @property string $id
  11 + * @property integer $error
  12 + * @property string $record_type
  13 + * @property string $time_start
  14 + * @property string $importer_id
  15 + * @property string $time_end
  16 + * @property string $log_msg
  17 + * @property string $file_name
  18 + */
  19 +class Log extends \backend\components\base\BaseActiveRecord
  20 +{
  21 + /**
  22 + * @inheritdoc
  23 + */
  24 + public static function tableName()
  25 + {
  26 + return 'w_log';
  27 + }
  28 +
  29 + /**
  30 + * @inheritdoc
  31 + */
  32 + public function rules()
  33 + {
  34 + return [
  35 + [['error', 'record_type', 'importer_id'], 'integer'],
  36 + [['time_start', 'time_end'], 'safe'],
  37 + [['importer_id'], 'required'],
  38 + [['log_msg'], 'string'],
  39 + [['file_name'], 'string', 'max' => 100]
  40 + ];
  41 + }
  42 +
  43 + public function getImporter()
  44 + {
  45 + return Importers::findOne( $this->importer_id )->name;
  46 + }
  47 +
  48 + /**
  49 + * @inheritdoc
  50 + */
  51 + public function attributeLabels()
  52 + {
  53 + return [
  54 + 'id' => 'ID',
  55 + 'error' => 'Статус',
  56 + 'record_type' => 'Тип загрузки',
  57 + 'time_start' => 'Начало загрузки',
  58 + 'importer_id' => 'ID поставщика',
  59 + 'importer' => 'Файл поставщика',
  60 + 'time_end' => 'Конец загрузки',
  61 + 'log_msg' => 'Лог',
  62 + 'file_name' => 'Загружаемый файл',
  63 + ];
  64 + }
  65 +}
backend/models/LogSearch.php 0 → 100644
  1 +<?php
  2 +
  3 +namespace backend\models;
  4 +
  5 +use Yii;
  6 +use yii\base\Model;
  7 +use yii\data\ActiveDataProvider;
  8 +use backend\models\Log;
  9 +
  10 +/**
  11 + * LogSearch represents the model behind the search form about `backend\models\Log`.
  12 + */
  13 +class LogSearch extends Log
  14 +{
  15 + public $date_to;
  16 + /**
  17 + * @inheritdoc
  18 + */
  19 + public function rules()
  20 + {
  21 + return [
  22 + [['id', 'error', 'record_type', 'importer_id'], 'integer'],
  23 + [['time_start','date_to', 'time_end', 'file_name'], 'safe'],
  24 + ];
  25 + }
  26 +
  27 + /**
  28 + * @inheritdoc
  29 + */
  30 + public function scenarios()
  31 + {
  32 + // bypass scenarios() implementation in the parent class
  33 + return Model::scenarios();
  34 + }
  35 +
  36 + /**
  37 + * Creates data provider instance with search query applied
  38 + *
  39 + * @param array $params
  40 + *
  41 + * @return ActiveDataProvider
  42 + */
  43 + public function search($params)
  44 + {
  45 + $query = Log::find();
  46 +
  47 + $dataProvider = new ActiveDataProvider([
  48 + 'query' => $query,
  49 + ]);
  50 +
  51 + $this->load($params);
  52 +
  53 + if (!$this->validate()) {
  54 + // uncomment the following line if you do not want to return any records when validation fails
  55 + // $query->where('0=1');
  56 + return $dataProvider;
  57 + }
  58 +
  59 + $query->andFilterWhere([
  60 + 'error' => $this->error,
  61 + 'record_type' => $this->record_type,
  62 + 'importer_id' => $this->importer_id,
  63 + ]);
  64 +
  65 +// $query->andFilterWhere(['like', 'log_msg', $this->log_msg])
  66 +// ->andFilterWhere(['like', 'file_name', $this->file_name]);
  67 +
  68 + // отбор по дате
  69 + if( !empty( $this->time_start ) || !empty( $this->date_to ) ){
  70 + $date_from = \Yii::$app->converter->convertTo( 'timestamp', $this->time_start );
  71 + // в БД time_start хранится в timestamp, а не в строке unixtimestamp, поэтому нужно преобразовать в mysql timestamp
  72 + $date_from = date('Y-m-d H:i:s', $date_from);
  73 +
  74 + $date_to = \Yii::$app->converter->convertTo( 'timestamp', $this->date_to, ['begin_of_the_day' => false] );
  75 + $date_to = date('Y-m-d H:i:s', $date_to);
  76 +
  77 + $query->andFilterWhere([
  78 + 'between', 'time_start', $date_from, $date_to
  79 + ]);
  80 + }
  81 + // всегда сортируем по дате
  82 + $query->orderBy('time_start DESC');
  83 +
  84 + return $dataProvider;
  85 + }
  86 +}
backend/views/cart/index.php
@@ -80,6 +80,7 @@ Pjax::begin([&#39;id&#39; =&gt; &#39;gridViewContent&#39;]); @@ -80,6 +80,7 @@ Pjax::begin([&#39;id&#39; =&gt; &#39;gridViewContent&#39;]);
80 'separator' =>'по', 80 'separator' =>'по',
81 'attribute' => 'dt', 81 'attribute' => 'dt',
82 'type' => DatePicker::TYPE_RANGE, 82 'type' => DatePicker::TYPE_RANGE,
  83 + 'value2'=> date('dd-M-yyyy'),
83 'attribute2' => 'date_to', 84 'attribute2' => 'date_to',
84 ]), 85 ]),
85 ], 86 ],
backend/views/layouts/column.php
@@ -289,6 +289,7 @@ $this-&gt;beginContent(&#39;@app/views/layouts/main.php&#39;); @@ -289,6 +289,7 @@ $this-&gt;beginContent(&#39;@app/views/layouts/main.php&#39;);
289 ['label' => "Прайс файлы", 'url' => ['#'], 'items' => [ 289 ['label' => "Прайс файлы", 'url' => ['#'], 'items' => [
290 ['label' => 'Файлы на сервере', 'url' => ['parser/server-files']], 290 ['label' => 'Файлы на сервере', 'url' => ['parser/server-files']],
291 ['label' => 'Загрузить файл на сервер', 'url' => ['parser/index', 'mode' => 1]], 291 ['label' => 'Загрузить файл на сервер', 'url' => ['parser/index', 'mode' => 1]],
  292 + ['label' => 'Журнал загрузок', 'url' => ['log/index']],
292 ['label' => 'Ручная загрузка', 'url' => ['parser/index']], 293 ['label' => 'Ручная загрузка', 'url' => ['parser/index']],
293 ['label' => 'Проверка прайс файлов', 'url' => ['check-price/index']], 294 ['label' => 'Проверка прайс файлов', 'url' => ['check-price/index']],
294 ['label' => 'Управление префиксами', 'url' => ['importers-prefix/index']], 295 ['label' => 'Управление префиксами', 'url' => ['importers-prefix/index']],
backend/views/log/_form.php 0 → 100644
  1 +<?php
  2 +
  3 +use yii\helpers\Html;
  4 +use yii\widgets\ActiveForm;
  5 +
  6 +/* @var $this yii\web\View */
  7 +/* @var $model backend\models\Log */
  8 +/* @var $form yii\widgets\ActiveForm */
  9 +?>
  10 +
  11 +<div class="log-form">
  12 +
  13 + <?php $form = ActiveForm::begin(); ?>
  14 +
  15 + <?= $form->field($model, 'error')->textInput() ?>
  16 +
  17 + <?= $form->field($model, 'record_type')->textInput(['maxlength' => true]) ?>
  18 +
  19 + <?= $form->field($model, 'time_start')->textInput() ?>
  20 +
  21 + <?= $form->field($model, 'importer_id')->textInput(['maxlength' => true]) ?>
  22 +
  23 + <?= $form->field($model, 'time_end')->textInput() ?>
  24 +
  25 + <?= $form->field($model, 'log_msg')->textInput(['maxlength' => true]) ?>
  26 +
  27 + <?= $form->field($model, 'file_name')->textInput(['maxlength' => true]) ?>
  28 +
  29 + <div class="form-group">
  30 + <?= Html::submitButton($model->isNewRecord ? Yii::t('app', 'Create') : Yii::t('app', 'Update'), ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
  31 + </div>
  32 +
  33 + <?php ActiveForm::end(); ?>
  34 +
  35 +</div>
backend/views/log/_search.php 0 → 100644
  1 +<?php
  2 +
  3 +use yii\helpers\Html;
  4 +use yii\widgets\ActiveForm;
  5 +
  6 +/* @var $this yii\web\View */
  7 +/* @var $model backend\models\LogSearch */
  8 +/* @var $form yii\widgets\ActiveForm */
  9 +?>
  10 +
  11 +<div class="log-search">
  12 +
  13 + <?php $form = ActiveForm::begin([
  14 + 'action' => ['index'],
  15 + 'method' => 'get',
  16 + ]); ?>
  17 +
  18 + <?= $form->field($model, 'id') ?>
  19 +
  20 + <?= $form->field($model, 'error') ?>
  21 +
  22 + <?= $form->field($model, 'record_type') ?>
  23 +
  24 + <?php //$form->field($model, 'time_start') ?>
  25 +
  26 + <?= $form->field($model, 'importer_id') ?>
  27 +
  28 + <?php // echo $form->field($model, 'time_end') ?>
  29 +
  30 + <?php // echo $form->field($model, 'log_msg') ?>
  31 +
  32 + <?php // echo $form->field($model, 'file_name') ?>
  33 +
  34 + <div class="form-group">
  35 + <?= Html::submitButton(Yii::t('app', 'Search'), ['class' => 'btn btn-primary']) ?>
  36 + <?= Html::resetButton(Yii::t('app', 'Reset'), ['class' => 'btn btn-default']) ?>
  37 + </div>
  38 +
  39 + <?php ActiveForm::end(); ?>
  40 +
  41 +</div>
backend/views/log/index.php 0 → 100644
  1 +<?php
  2 +
  3 +use yii\helpers\Html;
  4 +use yii\grid\GridView;
  5 +use kartik\date\DatePicker;
  6 +
  7 +/* @var $this yii\web\View */
  8 +/* @var $searchModel backend\models\LogSearch */
  9 +/* @var $dataProvider yii\data\ActiveDataProvider */
  10 +
  11 +$this->title = Yii::t('app', 'Журнал загрузок');
  12 +$this->params['breadcrumbs'][] = $this->title;
  13 +?>
  14 +<div class="log-index">
  15 +
  16 + <h1><?= Html::encode($this->title) ?></h1>
  17 + <?php // echo $this->render('_search', ['model' => $searchModel]); ?>
  18 +
  19 +
  20 + <?= GridView::widget([
  21 + 'dataProvider' => $dataProvider,
  22 + 'filterModel' => $searchModel,
  23 + 'columns' => [
  24 + ['class' => 'yii\grid\SerialColumn'],
  25 + 'log_msg:ntext',
  26 + ['attribute' =>'record_type',
  27 + 'value' => function( $model ) {
  28 + $value = 'Почта';
  29 + if ( $model->record_type == 1 ) {
  30 + $value = 'Фон';
  31 + }
  32 + return $value;
  33 + },
  34 + 'filter' => [ 1 => 'Фон' , 2 => 'Почта' ]
  35 + ],
  36 + ['attribute' => 'time_start',
  37 + 'filter' => DatePicker::widget([
  38 + 'model' =>$searchModel,
  39 + 'language' =>'ru',
  40 + 'size' =>'xs',
  41 + 'separator' =>'по',
  42 + 'type' => DatePicker::TYPE_RANGE,
  43 + 'value2'=> date('dd-M-yyyy'),
  44 + 'attribute' => 'time_start',
  45 + 'attribute2' => 'date_to',
  46 + ]),
  47 + ],
  48 + ['attribute' => 'importer_id',
  49 + 'label' => 'Файл поставщика',
  50 + 'value' => function( $model ) {
  51 + return $model->importer;
  52 + },
  53 + ],
  54 +
  55 + ['attribute' => 'error',
  56 + 'value' => function( $model ) {
  57 + $value = 'Успешно';
  58 + if ($model->error) {
  59 + $value = 'C ошибкой';
  60 + }
  61 + return $value;
  62 + },
  63 + 'filter' => [ 'Успешно' ,'C ошибкой' ]
  64 + ],
  65 + ['class' => 'yii\grid\ActionColumn',
  66 + 'template' => '{view}'],
  67 + ],
  68 + ]); ?>
  69 +
  70 +</div>
backend/views/log/view.php 0 → 100644
  1 +<?php
  2 +
  3 +use yii\helpers\Html;
  4 +use yii\widgets\DetailView;
  5 +
  6 +/* @var $this yii\web\View */
  7 +/* @var $model common\models\Currency */
  8 +
  9 +$this->title = "Лог загрузки файла";
  10 +$this->params['breadcrumbs'][] = ['label' => 'Currencies', 'url' => ['index']];
  11 +$this->params['breadcrumbs'][] = $this->title;
  12 +?>
  13 +<div class="log-view">
  14 +
  15 + <h3><?= Html::encode($this->title) ?></h3>
  16 +
  17 + <?= DetailView::widget([
  18 + 'model' => $model,
  19 + 'attributes' => [
  20 + ['attribute' => 'error',
  21 + 'value' => $model->error ? 'C ошибкой' : 'Успешно',
  22 + ],
  23 + ['attribute' =>'record_type',
  24 + 'value' => $model->record_type == 1 ? 'Фоновая (ручная) загрузка' : 'Загрузка из вложений в почту',
  25 + ],
  26 + 'importer_id',
  27 + 'time_start',
  28 + 'time_end',
  29 + 'file_name',
  30 + 'log_msg',
  31 + ],
  32 + ]) ?>
  33 +
  34 +</div>
common/config/bootstrap.php
@@ -6,4 +6,5 @@ Yii::setAlias(&#39;console&#39;, dirname(dirname(__DIR__)) . &#39;/console&#39;); @@ -6,4 +6,5 @@ Yii::setAlias(&#39;console&#39;, dirname(dirname(__DIR__)) . &#39;/console&#39;);
6 Yii::setAlias('auto_upload', dirname(dirname(__DIR__)) . '/storage/parser_data/auto'); 6 Yii::setAlias('auto_upload', dirname(dirname(__DIR__)) . '/storage/parser_data/auto');
7 Yii::setAlias('manual_upload', dirname(dirname(__DIR__)) . '/storage/parser_data/manual'); 7 Yii::setAlias('manual_upload', dirname(dirname(__DIR__)) . '/storage/parser_data/manual');
8 Yii::setAlias('temp_upload', dirname(dirname(__DIR__)) . '/storage/parser_data/temp'); 8 Yii::setAlias('temp_upload', dirname(dirname(__DIR__)) . '/storage/parser_data/temp');
  9 +Yii::setAlias('mail_upload', dirname(dirname(__DIR__)) . '/storage/parser_data/mail');
9 Yii::setAlias('storage', dirname(dirname(__DIR__)) . '/storage'); 10 Yii::setAlias('storage', dirname(dirname(__DIR__)) . '/storage');
@@ -580,16 +580,16 @@ @@ -580,16 +580,16 @@
580 }, 580 },
581 { 581 {
582 "name": "guzzlehttp/guzzle", 582 "name": "guzzlehttp/guzzle",
583 - "version": "6.1.0", 583 + "version": "6.1.1",
584 "source": { 584 "source": {
585 "type": "git", 585 "type": "git",
586 "url": "https://github.com/guzzle/guzzle.git", 586 "url": "https://github.com/guzzle/guzzle.git",
587 - "reference": "66fd14b4d0b8f2389eaf37c5458608c7cb793a81" 587 + "reference": "c6851d6e48f63b69357cbfa55bca116448140e0c"
588 }, 588 },
589 "dist": { 589 "dist": {
590 "type": "zip", 590 "type": "zip",
591 - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/66fd14b4d0b8f2389eaf37c5458608c7cb793a81",  
592 - "reference": "66fd14b4d0b8f2389eaf37c5458608c7cb793a81", 591 + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/c6851d6e48f63b69357cbfa55bca116448140e0c",
  592 + "reference": "c6851d6e48f63b69357cbfa55bca116448140e0c",
593 "shasum": "" 593 "shasum": ""
594 }, 594 },
595 "require": { 595 "require": {
@@ -638,7 +638,7 @@ @@ -638,7 +638,7 @@
638 "rest", 638 "rest",
639 "web service" 639 "web service"
640 ], 640 ],
641 - "time": "2015-09-08 17:36:26" 641 + "time": "2015-11-23 00:47:50"
642 }, 642 },
643 { 643 {
644 "name": "guzzlehttp/promises", 644 "name": "guzzlehttp/promises",
@@ -994,16 +994,16 @@ @@ -994,16 +994,16 @@
994 }, 994 },
995 { 995 {
996 "name": "kartik-v/yii2-krajee-base", 996 "name": "kartik-v/yii2-krajee-base",
997 - "version": "v1.7.7", 997 + "version": "v1.7.9",
998 "source": { 998 "source": {
999 "type": "git", 999 "type": "git",
1000 "url": "https://github.com/kartik-v/yii2-krajee-base.git", 1000 "url": "https://github.com/kartik-v/yii2-krajee-base.git",
1001 - "reference": "c0adff9d9762f4fd3bf0e7cd0000fcab0bf00f19" 1001 + "reference": "6f10fd0a0bfccd729764c65fa65eb4ccf2cbade9"
1002 }, 1002 },
1003 "dist": { 1003 "dist": {
1004 "type": "zip", 1004 "type": "zip",
1005 - "url": "https://api.github.com/repos/kartik-v/yii2-krajee-base/zipball/c0adff9d9762f4fd3bf0e7cd0000fcab0bf00f19",  
1006 - "reference": "c0adff9d9762f4fd3bf0e7cd0000fcab0bf00f19", 1005 + "url": "https://api.github.com/repos/kartik-v/yii2-krajee-base/zipball/6f10fd0a0bfccd729764c65fa65eb4ccf2cbade9",
  1006 + "reference": "6f10fd0a0bfccd729764c65fa65eb4ccf2cbade9",
1007 "shasum": "" 1007 "shasum": ""
1008 }, 1008 },
1009 "require": { 1009 "require": {
@@ -1036,7 +1036,7 @@ @@ -1036,7 +1036,7 @@
1036 "widget", 1036 "widget",
1037 "yii2" 1037 "yii2"
1038 ], 1038 ],
1039 - "time": "2015-06-16 05:19:57" 1039 + "time": "2015-11-25 07:03:35"
1040 }, 1040 },
1041 { 1041 {
1042 "name": "kartik-v/yii2-widget-datepicker", 1042 "name": "kartik-v/yii2-widget-datepicker",
@@ -1650,16 +1650,16 @@ @@ -1650,16 +1650,16 @@
1650 }, 1650 },
1651 { 1651 {
1652 "name": "phpunit/phpunit", 1652 "name": "phpunit/phpunit",
1653 - "version": "4.8.18", 1653 + "version": "4.8.19",
1654 "source": { 1654 "source": {
1655 "type": "git", 1655 "type": "git",
1656 "url": "https://github.com/sebastianbergmann/phpunit.git", 1656 "url": "https://github.com/sebastianbergmann/phpunit.git",
1657 - "reference": "fa33d4ad96481b91df343d83e8c8aabed6b1dfd3" 1657 + "reference": "b2caaf8947aba5e002d42126723e9d69795f32b4"
1658 }, 1658 },
1659 "dist": { 1659 "dist": {
1660 "type": "zip", 1660 "type": "zip",
1661 - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/fa33d4ad96481b91df343d83e8c8aabed6b1dfd3",  
1662 - "reference": "fa33d4ad96481b91df343d83e8c8aabed6b1dfd3", 1661 + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/b2caaf8947aba5e002d42126723e9d69795f32b4",
  1662 + "reference": "b2caaf8947aba5e002d42126723e9d69795f32b4",
1663 "shasum": "" 1663 "shasum": ""
1664 }, 1664 },
1665 "require": { 1665 "require": {
@@ -1718,7 +1718,7 @@ @@ -1718,7 +1718,7 @@
1718 "testing", 1718 "testing",
1719 "xunit" 1719 "xunit"
1720 ], 1720 ],
1721 - "time": "2015-11-11 11:32:49" 1721 + "time": "2015-11-30 08:18:59"
1722 }, 1722 },
1723 { 1723 {
1724 "name": "phpunit/phpunit-mock-objects", 1724 "name": "phpunit/phpunit-mock-objects",
@@ -1943,16 +1943,16 @@ @@ -1943,16 +1943,16 @@
1943 }, 1943 },
1944 { 1944 {
1945 "name": "sebastian/environment", 1945 "name": "sebastian/environment",
1946 - "version": "1.3.2", 1946 + "version": "1.3.3",
1947 "source": { 1947 "source": {
1948 "type": "git", 1948 "type": "git",
1949 "url": "https://github.com/sebastianbergmann/environment.git", 1949 "url": "https://github.com/sebastianbergmann/environment.git",
1950 - "reference": "6324c907ce7a52478eeeaede764f48733ef5ae44" 1950 + "reference": "6e7133793a8e5a5714a551a8324337374be209df"
1951 }, 1951 },
1952 "dist": { 1952 "dist": {
1953 "type": "zip", 1953 "type": "zip",
1954 - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/6324c907ce7a52478eeeaede764f48733ef5ae44",  
1955 - "reference": "6324c907ce7a52478eeeaede764f48733ef5ae44", 1954 + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/6e7133793a8e5a5714a551a8324337374be209df",
  1955 + "reference": "6e7133793a8e5a5714a551a8324337374be209df",
1956 "shasum": "" 1956 "shasum": ""
1957 }, 1957 },
1958 "require": { 1958 "require": {
@@ -1989,7 +1989,7 @@ @@ -1989,7 +1989,7 @@
1989 "environment", 1989 "environment",
1990 "hhvm" 1990 "hhvm"
1991 ], 1991 ],
1992 - "time": "2015-08-03 06:14:51" 1992 + "time": "2015-12-02 08:37:27"
1993 }, 1993 },
1994 { 1994 {
1995 "name": "sebastian/exporter", 1995 "name": "sebastian/exporter",
@@ -2251,25 +2251,25 @@ @@ -2251,25 +2251,25 @@
2251 }, 2251 },
2252 { 2252 {
2253 "name": "symfony/browser-kit", 2253 "name": "symfony/browser-kit",
2254 - "version": "v2.7.6", 2254 + "version": "v2.8.0",
2255 "source": { 2255 "source": {
2256 "type": "git", 2256 "type": "git",
2257 "url": "https://github.com/symfony/browser-kit.git", 2257 "url": "https://github.com/symfony/browser-kit.git",
2258 - "reference": "07d664a052572ccc28eb2ab7dbbe82155b1ad367" 2258 + "reference": "589f32fe4f43155ea303d505171634c45f15e876"
2259 }, 2259 },
2260 "dist": { 2260 "dist": {
2261 "type": "zip", 2261 "type": "zip",
2262 - "url": "https://api.github.com/repos/symfony/browser-kit/zipball/07d664a052572ccc28eb2ab7dbbe82155b1ad367",  
2263 - "reference": "07d664a052572ccc28eb2ab7dbbe82155b1ad367", 2262 + "url": "https://api.github.com/repos/symfony/browser-kit/zipball/589f32fe4f43155ea303d505171634c45f15e876",
  2263 + "reference": "589f32fe4f43155ea303d505171634c45f15e876",
2264 "shasum": "" 2264 "shasum": ""
2265 }, 2265 },
2266 "require": { 2266 "require": {
2267 "php": ">=5.3.9", 2267 "php": ">=5.3.9",
2268 - "symfony/dom-crawler": "~2.0,>=2.0.5" 2268 + "symfony/dom-crawler": "~2.0,>=2.0.5|~3.0.0"
2269 }, 2269 },
2270 "require-dev": { 2270 "require-dev": {
2271 - "symfony/css-selector": "~2.0,>=2.0.5",  
2272 - "symfony/process": "~2.3.34|~2.7,>=2.7.6" 2271 + "symfony/css-selector": "~2.0,>=2.0.5|~3.0.0",
  2272 + "symfony/process": "~2.3.34|~2.7,>=2.7.6|~3.0.0"
2273 }, 2273 },
2274 "suggest": { 2274 "suggest": {
2275 "symfony/process": "" 2275 "symfony/process": ""
@@ -2277,13 +2277,16 @@ @@ -2277,13 +2277,16 @@
2277 "type": "library", 2277 "type": "library",
2278 "extra": { 2278 "extra": {
2279 "branch-alias": { 2279 "branch-alias": {
2280 - "dev-master": "2.7-dev" 2280 + "dev-master": "2.8-dev"
2281 } 2281 }
2282 }, 2282 },
2283 "autoload": { 2283 "autoload": {
2284 "psr-4": { 2284 "psr-4": {
2285 "Symfony\\Component\\BrowserKit\\": "" 2285 "Symfony\\Component\\BrowserKit\\": ""
2286 - } 2286 + },
  2287 + "exclude-from-classmap": [
  2288 + "/Tests/"
  2289 + ]
2287 }, 2290 },
2288 "notification-url": "https://packagist.org/downloads/", 2291 "notification-url": "https://packagist.org/downloads/",
2289 "license": [ 2292 "license": [
@@ -2301,29 +2304,30 @@ @@ -2301,29 +2304,30 @@
2301 ], 2304 ],
2302 "description": "Symfony BrowserKit Component", 2305 "description": "Symfony BrowserKit Component",
2303 "homepage": "https://symfony.com", 2306 "homepage": "https://symfony.com",
2304 - "time": "2015-10-23 14:47:27" 2307 + "time": "2015-11-02 20:29:24"
2305 }, 2308 },
2306 { 2309 {
2307 "name": "symfony/console", 2310 "name": "symfony/console",
2308 - "version": "v2.7.6", 2311 + "version": "v2.8.0",
2309 "source": { 2312 "source": {
2310 "type": "git", 2313 "type": "git",
2311 "url": "https://github.com/symfony/console.git", 2314 "url": "https://github.com/symfony/console.git",
2312 - "reference": "5efd632294c8320ea52492db22292ff853a43766" 2315 + "reference": "d232bfc100dfd32b18ccbcab4bcc8f28697b7e41"
2313 }, 2316 },
2314 "dist": { 2317 "dist": {
2315 "type": "zip", 2318 "type": "zip",
2316 - "url": "https://api.github.com/repos/symfony/console/zipball/5efd632294c8320ea52492db22292ff853a43766",  
2317 - "reference": "5efd632294c8320ea52492db22292ff853a43766", 2319 + "url": "https://api.github.com/repos/symfony/console/zipball/d232bfc100dfd32b18ccbcab4bcc8f28697b7e41",
  2320 + "reference": "d232bfc100dfd32b18ccbcab4bcc8f28697b7e41",
2318 "shasum": "" 2321 "shasum": ""
2319 }, 2322 },
2320 "require": { 2323 "require": {
2321 - "php": ">=5.3.9" 2324 + "php": ">=5.3.9",
  2325 + "symfony/polyfill-mbstring": "~1.0"
2322 }, 2326 },
2323 "require-dev": { 2327 "require-dev": {
2324 "psr/log": "~1.0", 2328 "psr/log": "~1.0",
2325 - "symfony/event-dispatcher": "~2.1",  
2326 - "symfony/process": "~2.1" 2329 + "symfony/event-dispatcher": "~2.1|~3.0.0",
  2330 + "symfony/process": "~2.1|~3.0.0"
2327 }, 2331 },
2328 "suggest": { 2332 "suggest": {
2329 "psr/log": "For using the console logger", 2333 "psr/log": "For using the console logger",
@@ -2333,13 +2337,16 @@ @@ -2333,13 +2337,16 @@
2333 "type": "library", 2337 "type": "library",
2334 "extra": { 2338 "extra": {
2335 "branch-alias": { 2339 "branch-alias": {
2336 - "dev-master": "2.7-dev" 2340 + "dev-master": "2.8-dev"
2337 } 2341 }
2338 }, 2342 },
2339 "autoload": { 2343 "autoload": {
2340 "psr-4": { 2344 "psr-4": {
2341 "Symfony\\Component\\Console\\": "" 2345 "Symfony\\Component\\Console\\": ""
2342 - } 2346 + },
  2347 + "exclude-from-classmap": [
  2348 + "/Tests/"
  2349 + ]
2343 }, 2350 },
2344 "notification-url": "https://packagist.org/downloads/", 2351 "notification-url": "https://packagist.org/downloads/",
2345 "license": [ 2352 "license": [
@@ -2357,20 +2364,20 @@ @@ -2357,20 +2364,20 @@
2357 ], 2364 ],
2358 "description": "Symfony Console Component", 2365 "description": "Symfony Console Component",
2359 "homepage": "https://symfony.com", 2366 "homepage": "https://symfony.com",
2360 - "time": "2015-10-20 14:38:46" 2367 + "time": "2015-11-30 12:35:10"
2361 }, 2368 },
2362 { 2369 {
2363 "name": "symfony/css-selector", 2370 "name": "symfony/css-selector",
2364 - "version": "v2.7.6", 2371 + "version": "v2.8.0",
2365 "source": { 2372 "source": {
2366 "type": "git", 2373 "type": "git",
2367 "url": "https://github.com/symfony/css-selector.git", 2374 "url": "https://github.com/symfony/css-selector.git",
2368 - "reference": "e1b865b26be4a56d22a8dee398375044a80c865b" 2375 + "reference": "b600fec37c0efca08046d481d79e7eabc07108ff"
2369 }, 2376 },
2370 "dist": { 2377 "dist": {
2371 "type": "zip", 2378 "type": "zip",
2372 - "url": "https://api.github.com/repos/symfony/css-selector/zipball/e1b865b26be4a56d22a8dee398375044a80c865b",  
2373 - "reference": "e1b865b26be4a56d22a8dee398375044a80c865b", 2379 + "url": "https://api.github.com/repos/symfony/css-selector/zipball/b600fec37c0efca08046d481d79e7eabc07108ff",
  2380 + "reference": "b600fec37c0efca08046d481d79e7eabc07108ff",
2374 "shasum": "" 2381 "shasum": ""
2375 }, 2382 },
2376 "require": { 2383 "require": {
@@ -2379,13 +2386,16 @@ @@ -2379,13 +2386,16 @@
2379 "type": "library", 2386 "type": "library",
2380 "extra": { 2387 "extra": {
2381 "branch-alias": { 2388 "branch-alias": {
2382 - "dev-master": "2.7-dev" 2389 + "dev-master": "2.8-dev"
2383 } 2390 }
2384 }, 2391 },
2385 "autoload": { 2392 "autoload": {
2386 "psr-4": { 2393 "psr-4": {
2387 "Symfony\\Component\\CssSelector\\": "" 2394 "Symfony\\Component\\CssSelector\\": ""
2388 - } 2395 + },
  2396 + "exclude-from-classmap": [
  2397 + "/Tests/"
  2398 + ]
2389 }, 2399 },
2390 "notification-url": "https://packagist.org/downloads/", 2400 "notification-url": "https://packagist.org/downloads/",
2391 "license": [ 2401 "license": [
@@ -2407,27 +2417,28 @@ @@ -2407,27 +2417,28 @@
2407 ], 2417 ],
2408 "description": "Symfony CssSelector Component", 2418 "description": "Symfony CssSelector Component",
2409 "homepage": "https://symfony.com", 2419 "homepage": "https://symfony.com",
2410 - "time": "2015-10-11 09:39:48" 2420 + "time": "2015-10-30 20:15:42"
2411 }, 2421 },
2412 { 2422 {
2413 "name": "symfony/dom-crawler", 2423 "name": "symfony/dom-crawler",
2414 - "version": "v2.7.6", 2424 + "version": "v2.8.0",
2415 "source": { 2425 "source": {
2416 "type": "git", 2426 "type": "git",
2417 "url": "https://github.com/symfony/dom-crawler.git", 2427 "url": "https://github.com/symfony/dom-crawler.git",
2418 - "reference": "5fef7d8b80d8f9992df99d8ee283f420484c9612" 2428 + "reference": "740c98235f5b6e2b0b13df2fb97c7a1c7d1a18fc"
2419 }, 2429 },
2420 "dist": { 2430 "dist": {
2421 "type": "zip", 2431 "type": "zip",
2422 - "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/5fef7d8b80d8f9992df99d8ee283f420484c9612",  
2423 - "reference": "5fef7d8b80d8f9992df99d8ee283f420484c9612", 2432 + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/740c98235f5b6e2b0b13df2fb97c7a1c7d1a18fc",
  2433 + "reference": "740c98235f5b6e2b0b13df2fb97c7a1c7d1a18fc",
2424 "shasum": "" 2434 "shasum": ""
2425 }, 2435 },
2426 "require": { 2436 "require": {
2427 - "php": ">=5.3.9" 2437 + "php": ">=5.3.9",
  2438 + "symfony/polyfill-mbstring": "~1.0"
2428 }, 2439 },
2429 "require-dev": { 2440 "require-dev": {
2430 - "symfony/css-selector": "~2.3" 2441 + "symfony/css-selector": "~2.8|~3.0.0"
2431 }, 2442 },
2432 "suggest": { 2443 "suggest": {
2433 "symfony/css-selector": "" 2444 "symfony/css-selector": ""
@@ -2435,13 +2446,16 @@ @@ -2435,13 +2446,16 @@
2435 "type": "library", 2446 "type": "library",
2436 "extra": { 2447 "extra": {
2437 "branch-alias": { 2448 "branch-alias": {
2438 - "dev-master": "2.7-dev" 2449 + "dev-master": "2.8-dev"
2439 } 2450 }
2440 }, 2451 },
2441 "autoload": { 2452 "autoload": {
2442 "psr-4": { 2453 "psr-4": {
2443 "Symfony\\Component\\DomCrawler\\": "" 2454 "Symfony\\Component\\DomCrawler\\": ""
2444 - } 2455 + },
  2456 + "exclude-from-classmap": [
  2457 + "/Tests/"
  2458 + ]
2445 }, 2459 },
2446 "notification-url": "https://packagist.org/downloads/", 2460 "notification-url": "https://packagist.org/downloads/",
2447 "license": [ 2461 "license": [
@@ -2459,20 +2473,20 @@ @@ -2459,20 +2473,20 @@
2459 ], 2473 ],
2460 "description": "Symfony DomCrawler Component", 2474 "description": "Symfony DomCrawler Component",
2461 "homepage": "https://symfony.com", 2475 "homepage": "https://symfony.com",
2462 - "time": "2015-10-11 09:39:48" 2476 + "time": "2015-11-02 20:29:39"
2463 }, 2477 },
2464 { 2478 {
2465 "name": "symfony/event-dispatcher", 2479 "name": "symfony/event-dispatcher",
2466 - "version": "v2.7.6", 2480 + "version": "v2.8.0",
2467 "source": { 2481 "source": {
2468 "type": "git", 2482 "type": "git",
2469 "url": "https://github.com/symfony/event-dispatcher.git", 2483 "url": "https://github.com/symfony/event-dispatcher.git",
2470 - "reference": "87a5db5ea887763fa3a31a5471b512ff1596d9b8" 2484 + "reference": "a5eb815363c0388e83247e7e9853e5dbc14999cc"
2471 }, 2485 },
2472 "dist": { 2486 "dist": {
2473 "type": "zip", 2487 "type": "zip",
2474 - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/87a5db5ea887763fa3a31a5471b512ff1596d9b8",  
2475 - "reference": "87a5db5ea887763fa3a31a5471b512ff1596d9b8", 2488 + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/a5eb815363c0388e83247e7e9853e5dbc14999cc",
  2489 + "reference": "a5eb815363c0388e83247e7e9853e5dbc14999cc",
2476 "shasum": "" 2490 "shasum": ""
2477 }, 2491 },
2478 "require": { 2492 "require": {
@@ -2480,10 +2494,10 @@ @@ -2480,10 +2494,10 @@
2480 }, 2494 },
2481 "require-dev": { 2495 "require-dev": {
2482 "psr/log": "~1.0", 2496 "psr/log": "~1.0",
2483 - "symfony/config": "~2.0,>=2.0.5",  
2484 - "symfony/dependency-injection": "~2.6",  
2485 - "symfony/expression-language": "~2.6",  
2486 - "symfony/stopwatch": "~2.3" 2497 + "symfony/config": "~2.0,>=2.0.5|~3.0.0",
  2498 + "symfony/dependency-injection": "~2.6|~3.0.0",
  2499 + "symfony/expression-language": "~2.6|~3.0.0",
  2500 + "symfony/stopwatch": "~2.3|~3.0.0"
2487 }, 2501 },
2488 "suggest": { 2502 "suggest": {
2489 "symfony/dependency-injection": "", 2503 "symfony/dependency-injection": "",
@@ -2492,13 +2506,16 @@ @@ -2492,13 +2506,16 @@
2492 "type": "library", 2506 "type": "library",
2493 "extra": { 2507 "extra": {
2494 "branch-alias": { 2508 "branch-alias": {
2495 - "dev-master": "2.7-dev" 2509 + "dev-master": "2.8-dev"
2496 } 2510 }
2497 }, 2511 },
2498 "autoload": { 2512 "autoload": {
2499 "psr-4": { 2513 "psr-4": {
2500 "Symfony\\Component\\EventDispatcher\\": "" 2514 "Symfony\\Component\\EventDispatcher\\": ""
2501 - } 2515 + },
  2516 + "exclude-from-classmap": [
  2517 + "/Tests/"
  2518 + ]
2502 }, 2519 },
2503 "notification-url": "https://packagist.org/downloads/", 2520 "notification-url": "https://packagist.org/downloads/",
2504 "license": [ 2521 "license": [
@@ -2516,20 +2533,20 @@ @@ -2516,20 +2533,20 @@
2516 ], 2533 ],
2517 "description": "Symfony EventDispatcher Component", 2534 "description": "Symfony EventDispatcher Component",
2518 "homepage": "https://symfony.com", 2535 "homepage": "https://symfony.com",
2519 - "time": "2015-10-11 09:39:48" 2536 + "time": "2015-10-30 20:15:42"
2520 }, 2537 },
2521 { 2538 {
2522 "name": "symfony/finder", 2539 "name": "symfony/finder",
2523 - "version": "v2.7.6", 2540 + "version": "v2.8.0",
2524 "source": { 2541 "source": {
2525 "type": "git", 2542 "type": "git",
2526 "url": "https://github.com/symfony/finder.git", 2543 "url": "https://github.com/symfony/finder.git",
2527 - "reference": "2ffb4e9598db3c48eb6d0ae73b04bbf09280c59d" 2544 + "reference": "ead9b07af4ba77b6507bee697396a5c79e633f08"
2528 }, 2545 },
2529 "dist": { 2546 "dist": {
2530 "type": "zip", 2547 "type": "zip",
2531 - "url": "https://api.github.com/repos/symfony/finder/zipball/2ffb4e9598db3c48eb6d0ae73b04bbf09280c59d",  
2532 - "reference": "2ffb4e9598db3c48eb6d0ae73b04bbf09280c59d", 2548 + "url": "https://api.github.com/repos/symfony/finder/zipball/ead9b07af4ba77b6507bee697396a5c79e633f08",
  2549 + "reference": "ead9b07af4ba77b6507bee697396a5c79e633f08",
2533 "shasum": "" 2550 "shasum": ""
2534 }, 2551 },
2535 "require": { 2552 "require": {
@@ -2538,13 +2555,16 @@ @@ -2538,13 +2555,16 @@
2538 "type": "library", 2555 "type": "library",
2539 "extra": { 2556 "extra": {
2540 "branch-alias": { 2557 "branch-alias": {
2541 - "dev-master": "2.7-dev" 2558 + "dev-master": "2.8-dev"
2542 } 2559 }
2543 }, 2560 },
2544 "autoload": { 2561 "autoload": {
2545 "psr-4": { 2562 "psr-4": {
2546 "Symfony\\Component\\Finder\\": "" 2563 "Symfony\\Component\\Finder\\": ""
2547 - } 2564 + },
  2565 + "exclude-from-classmap": [
  2566 + "/Tests/"
  2567 + ]
2548 }, 2568 },
2549 "notification-url": "https://packagist.org/downloads/", 2569 "notification-url": "https://packagist.org/downloads/",
2550 "license": [ 2570 "license": [
@@ -2562,20 +2582,76 @@ @@ -2562,20 +2582,76 @@
2562 ], 2582 ],
2563 "description": "Symfony Finder Component", 2583 "description": "Symfony Finder Component",
2564 "homepage": "https://symfony.com", 2584 "homepage": "https://symfony.com",
2565 - "time": "2015-10-11 09:39:48" 2585 + "time": "2015-10-30 20:15:42"
  2586 + },
  2587 + {
  2588 + "name": "symfony/polyfill-mbstring",
  2589 + "version": "v1.0.0",
  2590 + "source": {
  2591 + "type": "git",
  2592 + "url": "https://github.com/symfony/polyfill-mbstring.git",
  2593 + "reference": "0b6a8940385311a24e060ec1fe35680e17c74497"
  2594 + },
  2595 + "dist": {
  2596 + "type": "zip",
  2597 + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/0b6a8940385311a24e060ec1fe35680e17c74497",
  2598 + "reference": "0b6a8940385311a24e060ec1fe35680e17c74497",
  2599 + "shasum": ""
  2600 + },
  2601 + "require": {
  2602 + "php": ">=5.3.3"
  2603 + },
  2604 + "type": "library",
  2605 + "extra": {
  2606 + "branch-alias": {
  2607 + "dev-master": "1.0-dev"
  2608 + }
  2609 + },
  2610 + "autoload": {
  2611 + "psr-4": {
  2612 + "Symfony\\Polyfill\\Mbstring\\": ""
  2613 + },
  2614 + "files": [
  2615 + "bootstrap.php"
  2616 + ]
  2617 + },
  2618 + "notification-url": "https://packagist.org/downloads/",
  2619 + "license": [
  2620 + "MIT"
  2621 + ],
  2622 + "authors": [
  2623 + {
  2624 + "name": "Nicolas Grekas",
  2625 + "email": "p@tchwork.com"
  2626 + },
  2627 + {
  2628 + "name": "Symfony Community",
  2629 + "homepage": "https://symfony.com/contributors"
  2630 + }
  2631 + ],
  2632 + "description": "Symfony polyfill for the Mbstring extension",
  2633 + "homepage": "https://symfony.com",
  2634 + "keywords": [
  2635 + "compatibility",
  2636 + "mbstring",
  2637 + "polyfill",
  2638 + "portable",
  2639 + "shim"
  2640 + ],
  2641 + "time": "2015-11-04 20:28:58"
2566 }, 2642 },
2567 { 2643 {
2568 "name": "symfony/yaml", 2644 "name": "symfony/yaml",
2569 - "version": "v2.7.6", 2645 + "version": "v2.8.0",
2570 "source": { 2646 "source": {
2571 "type": "git", 2647 "type": "git",
2572 "url": "https://github.com/symfony/yaml.git", 2648 "url": "https://github.com/symfony/yaml.git",
2573 - "reference": "eca9019c88fbe250164affd107bc8057771f3f4d" 2649 + "reference": "f79824187de95064a2f5038904c4d7f0227fedb5"
2574 }, 2650 },
2575 "dist": { 2651 "dist": {
2576 "type": "zip", 2652 "type": "zip",
2577 - "url": "https://api.github.com/repos/symfony/yaml/zipball/eca9019c88fbe250164affd107bc8057771f3f4d",  
2578 - "reference": "eca9019c88fbe250164affd107bc8057771f3f4d", 2653 + "url": "https://api.github.com/repos/symfony/yaml/zipball/f79824187de95064a2f5038904c4d7f0227fedb5",
  2654 + "reference": "f79824187de95064a2f5038904c4d7f0227fedb5",
2579 "shasum": "" 2655 "shasum": ""
2580 }, 2656 },
2581 "require": { 2657 "require": {
@@ -2584,13 +2660,16 @@ @@ -2584,13 +2660,16 @@
2584 "type": "library", 2660 "type": "library",
2585 "extra": { 2661 "extra": {
2586 "branch-alias": { 2662 "branch-alias": {
2587 - "dev-master": "2.7-dev" 2663 + "dev-master": "2.8-dev"
2588 } 2664 }
2589 }, 2665 },
2590 "autoload": { 2666 "autoload": {
2591 "psr-4": { 2667 "psr-4": {
2592 "Symfony\\Component\\Yaml\\": "" 2668 "Symfony\\Component\\Yaml\\": ""
2593 - } 2669 + },
  2670 + "exclude-from-classmap": [
  2671 + "/Tests/"
  2672 + ]
2594 }, 2673 },
2595 "notification-url": "https://packagist.org/downloads/", 2674 "notification-url": "https://packagist.org/downloads/",
2596 "license": [ 2675 "license": [
@@ -2608,7 +2687,7 @@ @@ -2608,7 +2687,7 @@
2608 ], 2687 ],
2609 "description": "Symfony Yaml Component", 2688 "description": "Symfony Yaml Component",
2610 "homepage": "https://symfony.com", 2689 "homepage": "https://symfony.com",
2611 - "time": "2015-10-11 09:39:48" 2690 + "time": "2015-11-30 12:35:10"
2612 }, 2691 },
2613 { 2692 {
2614 "name": "yiisoft/yii2", 2693 "name": "yiisoft/yii2",
console/controllers/ParserController.php
1 <?php 1 <?php
2 namespace console\controllers; 2 namespace console\controllers;
3 3
  4 +use backend\models\Log;
4 use common\components\archives\ArchiveCreator; 5 use common\components\archives\ArchiveCreator;
5 use common\components\CustomVarDamp; 6 use common\components\CustomVarDamp;
6 use common\components\mail\ImapMailReader; 7 use common\components\mail\ImapMailReader;
@@ -11,115 +12,26 @@ use common\components\PriceWriter; @@ -11,115 +12,26 @@ use common\components\PriceWriter;
11 use backend\models\ImportersFiles; 12 use backend\models\ImportersFiles;
12 use backend\models\Importers; 13 use backend\models\Importers;
13 use yii\base\ErrorException; 14 use yii\base\ErrorException;
  15 +use yii\helpers\Html;
14 16
15 class ParserController extends Controller 17 class ParserController extends Controller
16 { 18 {
17 - public function actionParseCsv()  
18 - {  
19 - \Yii::info('Начало загрузки файлов прайсов csv', 'parser');  
20 - foreach (glob(\Yii::getAlias('@auto_upload') . '/*.csv') as $file_path) {  
21 - $file_name = basename($file_path, ".csv");  
22 - \Yii::info("Обработка файла - $file_path", 'parser');  
23 - $importer_id = ImportersFiles::findOne(['id' => $file_name])->importer_id;  
24 - $current_importer = Importers::findOne(['id' => $importer_id]);  
25 - $keys = $current_importer->keys;  
26 - $mult_array = $current_importer->multiply;  
27 -  
28 - // получим настройки ценообразования и передадим их отдельно в конвертер  
29 - $sign = '';  
30 - $multiplier = '';  
31 - extract( $mult_array );  
32 -  
33 -  
34 - $config = ['record_id' => $file_name,  
35 - 'importer_id' => $importer_id,  
36 - 'parser_config' => ['keys' => $keys,  
37 - 'converter_conf' =>  
38 - ['sign' => $sign,  
39 - 'multiplier' => $multiplier],  
40 - 'mode' => 'console']  
41 - ];  
42 - if ( $this->parseFileConsole( $file_path, $config ) ) {  
43 - unlink(\Yii::getAlias('@temp_upload') . '/' . $file_name . '.csv');  
44 - \Yii::info("Загрузка файла - $file_path успешно завершена", 'parser');  
45 - } else {  
46 - \Yii::error("Загрузка файла - $file_path завершена с ошибкой", 'parser');  
47 - }  
48 - //при любом завершении скрипта файл с очереди автозагрузки нужно удалить  
49 - unlink(\Yii::getAlias('@auto_upload') . '/' . $file_name . '.csv');  
50 - }  
51 -  
52 - }  
53 -  
54 -  
55 - protected function parseFileConsole( $file_path, $configuration ){  
56 -  
57 - if( !file_exists( $file_path ) )  
58 - throw new ErrorException("$file_path - файл не найден!");  
59 -  
60 - $parser_config = [];  
61 - if ( isset( $configuration['parser_config'] ) ) {  
62 - $parser_config = $configuration['parser_config'];  
63 - }  
64 - $data = \Yii::$app->multiparser->parse( $file_path, $parser_config );  
65 - if ( ! $data ) {  
66 - throw new ErrorException("Ошибка обработки файла прайса!");  
67 - }  
68 -  
69 - $writer = new PriceWriter();  
70 - $writer->setConfiguration( $configuration );  
71 - $writer->setData( $data );  
72 - $writer->setMode( 1 ); //console-режим 19 + protected $start_time;
73 20
74 - $writer->writePriceToDB();  
75 - if ( $writer->hasValidationError() ) {  
76 - \Yii::error( $writer->getValidatedMsg(), 'parser' );  
77 - }else{  
78 - \Yii::info( $writer->getValidatedMsg(), 'parser' );  
79 - } 21 + public function actionParsePrices()
  22 + {
  23 + $this->start_time = date('Y-m-d H:i:s');
80 24
  25 + $path_arr = [
  26 + ['mode' => 1, 'path' => \Yii::getAlias('@auto_upload')],
  27 + ['mode' => 2, 'path' => \Yii::getAlias('@mail_upload')],
  28 + ];
81 29
82 - return true; 30 + $this->parseCsvFiles($path_arr);
  31 + $this->parseXmlFiles($path_arr);
83 32
84 } 33 }
85 34
86 - public function actionParseXml ()  
87 - {  
88 - \Yii::info('Начало загрузки файлов прайсов xml', 'parser');  
89 - foreach (glob(\Yii::getAlias('@auto_upload') . '/*.xml') as $file_path) {  
90 - $file_name = basename($file_path, ".xml");  
91 - \Yii::info("Обработка файла - $file_path", 'parser');  
92 -  
93 - $files_model = new ImportersFiles();  
94 - // id поставщика всегда = 1 - Склад  
95 - $files_model->importer_id = 1;  
96 - try {  
97 - $files_model->save();  
98 - } catch (ErrorException $e) {  
99 - throw $e;  
100 - }  
101 - // получим id только что записанной записи  
102 - $record_id = $files_model->find()  
103 - ->where(['importer_id' => $files_model->importer_id])  
104 - ->orderBy(['id' => SORT_DESC])  
105 - ->one()  
106 - ->id;  
107 -  
108 - $config = ['record_id' => $record_id,  
109 - 'importer_id' => 1,  
110 - 'parser_config' => [  
111 - 'mode' => 'console']  
112 - ];  
113 -  
114 - if ($this->parseFileConsole($file_path, $config)) {  
115 - //unlink(\Yii::getAlias('@auto_upload') . '/' . $file_name . '.xml');  
116 - \Yii::info("Загрузка файла - $file_path успешно завершена", 'parser');  
117 - } else {  
118 - \Yii::error("Загрузка файла - $file_path завершена с ошибкой", 'parser');  
119 - }  
120 - }  
121 - }  
122 -  
123 public function actionTest() 35 public function actionTest()
124 { 36 {
125 Console::output('It is working'); 37 Console::output('It is working');
@@ -134,13 +46,13 @@ class ParserController extends Controller @@ -134,13 +46,13 @@ class ParserController extends Controller
134 // получим разделитель для файлов поставщика 46 // получим разделитель для файлов поставщика
135 $importer_id_prefix = ImportersFiles::FILES_PREFIX; 47 $importer_id_prefix = ImportersFiles::FILES_PREFIX;
136 // подключимся к ящику 48 // подключимся к ящику
137 - $mail_reader = new ImapMailReader( '{imap.gmail.com:993/imap/ssl/novalidate-cert}', 'tsurkanovm@gmail.com', 'Wtvr@2000' ); 49 + $mail_reader = new ImapMailReader('{imap.gmail.com:993/imap/ssl/novalidate-cert}', 'tsurkanovm@gmail.com', 'Wtvr@2000');
138 50
139 // 1. получим все вложения 51 // 1. получим все вложения
140 \Yii::info('Начало сохранения файлов почты', 'mail'); 52 \Yii::info('Начало сохранения файлов почты', 'mail');
141 - $files = $this->getMailAttachments( $mail_reader, $importer_id_prefix ); 53 + $files = $this->getMailAttachments($mail_reader, $importer_id_prefix);
142 54
143 - if ( !$files ) { 55 + if (!$files) {
144 // нет файлов в ящиках (не было вложений в письмах) 56 // нет файлов в ящиках (не было вложений в письмах)
145 \Yii::warning('Вложений не найдено', 'mail'); 57 \Yii::warning('Вложений не найдено', 'mail');
146 return; 58 return;
@@ -148,43 +60,187 @@ class ParserController extends Controller @@ -148,43 +60,187 @@ class ParserController extends Controller
148 60
149 // 2. если в вложениях есть архивы - распакуем их и дополним итоговый массив 61 // 2. если в вложениях есть архивы - распакуем их и дополним итоговый массив
150 \Yii::info('Запуск распаковки архивов...', 'mail'); 62 \Yii::info('Запуск распаковки архивов...', 'mail');
151 - $this->UnpackFiles( $files ); 63 + $this->UnpackFiles($files);
152 64
153 65
154 // 3. переименуем, зарегистрируем прайсы и перенесем извлеченные файлы 66 // 3. переименуем, зарегистрируем прайсы и перенесем извлеченные файлы
155 // укажем папку куда нужно перенести все извлеченные вложения 67 // укажем папку куда нужно перенести все извлеченные вложения
156 \Yii::info('Запуск перемещения и регистрации прайсов...', 'mail'); 68 \Yii::info('Запуск перемещения и регистрации прайсов...', 'mail');
157 - $new_destination = \Yii::getAlias('@auto_upload') . '/'; 69 + $new_destination = \Yii::getAlias('@mail_upload') . '/';
  70 +
  71 + $this->registerAndReplaceFiles($files, $new_destination);
  72 +
  73 +
  74 + }
158 75
159 - $this->registerAndReplaceFiles( $files, $new_destination ); 76 + protected function parseCsvFiles($path_arr)
  77 + {
  78 + \Yii::info('Начало загрузки файлов прайсов csv', 'parser');
  79 + foreach ($path_arr as $path_config) {
  80 + foreach (glob($path_config['path'] . '/*.csv') as $file_path) {
  81 + $file_name = basename($file_path, ".csv");
  82 + \Yii::info("Обработка файла - $file_path", 'parser');
  83 + $importer_id = ImportersFiles::findOne(['id' => $file_name])->importer_id;
  84 + $current_importer = Importers::findOne(['id' => $importer_id]);
  85 + $keys = $current_importer->keys;
  86 + $mult_array = $current_importer->multiply;
  87 +
  88 + // получим настройки ценообразования и передадим их отдельно в конвертер
  89 + $sign = '';
  90 + $multiplier = '';
  91 + extract($mult_array);
  92 +
  93 + $config = [
  94 + 'record_id' => $file_name,
  95 + 'importer_id' => $importer_id,
  96 + 'mode' => $path_config['mode'],
  97 + 'parser_config' => ['keys' => $keys,
  98 + 'converter_conf' =>
  99 + ['sign' => $sign,
  100 + 'multiplier' => $multiplier],
  101 + 'mode' => 'console']
  102 + ];
  103 +
  104 + if ($this->parseFile($file_path, $config)) {
  105 + $temp_file = \Yii::getAlias('@temp_upload') . '/' . $file_name . '.csv';
  106 + if( file_exists( $temp_file ) )
  107 + unlink($temp_file);
  108 +
  109 + \Yii::info("Загрузка файла - $file_path успешно завершена", 'parser');
  110 + } else {
  111 + \Yii::error("Загрузка файла - $file_path завершена с ошибкой", 'parser');
  112 + }
  113 + //при любом завершении скрипта файл с очереди автозагрузки нужно удалить
  114 + $auto_file = $path_config['path'] . '/' . $file_name . '.csv';
  115 + if( file_exists( $auto_file ) )
  116 + unlink($auto_file);
  117 + }
  118 + }
  119 + }
160 120
  121 + protected function parseXmlFiles($path_arr)
  122 + {
  123 + \Yii::info('Начало загрузки файлов прайсов xml', 'parser');
  124 + foreach ($path_arr as $path_config) {
  125 + foreach (glob($path_config['path'] . '/*.xml') as $file_path) {
  126 + $file_name = basename($file_path, ".xml");
  127 + \Yii::info("Обработка файла - $file_path", 'parser');
  128 +
  129 + $files_model = new ImportersFiles();
  130 + // id поставщика всегда = 1 - Склад
  131 + $files_model->importer_id = 1;
  132 + try {
  133 + $files_model->save();
  134 + } catch (ErrorException $e) {
  135 + throw $e;
  136 + }
  137 + // получим id только что записанной записи
  138 + $record_id = $files_model->find()
  139 + ->where(['importer_id' => $files_model->importer_id])
  140 + ->orderBy(['id' => SORT_DESC])
  141 + ->one()
  142 + ->id;
  143 +
  144 + $config = ['record_id' => $record_id,
  145 + 'importer_id' => 1,
  146 + 'mode' => $path_config['mode'],
  147 + 'parser_config' => [
  148 + 'mode' => 'console']
  149 + ];
  150 +
  151 + if ($this->parseFile($file_path, $config)) {
  152 + \Yii::info("Загрузка файла - $file_path успешно завершена", 'parser');
  153 + } else {
  154 + \Yii::error("Загрузка файла - $file_path завершена с ошибкой", 'parser');
  155 + }
161 156
  157 + $auto_file = $path_config['path'] . '/' . $file_name . '.xml';
  158 + if( file_exists( $auto_file ) )
  159 + unlink($auto_file);
  160 + }
  161 + }
162 } 162 }
163 163
164 - private function getMailAttachments ($mail_reader, $importer_id_prefix = '') 164 + protected function parseFile($file_path, $configuration)
  165 + {
  166 + // регистрация в лог
  167 + $log_model = new Log();
  168 + $log_model->importer_id = $configuration['importer_id'];
  169 + $log_model->time_start = $this->start_time;
  170 + $log_model->file_name = $file_path;
  171 + $mode = $configuration['mode'];
  172 + unset($configuration['mode']);
  173 + $log_model->record_type = $mode;
  174 +
  175 + $log_msg = '';
  176 + $has_error = true;
  177 +
  178 + if (!file_exists($file_path)){
  179 + $log_msg = "$file_path - файл не найден!";
  180 + } else {
  181 + $parser_config = [];
  182 + if (isset($configuration['parser_config'])) {
  183 + $parser_config = $configuration['parser_config'];
  184 + }
  185 + $data = \Yii::$app->multiparser->parse($file_path, $parser_config);
  186 + if (!$data) {
  187 + $log_msg = "Ошибка обработки файла прайса. Парсер вернул пустой массив";
  188 + } else {
  189 + try {
  190 + $writer = new PriceWriter();
  191 + $writer->setMode($mode);
  192 + $writer->setConfiguration($configuration);
  193 + $writer->setData($data);
  194 +
  195 + $writer->writePriceToDB();
  196 + $error = $writer->hasValidationError();
  197 + $log_msg = strip_tags( $writer->getValidatedMsg() );
  198 + if ( $error ) {
  199 + \Yii::error($log_msg, 'parser');
  200 + } else {
  201 + \Yii::info($log_msg, 'parser');
  202 + }
  203 + } catch (\Exception $e) {
  204 + $log_msg = $e->getMessage();
  205 + }
  206 + }
  207 + }
  208 +
  209 + $log_model->error = (int) $error;
  210 + $log_model->log_msg = $log_msg;
  211 + // запишем данные в лог
  212 + $log_model->save();
  213 +
  214 +
  215 +
  216 + return true;
  217 +
  218 + }
  219 +
  220 + private function getMailAttachments($mail_reader, $importer_id_prefix = '')
165 { 221 {
166 // получим все внутренние ящики (по ярлыкам) 222 // получим все внутренние ящики (по ярлыкам)
167 $mailboxes = $mail_reader->getListMailboxes(); 223 $mailboxes = $mail_reader->getListMailboxes();
168 - // очистим массив в котором в итоге окажуться все файлы вложений, а также распакованные файлы из архивов 224 + // очистим массив в котором в итоге окажутся все файлы вложений, а также распакованные файлы из архивов
169 $files = []; 225 $files = [];
170 - foreach ( $mailboxes as $custom_label ) { 226 + foreach ($mailboxes as $custom_label) {
171 // получим поставщика исходя из маски ярлыка 227 // получим поставщика исходя из маски ярлыка
172 - $importer_id = ImportersFiles::getIdFromMailBox( $mail_reader->getHostname(), $custom_label ); 228 + $importer_id = ImportersFiles::getIdFromMailBox($mail_reader->getHostname(), $custom_label);
173 229
174 // читаем письма конкретного ярлыка 230 // читаем письма конкретного ярлыка
175 - $mail_reader->reOpen( $custom_label ); 231 + $mail_reader->reOpen($custom_label);
176 // создадим сейвер вложений для данного ярлыка (ящика) 232 // создадим сейвер вложений для данного ярлыка (ящика)
177 - $saver = new MailAttachmentsSaver( $mail_reader ); 233 + $saver = new MailAttachmentsSaver($mail_reader);
178 // если данный ярлык содержит id поставщика, то все вложения нужно промаркировать (в начало файла добавить id поставщика + разделитель $importer_id_prefix) 234 // если данный ярлык содержит id поставщика, то все вложения нужно промаркировать (в начало файла добавить id поставщика + разделитель $importer_id_prefix)
179 - if ( $importer_id ) {  
180 - $saver->setFileNamePrefix( $importer_id . $importer_id_prefix ); 235 + if ($importer_id) {
  236 + $saver->setFileNamePrefix($importer_id . $importer_id_prefix);
181 // $importer_id = ''; 237 // $importer_id = '';
182 } 238 }
183 // сохраняем вложения 239 // сохраняем вложения
184 - if( $saver->saveAttachmentsTo(\Yii::getAlias('@temp_upload'), 'UNSEEN') ){ 240 + if ($saver->saveAttachmentsTo(\Yii::getAlias('@temp_upload'), 'UNSEEN')) {
185 // закидываем вытащенные файлы в наш итоговый массив 241 // закидываем вытащенные файлы в наш итоговый массив
186 - $files = array_merge( $files, $saver->getSavedFilesArr() );  
187 - }else{ 242 + $files = array_merge($files, $saver->getSavedFilesArr());
  243 + } else {
188 // ящик не имеет писем с вложениями 244 // ящик не имеет писем с вложениями
189 continue; 245 continue;
190 } 246 }
@@ -193,7 +249,7 @@ class ParserController extends Controller @@ -193,7 +249,7 @@ class ParserController extends Controller
193 return $files; 249 return $files;
194 } 250 }
195 251
196 - private function UnpackFiles ( &$files, $importer_id_prefix = '') 252 + private function UnpackFiles(&$files, $importer_id_prefix = '')
197 { 253 {
198 // если в вложениях встречаются архивы - распакуем 254 // если в вложениях встречаются архивы - распакуем
199 // иициируем фабрику архиваторов 255 // иициируем фабрику архиваторов
@@ -201,13 +257,13 @@ class ParserController extends Controller @@ -201,13 +257,13 @@ class ParserController extends Controller
201 // получим все расширения которые поддерживает фабрика 257 // получим все расширения которые поддерживает фабрика
202 $arch_extensions = $arch_creator->getHandleExtension(); 258 $arch_extensions = $arch_creator->getHandleExtension();
203 // выбираем только те файлы которые мы можем распаковать 259 // выбираем только те файлы которые мы можем распаковать
204 - $arch_files = array_intersect( $files , $arch_extensions ); 260 + $arch_files = array_intersect($files, $arch_extensions);
205 foreach ($arch_files as $arch_name => $arch_ext) { 261 foreach ($arch_files as $arch_name => $arch_ext) {
206 // создаем конкретный архиватор по расширению 262 // создаем конкретный архиватор по расширению
207 - $arch_reader = $arch_creator->create( $arch_name, $arch_ext ); 263 + $arch_reader = $arch_creator->create($arch_name, $arch_ext);
208 // определим ид поставщика по имени файла 264 // определим ид поставщика по имени файла
209 $importer_id = ImportersFiles::getIdFromFileName($arch_name); 265 $importer_id = ImportersFiles::getIdFromFileName($arch_name);
210 - if( $importer_id ){ 266 + if ($importer_id) {
211 // если файл архива содержит поставщика (на предыдущих этапах мы его туда записали) 267 // если файл архива содержит поставщика (на предыдущих этапах мы его туда записали)
212 // то нужно все вложенные файлы также промаркировать 268 // то нужно все вложенные файлы также промаркировать
213 $arch_reader->setFileNamePrefix($importer_id . $importer_id_prefix); 269 $arch_reader->setFileNamePrefix($importer_id . $importer_id_prefix);
@@ -217,42 +273,42 @@ class ParserController extends Controller @@ -217,42 +273,42 @@ class ParserController extends Controller
217 // распаковываем файлы 273 // распаковываем файлы
218 $arch_reader->extractTo(\Yii::getAlias('@temp_upload') . '/'); 274 $arch_reader->extractTo(\Yii::getAlias('@temp_upload') . '/');
219 // убираем файл архива из итогового массива 275 // убираем файл архива из итогового массива
220 - unset( $files[$arch_name] ); 276 + unset($files[$arch_name]);
221 // удаляем файл архива 277 // удаляем файл архива
222 unlink($arch_name); 278 unlink($arch_name);
223 // добавляем распакованные файлы к итоговому массиву 279 // добавляем распакованные файлы к итоговому массиву
224 - $files = array_merge( $files, $arch_reader->getExtractedFiles()); 280 + $files = array_merge($files, $arch_reader->getExtractedFiles());
225 } 281 }
226 282
227 } 283 }
228 284
229 - private function registerAndReplaceFiles ( &$files, $new_destination ) 285 + private function registerAndReplaceFiles(&$files, $new_destination)
230 { 286 {
231 - foreach ( $files as $name => $ext ) { 287 + foreach ($files as $name => $ext) {
232 // имена файлов для расширения csv нужно поменять, 288 // имена файлов для расширения csv нужно поменять,
233 // для остальных оставляем оригинальные имена вложений (плюс ид поставщика если письмо от поставщика) 289 // для остальных оставляем оригинальные имена вложений (плюс ид поставщика если письмо от поставщика)
234 - $file_name = pathinfo( $name, PATHINFO_BASENAME );  
235 - if( $ext == 'csv' ){ 290 + $file_name = pathinfo($name, PATHINFO_BASENAME);
  291 + if ($ext == 'csv') {
236 // определим ид поставщика по имени файла 292 // определим ид поставщика по имени файла
237 - $importer_id = ImportersFiles::getIdFromFileName( basename( $name ) );; 293 + $importer_id = ImportersFiles::getIdFromFileName(basename($name));;
238 294
239 // зарегистрируем прайс 295 // зарегистрируем прайс
240 - if ( $importer_id ) { 296 + if ($importer_id) {
241 $files_model = new ImportersFiles(); 297 $files_model = new ImportersFiles();
242 $files_model->importer_id = $importer_id; 298 $files_model->importer_id = $importer_id;
243 if ($files_model->save()) { 299 if ($files_model->save()) {
244 // имя файла переименуем на id записи 300 // имя файла переименуем на id записи
245 $file_name = \Yii::$app->db->getLastInsertID() . '.csv'; 301 $file_name = \Yii::$app->db->getLastInsertID() . '.csv';
246 302
247 - } else{ 303 + } else {
248 304
249 $files_model->throwStringErrorException(); 305 $files_model->throwStringErrorException();
250 } 306 }
251 } 307 }
252 } 308 }
253 - if( rename( $name, $new_destination . $file_name ) ){ 309 + if (rename($name, $new_destination . $file_name)) {
254 \Yii::info("Вложение {$name} сохранено", 'mail'); 310 \Yii::info("Вложение {$name} сохранено", 'mail');
255 - } else{ 311 + } else {
256 new \ErrorException("Нет возможности переписать файл {$name}"); 312 new \ErrorException("Нет возможности переписать файл {$name}");
257 } 313 }
258 } 314 }
console/migrations/m151203_134605_addLogTable.php 0 → 100644
  1 +<?php
  2 +
  3 +use yii\db\Schema;
  4 +use yii\db\Migration;
  5 +
  6 +class m151203_134605_addLogTable extends Migration
  7 +{
  8 + public function up()
  9 + {
  10 + $table = <<< MySQL
  11 + CREATE TABLE `w_log` (
  12 + `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  13 + `error` BOOL NOT NULL DEFAULT FALSE,
  14 + `record_type` int(1) unsigned NOT NULL DEFAULT 1,
  15 + `time_start` timestamp NULL DEFAULT NULL,
  16 + `importer_id` int(6) unsigned NOT NULL,
  17 + `time_end` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  18 + `log_msg` MEDIUMTEXT,
  19 + `file_name` VARCHAR(100),
  20 + PRIMARY KEY (`id`),
  21 + KEY `record_type` (`error`,`record_type`),
  22 + KEY `time_start` (`time_start`)
  23 + ) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;
  24 +MySQL;
  25 +
  26 + $this->execute($table);
  27 + }
  28 +
  29 + public function down()
  30 + {
  31 + // вернем все как было
  32 + $drop_table = 'drop table if exists w_log';
  33 +
  34 + $this->execute($drop_table);
  35 +
  36 + }
  37 +
  38 + /*
  39 + // Use safeUp/safeDown to run migration code within a transaction
  40 + public function safeUp()
  41 + {
  42 + }
  43 +
  44 + public function safeDown()
  45 + {
  46 + }
  47 + */
  48 +}
test.html deleted
1 -yii\web\Cookie Object ( [name] => _frontendUser [value] => [1,"admin",2592000] [domain] => [expire] => 1451578203 [path] => / [secure] => [httpOnly] => 1 ) 1  
2 -yii\web\Cookie Object ( [name] => _frontendUser [value] => [4201,"wwww",2592000] [domain] => [expire] => 1451578282 [path] => / [secure] => [httpOnly] => 1 ) 1  
3 \ No newline at end of file 0 \ No newline at end of file