From 7d27736a029417476ab25d13511b49a6be9137f8 Mon Sep 17 00:00:00 2001 From: RedHood Date: Fri, 25 Dec 2020 11:14:41 +1000 Subject: [PATCH] =?UTF-8?q?=D0=9F=D0=B5=D1=80=D0=B5=D1=80=D0=B0=D0=B1?= =?UTF-8?q?=D0=BE=D1=82=D0=BA=D0=B0=20=D1=80=D0=B5=D0=B3=D0=B8=D1=81=D1=82?= =?UTF-8?q?=D1=80=D0=B0=D1=86=D0=B8=D0=B8=20=D0=B8=20=D0=B0=D1=83=D1=82?= =?UTF-8?q?=D0=B5=D0=BD=D1=82=D0=B8=D1=84=D0=B8=D0=BA=D0=B0=D1=86=D0=B8?= =?UTF-8?q?=D0=B8=20=D0=B2=20=D0=B5=D0=B4=D0=B8=D0=BD=D1=83=D1=8E=20=D0=BC?= =?UTF-8?q?=D0=BE=D0=B4=D0=B5=D0=BB=D1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../skillparts/system/config/web.php.example | 2 +- .../system/controllers/SiteController.php | 128 +++++++-------- mirzaev/skillparts/system/models/Account.php | 19 ++- .../skillparts/system/models/AccountForm.php | 151 ++++++++++++++++++ .../system/models/AuthenticationForm.php | 91 ----------- .../system/models/RegistrationForm.php | 28 ---- .../skillparts/system/views/site/account.php | 34 ++++ .../system/views/site/authentication.php | 51 ------ .../skillparts/system/views/site/profile.php | 63 ++++++++ .../system/views/site/registration.php | 21 --- mirzaev/skillparts/system/web/css/main.css | 1 + mirzaev/skillparts/system/web/js/account.js | 114 +++++++++---- 12 files changed, 409 insertions(+), 294 deletions(-) create mode 100644 mirzaev/skillparts/system/models/AccountForm.php delete mode 100644 mirzaev/skillparts/system/models/AuthenticationForm.php delete mode 100644 mirzaev/skillparts/system/models/RegistrationForm.php create mode 100644 mirzaev/skillparts/system/views/site/account.php delete mode 100644 mirzaev/skillparts/system/views/site/authentication.php create mode 100644 mirzaev/skillparts/system/views/site/profile.php delete mode 100644 mirzaev/skillparts/system/views/site/registration.php diff --git a/mirzaev/skillparts/system/config/web.php.example b/mirzaev/skillparts/system/config/web.php.example index 9934e07..3943420 100644 --- a/mirzaev/skillparts/system/config/web.php.example +++ b/mirzaev/skillparts/system/config/web.php.example @@ -5,7 +5,7 @@ $config = [ 'basePath' => dirname(__DIR__), 'bootstrap' => ['log'], 'aliases' => [ - '@vendor' => dirname(__DIR__) . '../../../../vendor', + '@vendor' => dirname(__DIR__) . '/../../../vendor', '@bower' => '@vendor/bower-asset', '@npm' => '@vendor/npm-asset', '@explosivebit' => '@vendor/explosivebit', diff --git a/mirzaev/skillparts/system/controllers/SiteController.php b/mirzaev/skillparts/system/controllers/SiteController.php index bd9eeec..1ff2c5d 100644 --- a/mirzaev/skillparts/system/controllers/SiteController.php +++ b/mirzaev/skillparts/system/controllers/SiteController.php @@ -7,10 +7,8 @@ use yii\filters\AccessControl; use yii\web\Controller; use yii\web\Response; use yii\filters\VerbFilter; -use app\models\AuthenticationForm; -use app\models\RegistrationForm; +use app\models\AccountForm; use app\models\ContactForm; -use app\models\Account; class SiteController extends Controller { @@ -106,13 +104,15 @@ class SiteController extends Controller */ public function actionAuthentication() { - $model = new AuthenticationForm(Yii::$app->request->post()['AuthenticationForm'] ?? Yii::$app->request->get()['AuthenticationForm']); + $model = new AccountForm(Yii::$app->request->post()['AccountForm'] ?? Yii::$app->request->get()['AccountForm'] ?? null); if (Yii::$app->request->isAjax) { // AJAX-POST-запрос + Yii::$app->response->format = Response::FORMAT_JSON; + if (!Yii::$app->user->isGuest) { - // Аккаунт уже авторизован + // Аккаунт уже аутентифицирован Yii::$app->response->statusCode = 403; return [ 'form' => $this->renderPartial('index'), @@ -120,26 +120,27 @@ class SiteController extends Controller ]; } - Yii::$app->response->format = Response::FORMAT_JSON; + if ($model->authentication()) { + // Данные прошли проверку - if (isset($model->mail, $model->pswd)) { - if ($model->load(Yii::$app->request->post()) && $model->authentication()) { - return [ - 'menu' => << - - - Выход ($model->mail) -

- HTML, - 'form' => $this->renderPartial('index'), - '_csrf' => Yii::$app->request->getCsrfToken() - ]; - } - } else { return [ - 'menu' => 'Вход', - 'form' => $this->renderPartial('authentication', compact('model')), + 'menu' => << + + + Выход ($model->mail) +

+ HTML, + 'form' => $this->renderPartial('index'), + '_csrf' => Yii::$app->request->getCsrfToken() + ]; + } else { + // Данные не прошли проверку + + Yii::$app->response->statusCode = 400; + + return [ + 'form' => $this->renderPartial('account', compact('model')), '_csrf' => Yii::$app->request->getCsrfToken() ]; } @@ -149,7 +150,7 @@ class SiteController extends Controller // GET-запрос и прочие if (!Yii::$app->user->isGuest) { - // Аккаунт уже авторизован + // Аккаунт уже аутентифицирован Yii::$app->response->redirect('/'); } } @@ -172,7 +173,6 @@ class SiteController extends Controller return [ 'menu' => 'Вход', - 'form' => $this->renderPartial('index'), '_csrf' => Yii::$app->request->getCsrfToken() ]; } @@ -187,13 +187,16 @@ class SiteController extends Controller */ public function actionRegistration() { - $model = new RegistrationForm(Yii::$app->request->post()['RegistrationForm'] ?? Yii::$app->request->get()['RegistrationForm']); + $model = new AccountForm(Yii::$app->request->post()['AccountForm'] ?? Yii::$app->request->get()['AccountForm'] ?? null); + $model->type = 0; if (Yii::$app->request->isAjax) { // AJAX-POST-запрос + Yii::$app->response->format = Response::FORMAT_JSON; + if (!Yii::$app->user->isGuest) { - // Аккаунт уже авторизован + // Аккаунт уже аутентифицирован Yii::$app->response->statusCode = 302; return [ 'form' => $this->renderPartial('index'), @@ -201,46 +204,27 @@ class SiteController extends Controller ]; } - Yii::$app->response->format = Response::FORMAT_JSON; - - if (isset($model->mail, $model->pswd)) { - // Аккаунт передал необходимые параметры - - // Инициализация нового аккаунта - $account = new Account(); - $account->mail = $model->mail; - $account->pswd = Yii::$app->security->generatePasswordHash($model->pswd); - - if ($model->load(Yii::$app->request->post()) && $model->validate() && $account->save()) { - // Данные прошли проверку и аккаунт был создан - - return [ - 'menu' => << - - - Выход ($account->mail) -

- HTML, - 'form' => $this->renderPartial('index'), - '_csrf' => Yii::$app->request->getCsrfToken() - ]; - } else { - // Данные не прошли проверку - - Yii::$app->response->statusCode = 400; - - return [ - 'form' => $this->renderPartial('registration', compact('model')), - '_csrf' => Yii::$app->request->getCsrfToken() - ]; - } - } else { - // Аккаунт не передал необходимые параметры + if ($model->registration()) { + // Данные прошли проверку и аккаунт был создан return [ - 'menu' => 'Вход', - 'form' => $this->renderPartial('registration', compact('model')), + 'menu' => << + + + Выход ($model->mail) +

+ HTML, + 'form' => $this->renderPartial('index'), + '_csrf' => Yii::$app->request->getCsrfToken() + ]; + } else { + // Данные не прошли проверку + + Yii::$app->response->statusCode = 400; + + return [ + 'form' => $this->renderPartial('account', compact('model')), '_csrf' => Yii::$app->request->getCsrfToken() ]; } @@ -251,7 +235,7 @@ class SiteController extends Controller // GET-запрос и прочие if (!Yii::$app->user->isGuest) { - // Аккаунт уже авторизован + // Аккаунт уже аутентифицирован Yii::$app->response->redirect('/'); } } @@ -259,6 +243,18 @@ class SiteController extends Controller return $this->render('registration', compact('model')); } + /** + * Displays профиль + * + * @return Response|string + */ + public function actionProfile() + { + $model = new Account(); + + return $this->render('profile', compact('model')); + } + /** * Displays contact page. * diff --git a/mirzaev/skillparts/system/models/Account.php b/mirzaev/skillparts/system/models/Account.php index 576325b..9126749 100644 --- a/mirzaev/skillparts/system/models/Account.php +++ b/mirzaev/skillparts/system/models/Account.php @@ -57,7 +57,7 @@ class Account extends ActiveRecord implements IdentityInterface */ public static function findIdentity($mail) { - return static::findOne(['mail' => $mail]); + return static::findByMail($mail); } /** @@ -82,6 +82,23 @@ class Account extends ActiveRecord implements IdentityInterface return static::findOne(['mail' => $mail]); } + /** + * Validates mail + * + * @param string $pswd password to validate + * @return bool if password provided is valid for current user + */ + public function validateMail($mail) + { + if (static::findByMail($mail)) { + // Почта найдена в базе данных + + return false; + } + + return true; + } + /** * Validates password * diff --git a/mirzaev/skillparts/system/models/AccountForm.php b/mirzaev/skillparts/system/models/AccountForm.php new file mode 100644 index 0000000..132e014 --- /dev/null +++ b/mirzaev/skillparts/system/models/AccountForm.php @@ -0,0 +1,151 @@ + 'Заполните поле'], + // Функция "Запомнить меня" + ['auto', 'boolean'], + // Проверка почты + ['mail', 'validateMail', 'message'=>'Неправильная почта'], + // Проверка пароля + ['pswd', 'validatePassword', 'message'=>'Неправильный пароль'], + ]; + } + + public function attributeLabels() + { + return [ + 'mail' => 'Почта', + 'pswd' => 'Пароль', + 'auto' => 'Запомнить' + ]; + } + + /** + * @param string $attribute the attribute currently being validated + * @param array $params the additional name-value pairs given in the rule + */ + public function validateMail($attribute, $params) + { + if (!$this->hasErrors() && $this->type === 0) { + // Проблем нет, обрабатывается событие регистрации + + $account = $this->getAccount(); + + if (!$account || !$account->validateMail($this->mail)) { + // Проверка не пройдена + $this->addError($attribute, 'Почта уже привязана к другому аккаунту'); + } + } + } + + /** + * Validates the password. + * This method serves as the inline validation for password. + * + * @param string $attribute the attribute currently being validated + * @param array $params the additional name-value pairs given in the rule + */ + public function validatePassword($attribute, $params) + { + if (!$this->hasErrors() && $this->type === 1) { + // Проблем нет, обрабатывается событие аутентификации + + $account = $this->getAccount(); + + if (!$account || !$account->validatePassword($this->pswd)) { + // Проверка не пройдена + + $this->addError($attribute, 'Проверьте входные данные'); + } + } + } + + /** + * Logs in a account using the provided accountname and password. + * @return bool whether the account is logged in successfully + */ + public function authentication() + { + if (isset($this->mail, $this->pswd) && $this->validate()) { + // Проверка пройдена + + // Аутентификация + return Yii::$app->user->login($this->getAccount(), $this->auto ? 3600*24*30 : 0); + } + + return false; + } + + /** + * @return bool + */ + public function registration() + { + // Инициализация нового аккаунта + $this->account = new Account(); + + if (isset($this->mail, $this->pswd) && $this->validate()) { + // Проверка пройдена + + // Запись параметров + $this->account->mail = $this->mail; + $this->account->pswd = Yii::$app->security->generatePasswordHash($this->pswd); + + // Регистрация + return $this->account->save(); + } + + return false; + } + + /** + * Finds account by [[accountname]] + * + * @return Account|null + */ + public function getAccount() + { + if ($this->account === false) { + $this->account = Account::findByMail($this->mail); + } + + return $this->account; + } +} diff --git a/mirzaev/skillparts/system/models/AuthenticationForm.php b/mirzaev/skillparts/system/models/AuthenticationForm.php deleted file mode 100644 index 24b2425..0000000 --- a/mirzaev/skillparts/system/models/AuthenticationForm.php +++ /dev/null @@ -1,91 +0,0 @@ - 'Почта', - 'pswd' => 'Пароль', - 'auto' => 'Запомнить' - ]; - } - - /** - * Validates the password. - * This method serves as the inline validation for password. - * - * @param string $attribute the attribute currently being validated - * @param array $params the additional name-value pairs given in the rule - */ - public function validatePassword($attribute, $params) - { - if (!$this->hasErrors()) { - $account = $this->getAccount(); - - if (!$account || !$account->validatePassword($this->pswd)) { - $this->addError($attribute, 'Не удалось идентифицировать'); - } - } - } - - /** - * Logs in a account using the provided accountname and password. - * @return bool whether the account is logged in successfully - */ - public function authentication() - { - if ($this->validate()) { - return Yii::$app->user->login($this->getAccount(), $this->auto ? 3600*24*30 : 0); - } - return false; - } - - /** - * Finds account by [[accountname]] - * - * @return Account|null - */ - public function getAccount() - { - if ($this->account === false) { - $this->account = Account::findByMail($this->mail); - } - - return $this->account; - } -} diff --git a/mirzaev/skillparts/system/models/RegistrationForm.php b/mirzaev/skillparts/system/models/RegistrationForm.php deleted file mode 100644 index 23364b0..0000000 --- a/mirzaev/skillparts/system/models/RegistrationForm.php +++ /dev/null @@ -1,28 +0,0 @@ - 'Заполните поле'], - ['mail', 'unique', 'targetClass' => Account::class, 'message' => 'Почта уже привязана к другому аккаунту'], - ]; - } - - public function attributeLabels() - { - return [ - 'mail' => 'Почта', - 'pswd' => 'Пароль', - ]; - } -} diff --git a/mirzaev/skillparts/system/views/site/account.php b/mirzaev/skillparts/system/views/site/account.php new file mode 100644 index 0000000..6f03fe6 --- /dev/null +++ b/mirzaev/skillparts/system/views/site/account.php @@ -0,0 +1,34 @@ + + +
+
+
+ 'form_account', + 'action' => false, + 'fieldConfig' => [ + 'template' => "{label}\n
{input}
\n
{error}
" + ], + 'options' => [ + 'onsubmit' => 'return false;' + ] + ]); ?> + + field($model, 'mail')->textInput(['autofocus' => true]) ?> + field($model, 'pswd')->passwordInput() ?> + field($model, 'auto')->checkbox() ?> + +
+ 'submit', 'onclick' => 'authentication(this.parentElement.parentElement);', 'class' => 'btn btn-primary col-4']) ?> + 'submit', 'onclick' => 'registration(this.parentElement.parentElement);', 'class' => 'btn btn-success col-7 ml-auto']) ?> +
+ + +
+
+
\ No newline at end of file diff --git a/mirzaev/skillparts/system/views/site/authentication.php b/mirzaev/skillparts/system/views/site/authentication.php deleted file mode 100644 index eb8d1b1..0000000 --- a/mirzaev/skillparts/system/views/site/authentication.php +++ /dev/null @@ -1,51 +0,0 @@ -title = 'Login'; -?> - -
-

title) ?>

- -

Please fill out the following fields to login:

- - 'form_authentication', - 'layout' => 'horizontal', - 'fieldConfig' => [ - 'template' => "{label}\n
{input}
\n
{error}
", - 'labelOptions' => ['class' => 'col-lg-1 control-label'], - ], - 'action' => false, - 'options' => [ - 'onsubmit' => 'authentication(this); return false;' - ] - ]); ?> - - field($model, 'mail')->textInput(['autofocus' => true]) ?> - - field($model, 'pswd')->passwordInput() ?> - - field($model, 'auto')->checkbox([ - 'template' => "
{input} {label}
\n
{error}
", - ]) ?> - -
-
- 'btn btn-primary', 'name' => 'login-button']) ?> -
-
- - - -
- You may login with admin/admin or demo/demo.
- To modify the username/password, please check out the code app\models\User::$users. -
-
\ No newline at end of file diff --git a/mirzaev/skillparts/system/views/site/profile.php b/mirzaev/skillparts/system/views/site/profile.php new file mode 100644 index 0000000..518a949 --- /dev/null +++ b/mirzaev/skillparts/system/views/site/profile.php @@ -0,0 +1,63 @@ +params['breadcrumbs'][] = $this->title; +?> +
+

title) ?>

+ + session->hasFlash('contactFormSubmitted')): ?> + +
+ Thank you for contacting us. We will respond to you as soon as possible. +
+ +

+ Note that if you turn on the Yii debugger, you should be able + to view the mail message on the mail panel of the debugger. + mailer->useFileTransport): ?> + Because the application is in development mode, the email is not sent but saved as + a file under mailer->fileTransportPath) ?>. + Please configure the useFileTransport property of the mail + application component to be false to enable email sending. + +

+ + + +

+ If you have business inquiries or other questions, please fill out the following form to contact us. + Thank you. +

+ +
+
+ + 'contact-form']); ?> + + field($model, 'name')->textInput(['autofocus' => true]) ?> + + field($model, 'email') ?> + + field($model, 'subject') ?> + + field($model, 'body')->textarea(['rows' => 6]) ?> + + field($model, 'verifyCode')->widget(Captcha::className(), [ + 'template' => '
{image}
{input}
', + ]) ?> + +
+ 'btn btn-primary', 'name' => 'contact-button']) ?> +
+ + + +
+
+ + +
diff --git a/mirzaev/skillparts/system/views/site/registration.php b/mirzaev/skillparts/system/views/site/registration.php deleted file mode 100644 index f293303..0000000 --- a/mirzaev/skillparts/system/views/site/registration.php +++ /dev/null @@ -1,21 +0,0 @@ - - - 'form_registration', - 'action' => false, - 'options' => [ - 'onsubmit' => 'registration(this); return false;' - ] -]) ?> -field($model, 'mail') ?> -field($model, 'pswd')->passwordInput() ?> -
-
- 'btn btn-success']) ?> -
-
- \ No newline at end of file diff --git a/mirzaev/skillparts/system/web/css/main.css b/mirzaev/skillparts/system/web/css/main.css index a88885c..8188513 100644 --- a/mirzaev/skillparts/system/web/css/main.css +++ b/mirzaev/skillparts/system/web/css/main.css @@ -25,6 +25,7 @@ body { main { flex-grow: 1; + display: grid; background-color: #f0eefb; } diff --git a/mirzaev/skillparts/system/web/js/account.js b/mirzaev/skillparts/system/web/js/account.js index aa84db9..923dc12 100644 --- a/mirzaev/skillparts/system/web/js/account.js +++ b/mirzaev/skillparts/system/web/js/account.js @@ -3,21 +3,26 @@ function identification() { url: '/identification', type: 'post', dataType: 'json', - data: { '_csrf': yii.getCsrfToken() }, + data: { + '_csrf': yii.getCsrfToken() + }, success: function (data) { // Обновление документа - document.getElementById('nav').innerHTML = data.menu; - $('meta[name=csrf-token]').prop("content", data._csrf); - - // Реинициализация - reinitialization(); + if (data.menu != undefined) { + document.getElementById('nav').innerHTML = data.menu; + } + if (data._csrf != undefined) { + $('meta[name=csrf-token]').prop("content", data._csrf); + } } }); }; function authentication(form) { if (form == undefined) { - form = { '_csrf': yii.getCsrfToken() }; + form = { + '_csrf': yii.getCsrfToken() + }; } else { form = $(form).serialize(); } @@ -29,9 +34,15 @@ function authentication(form) { data: form, success: function (data, status) { // Обновление документа - document.getElementById('nav').innerHTML = data.menu; - document.getElementsByTagName('main')[0].innerHTML = data.form; - $('meta[name=csrf-token]').prop("content", data._csrf); + if (data.menu != undefined) { + document.getElementById('nav').innerHTML = data.menu; + } + if (data.form != undefined) { + document.getElementsByTagName('main')[0].innerHTML = data.form; + } + if (data._csrf != undefined) { + $('meta[name=csrf-token]').prop("content", data._csrf); + } // Перенаправление history.pushState({}, document.title, '/'); @@ -40,11 +51,18 @@ function authentication(form) { reinitialization(); }, error: function (data, status) { - // Обновление документа - document.getElementsByTagName('main')[0].innerHTML = data.responseJSON.form; - $('meta[name=csrf-token]').prop("content", data.responseJSON._csrf); + if (data.responseJSON.form != undefined) { + // Обновление документа + document.getElementsByTagName('main')[0].innerHTML = data.responseJSON.form; + // Реинициализация + reinitialization(); + } + if (data.responseJSON._csrf != undefined) { + // Обновление документа + $('meta[name=csrf-token]').prop("content", data.responseJSON._csrf); + } - if (statis === 403) { + if (status === 403) { // Перенаправление history.pushState({}, document.title, '/'); } @@ -62,50 +80,76 @@ function deauthentication() { dataType: 'json', data: { '_csrf': yii.getCsrfToken() }, success: function (data) { - // Обновление документа - document.getElementById('nav').innerHTML = data.menu; - document.getElementsByTagName('main')[0].innerHTML = data.form; - $('meta[name=csrf-token]').prop("content", data._csrf); + if (data.menu != undefined) { + // Обновление документа + document.getElementById('nav').innerHTML = data.menu; + } + if (data.form != undefined) { + // Обновление документа + document.getElementsByTagName('main')[0].innerHTML = data.form; + // Реинициализация + reinitialization(); + } + if (data._csrf != undefined) { + // Обновление документа + $('meta[name=csrf-token]').prop("content", data._csrf); + } // Перенаправление history.pushState({}, document.title, '/'); - - // Реинициализация - reinitialization(); } }); }; function registration(form) { + if (form == undefined) { + form = { + '_csrf': yii.getCsrfToken() + }; + } else { + form = $(form).serialize(); + } + $.ajax({ url: '/registration', type: 'post', dataType: 'json', - data: $(form).serialize(), + data: form, success: function (data) { - // Обновление документа - document.getElementById('nav').innerHTML = data.menu; - document.getElementsByTagName('main')[0].innerHTML = data.form; - $('meta[name=csrf-token]').prop("content", data._csrf); + if (data.menu != undefined) { + // Обновление документа + document.getElementById('nav').innerHTML = data.menu; + } + if (data.form != undefined) { + // Обновление документа + document.getElementsByTagName('main')[0].innerHTML = data.form; + // Реинициализация + reinitialization(); + } + if (data._csrf != undefined) { + // Обновление документа + $('meta[name=csrf-token]').prop("content", data._csrf); + } // Перенаправление history.pushState({}, document.title, '/'); - - // Реинициализация - reinitialization(); }, error: function (data) { - // Обновление документа - document.getElementsByTagName('main')[0].innerHTML = data.responseJSON.form; - $('meta[name=csrf-token]').prop("content", data.responseJSON._csrf); + if (data.responseJSON.form != undefined) { + // Обновление документа + document.getElementsByTagName('main')[0].innerHTML = data.responseJSON.form; + // Реинициализация + reinitialization(); + } + if (data.responseJSON._csrf != undefined) { + // Обновление документа + $('meta[name=csrf-token]').prop("content", data.responseJSON._csrf); + } if (statis === 403) { // Перенаправление history.pushState({}, document.title, '/'); } - - // Реинициализация - reinitialization(); } }); };