Commit f487ec99 authored by Виталий Мурашко's avatar Виталий Мурашко

Merge branch 'master' of http://git.task-on.com/ktask/task-on.com

Conflicts:
	composer.json
parents 8066dbf3 44f09957
......@@ -22,6 +22,7 @@ class AppAsset extends AssetBundle
'plugins/bootstrap-datetimepicker/css/datetimepicker.css',
'plugins/switchery/switchery.min.css',
'plugins/powerange/powerange.min.css',
'plugins/jquery-tag-it/css/jquery.tagit.css',
'css/site.css',
];
public $js = [
......@@ -29,8 +30,14 @@ class AppAsset extends AssetBundle
'plugins/bootstrap-datetimepicker/js/bootstrap-datetimepicker.js',
'plugins/bootstrap-datetimepicker/js/locales/bootstrap-datetimepicker.ru.js',
'plugins/tinymce/js/tinymce/tinymce.min.js',
'plugins/jquery-tag-it/js/tag-it.min.js',
'js/form-load.js'
];
public $depends = [
'yii\web\JqueryAsset',
'yii\jui\JuiAsset',
'yii\bootstrap\BootstrapAsset',
'yii\bootstrap\BootstrapPluginAsset',
'backend\assets\HeadAsset',
];
}
......@@ -22,15 +22,19 @@ class HeadAsset extends AssetBundle
public $js = [
'plugins/switchery/switchery.min.js',
'plugins/powerange/powerange.min.js',
'plugins/pace/pace.min.js',
'js/form-slider-switcher.demo.min.js',
'js/apps.min.js',
'js/packages/adminBaseClasses/buttonSet.js',
'js/packages/adminBaseClasses/gridBase.js',
'js/apps.min.js',
];
public $jsOptions = [
'position' => \yii\web\View::POS_HEAD
];
public $depends = [
'yii\web\JqueryAsset',
'yii\jui\JuiAsset',
'yii\bootstrap\BootstrapAsset',
'yii\bootstrap\BootstrapPluginAsset',
];
}
......@@ -66,6 +66,10 @@ return [
'assetManager'=>[
'linkAssets' => true,
'bundles' => [
'xj\tagit\TagitAsset' => [
'js' => [],
'css' => []
],
'yii\bootstrap\BootstrapPluginAsset' => [
'js' => [
],
......
......@@ -54,11 +54,6 @@ AppAsset::register($this);
<?php $this->endBody() ?>
<?php
$this->registerJsFile('/plugins/jquery/jquery-1.9.1.js', ['position' => \yii\web\View::POS_END]);
$this->registerJsFile('/plugins/jquery/jquery-migrate-1.1.0.js', ['position' => \yii\web\View::POS_END ]);
$this->registerJsFile('/plugins/jquery-ui/ui/minified/jquery-ui.min.js', ['position' => \yii\web\View::POS_END ]);
$this->registerJsFile('/plugins/bootstrap/js/bootstrap.min.js', ['position' => \yii\web\View::POS_END ]);
$this->registerJsFile('/js/yii.activeForm.js', ['position' => \yii\web\View::POS_END]);
$this->registerJsFile('/plugins/jquery/jquery-1.9.1.js', ['position' => \yii\web\View::POS_HEAD]);
$this->registerJsFile('/plugins/jquery/jquery-migrate-1.1.0.js', ['position' => \yii\web\View::POS_HEAD ]);
......
<!-- ================== BEGIN BASE JS ================== -->
<?php $this->registerJsFile('/plugins/jquery/jquery-1.9.1.min.js', ['position' => \yii\web\View::POS_HEAD ]);?>
<?php $this->registerJsFile('/plugins/jquery/jquery-migrate-1.1.0.min.js', ['position' => \yii\web\View::POS_END ]);?>
<?php $this->registerJsFile('/plugins/jquery-ui/ui/minified/jquery-ui.min.js', ['position' => \yii\web\View::POS_END ]);?>
<?php $this->registerJsFile('/plugins/bootstrap/js/bootstrap.min.js', ['position' => \yii\web\View::POS_END ]);?>
<!--[if lt IE 9]>
......@@ -28,7 +26,6 @@
<?php $this->registerJsFile('/plugins/bootstrap-select/bootstrap-select.js', ['position' => \yii\web\View::POS_END ]);?>
<?php //$this->registerJsFile('/js/dashboard.min.js', ['position' => \yii\web\View::POS_END ]);?>
<?php $this->registerJsFile('/js/dashboard.js', ['position' => \yii\web\View::POS_END ]);?>
<?php $this->registerJsFile('/js/apps.min.js', ['position' => \yii\web\View::POS_END ]);?>
<!-- ================== END PAGE LEVEL JS ================== -->
......
......@@ -16,7 +16,3 @@
<?php $this->registerCssFile('/plugins/gritter/css/jquery.gritter.css', ['position' => \yii\web\View::POS_HEAD ]);?>
<?php $this->registerCssFile('/plugins/DataTables/css/data-table.css', ['position' => \yii\web\View::POS_HEAD ]);?>
<?php $this->registerJsFile('/plugins/pace/pace.min.js', ['position' => \yii\web\View::POS_HEAD ]);?>
<?php $this->registerJsFile('/js/form-load.js', ['position' => \yii\web\View::POS_END ]);?>
......@@ -9,7 +9,6 @@ use yii\widgets\Breadcrumbs;
/* @var $content string */
//die('-!-!-');
assets\AppAsset::register($this);
assets\HeadAsset::register($this);
?>
<?php $this->beginPage() ?>
<!DOCTYPE html>
......
......@@ -119,6 +119,6 @@ $this->params['breadcrumbs'][] = $this->title;
<?php
$this->registerJsFile('/js/login-v2.demo.min.js', ['position' => \yii\web\View::POS_END ]);
$this->registerJsFile('/js/apps.min.js', ['position' => \yii\web\View::POS_END ]);
// $this->registerJsFile('/js/apps.min.js', ['position' => \yii\web\View::POS_END ]);
$this->registerJs('App.init();LoginV2.init();', \yii\web\View::POS_READY);
?>
\ No newline at end of file
......@@ -33,6 +33,8 @@ $(function() {
toolbar2: "| responsivefilemanager | link unlink anchor | image media | forecolor backcolor | print preview code ",
image_advtab: true ,
forced_root_block : false,
force_br_newlines : false,
force_p_newlines : true,
external_filemanager_path:"/filemanager/",
filemanager_title:"Responsive Filemanager" ,
external_plugins: { "filemanager" : "/filemanager/plugin.min.js"}
......
......@@ -30,3 +30,7 @@ $(document).on('click', 'button.add-and-condition', function() {
}
})
});
$(document).on('click', '.delete_row', function() {
$(this).closest('tr').remove();
});
......@@ -236,12 +236,12 @@
that._lastTag().removeClass('remove ui-state-highlight');
}
// Comma/Space/Enter are all valid delimiters for new tags,
// Space/Enter are all valid delimiters for new tags,
// except when there is an open quote or if setting allowSpaces = true.
// Tab will also create a tag, unless the tag input is empty,
// in which case it isn't caught.
if (
(event.which === $.ui.keyCode.COMMA && event.shiftKey === false) ||
/*(event.which === $.ui.keyCode.COMMA && event.shiftKey === false) || */
event.which === $.ui.keyCode.ENTER ||
(
event.which == $.ui.keyCode.TAB &&
......
......@@ -3,7 +3,7 @@ this;this.element.is("input")?(this.tagList=b("<ul></ul>").insertAfter(this.elem
this.options.placeholderText);this.options.autocomplete.source||(this.options.autocomplete.source=function(a,e){var d=a.term.toLowerCase(),c=b.grep(this.options.availableTags,function(a){return 0===a.toLowerCase().indexOf(d)});this.options.allowDuplicates||(c=this._subtractArray(c,this.assignedTags()));e(c)});this.options.showAutocompleteOnFocus&&(this.tagInput.focus(function(b,d){a._showAutocomplete()}),"undefined"===typeof this.options.autocomplete.minLength&&(this.options.autocomplete.minLength=
0));b.isFunction(this.options.autocomplete.source)&&(this.options.autocomplete.source=b.proxy(this.options.autocomplete.source,this));b.isFunction(this.options.tagSource)&&(this.options.tagSource=b.proxy(this.options.tagSource,this));this.tagList.addClass("tagit").addClass("ui-widget ui-widget-content ui-corner-all").append(b('<li class="tagit-new"></li>').append(this.tagInput)).click(function(d){var c=b(d.target);c.hasClass("tagit-label")?(c=c.closest(".tagit-choice"),c.hasClass("removed")||a._trigger("onTagClicked",
d,{tag:c,tagLabel:a.tagLabel(c)})):a.tagInput.focus()});var c=!1;if(this.options.singleField)if(this.options.singleFieldNode){var d=b(this.options.singleFieldNode),f=d.val().split(this.options.singleFieldDelimiter);d.val("");b.each(f,function(b,d){a.createTag(d,null,!0);c=!0})}else this.options.singleFieldNode=b('<input type="hidden" style="display:none;" value="" name="'+this.options.fieldName+'" />'),this.tagList.after(this.options.singleFieldNode);c||this.tagList.children("li").each(function(){b(this).hasClass("tagit-new")||
(a.createTag(b(this).text(),b(this).attr("class"),!0),b(this).remove())});this.tagInput.keydown(function(c){if(c.which==b.ui.keyCode.BACKSPACE&&""===a.tagInput.val()){var d=a._lastTag();!a.options.removeConfirmation||d.hasClass("remove")?a.removeTag(d):a.options.removeConfirmation&&d.addClass("remove ui-state-highlight")}else a.options.removeConfirmation&&a._lastTag().removeClass("remove ui-state-highlight");if(c.which===b.ui.keyCode.COMMA&&!1===c.shiftKey||c.which===b.ui.keyCode.ENTER||c.which==
(a.createTag(b(this).text(),b(this).attr("class"),!0),b(this).remove())});this.tagInput.keydown(function(c){if(c.which==b.ui.keyCode.BACKSPACE&&""===a.tagInput.val()){var d=a._lastTag();!a.options.removeConfirmation||d.hasClass("remove")?a.removeTag(d):a.options.removeConfirmation&&d.addClass("remove ui-state-highlight")}else a.options.removeConfirmation&&a._lastTag().removeClass("remove ui-state-highlight");if(/*c.which===b.ui.keyCode.COMMA&&!1===c.shiftKey||*/c.which===b.ui.keyCode.ENTER||c.which==
b.ui.keyCode.TAB&&""!==a.tagInput.val()||c.which==b.ui.keyCode.SPACE&&!0!==a.options.allowSpaces&&('"'!=b.trim(a.tagInput.val()).replace(/^s*/,"").charAt(0)||'"'==b.trim(a.tagInput.val()).charAt(0)&&'"'==b.trim(a.tagInput.val()).charAt(b.trim(a.tagInput.val()).length-1)&&0!==b.trim(a.tagInput.val()).length-1))c.which===b.ui.keyCode.ENTER&&""===a.tagInput.val()||c.preventDefault(),a.options.autocomplete.autoFocus&&a.tagInput.data("autocomplete-open")||(a.tagInput.autocomplete("close"),a.createTag(a._cleanedInput()))}).blur(function(b){a.tagInput.data("autocomplete-open")||
a.createTag(a._cleanedInput())});if(this.options.availableTags||this.options.tagSource||this.options.autocomplete.source)d={select:function(b,c){a.createTag(c.item.value);return!1}},b.extend(d,this.options.autocomplete),d.source=this.options.tagSource||d.source,this.tagInput.autocomplete(d).bind("autocompleteopen.tagit",function(b,c){a.tagInput.data("autocomplete-open",!0)}).bind("autocompleteclose.tagit",function(b,c){a.tagInput.data("autocomplete-open",!1)}),this.tagInput.autocomplete("widget").addClass("tagit-autocomplete")},
destroy:function(){b.Widget.prototype.destroy.call(this);this.element.unbind(".tagit");this.tagList.unbind(".tagit");this.tagInput.removeData("autocomplete-open");this.tagList.removeClass("tagit ui-widget ui-widget-content ui-corner-all tagit-hidden-field");this.element.is("input")?(this.element.removeClass("tagit-hidden-field"),this.tagList.remove()):(this.element.children("li").each(function(){b(this).hasClass("tagit-new")?b(this).remove():(b(this).removeClass("tagit-choice ui-widget-content ui-state-default ui-state-highlight ui-corner-all remove tagit-choice-editable tagit-choice-read-only"),
......
......@@ -203,6 +203,11 @@ class BaseForm extends \yii\widgets\ActiveForm
$config['options'][] = ' ';
}
}
if (array_key_exists('activeForm', $config)) {
foreach($config['activeForm'] as $key=>$option) {
$this->options[$key] = $option;
}
}
unset($config['buttons']);
......
......@@ -22,7 +22,7 @@ class LangRequest extends Request
Languages::setCurrent($lang_url);
if( $lang_url !== null && $lang_url === Languages::getCurrent()->url &&
strpos($this->_lang_url, Languages::getCurrent()->url) === 1 )
strpos($this->_lang_url, Languages::getCurrent()->url) === 1)
{
$this->_lang_url = substr($this->_lang_url, strlen(Languages::getCurrent()->url) + 1);
}
......
<?php
namespace common\components;
use common\modules\triggers\components\conditions\vendor\ConditionBase;
use yii\helpers\Json;
/**
* API UniSender
*
......@@ -32,6 +35,16 @@ class UnisenderAPI {
*/
protected $Compression = false;
/**
* @var array
*/
protected $visitedLinks = [];
/**
* @var array
*/
protected $statuses = [];
/**
* @param string $ApiKey
* @param string $Encoding
......@@ -87,13 +100,93 @@ class UnisenderAPI {
);
}
/**
* @param $message_id
* @return array
*/
public function getMessageStatuses($message_id){
$this->statuses = $this->callMethod(
'checkEmail',
[
'email_id' => $message_id
]
);
$this->statuses = Json::decode($this->statuses);
return $this->statuses;
}
/**
* @return bool
*/
public function isLinkVisited(){
if (array_key_exists('result', $this->statuses) && array_key_exists('status', $this->statuses['result'])) {
if ($this->statuses['result']['status']==ConditionBase::MESSAGE_LINK_VISITED || $this->statuses['result']['status']==ConditionBase::MESSAGE_UNSUBSCRIBED || $this->statuses['result']['status']==ConditionBase::MESSAGE_SPAM_FOLDER)
return true;
}
return false;
}
/**
* @return bool
*/
public function isUnsubscribed(){
if (array_key_exists('result', $this->statuses) && array_key_exists('status', $this->statuses['result'])) {
if ($this->statuses['result']['status']==ConditionBase::MESSAGE_UNSUBSCRIBED)
return true;
}
return false;
}
/**
* @return bool
*/
public function isReaded(){
if (array_key_exists('result', $this->statuses) && array_key_exists('status', $this->statuses['result'])) {
if ($this->statuses['result']['status']==ConditionBase::MESSAGE_READ || $this->statuses['result']['status']==ConditionBase::MESSAGE_UNSUBSCRIBED || $this->statuses['result']['status']==ConditionBase::MESSAGE_SPAM_FOLDER)
return true;
}
return false;
}
/**
* @return bool
*/
public function isDelivered(){
if (array_key_exists('result', $this->statuses) && array_key_exists('status', $this->statuses['result'])) {
if ($this->statuses['result']['status']==ConditionBase::MESSAGE_DELIVERED || $this->statuses['result']['status']==ConditionBase::MESSAGE_LINK_VISITED || $this->statuses['result']['status']==ConditionBase::MESSAGE_READ || $this->statuses['result']['status']==ConditionBase::MESSAGE_UNSUBSCRIBED || $this->statuses['result']['status']==ConditionBase::MESSAGE_SPAM_FOLDER)
return true;
}
return false;
}
/**
* @param $campaign_id
* @return mixed
*/
public function getVisitedLinks($campaign_id){
return $this->callMethod(
$this->visitedLinks = $this->callMethod(
'getVisitedLinks',
[
'campaign_id' => $campaign_id
]
);
$this->visitedLinks = Json::decode($this->visitedLinks);
return $this->visitedLinks;
}
/**
* @param $email
* @param $link
* @return bool
*/
public function linkIsVisited($email, $link) {
if (array_key_exists('result', $this->visitedLinks) && array_key_exists('data', $this->visitedLinks['result'])) {
foreach($this->visitedLinks['result']['data'] as $transition) {
if ($transition[0]==$email && $transition[1]==$link)
return true;
}
}
return false;
}
public function createCampaign($message_id){
......
......@@ -47,7 +47,7 @@ class UrlManager extends \yii\web\UrlManager {
//Добавляем к URL префикс - буквенный идентификатор языка
if($url == '/')
{
return '/' . $lang->url;
return '/' . (!$lang->default?$lang->url:'');
}
// Делаем универсальный URL без языка для Eauth авторизации
elseif (strpos($url, '/eauth') !== false) {
......@@ -55,7 +55,7 @@ class UrlManager extends \yii\web\UrlManager {
}
else
{
return '/' . $lang->url . $url;
return (!$lang->default?'/'.$lang->url:'') . $url;
}
}
}
......@@ -5,16 +5,24 @@ use Yii;
use yii\base\Behavior;
use yii\db\ActiveRecord;
use yii\web\UploadedFile;
use yii\imagine\Image;
class FileUploadBehavior extends Behavior
{
public $path;
public $folder;
public $file;
public $unlinkFile = false;
public $field;
public $thumb = false;
public $thumbSize = ['100', '100'];
public function events()
{
return [
......@@ -31,24 +39,56 @@ class FileUploadBehavior extends Behavior
private function uploadFile()
{
if(!file_exists($this->getAbsolutePath()))
if(!file_exists($this->getAbsolutePath() . $this->folder))
{
mkdir($this->getAbsolutePath(), 0777, true);
mkdir($this->getAbsolutePath() . $this->folder, 0777, true);
}
$field = $this->field;
$this->owner->$field = $this->folder . date('dmYHis-') . uniqid() . '.' . $this->file->extension;
$filename = date('dmYHis-') . uniqid();
$this->owner->$field = $this->folder . $filename . '.' . $this->file->extension;
$this->file->saveAs($this->getAbsolutePath() . $this->owner->$field);
if($this->thumb)
{
list($width, $height) = $this->thumbSize;
try
{
Image::$driver = [Image::DRIVER_GD2];
Image::thumbnail($this->path . $this->owner->$field, $width, $height)
->save($this->getAbsolutePath().$this->folder.$filename.'.thumb.'.$this->file->extension, ['quality' => 80]);
}
catch (Exception $e)
{
throw $e;
}
}
}
private function deleteFile()
{
$field = $this->field;
if($this->owner->$field && file_exists($this->getAbsolutePath() . $this->owner->$field))
if($this->owner->$field)
{
unlink($this->getAbsolutePath() . $this->owner->$field);
// Удаление Thumbnail если есть
$path = pathinfo(Yii::getAlias($this->path . $this->owner->$field));
$thumb = $path['dirname'] . '/' . $path['filename'] . '.thumb.' . $path['extension'];
if(file_exists($thumb))
{
unlink($thumb);
}
// Удаление файла
if(file_exists($this->getAbsolutePath() . $this->owner->$field))
{
unlink($this->getAbsolutePath() . $this->owner->$field);
}
$this->owner->$field = null;
}
}
......
<?php
namespace common\modules\blog\components;
use Yii;
use yii\base\Behavior;
use yii\db\ActiveRecord;
use yii\helpers\ArrayHelper;
use common\modules\blog\models\PostTag;
use common\modules\blog\models\PostTagAssign;
class TagBehavior extends Behavior
{
public $tags;
public function events()
{
return [
ActiveRecord::EVENT_AFTER_FIND => 'eventFind',
ActiveRecord::EVENT_AFTER_UPDATE => 'Save',
ActiveRecord::EVENT_AFTER_INSERT => 'Insert',
ActiveRecord::EVENT_BEFORE_DELETE => 'Delete',
];
}
private function clearPostTags()
{
if($this->owner->postTagAssigns)
{
foreach ($this->owner->postTagAssigns as $tag)
{
$tag->delete();
}
}
}
private function insertPostTags()
{
if($this->tags)
{
foreach ($this->tags as $tag)
{
$tg = PostTag::find()->where(['name' => $tag])->one();
if(!$tg)
{
$tg = new PostTag;
$tg->name = $tag;
$tg->save();
}
$tgs = new PostTagAssign;
$tgs->post_id = $this->owner->id;
$tgs->tag_id = $tg->id;
$tgs->save();
}
}
}
public function eventFind($event)
{
$this->tags = array_keys(ArrayHelper::map($this->owner->postTags, 'name', 'id'));
}
public function Save($event)
{
$this->clearPostTags();
$this->insertPostTags();
return true;
}
public function Insert($event)
{
$this->insertPostTags();
return true;
}
public function Delete($event)
{
$this->clearPostTags();
return true;
}
}
......@@ -6,10 +6,13 @@ use Yii;
use common\components\AdminController;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;
use yii\web\Response;
use yii\helpers\ArrayHelper;
use common\modules\languages\models\Languages;
use common\modules\blog\models\Post;
use common\modules\blog\models\PostLang;
use common\modules\blog\models\PostTag;
use common\modules\blog\models\SearchPost;
/**
......@@ -24,6 +27,7 @@ class PostAdminController extends AdminController
'Update' => 'Редактирование записи',
'Delete' => 'Удаление записи',
'View' => 'Просмотр записи',
'Autocomplete' => 'Автокомплит для поля тегов'
];
}
......@@ -155,6 +159,13 @@ class PostAdminController extends AdminController
return $this->redirect(['index']);
}
public function actionAutocomplete($term)
{
Yii::$app->response->format = Response::FORMAT_JSON;
return array_keys(ArrayHelper::map(PostTag::find()->where(['like', 'name', $term])->all(), 'name', 'id'));
}
/**
* Finds the Post model based on its primary key value.
* If the model is not found, a 404 HTTP exception will be thrown.
......
......@@ -7,18 +7,58 @@ use common\components\BaseController;
use yii\web\NotFoundHttpException;
use common\modules\blog\models\Post;
use common\modules\blog\models\PostTag;
/**
* PostController implements the CRUD actions for Post model.
*/
class PostController extends BaseController
{
public static function actionsTitles(){
public static function actionsTitles()
{
return [
'Index' => 'Блог',
'Tag' => 'Просмотр тега',
'View' => 'Просмотр записи',
];
}
/**
* Displays all Post models.
* @return mixed
*/
public function actionIndex()
{
$this->meta_title = Yii::t('menu', 'Blog') . ' - ' . \Yii::$app->params['name'];
$models = Post::find()->where(['active' => 1])->all();
return $this->render('index', [
'models' => $models,
]);
}
/**
* Displays a single Post model.
* @param string $url
* @return mixed
*/
public function actionTag($tag)
{
$model = PostTag::find()->where(['name' => $tag])->one();
if(!$model || !$model->posts)
{
throw new NotFoundHttpException('The requested page does not exist.');
}
$this->meta_title = Yii::t('app', 'Tag') . ': ' . $model->name . ' - ' . \Yii::$app->params['name'];
return $this->render('tag', [
'model' => $model,
]);
}
/**
* Displays a single Post model.
* @param string $url
......@@ -26,8 +66,14 @@ class PostController extends BaseController
*/
public function actionView($url)
{
$model = $this->findModelByUrl($url);
$this->meta_title = $model->metaTag->title . ' - ' . \Yii::$app->params['name'];
$this->meta_description = $model->metaTag->description;
$this->meta_keywords = $model->metaTag->keywords;
return $this->render('view', [
'model' => $this->findModelByUrl($url),
'model' => $model,
]);
}
......@@ -40,7 +86,10 @@ class PostController extends BaseController
*/
protected function findModelByUrl($url)
{
if (($model = Post::find()->where(['url' => $url])->one()) !== null) {
if (($model = Post::find()->where([
'url' => $url,
'active' => 1
])->one()) !== null) {
return $model;
} else {
throw new NotFoundHttpException('The requested page does not exist.');
......
......@@ -6,7 +6,7 @@ use Yii;
use common\modules\languages\models\Languages;
use common\modules\blog\models\PostLang;
use common\modules\blog\models\PostTags;
use common\modules\blog\models\PostTag;
use common\models\MetaTags;
/**
......@@ -55,7 +55,7 @@ class Post extends \common\components\ActiveRecordModel
[['active', 'created_at', 'updated_at'], 'integer'],
[['url'], 'string', 'max' => 255],
[['url'], 'unique'],
[['preview', 'unlinkFile'], 'safe'],
[['preview', 'unlinkFile', 'tags'], 'safe'],
[['file'], 'file', 'skipOnEmpty' => true, 'extensions' => 'png, jpg, jpeg, gif'],
];
}
......@@ -76,8 +76,16 @@ class Post extends \common\components\ActiveRecordModel
'langClass' => 'common\modules\blog\models\PostLang',
'actions' => ['create', 'update']
],
'tags' => [
'class' => 'common\modules\blog\components\TagBehavior',
],
'Timestamp' => [
'class' => '\yii\behaviors\TimestampBehavior',
],
'file' => [
'class' => 'common\components\activeRecordBehaviors\FileUploadBehavior',
'thumb' => true,
'thumbSize' => ['280', '141'],
'path' => '@frontend/web',
'folder' => '/uploads/blog/',
'field' => 'preview'
......@@ -95,6 +103,7 @@ class Post extends \common\components\ActiveRecordModel
'url' => 'Ссылка',
'active' => 'Видимость',
'file' => 'Изображение',
'tags' => 'Теги',
'preview' => 'Изображение',
'unlinkFile' => 'Удалить изображение',
'created_at' => 'Дата добавления',
......@@ -151,8 +160,23 @@ class Post extends \common\components\ActiveRecordModel
/**
* @return \yii\db\ActiveQuery
*/
public function getTags()
public function getPostTags()
{
return $this->hasMany(PostTag::className(), ['id' => 'tag_id'])->viaTable('posts_tags_assign', ['post_id' => 'id']);
}
/**
* @return \yii\db\ActiveQuery
*/
public function getPostTagAssigns()
{
return $this->hasMany(PostTagAssign::className(), ['post_id' => 'id']);
}
public function getThumbnailUrl()
{
return $this->hasMany(PostTags::className(), ['id' => 'tag_id'])->viaTable('posts_tags_assign', ['post_id' => 'id']);
$path = pathinfo($this->preview);
return $path['dirname'] . '/' . $path['filename'] . '.thumb.' . $path['extension'];
}
}
......@@ -4,7 +4,10 @@ namespace common\modules\blog\models;
use Yii;
use yii\helpers\Url;
use common\modules\blog\models\Post;
use common\modules\blog\models\PostTagAssign;
/**
* This is the model class for table "posts_tags".
......@@ -62,6 +65,19 @@ class PostTag extends \common\components\ActiveRecordModel
*/
public function getPosts()
{
return $this->hasMany(Post::className(), ['id' => 'post_id'])->viaTable('posts_tags_assign', ['tag_id' => 'id']);
return $this->hasMany(Post::className(), ['id' => 'post_id'])->viaTable('posts_tags_assign', ['tag_id' => 'id'])->where(['active' => 1]);
}
/**
* @return \yii\db\ActiveQuery
*/
public function getAssigns()
{
return $this->hasMany(PostTagAssign::className(), ['tag_id' => 'id']);
}
public function getUrl()
{
return Url::to(['/blog/tag/' . $this->name]);
}
}
......@@ -5,7 +5,7 @@ namespace common\modules\blog\models;
use Yii;
use common\modules\blog\models\Post;
use common\modules\blog\models\PostTags;
use common\modules\blog\models\PostTag;
/**
* This is the model class for table "posts_tags_assign".
......@@ -44,7 +44,7 @@ class PostTagAssign extends \common\components\ActiveRecordModel
[['tag_id', 'post_id', 'created_at', 'updated_at'], 'integer'],
[['tag_id', 'post_id'], 'unique', 'targetAttribute' => ['tag_id', 'post_id'], 'message' => 'The combination of Tag ID and Post ID has already been taken.'],
[['post_id'], 'exist', 'skipOnError' => true, 'targetClass' => Post::className(), 'targetAttribute' => ['post_id' => 'id']],
[['tag_id'], 'exist', 'skipOnError' => true, 'targetClass' => PostTags::className(), 'targetAttribute' => ['tag_id' => 'id']],
[['tag_id'], 'exist', 'skipOnError' => true, 'targetClass' => PostTag::className(), 'targetAttribute' => ['tag_id' => 'id']],
];
}
......
<?php
use yii\helpers\Html;
use yii\helpers\Url;
use yii\widgets\ActiveForm;
use \xj\tagit\Tagit;
use common\modules\blog\models\Post;
use common\modules\content\widgets\MetaTagsWidget;
......@@ -39,6 +41,17 @@ use common\modules\content\widgets\MetaTagsWidget;
<?= $form->field($model, 'unlinkFile')->checkbox(); ?>
<?= $form->field($model, 'tags')->widget(Tagit::className(), [
'clientOptions' => [
'tagSource' => Url::to(['autocomplete']),
'autocomplete' => [
'delay' => 500,
'minLength' => 1,
],
'triggerKeys' => ['enter', 'space', 'tab'],
]
]); ?>
<ul class="nav nav-pills">
<?php $c = 0; foreach ($model->getLangsHelper() as $i => $content) : $c++; ?>
<li class="<?=($c==1?'active':'')?>"><a href="#lang-<?=$content->lang->url?>" data-toggle="tab"><?=$content->lang->name?></a></li>
......@@ -70,3 +83,7 @@ use common\modules\content\widgets\MetaTagsWidget;
<?php ActiveForm::end(); ?>
</div>
<script type="text/javascript">
$('.field-post-tags ul').addClass('primary');
</script>
\ No newline at end of file
<?php
use yii\helpers\Html;
use yii\helpers\ArrayHelper;
use yii\grid\GridView;
use common\modules\blog\models\Post;
......@@ -24,6 +25,10 @@ $this->params['breadcrumbs'][] = $this->title;
'columns' => [
// ['class' => 'yii\grid\SerialColumn'],
[
'attribute' => 'created_at',
'format' => ['date', 'php:d.m.Y H:i:s']
],
[
'attribute' => 'url',
'format' => 'raw',
......@@ -40,6 +45,22 @@ $this->params['breadcrumbs'][] = $this->title;
return Post::$active_title[$model->active];
}
],
[
'header' => 'Теги',
'format' => 'raw',
'value' => function($model)
{
if($model->postTags)
{
$b = '<span class="label label-primary">';
$e = '</span>';
return $b . implode($e.' '.$b, array_keys(ArrayHelper::map($model->postTags, 'name', 'id'))) . $e;
}
return null;
}
],
[
'class' => 'common\components\ColorActionColumn',
......
<?php
use yii\helpers\Url;
use common\modules\blog\models\Post;
use common\modules\blog\models\PostTag;
use common\models\Settings;
?>
<div class="col-md-4 col-xs-4 col-sm-12">
<aside class="sidebar">
<div class="sidebar_module">
<h2>Категории</h2>
<div class="sidebar_module_body">
<?php $tags = PostTag::find()
->innerJoinWith('posts')
->groupBy(['posts_tags_assign.tag_id'])
->where(['posts.active' => 1])
->orderBy('RAND()')
->limit(7)
->all();
foreach ($tags as $tag) : ?>
<a href="<?=$tag->url;?>" class="cat_link_mod"><?=$tag->name?></a>
<?php endforeach; ?>
</div>
</div>
<!-- <div class="sidebar_module">
<div class="sidebar_module_body">
<a href="#" class="sidebar_btn">
Предложить тему
<div class="blog_toltip_right">Предложите свою тему и мы напишем</div>
</a>
<a href="#" class="sidebar_btn">Послать статью</a>
</div>
</div> -->
<?php $posts = Post::find();
if($model)
{
$posts = $posts->where(['!=', 'id', $model->id]);
}
$posts = $posts->andWhere(['active' => 1])->orderBy('RAND()')->limit(3)->all();
if($posts) : ?>
<div class="sidebar_module">
<h2>Популярные</h2>
<div class="sidebar_module_body">
<?php foreach ($posts as $post) : ?>
<div class="article_itm">
<?php if($post->preview) : ?>
<img src="<?=$post->getThumbnailUrl()?>" alt="">
<?php endif; ?>
<a href="<?=Url::to(['/blog/'.$post->url])?>" class="article_itm_link"><?=$post->lang->title?></a>
</div>
<?php endforeach; ?>
</div>
</div>
<?php endif; ?>
<div class="sidebar_module">
<h2>Все секреты в наших соц сетях!</h2>
<div class="sidebar_module_body">
<ul class="sidebar_social">
<?php $s = Settings::getValue('social-link-fb'); if($s): ?><li><a href="<?=$s?>" class="sidebar_social_fb"></a></li><? endif; ?>
<!-- <li><a href="#" class="sidebar_social_ok"></a></li> -->
<?php $s = Settings::getValue('social-link-twitter'); if($s): ?><li><a href="<?=$s?>" class="sidebar_social_tw"></a></li><? endif; ?>
<?php $s = Settings::getValue('social-link-google'); if($s): ?><li><a href="<?=$s?>" class="sidebar_social_gp"></a></li><? endif; ?>
<?php $s = Settings::getValue('social-link-youtube'); if($s): ?><li><a href="<?=$s?>" class="sidebar_social_yt"></a></li><? endif; ?>
<?php $s = Settings::getValue('social-link-vk'); if($s): ?><li><a href="<?=$s?>" class="sidebar_social_vk"></a></li><? endif; ?>
<?php $s = Settings::getValue('social-link-instagram'); if($s): ?><li><a href="<?=$s?>" class="sidebar_social_inst"></a></li><? endif; ?>
</ul>
</div>
</div>
</aside>
</div>
\ No newline at end of file
<?php
use yii\widgets\ActiveForm;
use yii\helpers\Html;
use common\modules\bids\models\Bid;
?>
<div class="subsc_blog">
<h2 class="subsc_blog_title">Понравилось? Подпишись на обновления!</h2>
<div class="subsc_blog_txt">Мы страемся публиковать в данном разделе только полезный и уникальный контент для рынка. По этому подпишись и ты будешь первым, кто получит уведомление о свежей публикации</div>
<?php
$model = new Bid;
$model->scenario = Bid::SCENARIO_SUBSCRIBE;
$form = ActiveForm::begin([
'action' => '/',
'options' => [
'class' => 'subsc_blog_form bids-form',
],
]); ?>
<?php echo Html::hiddenInput('scenario', $model->scenario, ['class' => 'not_clear']); ?>
<?php echo Html::hiddenInput('Bid[form]', Bid::FORM_SUBSCRIBE, ['class' => 'not_clear']); ?>
<?php echo $form->field($model, 'email', [
'template' => '<div class="row"><div class="col-sm-4">{input}</div></div>',
'errorOptions' => []
])->textInput([
'placeholder' => 'E-mail*'
]); ?>
<?php echo Html::submitButton('Подписаться', ['class' => 'save-button']); ?>
<?php ActiveForm::end(); ?>
</div>
\ No newline at end of file
<?php
use yii\helpers\Html;
use yii\helpers\Url;
/* @var $this yii\web\View */
/* @var $model common\modules\blog\models\Post */
?>
<div class="blog_container">
<div class="container">
<div class="row">
<div class="col-md-8 col-xs-8 col-sm-12">
<section class="blog">
<h1><?=Yii::t('menu', 'Blog')?></h1>
<?php foreach ($models as $model) : ?>
<article class="article_short">
<a href="<?=Url::to(['/blog/'.$model->url])?>" class="article_short_title"><?=$model->lang->title?></a>
<div class="article_short_head">
<span class="article_short_date"><?=date('d.m.Y', $model->created_at)?></span>
<!-- <span class="article_short_view">
180
<div class="blog_toltip_left">Количество просмотров</div>
</span> -->
<!-- <ul class="article_short_social">
<li>
<a href="#"><img src="/images/icon/sh_social_vk.png" height="30" width="30" alt=""></a>
<a href="#"><img src="/images/icon/sh_social_fb.png" height="30" width="30" alt=""></a>
<a href="#"><img src="/images/icon/sh_social_tw.png" height="30" width="30" alt=""></a>
<a href="#"><img src="/images/icon/sh_social_gp.png" height="30" width="30" alt=""></a>
<a href="#"><img src="/images/icon/sh_social_t.png" height="30" width="30" alt=""></a>
</li>
</ul> -->
</div>
<div class="article_short_tags">
<?php foreach ($model->postTags as $tag) : ?>
<a href="<?=$tag->url;?>"># <?=$tag->name?></a>
<?php endforeach; ?>
</div>
<div class="article_short_txt">
<?php if($model->preview) :
echo Html::img($model->preview);
endif; ?>
<?=$model->lang->text?>
</div>
</article>
<?php endforeach; ?>
<?=$this->render('_subscribe')?>
</section>
</div>
<?=$this->render('_sidebar')?>
</div>
</div>
</div>
<div class="end_keys_neft"></div>
<?=$this->render('@app/views/layouts/footer');?>
\ No newline at end of file
<?php
use yii\helpers\Html;
use yii\helpers\Url;
/* @var $this yii\web\View */
/* @var $model common\modules\blog\models\Post */
?>
<div class="blog_container">
<div class="container">
<div class="row">
<div class="col-md-8 col-xs-8 col-sm-12">
<section class="blog">
<h1><?=Yii::t('app', 'Tag')?>: <?=$model->name;?></h1>
<?php foreach ($model->posts as $post) : ?>
<article class="article_short">
<a href="<?=Url::to(['/blog/'.$post->url])?>" class="article_short_title"><?=$post->lang->title?></a>
<div class="article_short_head">
<span class="article_short_date"><?=date('d.m.Y', $post->created_at)?></span>
<!-- <span class="article_short_view">
180
<div class="blog_toltip_left">Количество просмотров</div>
</span> -->
<!-- <ul class="article_short_social">
<li>
<a href="#"><img src="/images/icon/sh_social_vk.png" height="30" width="30" alt=""></a>
<a href="#"><img src="/images/icon/sh_social_fb.png" height="30" width="30" alt=""></a>
<a href="#"><img src="/images/icon/sh_social_tw.png" height="30" width="30" alt=""></a>
<a href="#"><img src="/images/icon/sh_social_gp.png" height="30" width="30" alt=""></a>
<a href="#"><img src="/images/icon/sh_social_t.png" height="30" width="30" alt=""></a>
</li>
</ul> -->
</div>
<div class="article_short_tags">
<?php foreach ($post->postTags as $tag) : ?>
<a href="<?=$tag->url;?>"># <?=$tag->name?></a>
<?php endforeach; ?>
</div>
<div class="article_short_txt">
<?php if($post->preview) :
echo Html::img($post->preview);
endif; ?>
<?=$post->lang->text?>
</div>
</article>
<?php endforeach; ?>
<?=$this->render('_subscribe')?>
</section>
</div>
<?=$this->render('_sidebar')?>
</div>
</div>
</div>
<div class="end_keys_neft"></div>
<?=$this->render('@app/views/layouts/footer');?>
\ No newline at end of file
<?php
use yii\helpers\Html;
use yii\widgets\DetailView;
/* @var $this yii\web\View */
/* @var $model common\modules\blog\models\Post */
$this->title = $model->id;
$this->params['breadcrumbs'][] = ['label' => 'Posts', 'url' => ['index']];
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="post-view">
<h1><?= Html::encode($this->title) ?></h1>
<p>
<?= Html::a('Update', ['update', 'id' => $model->id], ['class' => 'btn btn-primary']) ?>
<?= Html::a('Delete', ['delete', 'id' => $model->id], [
'class' => 'btn btn-danger',
'data' => [
'confirm' => 'Are you sure you want to delete this item?',
'method' => 'post',
],
]) ?>
</p>
<?= DetailView::widget([
'model' => $model,
'attributes' => [
'id',
'url:url',
'active',
'created_at',
'updated_at',
],
]) ?>
<div class="blog_container">
<div class="container">
<div class="row">
<div class="col-md-8 col-xs-8 col-sm-12">
<section class="blog">
<h1><?=$model->lang->title?></h1>
<article class="article_short">
<div class="article_short_head">
<span class="article_short_date"><?=date('d.m.Y', $model->created_at)?></span>
<!-- <span class="article_short_view">
180
<div class="blog_toltip_left">Количество просмотров</div>
</span> -->
<!-- <ul class="article_short_social">
<li>
<a href="#"><img src="/images/icon/sh_social_vk.png" height="30" width="30" alt=""></a>
<a href="#"><img src="/images/icon/sh_social_fb.png" height="30" width="30" alt=""></a>
<a href="#"><img src="/images/icon/sh_social_tw.png" height="30" width="30" alt=""></a>
<a href="#"><img src="/images/icon/sh_social_gp.png" height="30" width="30" alt=""></a>
<a href="#"><img src="/images/icon/sh_social_t.png" height="30" width="30" alt=""></a>
</li>
</ul> -->
</div>
<div class="article_short_tags">
<?php foreach ($model->postTags as $tag) : ?>
<a href="<?=$tag->url;?>"># <?=$tag->name?></a>
<?php endforeach; ?>
</div>
<div class="article_short_txt">
<?php if($model->preview) :
echo Html::img($model->preview);
endif; ?>
<?=$model->lang->text?>
</div>
</article>
<?=$this->render('_subscribe')?>
</section>
</div>
<?=$this->render('_sidebar', ['model' => $model])?>
</div>
</div>
</div>
<div class="end_keys_neft"></div>
<?=$this->render('@app/views/layouts/footer');?>
......@@ -6,14 +6,14 @@ use yii\helpers\Html;
<div class="lang_check">
<?= Html::a('<i class="icon-arrowDown"></i>' . $current->name, '#', ['class' => 'd_menu']) ?>
<?php foreach ($langs as $i => $lang): ?>
<?= Html::a('<i class="icon-arrowRight"></i>' . $lang->name, '/' . $lang->url . Yii::$app->getRequest()->getLangUrl(), ['class' => 'd_menu_hide']) ?>
<?= Html::a('<i class="icon-arrowRight"></i>' . $lang->name, (!$lang->default?'/'.$lang->url:'') . (Yii::$app->getRequest()->getLangUrl()==''?'/':Yii::$app->getRequest()->getLangUrl()), ['class' => 'd_menu_hide']) ?>
<?php endforeach;?>
</div>
<?php else : ?>
<nav class="top_nav clearfix">
<ul>
<?php foreach ($langs as $lang):?>
<li><?= Html::a($lang->name, '/' . $lang->url . Yii::$app->getRequest()->getLangUrl()) ?></li>
<li><?= Html::a($lang->name, (!$lang->default?'/'.$lang->url:'') . (Yii::$app->getRequest()->getLangUrl()==''?'/':Yii::$app->getRequest()->getLangUrl())) ?></li>
<?php endforeach;?>
</ul>
</nav>
......
......@@ -44,7 +44,9 @@ class Module extends \common\components\WebModule
public static function adminMenu()
{
return array(
);
return [
'Управление триггерами' => '/triggers/trigger-admin/manage',
'Добавление нового триггера' => '/triggers/trigger-admin/create'
];
}
}
......@@ -9,6 +9,8 @@
namespace common\modules\triggers\components\conditions;
use common\modules\triggers\controllers\TriggerAdminController;
use common\modules\triggers\models\TriggerCondition;
use common\modules\triggers\models\TriggerTrigger;
use yii\web\ServerErrorHttpException;
class Conditions {
......@@ -89,6 +91,12 @@ class Conditions {
return null;
}
/**
* @param $id
* @param $key
* @param array $values
* @return string
*/
public static function getConditionHtml($id, $key, $values=array()){
$condition = Conditions::init()->getConditionById($id);
$condition_key = rand(100,999);
......@@ -109,7 +117,9 @@ class Conditions {
* @return string
*/
public static function getControlButtons($condition_array=array(), $key=null){
// Сгенерировали случайный ключ (для массива в форме)
$key = ($key!==null) ? $key : rand(100000,999999);
// Сформировали и вернули новую строку в таблице
return '<tr data-key='.$key.'><td>'.Conditions::init()->getControlArea($condition_array, $key).'</td></tr>';
}
......@@ -131,8 +141,55 @@ class Conditions {
$html .= '<ul class="dropdown-menu">';
foreach(Conditions::init()->getConditions() as $id=>$condition)
$html .= '<li><a href="#" data-id="'.$id.'" class="add_condition">'.$condition->getName().'</a></li>';
$html .= '<li><a href="#" class="delete_row" style="color: darkred;">Удалить условия</a></li>';
$html .= '</ul>';
$html .= '</div>';
return $html;
}
/**
* Получаем триггер и проверяем срабатывание всех условий в его рамках
* @param \common\modules\triggers\models\TriggerSchedule $model
* @param $trigger_id
* @return bool
*/
public function handleMessageByTriggerId($model, $trigger_id) {
// Результирующий массив
$resultArray=[];
// Получили все условия в рамках триггера
$conditions = TriggerCondition::find()->where(['trigger_id' => $trigger_id])->all();
// Привели массив в понятный вид
$conditionsArray=[];
foreach($conditions as $i=>$condition) {
$conditionsArray[$i][] = $condition;
} // На выходе получаем массив необходимого формата
// Обрабатываем отформатированный массив
foreach($conditionsArray as $key=>$array) {
$resultArray[] = self::checkConditionsArray($array, $model);
}
// Проверяем результат
if (count($resultArray)>0) {
foreach($resultArray as $result)
if ($result===false)
return false;
return true;
}
return false;
}
/**
* Проверяем массив параметров на срабатывание хотябы одного условия
* @param $array
* @param $message
* @return bool
*/
public static function checkConditionsArray($array, $message){
foreach($array as $item) {
$object=Conditions::init()->getConditionById($item->condition_id);
$object->model=$item;
if ($object->check($message)==true)
return true;
}
return false;
}
}
\ No newline at end of file
......@@ -3,6 +3,8 @@ namespace common\modules\triggers\components\conditions\conditions;
use common\modules\triggers\components\conditions\vendor\ConditionBase;
use common\modules\triggers\components\conditions\vendor\ConditionInterface;
use common\modules\triggers\models\TriggerParam;
use common\components\UnisenderAPI;
class CheckClickingOnTheLink extends ConditionBase implements ConditionInterface {
const CONDITION_ID = 2;
......@@ -11,6 +13,8 @@ class CheckClickingOnTheLink extends ConditionBase implements ConditionInterface
public $params=[];
public $model;
/**
* @param null|string $conditionName
* @return $this mixed
......@@ -19,7 +23,35 @@ class CheckClickingOnTheLink extends ConditionBase implements ConditionInterface
return parent::init($conditionName);
}
public function check(){
return true;
/**
* Осуществляем проверку на переход по ссылке
* @param $message
* @return bool
*/
public function check($message){
// Если модель условия указана и полученное сообщение не нуль
if (!is_null($this->model) && !is_null($message)) {
// Получаем параметр link
$param = TriggerParam::find()->where(['condition_id' => $this->model->id, 'key' => 'link'])->one();
// Если параметр есть, он длиннее нуля и не равен #
if (!is_null($param) && strlen($param->value)>0 && $param->value!='#') {
// Если идентификатор кампании в сообщении не равен нулю
if (!is_null($message->campaign_id)) {
// Создаем объект унисендера
$sender=new UnisenderAPI();
// Делаем запрос на получение ссылок по которым переходили
$sender->getVisitedLinks($message->campaign_id);
// Возвращаем переход по конкретной ссылке
return $sender->linkIsVisited($message->email, $param->value);
}
} else {
// В противном случае срабатывает переход по любой ссылке
$sender=new UnisenderAPI();
// Делаем запрос на получение статуса сообщения
$sender->getMessageStatuses($message->message_id);
return $sender->isLinkVisited();
}
}
return false;
}
}
\ No newline at end of file
<?php
namespace common\modules\triggers\components\conditions\conditions;
use common\components\UnisenderAPI;
use common\modules\triggers\components\conditions\vendor\ConditionBase;
use common\modules\triggers\components\conditions\vendor\ConditionInterface;
class CheckEmailToDelivered extends ConditionBase implements ConditionInterface{
const CONDITION_ID = 3;
public $name = 'Письмо было получено';
/**
* @param null|string $conditionName
* @return $this mixed
*/
public static function init($conditionName=__CLASS__){
return parent::init($conditionName);
}
/**
* @param $message
* @return bool
*/
public function check($message){
if (!is_null($message)) {
// Создаем объект унисендера
$sender=new UnisenderAPI();
// Делаем запрос на получение статуса сообщения
$sender->getMessageStatuses($message->message_id);
return $sender->isDelivered();
}
return true;
}
}
\ No newline at end of file
<?php
namespace common\modules\triggers\components\conditions\conditions;
use common\components\UnisenderAPI;
use common\modules\triggers\components\conditions\vendor\ConditionBase;
use common\modules\triggers\components\conditions\vendor\ConditionInterface;
class CheckEmailToOpening extends ConditionBase implements ConditionInterface {
class CheckEmailToReading extends ConditionBase implements ConditionInterface {
const CONDITION_ID = 1;
public $name = 'Письмо было открыто';
public $name = 'Письмо было прочтено';
public $params=[];
......@@ -19,7 +20,18 @@ class CheckEmailToOpening extends ConditionBase implements ConditionInterface {
return parent::init($conditionName);
}
public function check(){
/**
* @param $message
* @return bool
*/
public function check($message){
if (!is_null($message)) {
// Создаем объект унисендера
$sender=new UnisenderAPI();
// Делаем запрос на получение статуса сообщения
$sender->getMessageStatuses($message->message_id);
return $sender->isReaded();
}
return true;
}
}
\ No newline at end of file
<?php
namespace common\modules\triggers\components\conditions\conditions;
use common\components\UnisenderAPI;
use common\modules\triggers\components\conditions\vendor\ConditionBase;
use common\modules\triggers\components\conditions\vendor\ConditionInterface;
class CheckEmailToUnsubscribed extends ConditionBase implements ConditionInterface{
const CONDITION_ID = 4;
public $name = 'Пользователь отписался';
/**
* @param null|string $conditionName
* @return $this mixed
*/
public static function init($conditionName=__CLASS__){
return parent::init($conditionName);
}
/**
* @param $message
* @return bool
*/
public function check($message){
if (!is_null($message)) {
// Создаем объект унисендера
$sender=new UnisenderAPI();
// Делаем запрос на получение статуса сообщения
$sender->getMessageStatuses($message->message_id);
return $sender->isUnsubscribed();
}
return true;
}
}
\ No newline at end of file
<?php
return [
'check-email-to-reading' => [
'class' => 'common\modules\triggers\components\conditions\conditions\CheckEmailToReading',
],
'check-email-to-opening' => [
'class' => 'common\modules\triggers\components\conditions\conditions\CheckEmailToOpening',
'class' => 'common\modules\triggers\components\conditions\conditions\CheckEmailToDelivered',
],
'check-email-to-unsubscribed' => [
'class' => 'common\modules\triggers\components\conditions\conditions\CheckEmailToUnsubscribed',
],
'check-clicking-on-the-link' => [
'class' => 'common\modules\triggers\components\conditions\conditions\CheckClickingOnTheLink',
......
......@@ -11,6 +11,12 @@ class ConditionBase {
public $config = [];
const MESSAGE_READ = 'ok_read';
const MESSAGE_LINK_VISITED = 'ok_link_visited';
const MESSAGE_UNSUBSCRIBED = 'ok_unsubscribed';
const MESSAGE_SPAM_FOLDER = 'ok_spam_folder';
const MESSAGE_DELIVERED = 'ok_delivered';
/**
* @param string $conditionName
* @return mixed
......
......@@ -5,5 +5,5 @@ interface ConditionInterface {
// Функция инициализации
public static function init($conditionName=null);
public function check();
public function check($model);
}
\ No newline at end of file
......@@ -3,6 +3,10 @@
namespace common\modules\triggers\controllers;
use common\components\BaseController;
use common\modules\triggers\components\conditions\Conditions;
use common\modules\triggers\models\TriggerSchedule;
use common\modules\triggers\models\TriggerTrigger;
use \DateTime;
/**
* Default controller for the `triggers` module
......@@ -11,7 +15,8 @@ class DefaultController extends BaseController
{
public static function actionsTitles(){
return [
'Index' => 'Главная страница модуля'
'Index' => 'Главная страница модуля',
'Rechecktriggers' => 'Запуск проверки срабатывания триггеров'
];
}
/**
......@@ -22,4 +27,29 @@ class DefaultController extends BaseController
{
return $this->render('index');
}
/**
* Метод для крона и ручного вызова. Проверяет таблицу с расписанием, выполняет сработавшие триггеры.
*/
public function actionRechecktriggers(){
/** @var TriggerTrigger[] $actualTriggers */
// Получили текущую дату и время
$timeNow = new DateTime();
// Получили все те сообщения которые еще не обработаны и имеют дату равную или меньше текущей
$uncheckedArray = TriggerSchedule::find()->where('checked=:checked AND time <= :time_now', [':checked' => 0, ':time_now' => $timeNow->format('Y-m-d H:i:s')])->all();
// Получили все актуальные триггеры в базе
$actualTriggers = TriggerTrigger::getActualTriggers();
// Перебираем эти сообщения в цикле
foreach($uncheckedArray as $message) {
// Проверяем каждое сообщение на срабатывание триггера
foreach($actualTriggers as $trigger) {
// Вызвали срабатывание условий
$triggerResult = Conditions::init()->handleMessageByTriggerId($message, $trigger->getPrimaryKey());
// Если триггер сработал инициируем действие
if ($triggerResult===true) {
$trigger->initAction($message);
}
}
}
}
}
......@@ -55,7 +55,8 @@ class TriggerAdminController extends AdminController {
public function actionGetresult($id){
$obj = new UnisenderAPI();
$result = $obj->getVisitedLinks($id);
var_dump($result);
$visited = $obj->linkIsVisited('bystrov@kupitsite.ru', 'http://www.google.com/');
var_dump($visited);
}
/**
......
<?php
namespace common\modules\triggers\models;
use Yii;
/**
* This is the model class for table "trigger_schedule".
*
* @property integer $id
* @property integer $sended
* @property integer $checked
* @property integer $message_id
* @property string $message
* @property string $email
* @property string $time
* @property string $date_create
* @property integer $list_id
* @property integer $campaign_id
*/
class TriggerSchedule extends \yii\db\ActiveRecord
{
/**
* @inheritdoc
*/
public static function tableName()
{
return 'trigger_schedule';
}
/**
* @inheritdoc
*/
public function rules()
{
return [
[['sended', 'checked', 'message_id', 'list_id', 'campaign_id'], 'integer'],
[['message', 'email'], 'required'],
[['message'], 'string'],
[['time', 'date_create'], 'safe'],
[['email'], 'string', 'max' => 255],
];
}
/**
* @inheritdoc
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'sended' => 'Sended',
'checked' => 'Checked',
'message_id' => 'Message ID',
'message' => 'Message',
'email' => 'Email',
'time' => 'Time',
'date_create' => 'Date Create',
'list_id' => 'List ID',
'campaign_id' => 'Campaign ID',
];
}
}
......@@ -92,10 +92,12 @@ class TriggerTrigger extends \common\components\ActiveRecordModel
}
// Тут добавляем кнопки управления
if (count($this->conditions)>0) {
// Условие если эта форма уже содержит параметры
foreach($this->conditions as $condition_array) {
$table .= Conditions::getControlButtons($condition_array);
}
} else
// И если это новая форма, еще пустая
$table .= Conditions::getControlButtons();
$table .= '</tbody>';
// Формируем футер
......@@ -188,4 +190,20 @@ class TriggerTrigger extends \common\components\ActiveRecordModel
'update' => ['active','name','description','owner_id','date_create','timeout','message_template_id','conditions'],
];
}
/**
* Метод возвращает массив актуальных на данный момент триггеров
* @return array|\yii\db\ActiveRecord[]
*/
public static function getActualTriggers() {
return TriggerTrigger::find()->indexBy('id')->all();
}
/**
* Тут выполняем то, что произойдет когда триггер сработает
* @param $message
*/
public function initAction($message){
echo "ASD";
}
}
<?php
use yii\db\Migration;
use yii\db\Schema;
class m160211_095231_add_campaign_id_column_to_trigger_schedule extends Migration
{
public function safeUp()
{
$this->addColumn(
'trigger_schedule',
'campaign_id',
Schema::TYPE_INTEGER.' DEFAULT NULL'
);
}
public function safeDown()
{
$this->dropColumn(
'trigger_schedule',
'campaign_id'
);
}
}
......@@ -153,6 +153,8 @@ return [
'faq/view/all' => 'faq/faq/all',
'faq/<url>' => 'faq/faq/view',
'faq' => 'faq/faq/index',
'blog' => 'blog/post/index',
'blog/tag/<tag>' => 'blog/post/tag',
'blog/<url>' => 'blog/post/view',
'school' => 'school/course/index',
'school/course/<id>' => 'school/course/view',
......
<?php
return [
'Update' => 'Редактировать',
'Delete' => 'Удалить',
'Request a call' => 'Заказать звонок',
'Tag' => 'Тег'
];
\ No newline at end of file
<?php
return [
'Update' => 'Редактировать',
'Delete' => '.удалить',
];
\ No newline at end of file
<?php
return [
'Create Category' => 'Создать категорию',
'Create Content' => 'Добавить контент',
'Delete' => 'Удалить',
'Update' => 'Редактировать',
'Title' => 'Заголовок',
'Name' => 'Название',
'Url' => 'Ссылка',
'Category ID' => 'Категория',
'Active' => 'Активность',
'References about us' => 'Отзывы о нас',
'Look all reviews' => 'Смотреть все отзывы',
];
\ No newline at end of file
<?php
return [
'Surname' => 'Фамилия',
'Name' => 'Имя',
'Patronymic' => 'Отчество',
'Name Add' => 'Фамилия, имя, отчество родственника',
'Status Add' => 'Степень родства',
'Status Fail' => 'Отклонена',
'Gender' => 'Ваш пол',
'Day' => 'День',
'Month' => 'Месяц',
'Year' => 'Год',
'Ser_doc' => 'Серия паспорта',
'Nom_doc' => 'Номер паспорта',
'Vyd_doc' => 'Кем выдан паспорт',
'Request Sum' => 'Сумма',
'Request Day' => 'Кол-во дней',
'Status' => 'Статус',
'Created At' => 'Создана',
];
\ No newline at end of file
......@@ -13,7 +13,7 @@ $reviews = Reviews::find()
<div class="container">
<div class="row">
<div class="col-md-12 col-xs-12 col-sm-12">
<span class="rev_title">Отзывы о нас</span>
<span class="rev_title"><?=Yii::t('reviews', 'References about us')?></span>
</div>
</div>
<?php foreach ($reviews as $review) : ?>
......@@ -55,7 +55,7 @@ $reviews = Reviews::find()
<?php endif; ?>
<?php endforeach; ?>
<a href="/otzyvy-art-proekt" class="all_rev__btn">Смотреть все отзывы</a>
<a href="/otzyvy-art-proekt" class="all_rev__btn"><?=Yii::t('reviews', 'Look all reviews')?></a>
</div>
</section>
<?php endif; ?>
\ No newline at end of file
......@@ -12,7 +12,7 @@ $reviews = Reviews::find()
<div class="container">
<div class="row" style="margin:50px -15px 0;">
<div class="col-md-12 col-xs-12 col-sm-12">
<span class="rev_title">Отзывы о нас</span>
<span class="rev_title"><?=Yii::t('reviews', 'References about us')?></span>
</div>
</div>
<?php foreach ($reviews as $review) : ?>
......
......@@ -4,7 +4,7 @@
<div class="col-md-4 col-xs-4 col-sm-12">
<a href="mailto:info@task-on.com" class="foot_mail">info@task-on.com</a>
</div>
<div class="col-md-4 col-xs-4 col-sm-12"><a href="#zvonok_form" class="zvonok_bt popup-form"><span>Заказать звонок</span></a></div>
<div class="col-md-4 col-xs-4 col-sm-12"><a href="#zvonok_form" class="zvonok_bt popup-form"><span><?=Yii::t('app', 'Request a call');?></span></a></div>
<div class="col-md-4 col-xs-4 col-sm-12">
<!-- <div class="phone_hover_foot">Стоимость звонка 0 руб,<br/> в том числе с мобильного</div> -->
<span class="foot_phone"><?=\common\models\Settings::getValue('content-phone');?></span>
......
......@@ -12,7 +12,7 @@ use common\modules\languages\widgets\Languages;
<ul>
<li><?=Html::a(\Yii::t('menu', 'About'), ['/about']);?></li>
<li><?=Html::a(\Yii::t('menu', 'Portfolio'), ['/portfolio']);?></li>
<li><?=Html::a(\Yii::t('menu', 'Blog'), ['/#']);?></li>
<li><?=Html::a(\Yii::t('menu', 'Blog'), ['/blog']);?></li>
<!-- <li><?=Html::a(\Yii::t('menu', 'Analytics school'), ['/school']);?></li> -->
<li><?=Html::a(\Yii::t('menu', 'Contacts'), ['/contacts']);?></li>
</ul>
......@@ -31,7 +31,7 @@ use common\modules\languages\widgets\Languages;
<ul>
<li><?=Html::a(\Yii::t('menu', 'About'), ['/about']);?></li>
<li><?=Html::a(\Yii::t('menu', 'Portfolio'), ['/portfolio']);?></li>
<li><?=Html::a(\Yii::t('menu', 'Blog'), ['/#']);?></li>
<li><?=Html::a(\Yii::t('menu', 'Blog'), ['/blog']);?></li>
<!-- <li><?=Html::a(\Yii::t('menu', 'Analytics school'), ['/school']);?></li> -->
<li><?=Html::a(\Yii::t('menu', 'Contacts'), ['/contacts']);?></li>
</ul>
......
......@@ -57,7 +57,8 @@ a.login_form_link, a.login_form_popup_link, a.reg_popup_link, a.reg_form_link{
.sh_ft .popup_text, .reg_form .popup_text{
margin-top: 10px;
}
.subsc_form input {
.subsc_form input,
.subsc_blog_form input {
display: block;
width: 273px;
height: 49px;
......@@ -71,4 +72,10 @@ a.login_form_link, a.login_form_popup_link, a.reg_popup_link, a.reg_form_link{
-ms-border-radius: 10px;
font-size: 16px;
color: #83999e;
}
.txt_server:before {
position: absolute;
}
.article_short_txt img {
width: auto !important;
}
\ No newline at end of file
This diff is collapsed.
......@@ -37,27 +37,26 @@ $(document).ready(function() {
});
$('.about_hide_block').hide();
$('.about_hide_btn').click(function(){
if ($('.about_hide_btn').text() == 'Подробнее'){
if ($('.about_hide_btn').text() == $(this).data('show')){
$('.about_hide_block').slideDown(1000);
$(this).text('Скрыть')
$(this).text($(this).data('hide'));
}
else {
$('.about_hide_block').slideUp(1000);
$(this).text('Подробнее');
$(this).text($(this).data('show'));
}
});
$('.dep_block__hide').hide();
$('.dep_block_hide__btn').click(function(){
if ($('.dep_block_hide__btn').text() == 'Смотреть полную схему'){
$('.line_hide').fadeTo( "slow" , 0);
if ($('.dep_block_hide__btn').text() == $(this).data('show')){
$('.dep_block__hide').slideDown(1000);
$(this).text('Скрыть полную схему')
$(this).text($(this).data('hide'));
}
else {
$('.line_hide').fadeTo( "slow" , 1);
$('.dep_block__hide').slideUp(1000);
$(this).text('Смотреть полную схему');
$(this).text($(this).data('show'));
}
});
......@@ -594,7 +593,6 @@ $(function() {
}
});
});
jQuery(document).ready(function(){
$(".box_off").on('click', function () {
......
......@@ -51,12 +51,20 @@ body
font-family: "RobotoRegular"
position: relative
overflow-x: hidden
min-width: 320px
.hidden
display: none
strong
font-family: "RobotoBold"
color: #494949
line-height: 22px
i
font-style: italic
color: #494949
line-height: 22px
u
color: #494949
line-height: 22px
.container
+r(768,970)
width: 750px
......@@ -8658,4 +8666,402 @@ a.appl_btn
font-size: 17px
line-height: 26px
+r(320,479)
font-size: 14px
\ No newline at end of file
font-size: 14px
.blog_container
background: #fff
width: 100%
padding-top: 46px
.blog
padding-bottom: 30px
h1
font-size: 29px
font-family: "RobotoBold"
color: #2d3642
margin-bottom: 16px
.subsc_blog
background: #F1F1F1
padding: 20px
&_title
color: #2d323a
font-size: 25px
font-family: "RobotoBold"
+r(320,479)
font-size: 17px
&_txt
font-size: 17px
color: #2d323a
line-height: 26px
margin: 15px 0px
+r(768,970)
margin: 10px 0 15px
+r(320,479)
font-size: 14px
.subsc_blog_form
input[type="email"]
display: block
width: 273px
height: 49px
background: #FDFDFD
border: 1px solid #E9E9E9
padding: 0 10px
+br(10px)
font-size: 16px
color: #83999e
+r(320,479)
width: 100%
&::-webkit-input-placeholder
color: #83999e
font-size: 16px
opacity: 1
&:-moz-placeholder
color: #83999e
font-size: 16px
opacity: 1
&::-moz-placeholder
color: #83999e
font-size: 16px
opacity: 1
&:-ms-input-placeholder
color: #83999e
font-size: 16px
opacity: 1
.field-input.input-error
background: #fff url(../images/icon-fail.png) no-repeat 96% center
border: 1px solid #E9A2A2
button
width: 178px
height: 50px
+br(50px)
text-align: center
color: #655d04
font-family: "RobotoBold"
font-size: 20px
background-image: linear-gradient(to top, #fdd000 0%, #fff04e 100%)
box-shadow: 2px 3.5px 5px rgba(0, 0, 0, 0.12)
color: #908505
border: none
border-bottom: 4px solid #D2BF00
line-height: 43px
display: inline-block
margin: 20px 0px 0px
&:hover, &:focus
background-image: linear-gradient(to top, #fde654 0%, #fef77d 100%)
box-shadow: 2px 3.5px 5px rgba(0, 0, 0, 0.12)
color: #908505
border-bottom: 4px solid #D2BF00
text-decoration: none
&:active
background-image: linear-gradient(to top, #f4db15 0%, #fbd20d 100%)
box-shadow: 2px 3.5px 5px rgba(0, 0, 0, 0.12)
color: #908505
border: none
border-top: 4px solid #D2BF00
text-decoration: none
.article_short
margin-bottom: 57px
&:last-child
margin-bottom: 0
&_title
font-size: 25px
line-height: 35px
color: #3d3d3d
font-family: "RobotoBold"
+r(768,970)
font-size: 20px
line-height: 27px
+r(320,479)
font-size: 20px
line-height: 27px
&:hover, &:focus, &:active
color: #49acc5
text-decoration: none
&_head
height: 30px
width: 100%
line-height: 30px
font-size: 13px
color: #949494
margin-top: 5px
+r(320,479)
height: auto
&_date
margin-right: 19px
&_view
position: relative
&:hover
.blog_toltip_left
display: block
&:before
content: ''
background: url(../images/icon/article_view.png) no-repeat
width: 21px
height: 14px
display: inline-block
vertical-align: middle
margin-right: 6px
margin-top: -3px
.blog_toltip_left
display: none
width: 209px
height: 66px
line-height: 65px
padding-left: 5px
background: url(../images/blog_toltip_left.png) no-repeat center center
text-align: center
font-size: 14px
font-family: "RobotoLight"
position: absolute
right: -214px
top: -23px
&_tags
margin-top: 11px
a
font-size: 14px
color: #49acc5
margin-right: 10px
&:hover, &:focus, &:active
text-decoration: underline
&_txt
overflow-x: auto
img
margin: 14px 0 11px
width: 100%
height: auto
p
font-size: 16px
line-height: 25px
color: #525252
+r(320,479)
font-size: 14px
line-height: 22px
a
color: #49acc5
&:hover, &:focus, &:active
text-decoration: underline
ol
margin-top: 25px
li
color: #3c4755
font-size: 16px
+r(320,479)
font-size: 14px
&:before
counter-increment: myCounter
content: counter(myCounter)
color: #fff
font-size: 15px
font-family: "RobotoBold"
background: #00AEC7
display: inline-block
text-align: center
margin: 4px 12px 4px 4px
line-height: 23px
width: 23px
height: 23px
+br(50px)
ul
margin-top: 32px
li
background: url(../images/icon/ul_list_blue.png) no-repeat left center
height: 30px
line-height: 30px
padding-left: 34px
font-size: 16px
color: #3c4755
+r(320,479)
font-size: 14px
line-height: 17px
margin-bottom: 10px
.tb_blog
margin-top: 23px
overflow-x: auto
tr
th
padding: 15px 20px
border: 1px solid #C7C7C7
vertical-align: top
color: #2d323a
font-size: 16px
line-height: 20px
thead
tr
th
background: #00AEC7
font-family: "RobotoBold"
color: #fff
font-size: 16px
line-height: 21px
padding: 0px 0px 0px 20px
border: 1px solid #C7C7C7
vertical-align: middle
&_social
float: right
+r(320,479)
float: none
.sidebar
margin-top: 5px
&_module
h2
font-size: 18px
line-height: 20px
color: #3d3d3d
font-family: "RobotoBold"
margin-bottom: 25px
&_body
a.cat_link_mod
display: inline-block
font-size: 14px
color: #fff
background: #00AEC7
padding: 14px 20px
+br(5px)
margin-right: 10px
font-family: "RobotoBold"
margin-bottom: 21px
+r(768,970)
margin-right: 0px
margin-bottom: 4px
&:hover, &:focus, &:active
text-decoration: none
background: #FFDF00
color: #2d3642
.article_itm
margin-bottom: 30px
img
max-width: 100%
height: auto
display: block
a.article_itm_link
font-size: 16px
color: #2d3642
line-height: 25px
+r(768,970)
line-height: 20px
&:hover, &:focus, &:active
color: #49acc5
text-decoration: none
&_social
li
display: inline-block
margin-right: 26px
margin-bottom: 26px
+r(768,970)
margin-right: 20px
margin-bottom: 20px
+r(480,767)
margin-right: 20px
margin-bottom: 20px
+r(320,479)
margin-right: 20px
margin-bottom: 20px
&:nth-child(4)
margin-right: 0
+r(768,970)
margin-right: 20px
+r(480,767)
margin-right: 20px
+r(320,479)
margin-right: 20px
&_fb
background: #324C84 url(../images/icon/sidebar_social_fb.png) no-repeat center center
width: 48px
height: 48px
display: inline-block
+br(50%)
&:hover, &:focus, &:active
background: #0093A9 url(../images/icon/sidebar_social_fb.png) no-repeat center center
&_ok
background: #daaa03 url(../images/icon/sidebar_social_ok.png) no-repeat center center
width: 48px
height: 48px
display: inline-block
+br(50%)
&:hover, &:focus, &:active
background: #0093A9 url(../images/icon/sidebar_social_ok.png) no-repeat center center
&_tw
background: #69baf3 url(../images/icon/sidebar_social_tw.png) no-repeat center center
width: 48px
height: 48px
display: inline-block
+br(50%)
&:hover, &:focus, &:active
background: #0093A9 url(../images/icon/sidebar_social_tw.png) no-repeat center center
&_gp
background: #ff5400 url(../images/icon/sidebar_social_gp.png) no-repeat center center
width: 48px
height: 48px
display: inline-block
+br(50%)
&:hover, &:focus, &:active
background: #0093A9 url(../images/icon/sidebar_social_gp.png) no-repeat center center
&_yt
background: #e73500 url(../images/icon/sidebar_social_yt.png) no-repeat center center
width: 48px
height: 48px
display: inline-block
+br(50%)
&:hover, &:focus, &:active
background: #0093A9 url(../images/icon/sidebar_social_yt.png) no-repeat center center
&_vk
background: #5872c4 url(../images/icon/sidebar_social_vk.png) no-repeat center center
width: 48px
height: 48px
display: inline-block
+br(50%)
&:hover, &:focus, &:active
background: #0093A9 url(../images/icon/sidebar_social_vk.png) no-repeat center center
&_inst
background: #745e51 url(../images/icon/sidebar_social_inst.png) no-repeat center center
width: 48px
height: 48px
display: inline-block
+br(50%)
&:hover, &:focus, &:active
background: #0093A9 url(../images/icon/sidebar_social_inst.png) no-repeat center center
&_btn
width: 190px
height: 35px
+br(50px)
text-align: center
color: #655d04
font-size: 15px
background-image: linear-gradient(to top, #fdd000 0%, #fff04e 100%)
box-shadow: 2px 3.5px 5px rgba(0, 0, 0, 0.12)
color: #908505
border: none
border-bottom: 4px solid #D2BF00
line-height: 30px
display: inline-block
margin: 15px 0px 15px
position: relative
&:hover, &:focus
background-image: linear-gradient(to top, #fde654 0%, #fef77d 100%)
box-shadow: 2px 3.5px 5px rgba(0, 0, 0, 0.12)
color: #908505
border-bottom: 4px solid #D2BF00
text-decoration: none
.blog_toltip_right
display: block
&:active
background-image: linear-gradient(to top, #f4db15 0%, #fbd20d 100%)
box-shadow: 2px 3.5px 5px rgba(0, 0, 0, 0.12)
color: #908505
border: none
border-top: 4px solid #D2BF00
text-decoration: none
&:last-child
margin-bottom: 40px
.blog_toltip_right
display: none
width: 209px
height: 66px
line-height: 17px
color: #3c4755
background: url(../images/blog_toltip_right.png) no-repeat center center
text-align: left
font-size: 14px
font-family: "RobotoLight"
position: absolute
padding: 14px 30px 14px 20px
left: -215px
top: -16px
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment