diff --git a/assets/FormAsset.php b/assets/FormAsset.php new file mode 100644 index 0000000..7b227b9 --- /dev/null +++ b/assets/FormAsset.php @@ -0,0 +1,23 @@ + + * @link http://skeeks.com/ + * @copyright 2010 SkeekS (СкикС) + * @date 12.03.2015 + */ + +namespace skeeks\modules\cms\form\assets; +use skeeks\cms\base\AssetBundle; + +/** + * Class SliderAsset + * @package skeeks\modules\cms\slider\assets + */ +class FormAsset extends AssetBundle +{ + public $sourcePath = '@vendor/skeeks/cms-module-form/assets'; + + public $css = []; + public $js = []; + public $depends = []; +} diff --git a/assets/icons/form-submits.png b/assets/icons/form-submits.png new file mode 100644 index 0000000..7348aed Binary files /dev/null and b/assets/icons/form-submits.png differ diff --git a/assets/icons/forms.png b/assets/icons/forms.png new file mode 100644 index 0000000..f6bc923 Binary files /dev/null and b/assets/icons/forms.png differ diff --git a/config/admin/menu.php b/config/admin/menu.php index 29dddc7..cabe574 100644 --- a/config/admin/menu.php +++ b/config/admin/menu.php @@ -10,17 +10,20 @@ return [ [ 'label' => 'Конструктор форм', 'priority' => 0, + "img" => ['\skeeks\modules\cms\form\assets\FormAsset', 'icons/forms.png'], 'items' => [ [ "label" => "Формы", - "url" => ["form/admin-form"] + "url" => ["form/admin-form"], + "img" => ['\skeeks\modules\cms\form\assets\FormAsset', 'icons/forms.png'], ], [ "label" => "Сообщения с форм", - "url" => ["form/admin-message"] + "url" => ["form/admin-form-send-message"], + "img" => ['\skeeks\modules\cms\form\assets\FormAsset', 'icons/form-submits.png'], ], ] diff --git a/controllers/AdminFormSendMessageController.php b/controllers/AdminFormSendMessageController.php index feb1f09..2baa013 100644 --- a/controllers/AdminFormSendMessageController.php +++ b/controllers/AdminFormSendMessageController.php @@ -26,8 +26,47 @@ class AdminFormSendMessageController extends AdminModelEditorSmartController $this->_label = "Сообщения с форм"; $this->_modelShowAttribute = "id"; $this->_modelClassName = FormSendMessage::className(); + $this->modelValidate = true; $this->enableScenarios = true; + + $this->gridColumns = [ + [ + 'class' => \yii\grid\DataColumn::className(), + 'value' => function(FormSendMessage $model) + { + + if ($form = Form::find()->where(['id' => $model->form_id])->one()) + { + return $form->name; + } + + }, + 'attribute' => 'form_id', + 'format' => 'html' + ], + + ['class' => \skeeks\cms\grid\CreatedAtColumn::className()], + ['class' => \skeeks\cms\grid\CreatedByColumn::className()], + 'page_url', + 'ip' + + + ]; + parent::init(); } + + + /** + * @return array + */ + public function behaviors() + { + $behaviors = parent::behaviors(); + + unset($behaviors[self::BEHAVIOR_ACTION_MANAGER]['actions']['create']); + + return $behaviors; + } } \ No newline at end of file diff --git a/controllers/BackendController.php b/controllers/BackendController.php index b758c84..cb55e8d 100644 --- a/controllers/BackendController.php +++ b/controllers/BackendController.php @@ -8,6 +8,8 @@ namespace skeeks\modules\cms\form\controllers; use skeeks\cms\base\Controller; use skeeks\modules\cms\form\models\Form; +use skeeks\modules\cms\form\models\FormField; +use skeeks\modules\cms\form\models\FormSendMessage; use yii\filters\VerbFilter; use yii\helpers\ArrayHelper; use yii\web\Response; @@ -63,8 +65,28 @@ class BackendController extends Controller if ($model->load(\Yii::$app->request->post()) && $model->validate()) { - $response['success'] = true; - $response['message'] = 'Успешно отправлена'; + //Все проверки прошли, формируем модель отправленного сообщения и сохраняем ее + $modelFormSendMessage = new FormSendMessage(); + + $modelFormSendMessage->data_values = $model->attributeValues(); + $modelFormSendMessage->data_labels = $model->attributeLabels(); + + $modelFormSendMessage->page_url = \Yii::$app->request->referrer; + $modelFormSendMessage->form_id = $formId; + + if ($modelFormSendMessage->save()) + { + $modelFormSendMessage->notify(); + + $response['success'] = true; + $response['message'] = 'Успешно отправлена'; + } else + { + $response['message'] = 'Не удалось сохранить сообщение в базу'; + } + } else + { + $response['message'] = 'Форма заполнена неправильно'; } return $response; diff --git a/mail/send-message.php b/mail/send-message.php new file mode 100644 index 0000000..58ca869 --- /dev/null +++ b/mail/send-message.php @@ -0,0 +1,48 @@ + + * @link http://skeeks.com/ + * @copyright 2010 SkeekS (СкикС) + * @date 19.03.2015 + */ +use skeeks\cms\mail\helpers\Html; +/** + * @var $formSendMessage \skeeks\modules\cms\form\models\FormSendMessage + * @var $form \skeeks\modules\cms\form\models\Form + * @var $formField \skeeks\modules\cms\form\models\FormField + */ +?> + + Отправка формы «name)?>» #id; ?> + + + + Форма была заполнена и успешно отправлена со страницы: page_url, $formSendMessage->page_url); ?>
+ Дата и время отправки: formatter->asDatetime($formSendMessage->created_at) ?>
+ Уникальный номер сообщения: id; ?> + + + + Данные формы: + + + +fields() as $formField) : ?> + data_values, $formField->attribute)) : ?> + + normalName() ?>: + + +
+ + + + + + + Дополнительная информация: + + + + Дополнительные данные по данному сообщению можно посмотреть $formSendMessage->id])->enableAdmin()->enableAbsolute()->toString()); ?>. + \ No newline at end of file diff --git a/migrations/m150307_162735_create_form_field_table.php b/migrations/m150307_162735_create_form_field_table.php index b889f54..2462ea3 100644 --- a/migrations/m150307_162735_create_form_field_table.php +++ b/migrations/m150307_162735_create_form_field_table.php @@ -32,6 +32,8 @@ class m150307_162735_create_form_field_table extends Migration 'created_at' => Schema::TYPE_INTEGER . ' NULL', 'updated_at' => Schema::TYPE_INTEGER . ' NULL', + 'name' => Schema::TYPE_STRING . '(255) NULL', + 'label' => Schema::TYPE_STRING . '(255) NULL', 'hint' => Schema::TYPE_TEXT . ' NULL', @@ -53,6 +55,7 @@ class m150307_162735_create_form_field_table extends Migration $this->execute("ALTER TABLE {{%form_field}} ADD INDEX(created_at);"); $this->execute("ALTER TABLE {{%form_field}} ADD INDEX(updated_at);"); + $this->execute("ALTER TABLE {{%form_field}} ADD INDEX(name);"); $this->execute("ALTER TABLE {{%form_field}} ADD INDEX(label);"); $this->execute("ALTER TABLE {{%form_field}} ADD INDEX(element);"); $this->execute("ALTER TABLE {{%form_field}} ADD INDEX(priority);"); diff --git a/migrations/m150307_162740_create_form_send_messages_table.php b/migrations/m150307_162740_create_form_send_messages_table.php index b40da9a..3c281d4 100644 --- a/migrations/m150307_162740_create_form_send_messages_table.php +++ b/migrations/m150307_162740_create_form_send_messages_table.php @@ -32,11 +32,31 @@ class m150307_162740_create_form_send_messages_table extends Migration 'created_at' => Schema::TYPE_INTEGER . ' NULL', 'updated_at' => Schema::TYPE_INTEGER . ' NULL', - 'data' => Schema::TYPE_TEXT . ' NULL', - 'additional_data' => Schema::TYPE_TEXT . ' NULL', + 'processed_by' => Schema::TYPE_INTEGER . ' NULL', //пользователь который принял заявку + + 'data_values' => Schema::TYPE_TEXT . ' NULL', //Данные с формы в серилизованном виде + 'data_labels' => Schema::TYPE_TEXT . ' NULL', //Данные с формы в серилизованном виде + + 'emails' => Schema::TYPE_TEXT . ' NULL', //email на которые были отправлены уведомления + 'phones' => Schema::TYPE_TEXT . ' NULL', //Телефоны на которые были отправлены уведомления + + 'email_message' => Schema::TYPE_TEXT . ' NULL', //Телефоны на которые были отправлены уведомления + 'phone_message' => Schema::TYPE_TEXT . ' NULL', //Телефоны на которые были отправлены уведомления + + 'status' => Schema::TYPE_SMALLINT . ' NOT NULL DEFAULT 10', //статус, активна некативна, удалено 'form_id' => Schema::TYPE_INTEGER . '(255) NULL', + 'ip' => Schema::TYPE_STRING . '(32) NULL', + 'page_url' => Schema::TYPE_STRING . '(500) NULL', + + 'data_server' => Schema::TYPE_TEXT . ' NULL', + 'data_session' => Schema::TYPE_TEXT . ' NULL', + 'data_cookie' => Schema::TYPE_TEXT . ' NULL', + 'data_request' => Schema::TYPE_TEXT . ' NULL', + 'additional_data' => Schema::TYPE_TEXT . ' NULL', + + ], $tableOptions); $this->execute("ALTER TABLE {{%form_send_message}} ADD INDEX(updated_by);"); @@ -46,6 +66,10 @@ class m150307_162740_create_form_send_messages_table extends Migration $this->execute("ALTER TABLE {{%form_send_message}} ADD INDEX(updated_at);"); $this->execute("ALTER TABLE {{%form_send_message}} ADD INDEX(form_id);"); + $this->execute("ALTER TABLE {{%form_send_message}} ADD INDEX(processed_by);"); + $this->execute("ALTER TABLE {{%form_send_message}} ADD INDEX(status);"); + $this->execute("ALTER TABLE {{%form_send_message}} ADD INDEX(ip);"); + $this->execute("ALTER TABLE {{%form_send_message}} ADD INDEX(page_url);"); $this->execute("ALTER TABLE {{%form_send_message}} COMMENT = 'Сообщения с форм';"); @@ -63,13 +87,20 @@ class m150307_162740_create_form_send_messages_table extends Migration 'form_send_message_form_id', "{{%form_send_message}}", 'form_id', '{{%form_form}}', 'id', 'SET NULL', 'SET NULL' ); + + + $this->addForeignKey( + 'form_send_message_processed_by', "{{%form_send_message}}", + 'processed_by', '{{%cms_user}}', 'id', 'SET NULL', 'SET NULL' + ); } public function down() { $this->dropForeignKey("form_send_message_created_by", "{{%form_send_message}}"); $this->dropForeignKey("form_send_message_updated_by", "{{%form_send_message}}"); - + $this->dropForeignKey("form_send_message_processed_by", "{{%form_send_message}}"); + $this->dropForeignKey("form_send_message_form_id", "{{%form_send_message}}"); $this->dropTable("{{%form_send_message}}"); diff --git a/models/Form.php b/models/Form.php index c01cafc..5657b8a 100644 --- a/models/Form.php +++ b/models/Form.php @@ -94,7 +94,7 @@ class Form extends Core /** * @return \yii\db\ActiveQuery */ - public function getFormEmails() + public function findFormEmails() { return $this->hasMany(FormEmail::className(), ['form_id' => 'id']); } diff --git a/models/FormField.php b/models/FormField.php index ec9a015..efec303 100644 --- a/models/FormField.php +++ b/models/FormField.php @@ -70,11 +70,21 @@ class FormField extends Core [['priority'], 'integer'], [['rules'], 'safe'], [[ 'form_id', 'element'], 'required'], + ['attribute', 'default', 'value' => function(FormField $model, $attribute) { return "sx_field_" . md5(rand(1, 10) . time()); }], - [['label', 'attribute'], 'string', 'max' => 255], + + ['name', 'default', 'value' => function(FormField $model, $attribute) + { + if (!$model->$attribute) + { + return $model->label; + } + }], + + [['label', 'attribute', 'name'], 'string', 'max' => 255], [['attribute', 'form_id'], 'unique', 'targetAttribute' => ['attribute', 'form_id'], 'message' => 'Этот элемент уже привязан к форме'] ]); @@ -102,7 +112,8 @@ class FormField extends Core 'form_id' => \Yii::t('app', 'Форма'), 'attribute' => \Yii::t('app', 'Уникальный код (необязательно)'), 'hint' => \Yii::t('app', 'Небольшая подсказка элемента'), - 'label' => \Yii::t('app', 'Название'), + 'name' => \Yii::t('app', 'Название'), + 'label' => \Yii::t('app', 'Label элемента'), ]); } @@ -202,4 +213,23 @@ class FormField extends Core return ''; } + + + /** + * @return string + */ + public function normalName() + { + if ($this->name) + { + return (string) $this->name; + } + + if ($this->label) + { + return (string) $this->label; + } + + return (string) $this->attribute; + } } \ No newline at end of file diff --git a/models/FormSendMessage.php b/models/FormSendMessage.php index afd2ef1..aaaee4f 100644 --- a/models/FormSendMessage.php +++ b/models/FormSendMessage.php @@ -8,14 +8,43 @@ namespace skeeks\modules\cms\form\models; use skeeks\cms\base\db\ActiveRecord; +use skeeks\cms\helpers\Request; use skeeks\cms\models\behaviors\HasDescriptionsBehavior; +use skeeks\cms\models\behaviors\HasJsonFieldsBehavior; use skeeks\cms\models\behaviors\HasStatus; use skeeks\cms\models\behaviors\Implode; +use skeeks\cms\models\behaviors\Serialize; use skeeks\cms\models\Core; +use yii\helpers\ArrayHelper; +use yii\helpers\Html; /** - * Class FormSendMessage - * @package skeeks\modules\cms\form\models + * This is the model class for table "{{%form_send_message}}". + * + * @property integer $id + * @property integer $created_by + * @property integer $updated_by + * @property integer $created_at + * @property integer $updated_at + * @property integer $processed_by + * @property string $data + * @property string $emails + * @property string $phones + * @property string $email_message + * @property string $phone_message + * @property integer $status + * @property integer $form_id + * @property string $ip + * @property string $page_url + * @property string $data_server + * @property string $data_session + * @property string $data_cookie + * @property string $additional_data + * + * @property CmsUser $processedBy + * @property CmsUser $createdBy + * @property FormForm $form + * @property CmsUser $updatedBy */ class FormSendMessage extends Core { @@ -32,7 +61,20 @@ class FormSendMessage extends Core */ public function behaviors() { - return array_merge(parent::behaviors(), []); + return array_merge(parent::behaviors(), [ + + Serialize::className() => + [ + 'class' => Serialize::className(), + 'fields' => ['data_labels', 'data_values', 'data_server', 'data_session', 'data_cookie', 'additional_data', 'data_request'] + ], + + Implode::className() => + [ + 'class' => Implode::className(), + 'fields' => ['emails', 'phones'] + ] + ]); } /** @@ -41,8 +83,37 @@ class FormSendMessage extends Core public function rules() { return array_merge(parent::rules(), [ - [['created_by', 'updated_by', 'created_at', 'updated_at', 'form_id'], 'integer'], - [['data', 'additional_data'], 'string'] + [['created_by', 'updated_by', 'created_at', 'updated_at', 'processed_by', 'status', 'form_id'], 'integer'], + [['emails', 'phones', 'email_message', 'phone_message', 'data_server', 'data_session', 'data_cookie', 'data_request', 'additional_data', 'data_labels', 'data_values'], 'safe'], + [['ip'], 'string', 'max' => 32], + [['page_url'], 'string', 'max' => 500], + [['form_id'], 'required'], + + ['data_request', 'default', 'value' => function(FormSendMessage $model, $attribute) + { + return $_REQUEST; + }], + + ['data_server', 'default', 'value' => function(FormSendMessage $model, $attribute) + { + return $_SERVER; + }], + + ['data_cookie', 'default', 'value' => function(FormSendMessage $model, $attribute) + { + return $_COOKIE; + }], + + ['data_session', 'default', 'value' => function(FormSendMessage $model, $attribute) + { + \Yii::$app->session->open(); + return $_SESSION; + }], + + ['ip', 'default', 'value' => function(FormSendMessage $model, $attribute) + { + return Request::getRealUserIp(); + }], ]); } @@ -68,4 +139,56 @@ class FormSendMessage extends Core ]); } + /** + * @return \yii\db\ActiveQuery + */ + public function getProcessedBy() + { + return $this->hasOne(CmsUser::className(), ['id' => 'processed_by']); + } + + /** + * @return \yii\db\ActiveQuery + */ + public function findForm() + { + return $this->hasOne(Form::className(), ['id' => 'form_id']); + } + + + + /** + * Уведомить всех кого надо и как надо + */ + public function notify() + { + /** + * @var Form $form + */ + $form = $this->findForm()->one(); + + if ($form) + { + $emails = $form->findFormEmails()->all(); + + if ($emails) + { + foreach ($emails as $formEmail) + { + //\Yii::$app->mailer->setViewPath(\Yii::$app->getModule('form')->basePath . '/mail'); + + + \Yii::$app->mailer->compose('@skeeks/modules/cms/form/mail/send-message', [ + 'form' => $form, + 'formSendMessage' => $this + ]) + ->setFrom([\Yii::$app->params['supportEmail'] => \Yii::$app->name]) + ->setTo($formEmail->value) + ->setSubject("Отправка формы «{$form->name}» #" . $this->id) + ->send(); + + } + } + } + } } \ No newline at end of file diff --git a/models/FormValidateModel.php b/models/FormValidateModel.php index f1ba036..e5d576e 100644 --- a/models/FormValidateModel.php +++ b/models/FormValidateModel.php @@ -50,10 +50,28 @@ class FormValidateModel extends Model /** + * @return array + */ + public function attributeValues() + { + $result = parent::rules(); + + foreach ($this->modelForm->fields() as $field) + { + if ($this->getAttribute($field->attribute)) + { + $result[$field->attribute] = $this->getAttribute($field->attribute); + } + } + + return $result; + } + + + /** * @var array attribute values indexed by attribute names */ private $_attributes = []; - private $_related = []; public function rules() @@ -85,15 +103,9 @@ class FormValidateModel extends Model } elseif ($this->hasAttribute($name)) { return null; } else { - if (isset($this->_related[$name]) || array_key_exists($name, $this->_related)) { - return $this->_related[$name]; - } + $value = parent::__get($name); - if ($value instanceof ActiveQueryInterface) { - return $this->_related[$name] = $value->findFor($name, $this); - } else { - return $value; - } + return $value; } } @@ -137,8 +149,6 @@ class FormValidateModel extends Model { if ($this->hasAttribute($name)) { unset($this->_attributes[$name]); - } elseif (array_key_exists($name, $this->_related)) { - unset($this->_related[$name]); } elseif ($this->getRelation($name, false) === null) { parent::__unset($name); } @@ -222,7 +232,7 @@ class FormValidateModel extends Model foreach ($this->modelForm->fields() as $field) { - $result[$field->attribute] = $field->label; + $result[$field->attribute] = $field->normalName(); } return $result; diff --git a/views/admin-form-field/_form.php b/views/admin-form-field/_form.php index 2a8cc8f..a780eea 100644 --- a/views/admin-form-field/_form.php +++ b/views/admin-form-field/_form.php @@ -43,7 +43,9 @@ use common\models\User; isNewRecord) : ?> field($model, 'attribute')->textInput(); ?> - field($model, 'label')->textInput(); ?> + + field($model, 'name')->textInput()->hint('В момент отправки данных формы, будет использоваться это название.'); ?> + field($model, 'label')->textInput()->hint('В момент отправки данных формы, будет использоваться это название.');; ?> field($model, 'hint')->textInput(); ?> field($model, 'rules')->widget( \skeeks\widget\chosen\Chosen::className(), diff --git a/views/admin-form/_form.php b/views/admin-form/_form.php index 689b72a..d786734 100644 --- a/views/admin-form/_form.php +++ b/views/admin-form/_form.php @@ -76,7 +76,7 @@ use common\models\User; 'sortable' => true, 'columns' => [ //['class' => 'yii\grid\SerialColumn'], - 'attribute', + 'name', 'label', 'hint', ], diff --git a/widgets/ActiveForm.php b/widgets/ActiveForm.php index 82c44b9..b76ddb1 100644 --- a/widgets/ActiveForm.php +++ b/widgets/ActiveForm.php @@ -69,7 +69,7 @@ class ActiveForm extends \skeeks\cms\base\widgets\ActiveForm var response = data.response; if (response.success == true) { - $('input', Jform).each(function(i,s) + $('input, select, textarea', Jform).each(function(i,s) { if ($(this).attr('name') != '_csrf' && $(this).attr('name') != 'sx-auto-form') {