Commit 97be095e30b29a6b7f1534d3b4653b6e54b16eb9

Authored by alexanderWeb
1 parent 9744f0d3

message

(2).bowerrc 0 → 100644
  1 +{
  2 + "directory" : "vendor/bower"
  3 +}
... ...
backend/config/main.php
... ... @@ -23,6 +23,16 @@ return [
23 23 ],
24 24 ],
25 25 'components' => [
  26 + 'mailer' => [
  27 + 'class' => 'yii\swiftmailer\Mailer',
  28 + 'transport' => [
  29 + 'class' => 'Swift_SpoolTransport',
  30 + 'constructArgs' => [
  31 + 'spool' => new common\components\DbSpool(),
  32 + ]
  33 + ],
  34 + 'useFileTransport' => false,
  35 + ],
26 36 'user' => [
27 37 'identityClass' => 'common\models\User',
28 38 'enableAutoLogin' => true,
... ...
backend/config/params.php
1 1 <?php
2 2 return [
3 3 'adminEmail' => 'admin@example.com',
  4 + 'lang_id'=>1
4 5 ];
... ...
backend/controllers/AjaxController.php 0 → 100644
  1 +<?php
  2 +namespace backend\controllers;
  3 +
  4 +use backend\models\Language;
  5 +use backend\models\MessageLang;
  6 +use backend\models\Message;
  7 +use yii\web\Controller;
  8 +use yii\web\ForbiddenHttpException;
  9 +use yii\web\NotFoundHttpException;
  10 +
  11 +class AjaxController extends Controller
  12 +{
  13 + public function beforeAction($action)
  14 + {
  15 + if(!\Yii::$app->request->getIsAjax()) {
  16 + //throw new ForbiddenHttpException('Permission denied');
  17 + }
  18 +
  19 + if(!parent::beforeAction($action)) {
  20 + return false;
  21 + }
  22 +
  23 + return true;
  24 + }
  25 + public function actionMessageForm($lang_id, $widget_id)
  26 + {
  27 + $model = Language::find()->where(['>=', 'language_id', 1])->andWhere(['active' => 1, 'language_id' => $lang_id])->one();
  28 + if(!$model) {
  29 + throw new NotFoundHttpException('Language not found');
  30 + }
  31 + $message_lang = new MessageLang();
  32 + return $this->renderAjax('message_form', ['model' => $model, 'message_lang' => $message_lang, 'widget_id' => $widget_id]);
  33 + }
  34 +
  35 + /* public function actionRemoveImage()
  36 + {
  37 + $post = \Yii::$app->request->post();
  38 + if(!empty($post['article_media_id'])) {
  39 + $article_media = ArticleMedia::findOne($post['article_media_id']);
  40 + if($post['remove_media']) {
  41 + $media = $article_media->media->delete();
  42 + }
  43 + if(!empty($article_media)) {
  44 + $article_media->delete();
  45 + }
  46 + return true;
  47 + } else {
  48 + return false;
  49 + }
  50 + }
  51 +
  52 + public function actionRemoveImageCategory()
  53 + {
  54 + $post = \Yii::$app->request->post();
  55 + if(!empty($post['category_media_id'])) {
  56 + $category_media = ArticleCategoryMedia::findOne($post['category_media_id']);
  57 + if($post['remove_media']) {
  58 + $media = $category_media->media->delete();
  59 + }
  60 + if(!empty($category_media)) {
  61 + $category_media->delete();
  62 + }
  63 + return true;
  64 + } else {
  65 + return false;
  66 + }
  67 + }*/
  68 +}
... ...
backend/controllers/MailerQueueController.php 0 → 100644
  1 +<?php
  2 +
  3 +namespace backend\controllers;
  4 +
  5 +use backend\models\Message;
  6 +use backend\models\MessageLang;
  7 +use Yii;
  8 +use common\models\MailerQueue;
  9 +use common\components\DbSpool;
  10 +use yii\data\ActiveDataProvider;
  11 +use yii\web\Controller;
  12 +use yii\web\NotFoundHttpException;
  13 +use yii\filters\VerbFilter;
  14 +
  15 +/**
  16 + * MailerQueueController implements the CRUD actions for MailerQueue model.
  17 + */
  18 +class MailerQueueController extends Controller
  19 +{
  20 + public function behaviors()
  21 + {
  22 + return [
  23 + 'verbs' => [
  24 + 'class' => VerbFilter::className(),
  25 + 'actions' => [
  26 + 'delete' => ['post'],
  27 + ],
  28 + ],
  29 + ];
  30 + }
  31 +
  32 + /**
  33 + * @param integer $id message id
  34 + * add message to queue
  35 + */
  36 + public function actionSpooler($id)
  37 + {
  38 + $curr_lang=2;
  39 + $message_tempalete = Message::findOne(['id'=>$id]);
  40 + $message_template_langs = $message_tempalete->getMessageLangs()->where(['>=', 'lang_id', '1'])->indexBy('lang_id')->all();
  41 + $message = \Swift_Message::newInstance();
  42 + $spool = new DbSpool();
  43 + $transport = \Swift_SpoolTransport::newInstance($spool);
  44 + $mailer = \Swift_Mailer::newInstance($transport);
  45 + foreach ($message_template_langs as $message_template_lang)
  46 + {
  47 + if($message_template_lang->lang_id == $curr_lang )
  48 + {
  49 + $message ->setSubject($message_template_lang->title)
  50 + ->setFrom('info@example.com')
  51 + ->setTo('alexandr.khivrich@gmail.com')
  52 + ->setBody($message_template_lang->body);
  53 + if($message_template_lang->is_html)
  54 + {
  55 + $message ->setContentType('text\html');
  56 + }
  57 + break;
  58 + }
  59 + }
  60 + $result = $mailer->send($message);
  61 + }
  62 +
  63 + /**
  64 + * Send Queue messages
  65 + */
  66 + public function actionSend()
  67 + {
  68 + $messageLimit = 10;
  69 + $timeLimit = 0;
  70 +
  71 + $spool = new DbSpool();
  72 + //$transportReal = \Swift_MailTransport::newInstance();
  73 + $transportReal = \Swift_SmtpTransport::newInstance(
  74 + "smtp.gmail.com",
  75 + "465",
  76 + "ssl"
  77 + )
  78 + ->setUsername("alexandr.khivrich@gmail.com")
  79 + ->setPassword("10181997Nadia");
  80 +
  81 + $spool->setMessageLimit($messageLimit);
  82 + $spool->setTimeLimit($timeLimit);
  83 + $sent = $spool->flushQueue($transportReal);
  84 +
  85 + echo sprintf('sent %s emails', $sent);
  86 + }
  87 + /**
  88 + * Finds the MailerQueue model based on its primary key value.
  89 + * If the model is not found, a 404 HTTP exception will be thrown.
  90 + * @param integer $id
  91 + * @return MailerQueue the loaded model
  92 + * @throws NotFoundHttpException if the model cannot be found
  93 + */
  94 + protected function findModel($id)
  95 + {
  96 + if (($model = MailerQueue::findOne($id)) !== null) {
  97 + return $model;
  98 + } else {
  99 + throw new NotFoundHttpException('The requested page does not exist.');
  100 + }
  101 + }
  102 +}
... ...
backend/controllers/MessageController.php 0 → 100644
  1 +<?php
  2 +
  3 +namespace backend\controllers;
  4 +use common\models\Language;
  5 +use backend\models\MessageLang;
  6 +use Yii;
  7 +use backend\models\Message;
  8 +use app\models\MessageSearch;
  9 +use yii\web\Controller;
  10 +use yii\web\NotFoundHttpException;
  11 +use yii\filters\VerbFilter;
  12 +use yii\data\ActiveDataProvider;
  13 +/**
  14 + * MessageController implements the CRUD actions for Message model.
  15 + */
  16 +class MessageController extends Controller
  17 +{
  18 + public function behaviors()
  19 + {
  20 + return [
  21 + 'verbs' => [
  22 + 'class' => VerbFilter::className(),
  23 + 'actions' => [
  24 + 'delete' => ['post'],
  25 + ],
  26 + ],
  27 + ];
  28 + }
  29 +
  30 + /**
  31 + * Lists all Message models.
  32 + * @return mixed
  33 + */
  34 + public function actionIndex()
  35 + {
  36 + $searchModel = new MessageSearch();
  37 + $dataProvider = $searchModel->search(Yii::$app->request->queryParams);
  38 +
  39 + return $this->render('index', [
  40 + 'searchModel' => $searchModel,
  41 + 'dataProvider' => $dataProvider,
  42 + ]);
  43 + }
  44 +
  45 + /**
  46 + * Displays a single Message model.
  47 + * @param integer $id
  48 + * @return mixed
  49 + */
  50 + public function actionView($id)
  51 + {
  52 + return $this->render('view', [
  53 + 'model' => $this->findModel($id),
  54 + 'model_lang'=>$model_lang = MessageLang::findOne(['message_id'=>$id])
  55 + ]);
  56 + }
  57 +
  58 + /**
  59 + * Creates a new Message 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 + $message_langs = array();
  66 + $message = new Message();
  67 + $images = array();
  68 + $message->loadDefaultValues();
  69 + $langs = Language::getActiveLanguages();
  70 + $default_lang = Language::getDefaultLang();
  71 + $isValid = false;
  72 +
  73 + if(!empty(\Yii::$app->request->post()))
  74 + {
  75 +
  76 + $isValid = true;
  77 + $message->load(\Yii::$app->request->post());
  78 + $isValid = $message->validate();
  79 + if(empty(\Yii::$app->request->post()['MessageLang']))
  80 + {
  81 +
  82 + $message_langs[$default_lang->language_id] = new MessageLang();
  83 + $isValid = MessageLang::validateMultiple($message_langs) && $isValid;
  84 + }
  85 + else
  86 + {
  87 + foreach(\Yii::$app->request->post()['MessageLang'] as $index => $message_lang) {
  88 + $message_langs[$index] = new MessageLang();
  89 + }
  90 + MessageLang::loadMultiple($message_langs, \Yii::$app->request->post());
  91 + // $isValid = MessageLang::validateMultiple($message_langs) && $isValid;
  92 + }
  93 + }
  94 + else
  95 + {
  96 + $message_langs[$default_lang->language_id] = new MessageLang();
  97 + }
  98 + if($isValid)
  99 + {
  100 + $message->save();
  101 + $first = 1;
  102 + foreach($message_langs as $message_lang) {
  103 + $message_lang->message_id=$message->id;
  104 + $message_lang->save();
  105 + }
  106 + $this->redirect('index');
  107 + }
  108 + else
  109 + {
  110 + return $this->render('create', [
  111 + 'message_langs' => $message_langs,
  112 + 'message' => $message,
  113 + 'langs' => $langs,
  114 + ]);
  115 + }
  116 + }
  117 +
  118 + /**
  119 + * Updates an existing Message model.
  120 + * If update is successful, the browser will be redirected to the 'view' page.
  121 + * @param integer $id
  122 + * @return mixed
  123 + */
  124 + public function actionUpdate($id)
  125 + {
  126 + $message = $this->findModel($id);
  127 + $message_langs=$message->getMessageLangs()->where(['>=', 'lang_id', '1'])->indexBy('lang_id')->all();
  128 + $langs = Language::getActiveLanguages();
  129 + $default_lang = Language::getDefaultLang();
  130 + $isValid = false;
  131 + $post=\Yii::$app->request->post();
  132 + if(!empty($post))
  133 + {
  134 + $message->load($post);
  135 + $isValid = $message->validate();
  136 + }
  137 + if(empty($post['MessageLang']))
  138 + {
  139 + $isValid = MessageLang::validateMultiple($message_langs) && $isValid;
  140 + }
  141 + else
  142 + {
  143 + foreach($post['MessageLang'] as $index => $message_lang)
  144 + {
  145 + if (!array_key_exists($index, $message_langs))
  146 + {
  147 + $message_langs[$index] = new MessageLang();
  148 + $message_langs[$index]->message_id = $message->id;
  149 + }
  150 + }
  151 + MessageLang::loadMultiple($message_langs,$post);
  152 + }
  153 + if($isValid)
  154 + {
  155 + $message->save();
  156 + $first = 1;
  157 + foreach($message_langs as $message_lang) {
  158 + $message_lang->message_id=$message->id;
  159 + $message_lang->save();
  160 + }
  161 + $this->redirect('index');
  162 + }
  163 + else
  164 + {
  165 + return $this->render('update', [
  166 + 'message_langs' => $message_langs,
  167 + 'message' => $message,
  168 + 'langs' => $langs,
  169 + ]);
  170 + }
  171 + }
  172 +
  173 + /**
  174 + * Deletes an existing Message model.
  175 + * If deletion is successful, the browser will be redirected to the 'index' page.
  176 + * @param integer $id
  177 + * @return mixed
  178 + */
  179 + public function actionDelete($id)
  180 + {
  181 + foreach(MessageLang::findAll(['message_id'=>$id])as $message_lang)
  182 + {
  183 + $message_lang->delete();
  184 + }
  185 +
  186 + $this->findModel($id)->delete();
  187 + return $this->redirect(['index']);
  188 + }
  189 +
  190 + /**
  191 + * Finds the Message model based on its primary key value.
  192 + * If the model is not found, a 404 HTTP exception will be thrown.
  193 + * @param integer $id
  194 + * @return Message the loaded model
  195 + * @throws NotFoundHttpException if the model cannot be found
  196 + */
  197 + protected function findModel($id)
  198 + {
  199 + if (($model = Message::findOne($id)) !== null) {
  200 + return $model;
  201 + } else {
  202 + throw new NotFoundHttpException('The requested page does not exist.');
  203 + }
  204 + }
  205 +}
... ...
backend/models/Message.php 0 → 100644
  1 +<?php
  2 +
  3 +namespace backend\models;
  4 +
  5 +use Yii;
  6 +
  7 +/**
  8 + * This is the model class for table "message".
  9 + *
  10 + * @property integer $id
  11 + * @property string $name
  12 + * @property boolean $is_sevice_sender
  13 + * @property boolean $is_server_sender
  14 + * @property boolean $is_sms
  15 + *
  16 + * @property MessageLang[] $messageLangs
  17 + */
  18 +class Message extends \yii\db\ActiveRecord
  19 +{
  20 + /**
  21 + * @inheritdoc
  22 + */
  23 + public static function tableName()
  24 + {
  25 + return 'message';
  26 + }
  27 +
  28 + /**
  29 + * @inheritdoc
  30 + */
  31 + public function rules()
  32 + {
  33 + return [
  34 + [['is_sevice_sender', 'is_sevice_sender', 'is_sms'], 'boolean'],
  35 + [['name'], 'string', 'max' => 255]
  36 + ];
  37 + }
  38 +
  39 + /**
  40 + * @inheritdoc
  41 + */
  42 + public function attributeLabels()
  43 + {
  44 + return [
  45 + 'id' => 'ID',
  46 + 'name' => 'Name',
  47 + 'is_sevice_sender' => 'Sevice sender',
  48 + 'is_server_sender' => 'Server sender',
  49 + 'is_sms' => 'Is SMS',
  50 + ];
  51 + }
  52 +
  53 + /**
  54 + * @return \yii\db\ActiveQuery
  55 + */
  56 + public function getMessageLangs()
  57 + {
  58 + return $this->hasMany(MessageLang::className(), ['message_id' => 'id']);
  59 + }
  60 +}
... ...
backend/models/MessageLang.php 0 → 100644
  1 +<?php
  2 +
  3 +namespace backend\models;
  4 +
  5 +use Yii;
  6 +
  7 +/**
  8 + * This is the model class for table "message_lang".
  9 + *
  10 + * @property string $body
  11 + * @property string $title
  12 + * @property integer $lang_id
  13 + * @property string $body_sms
  14 + * @property boolean $is_html
  15 + * @property integer $message_id
  16 + * @property integer $id
  17 + *
  18 + * @property Language $lang
  19 + * @property Message $message
  20 + */
  21 +class MessageLang extends \yii\db\ActiveRecord
  22 +{
  23 + /**
  24 + * @inheritdoc
  25 + */
  26 + public static function tableName()
  27 + {
  28 + return 'message_lang';
  29 + }
  30 +
  31 + /**
  32 + * @inheritdoc
  33 + */
  34 + public function rules()
  35 + {
  36 + return [
  37 + [['body', 'message_id'], 'required'],
  38 + [['body', 'body_sms'], 'string'],
  39 + [['lang_id', 'message_id'], 'integer'],
  40 + [['is_html'], 'boolean'],
  41 + [['title'], 'string', 'max' => 255]
  42 + ];
  43 + }
  44 +
  45 + /**
  46 + * @inheritdoc
  47 + */
  48 + public function attributeLabels()
  49 + {
  50 + return [
  51 + 'body' => 'Body',
  52 + 'title' => 'Title',
  53 + 'lang_id' => 'Lang ID',
  54 + 'body_sms' => 'SMS',
  55 + 'is_html' => 'Is Html',
  56 + 'message_id' => 'Message ID',
  57 + 'id' => 'ID',
  58 + ];
  59 + }
  60 +
  61 + /**
  62 + * @return \yii\db\ActiveQuery
  63 + */
  64 + public function getLang()
  65 + {
  66 + return $this->hasOne(Language::className(), ['language_id' => 'lang_id']);
  67 + }
  68 +
  69 + /**
  70 + * @return \yii\db\ActiveQuery
  71 + */
  72 + public function getMessage()
  73 + {
  74 + return $this->hasOne(Message::className(), ['id' => 'message_id']);
  75 + }
  76 +}
... ...
backend/models/MessageSearch.php 0 → 100644
  1 +<?php
  2 +
  3 +namespace app\models;
  4 +
  5 +use Yii;
  6 +use yii\base\Model;
  7 +use yii\data\ActiveDataProvider;
  8 +use backend\models\Message;
  9 +
  10 +/**
  11 + * MessageSearch represents the model behind the search form about `backend\models\Message`.
  12 + */
  13 +class MessageSearch extends Message
  14 +{
  15 + /**
  16 + * @inheritdoc
  17 + */
  18 + public function rules()
  19 + {
  20 + return [
  21 + [['id'], 'integer'],
  22 + [['name'], 'safe'],
  23 + ];
  24 + }
  25 +
  26 + /**
  27 + * @inheritdoc
  28 + */
  29 + public function scenarios()
  30 + {
  31 + // bypass scenarios() implementation in the parent class
  32 + return Model::scenarios();
  33 + }
  34 +
  35 + /**
  36 + * Creates data provider instance with search query applied
  37 + *
  38 + * @param array $params
  39 + *
  40 + * @return ActiveDataProvider
  41 + */
  42 + public function search($params)
  43 + {
  44 + $query = Message::find();
  45 +
  46 + $dataProvider = new ActiveDataProvider([
  47 + 'query' => $query,
  48 + ]);
  49 +
  50 + $this->load($params);
  51 +
  52 + if (!$this->validate()) {
  53 + // uncomment the following line if you do not want to return any records when validation fails
  54 + // $query->where('0=1');
  55 + return $dataProvider;
  56 + }
  57 +
  58 + $query->andFilterWhere([
  59 + 'id' => $this->id,
  60 + ]);
  61 +
  62 + $query->andFilterWhere(['like', 'name', $this->name]);
  63 +
  64 + return $dataProvider;
  65 + }
  66 +}
... ...
backend/views/ajax/message_form.php 0 → 100644
  1 +<?php
  2 +
  3 +use yii\bootstrap\ActiveField;
  4 +use mihaildev\ckeditor\CKEditor;
  5 +
  6 +$form = \yii\bootstrap\ActiveForm::begin();
  7 +?>
  8 +<div role="" class="tab-pane active ajax-loaded" id="<?=$widget_id?>-<?=$model->language_id?>">
  9 +
  10 + <?= (new ActiveField(['model' => $message_lang, 'attribute' => "[$model->language_id]lang_id"]))->label(false)->hiddenInput(['value' => $model->language_id]) ?>
  11 +
  12 + <?= (new ActiveField(['model' => $message_lang, 'attribute' => "[$model->language_id]title", 'form' => $form]))->textInput() ?>
  13 +
  14 + <?= (new ActiveField(['model' => $message_lang, 'attribute' => "[$model->language_id]body", 'form' => $form]))->widget(CKEditor::className(),['editorOptions' => [ 'preset' => 'full', 'inline' => false, ], ]); ?>
  15 +
  16 + <?= (new ActiveField(['model' => $message_lang, 'attribute' => "[$model->language_id]body_sms"]))->textarea() ?>
  17 +</div>
  18 +<?php
  19 +$form->end();
  20 +?>
... ...
backend/views/language/index.php
... ... @@ -24,7 +24,7 @@ echo $this-&gt;render(&#39;layout&#39;);
24 24 [
25 25 'class' => Column::className(),
26 26 'content' => function($model, $key, $index, $column) {
27   - return '<span class="f32"><span class="flag '.$model->country_code.'"></span></span>';
  27 + return '<span class="f32"><span class="flag '.$model->lang_code.'"></span></span>';
28 28 }
29 29 ],
30 30 'language_name',
... ...
backend/views/layouts/left.php
... ... @@ -38,6 +38,7 @@
38 38 ['label' => 'Gii', 'icon' => 'fa fa-file-code-o', 'url' => ['/gii']],
39 39 ['label' => 'Debug', 'icon' => 'fa fa-dashboard', 'url' => ['/debug']],
40 40 ['label' => 'Login', 'url' => ['site/login'], 'visible' => Yii::$app->user->isGuest],
  41 + ['label'=>'Messages','url'=>['/message']],
41 42 ['label' => 'Пользователи', 'icon' => 'fa fa-file-code-o', 'url' => ['/user/']],
42 43 [
43 44 'label' => Yii::t('app', 'Blog'),
... ...
backend/views/message/_form.php 0 → 100644
  1 +<?php
  2 +
  3 +use yii\helpers\Html;
  4 +use common\widgets\Multilang;
  5 +use mihaildev\ckeditor\CKEditor;
  6 +use yii\bootstrap\ActiveForm;
  7 +use yii\helpers\Json;
  8 +use yii\helpers\Url;
  9 +use yii\widgets\Pjax;
  10 +use backend\models\Message;
  11 +use yii\helpers\ArrayHelper;
  12 +/* @var $this yii\web\View */
  13 +/* @var $model backend\models\Message */
  14 +/* @var $form yii\widgets\ActiveForm */
  15 +$def_lang = array_keys($langs)[0];
  16 +?>
  17 +
  18 +<div class="message-form">
  19 + <?php $form = \yii\bootstrap\ActiveForm::begin(['options' => ['enctype' => 'multipart/form-data']]); ?>
  20 + <?= $form->field($message,'name')->textInput()?>
  21 + <?= $form->field($message,'is_sevice_sender')->checkbox()?>
  22 + <?= $form->field($message,'is_server_sender')->checkbox()?>
  23 + <?= $form->field($message,'is_sms')->checkbox()?>
  24 + <?php
  25 + $multilang = Multilang::begin(['ajaxpath' => Url::to(['/ajax/message-form']), 'form' => $form, 'data_langs' => $message_langs]);
  26 + ?>
  27 + <?php
  28 + $first = 1;
  29 + foreach($message_langs as $index => $message_lang) {
  30 + ?>
  31 + <div role="" class="tab-pane <?php if($first) { echo 'active main-tab'; } ?>" id="<?=$multilang->id?>-<?=$index?>">
  32 +
  33 + <?= $form->field($message_langs[$index], "[$index]lang_id")->label(false)->hiddenInput(['value' =>$index]) ?>
  34 +
  35 + <?= $form->field($message_langs[$index], "[$index]title")->textInput() ?>
  36 +
  37 + <?= $form->field($message_langs[$index], "[$index]body")->widget(CKEditor::className(),['editorOptions' => [ 'preset' => 'full', 'inline' => false, ], ]); ?>
  38 +
  39 + <?= $form->field($message_langs[$index], "[$index]body_sms")->textarea()?>
  40 + </div>
  41 + <?php
  42 + $first = 0;
  43 + }
  44 + ?>
  45 + <?php
  46 + $multilang->end();
  47 + ?>
  48 + <div class="form-group">
  49 + <?= Html::submitButton($message->isNewRecord ? 'Create' : 'Update', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
  50 + </div>
  51 + <?php ActiveForm::end(); ?>
  52 +
  53 +</div>
... ...
backend/views/message/_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 app\models\MessageSearch */
  8 +/* @var $form yii\widgets\ActiveForm */
  9 +?>
  10 +
  11 +<div class="message-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, 'name') ?>
  21 +
  22 + <div class="form-group">
  23 + <?= Html::submitButton('Search', ['class' => 'btn btn-primary']) ?>
  24 + <?= Html::resetButton('Reset', ['class' => 'btn btn-default']) ?>
  25 + </div>
  26 +
  27 + <?php ActiveForm::end(); ?>
  28 +
  29 +</div>
... ...
backend/views/message/create.php 0 → 100644
  1 +<?php
  2 +
  3 +use yii\helpers\Html;
  4 +
  5 +
  6 +/* @var $this yii\web\View */
  7 +/* @var $model backend\models\Message */
  8 +
  9 +$this->title = 'Create Message';
  10 +$this->params['breadcrumbs'][] = ['label' => 'Messages', 'url' => ['index']];
  11 +$this->params['breadcrumbs'][] = $this->title;
  12 +?>
  13 +<div class="message-create">
  14 +
  15 + <h1><?= Html::encode($this->title) ?></h1>
  16 +
  17 + <?= $this->render('_form', [
  18 + 'message_langs' => $message_langs,
  19 + 'message' => $message,
  20 + 'langs' => $langs,
  21 + ]) ?>
  22 +
  23 +</div>
... ...
backend/views/message/index.php 0 → 100644
  1 +<?php
  2 +
  3 +use yii\helpers\Html;
  4 +use yii\grid\GridView;
  5 +
  6 +/* @var $this yii\web\View */
  7 +/* @var $searchModel app\models\MessageSearch */
  8 +/* @var $dataProvider yii\data\ActiveDataProvider */
  9 +
  10 +$this->title = 'Messages';
  11 +$this->params['breadcrumbs'][] = $this->title;
  12 +?>
  13 +<div class="message-index">
  14 +
  15 + <h1><?= Html::encode($this->title) ?></h1>
  16 + <?php // echo $this->render('_search', ['model' => $searchModel]); ?>
  17 +
  18 + <p>
  19 + <?= Html::a('Create Message', ['create'], ['class' => 'btn btn-success']) ?>
  20 + </p>
  21 +
  22 + <?= GridView::widget([
  23 + 'dataProvider' => $dataProvider,
  24 + 'filterModel' => $searchModel,
  25 + 'columns' => [
  26 + ['class' => 'yii\grid\SerialColumn'],
  27 +
  28 + 'id',
  29 + 'name',
  30 +
  31 + ['class' => 'yii\grid\ActionColumn'],
  32 + ],
  33 + ]); ?>
  34 +
  35 +</div>
... ...
backend/views/message/update.php 0 → 100644
  1 +<?php
  2 +
  3 +use yii\helpers\Html;
  4 +
  5 +/* @var $this yii\web\View */
  6 +/* @var $model backend\models\Message */
  7 +
  8 +$this->title = 'Update Message: ' . ' ' . $model->name;
  9 +$this->params['breadcrumbs'][] = ['label' => 'Messages', 'url' => ['index']];
  10 +$this->params['breadcrumbs'][] = ['label' => $model->name, 'url' => ['view', 'id' => $model->id]];
  11 +$this->params['breadcrumbs'][] = 'Update';
  12 +?>
  13 +<div class="message-update">
  14 +
  15 + <h1><?= Html::encode($this->title) ?></h1>
  16 +
  17 + <?= $this->render('_form', [
  18 + 'message_langs' => $message_langs,
  19 + 'message' => $message,
  20 + 'langs' => $langs,
  21 + ]) ?>
  22 +
  23 +</div>
... ...
backend/views/message/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 backend\models\Message */
  8 +
  9 +$this->title = $model->name;
  10 +$this->params['breadcrumbs'][] = ['label' => 'Messages', 'url' => ['index']];
  11 +$this->params['breadcrumbs'][] = $this->title;
  12 +?>
  13 +<div class="message-view">
  14 +
  15 + <h1><?= Html::encode($this->title) ?></h1>
  16 +
  17 + <p>
  18 + <?= Html::a('Update', ['update', 'id' => $model->id], ['class' => 'btn btn-primary']) ?>
  19 + <?= Html::a('Delete', ['delete', 'id' => $model->id], [
  20 + 'class' => 'btn btn-danger',
  21 + 'data' => [
  22 + 'confirm' => 'Are you sure you want to delete this item?',
  23 + 'method' => 'post',
  24 + ],
  25 + ]) ?>
  26 + </p>
  27 +
  28 + <?= DetailView::widget([
  29 + 'model' => $model,
  30 + 'attributes' => [
  31 + 'id',
  32 + 'name',
  33 + [
  34 + 'label'=>'Lang',
  35 + 'value'=>$model_lang->lang->language_name
  36 + ]
  37 + ],
  38 + ]) ?>
  39 +
  40 +</div>
... ...
backend/web/js/option.js
... ... @@ -36,42 +36,6 @@ $(function() {
36 36 $(document).on('click', '.remove_lang', function() {
37 37 $(this).parents('.form-wrapper').remove();
38 38 });
39   - if($('#lang-tabs li').length > 1) {
40   - $('#lang-tabs li').append('<span class="glyphicon glyphicon-remove-circle remove-lang"></span>')
41   - }
42   - $(document).on('click', '#lang-dropdown li a[data-lang]', function() {
43   - var lang = $(this).data('lang');
44   - var flag = $(this).find('span').first().clone();
45   - var el = $(this);
46   - $.get('/blog/ajax/category-form', { lang_id: lang }, function(data) {
47   - $('#lang-tabs li').removeClass('active');
48   - $('#lang-tabs').append('<li role="lang_inputs" class="active" data-lang="'+lang+'"><a href="#lang-'+lang+'" aria-controls="lang-'+lang+'" role="tab" data-toggle="tab">'+$('<p>').append($(flag)).html()+'</a></li>');
49   - $('.lang-tab-content .tab-pane.active').removeClass('active');
50   - $('.lang-tab-content').append($(data).find('.ajax-loaded').first());
51   - $('body').append($(data).filter('script'));
52   - $(el).parent().remove();
53   - if(!$('#lang-dropdown li').length) {
54   - $('#dropdownLang').addClass('disabled');
55   - }
56   - if($('#lang-tabs li').length > 1) {
57   - $('#lang-tabs li').append('<span class="glyphicon glyphicon-remove-circle remove-lang"></span>')
58   - }
59   - });
60   - });
61   - $(document).on('click', '.remove-lang', function() {
62   - var lang = $(this).parent().data('lang');
63   - var flag = $(this).parent().find('span.flag').first().clone();
64   - $('#lang-'+lang).remove();
65   - $('#lang-dropdown').append('<li><a href="#lang-tabs" data-lang="'+lang+'">'+$('<p>').append($(flag)).html()+'</a></li>');
66   - $('#dropdownLang').removeClass('disabled');
67   - $(this).parent().remove();
68   - if($('#lang-tabs li').length <= 1) {
69   - $('#lang-tabs li').find('.remove-lang').remove();
70   - }
71   - if(!$('#lang-tabs>li.active').length) {
72   - $('#lang-tabs>li').first().find('a').tab('show');
73   - }
74   - });
75 39 $(document).on('change', '.image_inputs_field', function() {
76 40 readURL(this);
77 41 });
... ... @@ -89,4 +53,55 @@ $(function() {
89 53 }
90 54 return false;
91 55 });
  56 + $.each($('.nav-tabs.f32'), function(key, value) {
  57 + if($(value).find('li').length > 1) {
  58 + $(value).find('li').append('<span class="glyphicon glyphicon-remove-circle remove-lang"></span>');
  59 + }
  60 + });
  61 + $(document).on('click', '.dropdown-menu.f32 li a[data-lang]', function() {
  62 + var lang = $(this).data('lang');
  63 + var flag = $(this).find('span').first().clone();
  64 + var el = $(this);
  65 + var id = $(this).attr('href').substr(1);
  66 + $.get(form[id], { lang_id: lang, widget_id: id }, function(data) {
  67 + $('#'+id+'-tabs li').removeClass('active');
  68 + $('#'+id+'-tabs').append('<li role="lang_inputs" class="active" data-lang="'+lang+'"><a href="#'+id+'-'+lang+'" aria-controls="'+id+'-'+lang+'" role="tab" data-toggle="tab">'+$('<p>').append($(flag)).html()+'</a></li>');
  69 + $('#tab-content-'+id+' .tab-pane.active').removeClass('active');
  70 + $('#tab-content-'+id).append($(data).find('.ajax-loaded').first());
  71 + $('body').append($(data).filter('script'));
  72 + $(el).parent().remove();
  73 + if(!$('#lang-'+id+' li').length) {
  74 + $('#'+id+'Lang').addClass('disabled');
  75 + }
  76 + if($('#'+id+'-tabs li').length > 1) {
  77 + $('#'+id+'-tabs li').append('<span class="glyphicon glyphicon-remove-circle remove-lang"></span>')
  78 + }
  79 + });
  80 + });
  81 + $(document).on('click', '.remove-lang', function() {
  82 + var lang = $(this).parent().data('lang');
  83 + var flag = $(this).parent().find('span.flag').first().clone();
  84 + var id = $(this).parent().find('a[aria-controls]').first().attr('aria-controls').substr(0,8);
  85 + $('#'+id+'-'+lang).remove();
  86 + $('#lang-'+id).append('<li><a href="#'+id+'" data-lang="'+lang+'">'+$('<p>').append($(flag)).html()+'</a></li>');
  87 + $('#'+id+'Lang').removeClass('disabled');
  88 + $(this).parent().remove();
  89 + if($('#'+id+'-tabs li').length <= 1) {
  90 + $('#'+id+'-tabs li').find('.remove-lang').remove();
  91 + }
  92 + if(!$('#'+id+'-tabs>li.active').length) {
  93 + $('#'+id+'-tabs>li').first().find('a').tab('show');
  94 + }
  95 + });
  96 + $('#message-is_sms').change()
  97 + {
  98 + if ($('#message-is_sms').is(":checked"))
  99 + {
  100 +
  101 + $(".field-message-cmctext").css({'display': 'block'});
  102 + }
  103 + else {
  104 + $(".field-message-cmctext").css({'display': 'none'});
  105 + }
  106 + }
92 107 });
93 108 \ No newline at end of file
... ...
common/components/DbSpool.php 0 → 100644
  1 +<?php
  2 +namespace common\components;
  3 +use common\models\MailerQueue;
  4 +use yii\swiftmailer\Message;
  5 +use yii\helpers\HtmlPurifier;
  6 +use yii\helpers\Json;
  7 +
  8 +class DbSpool extends \Swift_ConfigurableSpool
  9 +{
  10 +
  11 + /**
  12 + * File WriteRetry Limit
  13 + *
  14 + * @var int
  15 + */
  16 + private $_retryLimit = 10;
  17 +
  18 +// /**
  19 +// * Create a new DbSpool.
  20 +// *
  21 +// * @param string $path
  22 +//
  23 +// */
  24 + public function __construct()
  25 + {
  26 +
  27 + }
  28 + public function __destruct()
  29 + {
  30 + /* if (method_exists($this->_cache, 'clearAll'))
  31 + {
  32 + $this->_cache->clearAll($this->_cacheKey);
  33 + }*/
  34 + }
  35 + /**
  36 + * Tests if this Spool mechanism has started.
  37 + *
  38 + * @return bool
  39 + */
  40 + public function isStarted()
  41 + {
  42 + return true;
  43 + }
  44 +
  45 + /**
  46 + * Starts this Spool mechanism.
  47 + */
  48 + public function start()
  49 + {
  50 +
  51 + }
  52 +
  53 + /**
  54 + * Stops this Spool mechanism.
  55 + */
  56 + public function stop()
  57 + {
  58 +
  59 + }
  60 +
  61 + /**
  62 + * Allow to manage the enqueuing retry limit.
  63 + *
  64 + * Default, is ten and allows over 64^20 different fileNames
  65 + *
  66 + * @param int $limit
  67 + */
  68 + public function setRetryLimit($limit)
  69 + {
  70 + $this->_retryLimit = $limit;
  71 + }
  72 +
  73 + /**
  74 + * Queues a message.
  75 + *
  76 + * @param Swift_Mime_Message $message The message to store
  77 + *
  78 + * @return bool
  79 + *
  80 + * @throws Swift_IoException
  81 + */
  82 + public function queueMessage(\Swift_Mime_Message $message)
  83 + {
  84 +
  85 + $message->getBody();
  86 + $queueObject = new MailerQueue();
  87 +
  88 + $queueObject->text_body = $message->getBody();
  89 + $queueObject->subject = $message->getSubject();
  90 + $queueObject->to = Json::encode($message->getTo());
  91 + $queueObject->save();
  92 + }
  93 +
  94 + /**
  95 + * Sends messages using the given transport instance.
  96 + *
  97 + * @param Swift_Transport $transport A transport instance
  98 + * @param string[] $failedRecipients An array of failures by-reference
  99 + *
  100 + * @return int The number of sent e-mail's
  101 + */
  102 + public function flushQueue(\Swift_Transport $transport, &$failedRecipients = null)
  103 + {
  104 + if (!$transport->isStarted())
  105 + {
  106 + $transport->start();
  107 + }
  108 +
  109 + $failedRecipients = (array) $failedRecipients;
  110 +
  111 + $count = 0;
  112 + $emails = MailerQueue::find()
  113 + ->where('sent_time IS NULL')
  114 + ->orderBy('id')
  115 + ->all();
  116 +
  117 + if (!count($emails))
  118 + {
  119 + return 0;
  120 + }
  121 + // print_r($emails);
  122 + foreach($emails as $email)
  123 + {
  124 + //$message = unserialize($email->message_object);
  125 +
  126 + $message = \Swift_Message::newInstance($email->subject)
  127 + ->setFrom(array('info@example.com' => 'ArtWeb'))
  128 + ->setTo(Json::decode($email->to))
  129 + ->setBody($email->text_body);
  130 + try
  131 + {
  132 + $count+= $transport->send($message, $failedRecipients);
  133 + if($count > 0)
  134 + {
  135 +
  136 + $time = new \DateTime();
  137 + $email->setAttribute('sent_time', $time->format('Y-m-d H:i:s'));
  138 + $email->save();
  139 + }
  140 + else
  141 + {
  142 + throw new \Swift_SwiftException('The email was not sent.');
  143 + }
  144 + }
  145 + catch(\Swift_SwiftException $ex)
  146 + {
  147 +
  148 + }
  149 + }
  150 + return $count;
  151 + }
  152 +}
  153 +
... ...
common/config/main.php
... ... @@ -166,7 +166,17 @@ return [
166 166 /*========End=======
167 167 *end api sicial
168 168 * */
169   -
  169 + 'mailer' => [
  170 + 'class' => 'yii\swiftmailer\Mailer',
  171 + 'transport' => [
  172 + 'class' => 'Swift_SmtpTransport',
  173 + 'host' => 'smtp.gmail.com', // e.g. smtp.mandrillapp.com or smtp.gmail.com
  174 + 'username' => 'alexandr.khivrich@gmail.com',
  175 + 'password' => '10181997Nadia',
  176 + 'port' => '587', // Port 25 is a very common port too
  177 + 'encryption' => 'tls', // It is often used, check your provider or mail servers
  178 + ]
  179 + ],
170 180 ],
171 181 'language' => 'ru-RU'
172 182 ];
... ...
common/models/MailerQueue.php 0 → 100644
  1 +<?php
  2 +
  3 +namespace common\models;
  4 +
  5 +use Yii;
  6 +
  7 +/**
  8 + * This is the model class for table "mailer_queue".
  9 + *
  10 + * @property integer $id
  11 + * @property string $sent_time
  12 + * @property string $to
  13 + * @property string $text_body
  14 + * @property string $charset
  15 + * @property string $subject
  16 + */
  17 +class MailerQueue extends \yii\db\ActiveRecord
  18 +{
  19 + /**
  20 + * @inheritdoc
  21 + */
  22 + public static function tableName()
  23 + {
  24 + return 'mailer_queue';
  25 + }
  26 +
  27 + /**
  28 + * @inheritdoc
  29 + */
  30 + public function rules()
  31 + {
  32 + return [
  33 + [['sent_time'], 'safe'],
  34 + [['text_body'], 'string'],
  35 + [['to', 'subject'], 'string', 'max' => 255]
  36 + ];
  37 + }
  38 +
  39 + /**
  40 + * @inheritdoc
  41 + */
  42 + public function attributeLabels()
  43 + {
  44 + return [
  45 + 'id' => 'ID',
  46 + 'sent_time' => 'Sent Time',
  47 + 'to' => 'To',
  48 + 'text_body' => 'Text Body',
  49 + 'subject' => 'Subject',
  50 + ];
  51 + }
  52 +}
... ...
common/widgets/Multilang.php 0 → 100644
  1 +<?php
  2 +namespace common\widgets;
  3 +use common\models\Language;
  4 +use yii\base\InvalidParamException;
  5 +use yii\base\Widget;
  6 +use yii\bootstrap\ActiveForm;
  7 +
  8 +class Multilang extends Widget
  9 +{
  10 + public $id;
  11 +
  12 + public $langs;
  13 +
  14 + public $data_langs = [];
  15 +
  16 + public $ajaxpath;
  17 +
  18 + public $form;
  19 +
  20 + public function init()
  21 + {
  22 + parent::init();
  23 + if(empty($this->id))
  24 + {
  25 + $this->id = \Yii::$app->security->generateRandomString(8);
  26 + }
  27 + if(empty($this->langs))
  28 + {
  29 + $this->langs = Language::getActiveLanguages();
  30 + }
  31 + if(empty($this->ajaxpath))
  32 + {
  33 + throw new InvalidParamException('ajaxpath must be set');
  34 + }
  35 + if(empty($this->form))
  36 + {
  37 + throw new InvalidParamException('form must be set');
  38 + }
  39 + ob_start();
  40 + echo $this->render('multilang-begin', ['id' => $this->id, 'langs' => $this->langs, 'data_langs' => $this->data_langs, 'ajaxpath' => $this->ajaxpath, 'form' => $this->form]);
  41 + }
  42 +
  43 + public function run()
  44 + {
  45 + echo $this->render('multilang-end', ['id' => $this->id, 'langs' => $this->langs, 'data_langs' => $this->data_langs, 'ajaxpath' => $this->ajaxpath, 'form' => $this->form]);
  46 + $content = ob_get_clean();
  47 + return $content;
  48 + }
  49 +}
0 50 \ No newline at end of file
... ...
common/widgets/views/multilang-begin.php 0 → 100644
  1 +<?php
  2 +use yii\helpers\Url;
  3 +?>
  4 +<div class="dropdown pull-right">
  5 + <button class="btn btn-default dropdown-toggle" type="button" id="<?=$id?>Lang" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
  6 + <?= Yii::t('app', 'Add language') ?>
  7 + <span class="caret"></span>
  8 + </button>
  9 + <ul class="dropdown-menu f32" id="lang-<?=$id?>" aria-labelledby="<?=$id?>Menu">
  10 + <?php foreach($langs as $index => $lang) {
  11 + if(in_array($index, array_keys($data_langs))) continue;
  12 + ?>
  13 + <li><a href="#<?=$id?>" data-lang="<?=$lang->language_id?>"><span class="flag <?=$lang->lang_code?>"></span></a></li>
  14 + <?php } ?>
  15 + </ul>
  16 +</div>
  17 +<ul class="nav nav-tabs f32" id="<?=$id?>-tabs" role="tablist">
  18 + <?php
  19 + $first = 1;
  20 + foreach($data_langs as $index => $data_lang) {
  21 + ?>
  22 + <li role="lang_inputs" class="<?php if($first) { echo 'active'; }?>" data-lang="<?=$index?>"><a href="#<?=$id?>-<?=$index?>" aria-controls="<?=$id?>-<?=$index?>" role="tab" data-toggle="tab"><span class="flag <?=$langs[$index]->lang_code?>"></span></a></li>
  23 + <?php
  24 + $first = 0;
  25 + }
  26 + ?>
  27 +</ul>
  28 +<div class="tab-content lang-tab-content" id="tab-content-<?=$id?>">
  29 +
... ...
common/widgets/views/multilang-end.php 0 → 100644
  1 +<?php
  2 +use yii\helpers\Url;
  3 +?>
  4 +</div>
  5 +<script>
  6 + if(typeof form === 'undefined') {
  7 + var form = [];
  8 + }
  9 + form['<?=$id?>'] = '<?=$ajaxpath?>';
  10 +</script>
0 11 \ No newline at end of file
... ...
composer.json
... ... @@ -23,7 +23,8 @@
23 23 "kartik-v/yii2-widget-select2": "@dev",
24 24 "mihaildev/yii2-ckeditor": "*",
25 25 "developeruz/yii2-db-rbac": "*",
26   - "nodge/yii2-eauth": "*"
  26 + "nodge/yii2-eauth": "*",
  27 + "iutbay/yii2-kcfinder": "*"
27 28 },
28 29 "require-dev": {
29 30 "yiisoft/yii2-codeception": "*",
... ...
console/controllers/MailerQueueController.php 0 → 100644
  1 +<?php
  2 +
  3 +namespace backend\controllers;
  4 +
  5 +use Yii;
  6 +use common\components\DbSpool;
  7 +use yii\data\ActiveDataProvider;
  8 +use yii\web\Controller;
  9 +use yii\web\NotFoundHttpException;
  10 +use yii\filters\VerbFilter;
  11 +
  12 +/**
  13 + * MailerQueueController implements the CRUD actions for MailerQueue model.
  14 + */
  15 +class MailerQueueController extends Controller
  16 +{
  17 + public function behaviors()
  18 + {
  19 + return [
  20 + 'verbs' => [
  21 + 'class' => VerbFilter::className(),
  22 + 'actions' => [
  23 + 'delete' => ['post'],
  24 + ],
  25 + ],
  26 + ];
  27 + }
  28 + /**
  29 + * Send Queue messages
  30 + */
  31 + public function actionSend()
  32 + {
  33 + $messageLimit = 10;
  34 + $timeLimit = 0;
  35 +
  36 + $spool = new DbSpool();
  37 + $transportReal = \Swift_SmtpTransport::newInstance(
  38 + "smtp.gmail.com",
  39 + "465",
  40 + "ssl"
  41 + )
  42 + ->setUsername("alexandr.khivrich@gmail.com")
  43 + ->setPassword("10181997Nadia");
  44 +
  45 + $spool->setMessageLimit($messageLimit);
  46 + $spool->setTimeLimit($timeLimit);
  47 + $sent = $spool->flushQueue($transportReal);
  48 +
  49 + echo sprintf('sent %s emails', $sent);
  50 + }
  51 +}
... ...
frontend/models/OptionValues.php
... ... @@ -73,7 +73,7 @@ class OptionValues extends \yii\db\ActiveRecord
73 73 }
74 74 return $langs;
75 75 }
76   - public function beforeSave($insert) {
  76 + public function beforeSave($insert){
77 77 if (parent::beforeSave($insert)) {
78 78 $this->option_user = \Yii::$app->user->getId();
79 79 if($this->option_value_parent == 0) {
... ...
frontend/web/js/option.js
... ... @@ -36,42 +36,6 @@ $(function() {
36 36 $(document).on('click', '.remove_lang', function() {
37 37 $(this).parents('.form-wrapper').remove();
38 38 });
39   - if($('#lang-tabs li').length > 1) {
40   - $('#lang-tabs li').append('<span class="glyphicon glyphicon-remove-circle remove-lang"></span>')
41   - }
42   - $(document).on('click', '#lang-dropdown li a[data-lang]', function() {
43   - var lang = $(this).data('lang');
44   - var flag = $(this).find('span').first().clone();
45   - var el = $(this);
46   - $.get('/blog/ajax/category-form', { lang_id: lang }, function(data) {
47   - $('#lang-tabs li').removeClass('active');
48   - $('#lang-tabs').append('<li role="lang_inputs" class="active" data-lang="'+lang+'"><a href="#lang-'+lang+'" aria-controls="lang-'+lang+'" role="tab" data-toggle="tab">'+$('<p>').append($(flag)).html()+'</a></li>');
49   - $('.lang-tab-content .tab-pane.active').removeClass('active');
50   - $('.lang-tab-content').append($(data).find('.ajax-loaded').first());
51   - $('body').append($(data).filter('script'));
52   - $(el).parent().remove();
53   - if(!$('#lang-dropdown li').length) {
54   - $('#dropdownLang').addClass('disabled');
55   - }
56   - if($('#lang-tabs li').length > 1) {
57   - $('#lang-tabs li').append('<span class="glyphicon glyphicon-remove-circle remove-lang"></span>')
58   - }
59   - });
60   - });
61   - $(document).on('click', '.remove-lang', function() {
62   - var lang = $(this).parent().data('lang');
63   - var flag = $(this).parent().find('span.flag').first().clone();
64   - $('#lang-'+lang).remove();
65   - $('#lang-dropdown').append('<li><a href="#lang-tabs" data-lang="'+lang+'">'+$('<p>').append($(flag)).html()+'</a></li>');
66   - $('#dropdownLang').removeClass('disabled');
67   - $(this).parent().remove();
68   - if($('#lang-tabs li').length <= 1) {
69   - $('#lang-tabs li').find('.remove-lang').remove();
70   - }
71   - if(!$('#lang-tabs>li.active').length) {
72   - $('#lang-tabs>li').first().find('a').tab('show');
73   - }
74   - });
75 39 $(document).on('change', '.image_inputs_field', function() {
76 40 readURL(this);
77 41 });
... ... @@ -89,4 +53,44 @@ $(function() {
89 53 }
90 54 return false;
91 55 });
  56 + $.each($('.nav-tabs.f32'), function(key, value) {
  57 + if($(value).find('li').length > 1) {
  58 + $(value).find('li').append('<span class="glyphicon glyphicon-remove-circle remove-lang"></span>');
  59 + }
  60 + });
  61 + $(document).on('click', '.dropdown-menu.f32 li a[data-lang]', function() {
  62 + var lang = $(this).data('lang');
  63 + var flag = $(this).find('span').first().clone();
  64 + var el = $(this);
  65 + var id = $(this).attr('href').substr(1);
  66 + $.get(form[id], { lang_id: lang, widget_id: id }, function(data) {
  67 + $('#'+id+'-tabs li').removeClass('active');
  68 + $('#'+id+'-tabs').append('<li role="lang_inputs" class="active" data-lang="'+lang+'"><a href="#'+id+'-'+lang+'" aria-controls="'+id+'-'+lang+'" role="tab" data-toggle="tab">'+$('<p>').append($(flag)).html()+'</a></li>');
  69 + $('#tab-content-'+id+' .tab-pane.active').removeClass('active');
  70 + $('#tab-content-'+id).append($(data).find('.ajax-loaded').first());
  71 + $('body').append($(data).filter('script'));
  72 + $(el).parent().remove();
  73 + if(!$('#lang-'+id+' li').length) {
  74 + $('#'+id+'Lang').addClass('disabled');
  75 + }
  76 + if($('#'+id+'-tabs li').length > 1) {
  77 + $('#'+id+'-tabs li').append('<span class="glyphicon glyphicon-remove-circle remove-lang"></span>')
  78 + }
  79 + });
  80 + });
  81 + $(document).on('click', '.remove-lang', function() {
  82 + var lang = $(this).parent().data('lang');
  83 + var flag = $(this).parent().find('span.flag').first().clone();
  84 + var id = $(this).parent().find('a[aria-controls]').first().attr('aria-controls').substr(0,8);
  85 + $('#'+id+'-'+lang).remove();
  86 + $('#lang-'+id).append('<li><a href="#'+id+'" data-lang="'+lang+'">'+$('<p>').append($(flag)).html()+'</a></li>');
  87 + $('#'+id+'Lang').removeClass('disabled');
  88 + $(this).parent().remove();
  89 + if($('#'+id+'-tabs li').length <= 1) {
  90 + $('#'+id+'-tabs li').find('.remove-lang').remove();
  91 + }
  92 + if(!$('#'+id+'-tabs>li.active').length) {
  93 + $('#'+id+'-tabs>li').first().find('a').tab('show');
  94 + }
  95 + });
92 96 });
93 97 \ No newline at end of file
... ...
private 0 → 100644
  1 +-----BEGIN RSA PRIVATE KEY-----
  2 +MIIEpQIBAAKCAQEAq1wH6wvvKupU9Qb/OzNlQgNEQucwLrSm56lTGX0Tme56zSs5
  3 +k+44WdPQuF4xIHdzftGzna9OEat18fbdGXXrg8r2h2N7nmNkJz08DCrKQxVuyeVW
  4 +y1ktKu7qzy/5rQcSKbHARB0c/L8Iv9j63ZWu2EbBoz9rAxbUxImIwuXcLELlxHL1
  5 +aD33VYB7ODqI0b/FBN2Su+4QlzaOW8Nhu2ctUDM3R0j2cpGa0rqAGjIUtCZiUeUa
  6 ++TsYbJwoQg+kVN9gb06I6uDsijxVexYNeuFj+JGjQm80pXqcJn92e8G3FQISan6g
  7 +BkVClr9VBlc14HV3DLFy36RuLDzkA1vmUMNd6wIDAQABAoIBACaZzaLSBmdJcCfe
  8 +EqKYWkf7imXzxDPROAPZbcHBHig/w2PyR78eG42InGzbsv9YSSkZPffYZKKwWBpQ
  9 +fM/ec1Y140DuVQuB4i7AqYUoInXoHxPV2K5oATe5qCVR7lFe1WWVB/WQBVaeBe+J
  10 +hkFiFYfcsIQApi+E9hrrzGXy95z0enNpv8cJ1z9xVNts8oxXiFwzaY8Kcz56W5mS
  11 +/XDboVI2Od+NHY3rJnWj63OLyRIBnyjYfNFMXysRZs64lRUxKvt74RB2hx+q6wlF
  12 +djTEqTdMzm9tCCbGI5InXovCkXZToQ8ed+8071eohMxpFBqP6TSFEQf1Og+T8TzK
  13 +JndHcMkCgYEA2gxBgGJmHVDaK7eiI7Fqg+ehI0GamTT/ZBHW6xvKHgMI54CUQ4c+
  14 +acLBctailDP2VNd0gKe1RRE10dz5Akzw+MydUASQONqoO8LU5eLuyNlI7QT259Xd
  15 +Yfvw+BXUEN+WDtJNESbXhTYaO/3B7l2EzsWc6ToJRSoafiem4aEhsVUCgYEAyS9w
  16 +/W2U4IiIVzke2tjRm/vb+T3OmOv1i/y2f79PnQMPJ5oNyxdtZ3axOapMv0KZXApo
  17 +dWL205eYu0fYZpdVhtHuPAhK6tNi4CDPW2dGWB5dVaGfFMCF1CVoUJlpJT+DOfqp
  18 +d774ID5dZ1PpvJoODcPXa3Bmh+83NbmpIrH90j8CgYEAoYD+azd25zPhxQvI/qME
  19 +gBrq0ZBgECafG+HSzGXS+RPKXp5wMuxToEZuvr6XwSoTxJepZTnTHAs5T+5aSgfv
  20 +XHlB8+jNYi8i+NDAnF3P+9hlGZnZv7I6vb68pyST5MOXA/dkudWJQNPn7pNwNzvx
  21 +iK36IQ2pnB8pbFO2WdzdddkCgYEAoXvO+dyHb2Kn7TsQJSF7vfR/MKQHvH9JbL+/
  22 +zPJGeQUHmQXypF19l1qSDnM/fxV5+4LvLant7RD1qv2UGWTHZZwD2XPejnZ2Gui7
  23 +B+bxc7GLwTwlcIbH5OzRukApQZilQFiOxmsmxtrIJjQYnSYaubnEo5xo8Bt2+Uy5
  24 +EfxEfAkCgYEAvwGvYDdCcjozwnAdMSSHLa0rVoChet/cZTsqpagIF7zjMq9ljG2J
  25 +7pK+esJeAwpGTwXSpIPWHDIOhScsL6iiKu2BRPa6NostlpUjDzciPZzrizz+okuP
  26 +palma9L1DuQqUSC+Vqe25Qmnk7F+Hiw+Fu3L4pMcxw8/ZgUagMpkOHM=
  27 +-----END RSA PRIVATE KEY-----
... ...
private.pub 0 → 100644
  1 +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCrXAfrC+8q6lT1Bv87M2VCA0RC5zAutKbnqVMZfROZ7nrNKzmT7jhZ09C4XjEgd3N+0bOdr04Rq3Xx9t0ZdeuDyvaHY3ueY2QnPTwMKspDFW7J5VbLWS0q7urPL/mtBxIpscBEHRz8vwi/2Prdla7YRsGjP2sDFtTEiYjC5dwsQuXEcvVoPfdVgHs4OojRv8UE3ZK77hCXNo5bw2G7Zy1QMzdHSPZykZrSuoAaMhS0JmJR5Rr5OxhsnChCD6RU32BvTojq4OyKPFV7Fg164WP4kaNCbzSlepwmf3Z7wbcVAhJqfqAGRUKWv1UGVzXgdXcMsXLfpG4sPOQDW+ZQw13r alexandr.khivrich@gmail.com
... ...
res 0 → 100644
  1 +-----BEGIN RSA PRIVATE KEY-----
  2 +MIIEpAIBAAKCAQEAmHwDO+WhonC49gHe2DNx7OD16hfMU2JS3Y26AsE+dSlWiYlZ
  3 +U0NWkmDgM88e3EpzxXECInn42OjjHxaAPcPsAnICmLjMHjAvUzQQXoPMbbbuPJxD
  4 +aanh/NZnyeHy9xj6lrUgNvsrljRjdQ20SSAcdkcsOj4+HBBxnaFIzh+GW8Ha3b26
  5 +dBUYjOL/oxrUW0AKehpDJWlf6mzHBDa+DWCOSXK4zNI9K+y3lqeoWVIzKdrxHRfs
  6 +tnhBs7/La+pU+kxGY6B1PouB+McdG3CBZ/yMUX/o4dDamTCU85VbyoLo5R2d7Pv2
  7 +P2y2i4/tS3E9mCAbmrYIUwShYVgYlWyYJnWCgQIDAQABAoIBAHZECQYVzk18/Bfh
  8 +z4MEM6IzwMe1eYZaxkaMO+8TDmw0iafW3W8U1Tpm5L2KMTdOj4hdY/h1fapOxolA
  9 +HGrLYGttHdJx0e7AFJSF1wRXWODndtOPp0F2v44ohQsxsg4wU3s8NCYwnNe8/j61
  10 +SFVHEIw0G3t49xcxMc2+YAdur/jNqXAR8w4GplW03K73R8Y4jPStk4KPU8MnLfKZ
  11 +XWGq37hp5mVJlkDO91nxys4ZSvh2plKz3zRKfImEU99mWj7u8ZSKPpYU/LCm97FA
  12 +CdweW5PIyzWKSNAV/4Ge0o015rPSAlWEfGXQ8rW08oxzgEz59YOBSsxUo+4AE5zW
  13 +Gyls4AECgYEAylOrVBmzxoeNguyNlvmNsHOt8xz4XEA0RlZ6PnWSIT2PZ4NT1jAB
  14 +J9g/u2Il6zLJOvnN777+4Od4aITNVdS1xUYTkbJ8pv0dZEH9nO3BSKzHgx8S/Har
  15 +Rq02B2ZDvcV0r462QV/t1YXzrtcqSasyfZbiFSTQjYYRn7I0fB8LW0ECgYEAwO93
  16 +ufeogMRRb5lkI5kI85vcQChWeIwUA3HbZt6BiInmhtP8Ep9YVjamMR5bCy/m25yl
  17 +IJK82gD8RDuFqjJNyUoiJuHPUonxYM/msZvshEUOoCvQQkRAG5SYlSEW083Vw6wM
  18 +3b80nqYkYvNyJrhd93lfk9LBYJulOppYDOHAl0ECgYEAs2H1P+49xuH95DtI2bdO
  19 +GUimzCo+RMQj1MztOx1QPypuT29PUFJlY+dFsiQ1zE7NvP0nyc0D+3Ed/0TnLJcX
  20 +xdz4kq+19vPpMC+V5KGjQYT2qtlNIwsvlc0SXwMbQlCjwNb93f5oRmyp/bUE6CXh
  21 +8RlqPybRxPg9/eGoyPdZQUECgYBxrGW5Lx6bh4+HljO2+ZKZnWoebuXLrpSYFvwy
  22 +1sQxAzbMl5d8DWBJo3c1l3IC3F1DZT6xO2ODenMnbH5rcan8/+2xRPgW5GlQJg4A
  23 +9SJcKCfe3RGeCYJP/bQMoWtGrY7V88e82swQ8Uic+Fx4TcYnad6TROhkmC+4oHli
  24 +VZxYQQKBgQCx+bLdGDTfI4qYEvTyyRrTX3nv4Q31EjF2kByusObqzaliLWWnezIQ
  25 +yt4WMMcIP1cT4iJoSpmahkiMBwRhvAzXsPoupGVIYoT34I5zsL8aTCRHYRza75ij
  26 +ZreEZj3XBzYSDrigAIxsDyNzF6Ku1+VtGAL3gJXsJPDPKRH/88YOdw==
  27 +-----END RSA PRIVATE KEY-----
... ...
res.pub 0 → 100644
  1 +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCYfAM75aGicLj2Ad7YM3Hs4PXqF8xTYlLdjboCwT51KVaJiVlTQ1aSYOAzzx7cSnPFcQIiefjY6OMfFoA9w+wCcgKYuMweMC9TNBBeg8xttu48nENpqeH81mfJ4fL3GPqWtSA2+yuWNGN1DbRJIBx2Ryw6Pj4cEHGdoUjOH4Zbwdrdvbp0FRiM4v+jGtRbQAp6GkMlaV/qbMcENr4NYI5JcrjM0j0r7LeWp6hZUjMp2vEdF+y2eEGzv8tr6lT6TEZjoHU+i4H4xx0bcIFn/IxRf+jh0NqZMJTzlVvKgujlHZ3s+/Y/bLaLj+1LcT2YIBuatghTBKFhWBiVbJgmdYKB alexandr.khivrich@gmail.com
... ...