Module.php 4.86 KB
<?php

namespace frontend\modules\forms;

use yii\base\InvalidConfigException;
use yii\helpers\Html;
use yii\web\View;
use yii\widgets\ActiveForm;


/**
 * Module for generation forms adn saving data from frontend
 *
 * @package artbox\core\forms
 */
class Module extends \yii\base\Module
{
	/**
	 * ActiveRecord for insert to db
	 *
	 * @var null
	 */
	public $templateForm = '{form}';

	public $activeRecord = null;

	/**
	 * attributes which render in form
	 *
	 * @var array
	 */
	public $attributes = [];

	/**
	 * validation rules for DynamicModel
	 *
	 * @var array
	 */
	public $rules = [];

	/**
	 * scenario for ActiveRecord
	 *
	 * @var string
	 */
	public $scenario = 'default';

	/**
	 * Input types for attributes. textinput default
	 *
	 * @var array
	 */
	public $inputOptions = [];

	/**
	 * Labels by form (if ActiveRecord is null)
	 *
	 * @var array
	 */
	public $labels = [];

	/**
	 * Send or not email
	 *
	 * @var bool
	 */
	public $sendEmail = true;

	/**
	 * Email address
	 *
	 * @var string
	 */
	public $email = 'admin@example.com';

	/**
	 * Email template
	 *
	 * @var string
	 */
	public $emailFile = 'mail.php';

	/**
	 * Email subject
	 *
	 * @var string
	 */
	public $subject = '';

	/**
	 * mailer which send email
	 *
	 * @var null
	 */
	public $mailer = null;

	/**
	 * @var \yii\db\ActiveRecord $model ;
	 */
	public $model = null;

	/**
	 * send form with ajax
	 *
	 * @var bool
	 */
	public $ajax = false;

	/**
	 * callback function for ajax script of send form
	 *
	 * @var string
	 */
	public $successCallback = 'function (data) {
            alert("ok");
        }';

	/**
	 * error function for ajax script of send form
	 *
	 * @var string
	 */
	public $errorCallback = 'function (data) {
            alert("error");
        }';

	/**
	 * id form
	 *
	 * @var string
	 */
	public $formId = 'dynamic-form';

	/**
	 * options for submit button
	 *
	 * @var array
	 */
	public $buttonOptions = ['class' => 'btn'];

	/**
	 * content for submit button
	 *
	 * @var string
	 */
	public $buttonContent = 'Save';

	/**
	 * @var string
	 */
	public $classForm = 'form';

	public $id = 'forms';

	public $buttonTemplate = '{button}';

	public $locale = 'app';

	/**
	 * @inheritdoc
	 * @throws \yii\base\InvalidConfigException
	 */
	public function init()
	{
		parent::init();

		if ($this->activeRecord !== null) {
			$this->model = \Yii::createObject($this->activeRecord);
			$this->model->scenario = $this->scenario;
		} else {
			$this->model = new DynamicModel($this->attributes);
			$this->model->attributeLabels = $this->labels;
			foreach ($this->rules as $rule) {
				if (is_array($rule) && isset($rule[0], $rule[1])) {
					$attributes = $rule[0];
					$validator = $rule[1];
					unset($rule[0], $rule[1]);
					$this->model->addRule($attributes, $validator, $rule);
				} else {
					throw new InvalidConfigException(
						'Invalid validation rule: a rule must specify both attribute names and validator type.'
					);
				}
			}
		}
	}

	/**
	 * render html form with model
	 *
	 * @param \yii\web\View $view
	 */
	public function renderForm(View $view)
	{
		if ($this->ajax) {
			$js = <<<JS
$(document).on('submit', '#{$this->formId}', function(e) {
        e.preventDefault();
        e.stopImmediatePropagation();
        $.post(
            $(this).attr("action"), $(this).serialize(), {$this->successCallback}).fail({$this->errorCallback});
});
JS;

			$view->registerJs($js, View::POS_READY);
		}
		/**
		 * @var ActiveForm $form
		 */

		$form = ActiveForm::begin(
			[
				'id' => $this->formId,
				'action' => ($this->ajax) ? '/' . $this->id . '/save/ajax' : '/' . $this->id . '/save/no-ajax',
				'class' => $this->classForm,
			]
		);

		$content = '';
		foreach ($this->attributes as $field) {

			# если мы присвоили этому полю тип, то он его отрисовывает
			if (isset($this->inputOptions[$field]['type'])) {
				$function = $this->inputOptions[$field]['type'];
				$formStr = $form->field($this->model, $field)
					->$function(
						isset($this->inputOptions[$field]['options'])
							? $this->inputOptions[$field]['options'] : []
					);
			} # а если нет, то просто добавляет поле
			else {
				$formStr = $form->field($this->model, $field);
			}
			if (isset($this->labels[$field])) {
				$formStr->label(\Yii::t($this->locale, $this->labels[$field]));
			}
			if (isset($this->inputOptions[$field]['template'])) {

				$formStr = str_replace('{input}', $formStr, $this->inputOptions[$field]['template']);
			}
			$content .= $formStr;

		}
		$content .= $form->field($this->model, 'reCaptcha')->widget(\sashsvamir\yii2\recaptcha\ReCaptcha::className())->label(false);


		$content .= str_replace('{button}', Html::submitButton(\Yii::t($this->locale, $this->buttonContent), $this->buttonOptions), $this->buttonTemplate);
		$content = str_replace('{form}', $content, $this->templateForm);
		echo $content;
		ActiveForm::end();
	}
}