From 20400cf90d98dd82503e0b8f8da8faaa727a812c Mon Sep 17 00:00:00 2001 From: Antonio Ramirez Date: Sun, 15 Oct 2017 22:11:35 +0200 Subject: [PATCH] Close #55 add google captcha mechanism --- CHANGELOG.md | 1 + composer.json | 1 + .../how-to-use-recaptcha-widget.md | 142 +++++++++++++++ src/User/Command/CreateController.php | 1 - src/User/Component/ReCaptchaComponent.php | 75 ++++++++ src/User/Controller/RecoveryController.php | 3 +- src/User/Controller/SecurityController.php | 12 +- src/User/Controller/SettingsController.php | 13 +- src/User/Form/LoginForm.php | 4 +- src/User/Helper/MigrationHelper.php | 9 + .../TwoFactorQrCodeUriGeneratorService.php | 10 +- src/User/Validator/ReCaptchaValidator.php | 68 ++++++++ src/User/Validator/TwoFactorCodeValidator.php | 9 + src/User/Widget/ReCaptchaWidget.php | 163 ++++++++++++++++++ src/User/resources/i18n/ca/usuario.php | 21 +-- src/User/resources/i18n/da/usuario.php | 21 +-- src/User/resources/i18n/de-DU/usuario.php | 21 +-- src/User/resources/i18n/de/usuario.php | 21 +-- src/User/resources/i18n/es/usuario.php | 21 +-- src/User/resources/i18n/fa-IR/usuario.php | 21 +-- src/User/resources/i18n/fi/usuario.php | 21 +-- src/User/resources/i18n/fr/usuario.php | 21 +-- src/User/resources/i18n/hr/usuario.php | 21 +-- src/User/resources/i18n/hu/usuario.php | 21 +-- src/User/resources/i18n/it/usuario.php | 21 +-- src/User/resources/i18n/kk/usuario.php | 21 +-- src/User/resources/i18n/lt/usuario.php | 21 +-- src/User/resources/i18n/nl/usuario.php | 21 +-- src/User/resources/i18n/pl/usuario.php | 21 +-- src/User/resources/i18n/pt-BR/usuario.php | 21 +-- src/User/resources/i18n/pt-PT/usuario.php | 21 +-- src/User/resources/i18n/ro/usuario.php | 21 +-- src/User/resources/i18n/ru/usuario.php | 21 +-- src/User/resources/i18n/th/usuario.php | 21 +-- src/User/resources/i18n/tr_TR/usuario.php | 21 +-- src/User/resources/i18n/uk/usuario.php | 21 +-- src/User/resources/i18n/vi/usuario.php | 21 +-- src/User/resources/i18n/zh-CN/usuario.php | 21 +-- src/User/resources/views/admin/index.php | 2 +- src/User/resources/views/settings/account.php | 4 +- 40 files changed, 660 insertions(+), 361 deletions(-) create mode 100644 docs/helpful-guides/how-to-use-recaptcha-widget.md create mode 100644 src/User/Component/ReCaptchaComponent.php create mode 100644 src/User/Validator/ReCaptchaValidator.php create mode 100644 src/User/Widget/ReCaptchaWidget.php diff --git a/CHANGELOG.md b/CHANGELOG.md index e30f1a0..66e6cc0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # CHANGELOG ## 1.0.14 - Work in progress +- Enh #55: Provide google recaptcha mechanism (tonydspaniard) - Fix #20: Allow the assignment of a role on user creation via console (tonydspaniard) - Fix #59: Add instructions to add rbac migration path (tonydspaniard) - Fix #68: Fix user events documentation and events raised from User model (tonydspaniard) diff --git a/composer.json b/composer.json index a36d882..8280b34 100644 --- a/composer.json +++ b/composer.json @@ -49,6 +49,7 @@ "php": ">=5.5", "2amigos/yii2-selectize-widget": "^1.1", "yiisoft/yii2-authclient": "^2.1", + "yiisoft/yii2-httpclient": "^2.0", "yiisoft/yii2-bootstrap": "^2.0", "yiisoft/yii2-swiftmailer": "^2.0", "2amigos/2fa-library": "^1.0", diff --git a/docs/helpful-guides/how-to-use-recaptcha-widget.md b/docs/helpful-guides/how-to-use-recaptcha-widget.md new file mode 100644 index 0000000..2bb9dd3 --- /dev/null +++ b/docs/helpful-guides/how-to-use-recaptcha-widget.md @@ -0,0 +1,142 @@ +How to Use ReCaptcha Widget +============================ + +We have included a [Google ReCAPTCHA](https://developers.google.com/recaptcha) widget if you wish to use it instead of +Yii's captcha. The widget is based on reCaptcha v2.0. + +To make use of the widget you need to: + +- [Signup for a reCaptcha API site key](https://www.google.com/recaptcha/admin#createsite) +- Configure the `ReCaptchaComponent` on the `components` section of your application configuration +- Override the Form class you wish to add the captcha rule to +- Override the view where the form is rendering +- Configure Module and Application + +Configuring the ReCaptchaComponent +---------------------------------- + +Once you have the API site key you will also be displayed a secret key. You have to configure the component as follows: + +```php +'components' => [ + 'recaptcha' => [ // *important* this name must be like this + 'class' => 'Da\User\Component\ReCaptchaComponent', + 'key' => 'yourSiteKey', + 'secret' => 'secretKeyGivenByGoogle + ] +] +``` + +Override the Form +----------------- + +For the sake of the example, we are going to override the `Da\User\Form\RecoveryForm` class: + +```php +namespace app\forms; + +class RecoveryForm extends Da\User\Form\RecoveryForm { + + public $captcha; + + public function rules() { + + $rules = parent::rules(); + + $rules[] = [['captcha'], 'required']; + $rules[] = [['captcha'], 'Da\User\Validator\ReCaptchaValidator']; + + return $rules; + } +} + +``` + +Overriding the View +------------------- + +Create a new file and name it `request.php` and add it in `@app/views/user/recovery`. Add the captcha widget to it: + +```php +title = Yii::t('usuario', 'Recover your password'); +$this->params['breadcrumbs'][] = $this->title; +?> +
+
+
+
+

title) ?>

+
+
+ $model->formName(), + 'enableAjaxValidation' => true, + 'enableClientValidation' => false, + ] + ); ?> + + field($model, 'email')->textInput(['autofocus' => true]) ?> + + field($model, 'captcha')->widget(ReCaptchaWidget::className(), ['theme' => 'dark']) ?> + + 'btn btn-primary btn-block']) ?>
+ + +
+
+
+
+ +``` + +Configure Module and Application +-------------------------------- + +Finally, we have to configure the module and the application to ensure is using our form and our view: + +```php + +// ... + +'modules' => [ + 'user' => [ + 'class' => Da\User\Module::class, + 'classMap' => [ + 'RecoveryForm' => 'app\forms\RecoveryForm' + ], + 'controllerMap' => [ + 'recovery' => [ +                 'class' => '\app\controllers\RecoveryController' + ] + ] + ] +], + +// ... + +'components' => [ + 'view' => [ + 'theme' => [ + 'pathMap' => [ + '@Da/User/resources/views' => '@app/views/user' + ] + ] + ] +] + +``` + +© [2amigos](http://www.2amigos.us/) 2013-2017 diff --git a/src/User/Command/CreateController.php b/src/User/Command/CreateController.php index 7f2a67b..7749a13 100644 --- a/src/User/Command/CreateController.php +++ b/src/User/Command/CreateController.php @@ -39,7 +39,6 @@ class CreateController extends Controller if (null !== $role) { $this->assignRole($user, $role); } - } else { $this->stdout(Yii::t('usuario', 'Please fix following errors:') . "\n", Console::FG_RED); foreach ($user->errors as $errors) { diff --git a/src/User/Component/ReCaptchaComponent.php b/src/User/Component/ReCaptchaComponent.php new file mode 100644 index 0000000..31f57a5 --- /dev/null +++ b/src/User/Component/ReCaptchaComponent.php @@ -0,0 +1,75 @@ + + * + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. + */ + +namespace Da\User\Component; + +use Yii; +use yii\base\Component; +use yii\base\InvalidConfigException; +use yii\httpclient\Client; + +class ReCaptchaComponent extends Component +{ + /** + * @var string the ReCAPTCHA sitekey + */ + public $key; + /** + * @var string the shared key between the site and ReCAPTCHA + */ + public $secret; + + /** + * @inheritdoc + */ + public function init() + { + if (empty($this->key)) { + throw new InvalidConfigException(Yii::t('usuario', 'Required "key" cannot be empty.')); + } + + if (empty($this->secret)) { + throw new InvalidConfigException(Yii::t('usuario', 'Required "secret" cannot be empty.')); + } + + parent::init(); + } + + /** + * Verifies whether a user response is valid or not. + * + * @param $value + * + * @return bool + */ + public function verify($value) + { + $response = (new Client( + [ + 'baseUrl' => 'https://www.google.com/recaptcha/api', + 'responseConfig' => [ + 'format' => Client::FORMAT_JSON + ] + ] + )) + ->get( + 'site/verify', + [ + 'secret' => $this->secret, + 'response' => $value, + 'remoteip' => Yii::$app->request->getUserIP() + ] + ) + ->send(); + + return $response['success'] ? : false; + } +} diff --git a/src/User/Controller/RecoveryController.php b/src/User/Controller/RecoveryController.php index 527b224..ad1f931 100644 --- a/src/User/Controller/RecoveryController.php +++ b/src/User/Controller/RecoveryController.php @@ -156,10 +156,9 @@ class RecoveryController extends Controller if ($form->load(Yii::$app->getRequest()->post())) { if ($this->make(ResetPasswordService::class, [$form->password, $token->user])->run()) { - $this->trigger(ResetPasswordEvent::EVENT_AFTER_RESET, $event); - Yii::$app->session->setFlash('success',Yii::t('usuario', 'Password has been changed')); + Yii::$app->session->setFlash('success', Yii::t('usuario', 'Password has been changed')); return $this->render( '/shared/message', diff --git a/src/User/Controller/SecurityController.php b/src/User/Controller/SecurityController.php index 082ea21..55631a9 100644 --- a/src/User/Controller/SecurityController.php +++ b/src/User/Controller/SecurityController.php @@ -37,10 +37,10 @@ class SecurityController extends Controller /** * SecurityController constructor. * - * @param string $id - * @param Module $module + * @param string $id + * @param Module $module * @param SocialNetworkAccountQuery $socialNetworkAccountQuery - * @param array $config + * @param array $config */ public function __construct( $id, @@ -117,14 +117,12 @@ class SecurityController extends Controller $event = $this->make(FormEvent::class, [$form]); if (Yii::$app->request->isAjax && $form->load(Yii::$app->request->post())) { - Yii::$app->response->format = Response::FORMAT_JSON; return ActiveForm::validate($form); } if ($form->load(Yii::$app->request->post())) { - if ($this->module->enableTwoFactorAuthentication && $form->validate()) { if ($form->getUser()->auth_tf_enabled) { Yii::$app->session->set('credentials', ['login' => $form->login, 'pwd' => $form->password]); @@ -173,18 +171,15 @@ class SecurityController extends Controller $event = $this->make(FormEvent::class, [$form]); if (Yii::$app->request->isAjax && $form->load(Yii::$app->request->post())) { - Yii::$app->response->format = Response::FORMAT_JSON; return ActiveForm::validate($form); } if ($form->load(Yii::$app->request->post())) { - $this->trigger(FormEvent::EVENT_BEFORE_LOGIN, $event); if ($form->login()) { - Yii::$app->session->set('credentials', null); $form->getUser()->updateAttributes(['last_login_at' => time()]); @@ -202,7 +197,6 @@ class SecurityController extends Controller 'module' => $this->module, ] ); - } public function actionLogout() diff --git a/src/User/Controller/SettingsController.php b/src/User/Controller/SettingsController.php index d70f765..f8fb71b 100644 --- a/src/User/Controller/SettingsController.php +++ b/src/User/Controller/SettingsController.php @@ -52,12 +52,12 @@ class SettingsController extends Controller /** * SettingsController constructor. * - * @param string $id - * @param Module $module - * @param ProfileQuery $profileQuery - * @param UserQuery $userQuery + * @param string $id + * @param Module $module + * @param ProfileQuery $profileQuery + * @param UserQuery $userQuery * @param SocialNetworkAccountQuery $socialNetworkAccountQuery - * @param array $config + * @param array $config */ public function __construct( $id, @@ -294,8 +294,7 @@ class SettingsController extends Controller throw new NotFoundHttpException(); } - if($user->updateAttributes(['auth_tf_enabled' => '0'])) - { + if ($user->updateAttributes(['auth_tf_enabled' => '0'])) { Yii::$app ->getSession() ->setFlash('success', Yii::t('usuario', 'Two-factor authorization has been disabled.')); diff --git a/src/User/Form/LoginForm.php b/src/User/Form/LoginForm.php index 380c8ac..cd171eb 100644 --- a/src/User/Form/LoginForm.php +++ b/src/User/Form/LoginForm.php @@ -53,9 +53,9 @@ class LoginForm extends Model protected $securityHelper; /** - * @param UserQuery $query + * @param UserQuery $query * @param SecurityHelper $securityHelper - * @param array $config + * @param array $config */ public function __construct(UserQuery $query, SecurityHelper $securityHelper, $config = []) { diff --git a/src/User/Helper/MigrationHelper.php b/src/User/Helper/MigrationHelper.php index e4d76bb..ed30648 100644 --- a/src/User/Helper/MigrationHelper.php +++ b/src/User/Helper/MigrationHelper.php @@ -1,5 +1,14 @@ + * + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. + */ + namespace Da\User\Helper; use RuntimeException; diff --git a/src/User/Service/TwoFactorQrCodeUriGeneratorService.php b/src/User/Service/TwoFactorQrCodeUriGeneratorService.php index 715a2fb..e407b66 100644 --- a/src/User/Service/TwoFactorQrCodeUriGeneratorService.php +++ b/src/User/Service/TwoFactorQrCodeUriGeneratorService.php @@ -1,5 +1,14 @@ + * + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. + */ + namespace Da\User\Service; use Da\TwoFA\Manager; @@ -42,5 +51,4 @@ class TwoFactorQrCodeUriGeneratorService implements ServiceInterface return $dataUri; } - } diff --git a/src/User/Validator/ReCaptchaValidator.php b/src/User/Validator/ReCaptchaValidator.php new file mode 100644 index 0000000..56f646f --- /dev/null +++ b/src/User/Validator/ReCaptchaValidator.php @@ -0,0 +1,68 @@ + + * + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. + */ + +namespace Da\User\Validator; + +use Da\User\Component\ReCaptchaComponent; +use Yii; +use yii\validators\Validator; + +class ReCaptchaValidator extends Validator +{ + /** + * @inheritdoc + */ + public $skipOnEmpty = false; + /** + * @var string the message for client validation + */ + public $notCheckedMessage; + + /** + * @inheritdoc + */ + public function init() + { + parent::init(); + + if (null === $this->message) { + $this->message = Yii::t('usuario', 'The verification code is incorrect.'); + } + } + + /** + * @inheritdoc + */ + public function clientValidateAttribute($model, $attribute, $view) + { + $message = addslashes( + $this->notCheckedMessage ?: Yii::t('usuario', '{0} cannot be blank.', $model->getAttributeLabel($attribute)) + ); + + return "(function(messages){if(!grecaptcha.getResponse()){messages.push('{$message}');}})(messages);"; + } + + /** + * @inheritdoc + */ + protected function validateValue($value) + { + if (empty($value)) { + if (!($value = Yii::$app->request->post('g-recaptcha-response'))) { + return [$this->message, []]; + } + } + /** @var ReCaptchaComponent $recaptcha */ + $recaptcha = Yii::$app->get('recaptcha'); + + return $recaptcha->verify($value) ? null : [$this->message, []]; + } +} diff --git a/src/User/Validator/TwoFactorCodeValidator.php b/src/User/Validator/TwoFactorCodeValidator.php index 405ea24..fe9822d 100644 --- a/src/User/Validator/TwoFactorCodeValidator.php +++ b/src/User/Validator/TwoFactorCodeValidator.php @@ -1,5 +1,14 @@ + * + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. + */ + namespace Da\User\Validator; use Da\TwoFA\Manager; diff --git a/src/User/Widget/ReCaptchaWidget.php b/src/User/Widget/ReCaptchaWidget.php new file mode 100644 index 0000000..7f8883a --- /dev/null +++ b/src/User/Widget/ReCaptchaWidget.php @@ -0,0 +1,163 @@ + + * + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. + */ + +namespace Da\User\Widget; + +use Yii; +use yii\base\InvalidConfigException; +use yii\helpers\Html; +use yii\web\View; +use yii\widgets\InputWidget; + +class ReCaptchaWidget extends InputWidget +{ + /** + * @var string the color theme of the widget. Values can be 'dark' or 'light'. Optional. + */ + public $theme; + /** + * @var string the type of captcha. Values can be 'audio' or 'image'. Optional. + */ + public $type; + /** + * @var string the size of the widget. Values can be 'compact' or 'normal'. Optional. + */ + public $size; + /** + * @var string the tabindex of the widget and challenge. Optional. + */ + public $tabIndex; + /** + * @var string the name of the callbaqck function to be executed when the user submits a + * successful CAPTCHA response. The user's response, *g-recaptcha-response*, will be the input + * for the callback function. Optional. + */ + public $callback; + /** + * @var string the name of the callback function to be executed when the recaptcha response + * expires and the user needs to solve a new CAPTCHA. + */ + public $expiredCallback; + + /** + * @inheritdoc + */ + public function init() + { + if (Yii::$app->get('recaptcha')) { + throw new InvalidConfigException(Yii::t('usuario', 'The "recaptcha" component must be configured.')); + } + + parent::init(); + + $this->registerClientScript(); + } + + /** + * @inheritdoc + */ + public function run() + { + $html = []; + + $html[] = $this->hasModel() + ? Html::activeHiddenInput($this->model, $this->attribute, $this->options) + : Html::hiddenInput($this->name, null, $this->options); + + $html[] = Html::tag('div', '', $this->getCaptchaOptions()); + + return implode("\n", $html); + } + + /** + * @return array the google recaptcha options. + */ + protected function getCaptchaOptions() + { + $data = [ + 'sitekey' => Yii::$app->get('recaptcha')->key, + 'callback' => $this->callback, + 'expired-callback' => $this->expiredCallback, + 'theme' => $this->theme, + 'type' => $this->type, + 'size' => $this->size, + 'tabindex' => $this->tabIndex + ]; + + $options = [ + 'class' => 'g-recaptcha', + 'data' => array_filter($data) + ]; + + return $options; + } + + /** + * Registers the required libraries and scripts for the widget to work. + */ + protected function registerClientScript() + { + $view = $this->getView(); + + $view->registerJsFile( + '//www.google.com/recaptcha/api.js?hl=' . $this->getLanguageCode(), + [ + 'position' => View::POS_HEAD, + 'async' => true, + 'defer' => true + ] + ); + + $js = []; + $id = $this->options['id']; + + $js[] = empty($this->callback) + ? "var reCaptchaCallback = function(r){jQuery('#{$id}').val(r);};" + : "var reCaptchaCallback = function(r){jQuery('#{$id}').val(r); {$this->callback}(r);};"; + + $this->callback = 'reCaptchaCallback'; + + $js[] = empty($this->expiredCallback) + ? "var reCaptchaExpiredCallback = function(){jQuery('#{$id}').val('');};" + : "var reCaptchaExpiredCallback = function(){jQuery('#{$id}').val(''); {$this->expiredCallback}();};"; + + $this->expiredCallback = 'reCaptchaExpiredCallback'; + + $view->registerJs(implode("\n", $js), View::POS_BEGIN); + } + + /** + * @return bool|string the language code config option for google recatpcha library url. + */ + protected function getLanguageCode() + { + $language = Yii::$app->language; + + if (strpos($language, '-') === false) { + return $language; + } + + $except = [ + 'zh-HK', + 'zh-CN', + 'zh-TW', + 'en-GB', + 'de-AT', + 'de-CH', + 'pt-BR', + 'pt-PT' + ]; + + return in_array($language, $except) + ? $language + : substr($language, 0, strpos($language, '-')); + } +} diff --git a/src/User/resources/i18n/ca/usuario.php b/src/User/resources/i18n/ca/usuario.php index 4328617..dd49916 100644 --- a/src/User/resources/i18n/ca/usuario.php +++ b/src/User/resources/i18n/ca/usuario.php @@ -1,21 +1,14 @@ * - * Each array element represents the translation (value) of a message (key). - * If the value is empty, the message is considered as not translated. - * Messages that no longer need translation will have their translations - * enclosed between a pair of '@@' marks. - * - * Message string can be used with plural forms format. Check i18n section - * of the guide for details. - * - * NOTE: this file must be saved in UTF-8 encoding. + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. */ + return [ '(not set)' => '', 'A confirmation message has been sent to your new email address' => '', diff --git a/src/User/resources/i18n/da/usuario.php b/src/User/resources/i18n/da/usuario.php index 4328617..dd49916 100644 --- a/src/User/resources/i18n/da/usuario.php +++ b/src/User/resources/i18n/da/usuario.php @@ -1,21 +1,14 @@ * - * Each array element represents the translation (value) of a message (key). - * If the value is empty, the message is considered as not translated. - * Messages that no longer need translation will have their translations - * enclosed between a pair of '@@' marks. - * - * Message string can be used with plural forms format. Check i18n section - * of the guide for details. - * - * NOTE: this file must be saved in UTF-8 encoding. + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. */ + return [ '(not set)' => '', 'A confirmation message has been sent to your new email address' => '', diff --git a/src/User/resources/i18n/de-DU/usuario.php b/src/User/resources/i18n/de-DU/usuario.php index 4328617..dd49916 100644 --- a/src/User/resources/i18n/de-DU/usuario.php +++ b/src/User/resources/i18n/de-DU/usuario.php @@ -1,21 +1,14 @@ * - * Each array element represents the translation (value) of a message (key). - * If the value is empty, the message is considered as not translated. - * Messages that no longer need translation will have their translations - * enclosed between a pair of '@@' marks. - * - * Message string can be used with plural forms format. Check i18n section - * of the guide for details. - * - * NOTE: this file must be saved in UTF-8 encoding. + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. */ + return [ '(not set)' => '', 'A confirmation message has been sent to your new email address' => '', diff --git a/src/User/resources/i18n/de/usuario.php b/src/User/resources/i18n/de/usuario.php index e668c44..d4e59ef 100644 --- a/src/User/resources/i18n/de/usuario.php +++ b/src/User/resources/i18n/de/usuario.php @@ -1,21 +1,14 @@ * - * Each array element represents the translation (value) of a message (key). - * If the value is empty, the message is considered as not translated. - * Messages that no longer need translation will have their translations - * enclosed between a pair of '@@' marks. - * - * Message string can be used with plural forms format. Check i18n section - * of the guide for details. - * - * NOTE: this file must be saved in UTF-8 encoding. + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. */ + return [ 'A message has been sent to your email address. It contains a confirmation link that you must click to complete registration.' => '', 'Are you sure you want to switch to this user for the rest of this Session?' => '', diff --git a/src/User/resources/i18n/es/usuario.php b/src/User/resources/i18n/es/usuario.php index b2fc900..f22c442 100644 --- a/src/User/resources/i18n/es/usuario.php +++ b/src/User/resources/i18n/es/usuario.php @@ -1,21 +1,14 @@ * - * Each array element represents the translation (value) of a message (key). - * If the value is empty, the message is considered as not translated. - * Messages that no longer need translation will have their translations - * enclosed between a pair of '@@' marks. - * - * Message string can be used with plural forms format. Check i18n section - * of the guide for details. - * - * NOTE: this file must be saved in UTF-8 encoding. + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. */ + return [ 'Cannot assign role "{0}" as the AuthManager is not configured on your console application.' => 'No se puede asignar rol "{0}" ya que AuthManager no ha sido configurado en tu aplicación de consola.', 'Role "{0}" not found. Creating it.' => 'Rol "{0}" no encontrado. Creándolo.', diff --git a/src/User/resources/i18n/fa-IR/usuario.php b/src/User/resources/i18n/fa-IR/usuario.php index 4328617..dd49916 100644 --- a/src/User/resources/i18n/fa-IR/usuario.php +++ b/src/User/resources/i18n/fa-IR/usuario.php @@ -1,21 +1,14 @@ * - * Each array element represents the translation (value) of a message (key). - * If the value is empty, the message is considered as not translated. - * Messages that no longer need translation will have their translations - * enclosed between a pair of '@@' marks. - * - * Message string can be used with plural forms format. Check i18n section - * of the guide for details. - * - * NOTE: this file must be saved in UTF-8 encoding. + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. */ + return [ '(not set)' => '', 'A confirmation message has been sent to your new email address' => '', diff --git a/src/User/resources/i18n/fi/usuario.php b/src/User/resources/i18n/fi/usuario.php index 4328617..dd49916 100644 --- a/src/User/resources/i18n/fi/usuario.php +++ b/src/User/resources/i18n/fi/usuario.php @@ -1,21 +1,14 @@ * - * Each array element represents the translation (value) of a message (key). - * If the value is empty, the message is considered as not translated. - * Messages that no longer need translation will have their translations - * enclosed between a pair of '@@' marks. - * - * Message string can be used with plural forms format. Check i18n section - * of the guide for details. - * - * NOTE: this file must be saved in UTF-8 encoding. + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. */ + return [ '(not set)' => '', 'A confirmation message has been sent to your new email address' => '', diff --git a/src/User/resources/i18n/fr/usuario.php b/src/User/resources/i18n/fr/usuario.php index 4328617..dd49916 100644 --- a/src/User/resources/i18n/fr/usuario.php +++ b/src/User/resources/i18n/fr/usuario.php @@ -1,21 +1,14 @@ * - * Each array element represents the translation (value) of a message (key). - * If the value is empty, the message is considered as not translated. - * Messages that no longer need translation will have their translations - * enclosed between a pair of '@@' marks. - * - * Message string can be used with plural forms format. Check i18n section - * of the guide for details. - * - * NOTE: this file must be saved in UTF-8 encoding. + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. */ + return [ '(not set)' => '', 'A confirmation message has been sent to your new email address' => '', diff --git a/src/User/resources/i18n/hr/usuario.php b/src/User/resources/i18n/hr/usuario.php index 4328617..dd49916 100644 --- a/src/User/resources/i18n/hr/usuario.php +++ b/src/User/resources/i18n/hr/usuario.php @@ -1,21 +1,14 @@ * - * Each array element represents the translation (value) of a message (key). - * If the value is empty, the message is considered as not translated. - * Messages that no longer need translation will have their translations - * enclosed between a pair of '@@' marks. - * - * Message string can be used with plural forms format. Check i18n section - * of the guide for details. - * - * NOTE: this file must be saved in UTF-8 encoding. + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. */ + return [ '(not set)' => '', 'A confirmation message has been sent to your new email address' => '', diff --git a/src/User/resources/i18n/hu/usuario.php b/src/User/resources/i18n/hu/usuario.php index 0b01c0a..46ba35b 100644 --- a/src/User/resources/i18n/hu/usuario.php +++ b/src/User/resources/i18n/hu/usuario.php @@ -1,21 +1,14 @@ * - * Each array element represents the translation (value) of a message (key). - * If the value is empty, the message is considered as not translated. - * Messages that no longer need translation will have their translations - * enclosed between a pair of '@@' marks. - * - * Message string can be used with plural forms format. Check i18n section - * of the guide for details. - * - * NOTE: this file must be saved in UTF-8 encoding. + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. */ + return [ 'A message has been sent to your email address. It contains a confirmation link that you must click to complete registration.' => '', 'Awesome, almost there. Now you need to click the confirmation link sent to your new email address.' => '', diff --git a/src/User/resources/i18n/it/usuario.php b/src/User/resources/i18n/it/usuario.php index 9833cc7..d5ff647 100644 --- a/src/User/resources/i18n/it/usuario.php +++ b/src/User/resources/i18n/it/usuario.php @@ -1,21 +1,14 @@ * - * Each array element represents the translation (value) of a message (key). - * If the value is empty, the message is considered as not translated. - * Messages that no longer need translation will have their translations - * enclosed between a pair of '@@' marks. - * - * Message string can be used with plural forms format. Check i18n section - * of the guide for details. - * - * NOTE: this file must be saved in UTF-8 encoding. + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. */ + return [ 'A message has been sent to your email address. It contains a confirmation link that you must click to complete registration.' => '', 'Awesome, almost there. Now you need to click the confirmation link sent to your new email address.' => '', diff --git a/src/User/resources/i18n/kk/usuario.php b/src/User/resources/i18n/kk/usuario.php index 4328617..dd49916 100644 --- a/src/User/resources/i18n/kk/usuario.php +++ b/src/User/resources/i18n/kk/usuario.php @@ -1,21 +1,14 @@ * - * Each array element represents the translation (value) of a message (key). - * If the value is empty, the message is considered as not translated. - * Messages that no longer need translation will have their translations - * enclosed between a pair of '@@' marks. - * - * Message string can be used with plural forms format. Check i18n section - * of the guide for details. - * - * NOTE: this file must be saved in UTF-8 encoding. + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. */ + return [ '(not set)' => '', 'A confirmation message has been sent to your new email address' => '', diff --git a/src/User/resources/i18n/lt/usuario.php b/src/User/resources/i18n/lt/usuario.php index 4328617..dd49916 100644 --- a/src/User/resources/i18n/lt/usuario.php +++ b/src/User/resources/i18n/lt/usuario.php @@ -1,21 +1,14 @@ * - * Each array element represents the translation (value) of a message (key). - * If the value is empty, the message is considered as not translated. - * Messages that no longer need translation will have their translations - * enclosed between a pair of '@@' marks. - * - * Message string can be used with plural forms format. Check i18n section - * of the guide for details. - * - * NOTE: this file must be saved in UTF-8 encoding. + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. */ + return [ '(not set)' => '', 'A confirmation message has been sent to your new email address' => '', diff --git a/src/User/resources/i18n/nl/usuario.php b/src/User/resources/i18n/nl/usuario.php index 4328617..dd49916 100644 --- a/src/User/resources/i18n/nl/usuario.php +++ b/src/User/resources/i18n/nl/usuario.php @@ -1,21 +1,14 @@ * - * Each array element represents the translation (value) of a message (key). - * If the value is empty, the message is considered as not translated. - * Messages that no longer need translation will have their translations - * enclosed between a pair of '@@' marks. - * - * Message string can be used with plural forms format. Check i18n section - * of the guide for details. - * - * NOTE: this file must be saved in UTF-8 encoding. + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. */ + return [ '(not set)' => '', 'A confirmation message has been sent to your new email address' => '', diff --git a/src/User/resources/i18n/pl/usuario.php b/src/User/resources/i18n/pl/usuario.php index 58e766e..2c1831f 100644 --- a/src/User/resources/i18n/pl/usuario.php +++ b/src/User/resources/i18n/pl/usuario.php @@ -1,21 +1,14 @@ * - * Each array element represents the translation (value) of a message (key). - * If the value is empty, the message is considered as not translated. - * Messages that no longer need translation will have their translations - * enclosed between a pair of '@@' marks. - * - * Message string can be used with plural forms format. Check i18n section - * of the guide for details. - * - * NOTE: this file must be saved in UTF-8 encoding. + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. */ + return [ 'Cannot assign role "{0}" as the AuthManager is not configured on your console application.' => '', 'Role "{0}" not found. Creating it.' => '', diff --git a/src/User/resources/i18n/pt-BR/usuario.php b/src/User/resources/i18n/pt-BR/usuario.php index 4328617..dd49916 100644 --- a/src/User/resources/i18n/pt-BR/usuario.php +++ b/src/User/resources/i18n/pt-BR/usuario.php @@ -1,21 +1,14 @@ * - * Each array element represents the translation (value) of a message (key). - * If the value is empty, the message is considered as not translated. - * Messages that no longer need translation will have their translations - * enclosed between a pair of '@@' marks. - * - * Message string can be used with plural forms format. Check i18n section - * of the guide for details. - * - * NOTE: this file must be saved in UTF-8 encoding. + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. */ + return [ '(not set)' => '', 'A confirmation message has been sent to your new email address' => '', diff --git a/src/User/resources/i18n/pt-PT/usuario.php b/src/User/resources/i18n/pt-PT/usuario.php index 4328617..dd49916 100644 --- a/src/User/resources/i18n/pt-PT/usuario.php +++ b/src/User/resources/i18n/pt-PT/usuario.php @@ -1,21 +1,14 @@ * - * Each array element represents the translation (value) of a message (key). - * If the value is empty, the message is considered as not translated. - * Messages that no longer need translation will have their translations - * enclosed between a pair of '@@' marks. - * - * Message string can be used with plural forms format. Check i18n section - * of the guide for details. - * - * NOTE: this file must be saved in UTF-8 encoding. + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. */ + return [ '(not set)' => '', 'A confirmation message has been sent to your new email address' => '', diff --git a/src/User/resources/i18n/ro/usuario.php b/src/User/resources/i18n/ro/usuario.php index 2b22fa6..4e42361 100644 --- a/src/User/resources/i18n/ro/usuario.php +++ b/src/User/resources/i18n/ro/usuario.php @@ -1,21 +1,14 @@ * - * Each array element represents the translation (value) of a message (key). - * If the value is empty, the message is considered as not translated. - * Messages that no longer need translation will have their translations - * enclosed between a pair of '@@' marks. - * - * Message string can be used with plural forms format. Check i18n section - * of the guide for details. - * - * NOTE: this file must be saved in UTF-8 encoding. + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. */ + return [ 'A message has been sent to your email address. It contains a confirmation link that you must click to complete registration.' => '', 'Awesome, almost there. Now you need to click the confirmation link sent to your new email address.' => '', diff --git a/src/User/resources/i18n/ru/usuario.php b/src/User/resources/i18n/ru/usuario.php index 736aaea..51a6e07 100644 --- a/src/User/resources/i18n/ru/usuario.php +++ b/src/User/resources/i18n/ru/usuario.php @@ -1,21 +1,14 @@ * - * Each array element represents the translation (value) of a message (key). - * If the value is empty, the message is considered as not translated. - * Messages that no longer need translation will have their translations - * enclosed between a pair of '@@' marks. - * - * Message string can be used with plural forms format. Check i18n section - * of the guide for details. - * - * NOTE: this file must be saved in UTF-8 encoding. + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. */ + return [ 'A message has been sent to your email address. It contains a confirmation link that you must click to complete registration.' => '', 'Awesome, almost there. Now you need to click the confirmation link sent to your new email address.' => '', diff --git a/src/User/resources/i18n/th/usuario.php b/src/User/resources/i18n/th/usuario.php index 4328617..dd49916 100644 --- a/src/User/resources/i18n/th/usuario.php +++ b/src/User/resources/i18n/th/usuario.php @@ -1,21 +1,14 @@ * - * Each array element represents the translation (value) of a message (key). - * If the value is empty, the message is considered as not translated. - * Messages that no longer need translation will have their translations - * enclosed between a pair of '@@' marks. - * - * Message string can be used with plural forms format. Check i18n section - * of the guide for details. - * - * NOTE: this file must be saved in UTF-8 encoding. + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. */ + return [ '(not set)' => '', 'A confirmation message has been sent to your new email address' => '', diff --git a/src/User/resources/i18n/tr_TR/usuario.php b/src/User/resources/i18n/tr_TR/usuario.php index 4328617..dd49916 100644 --- a/src/User/resources/i18n/tr_TR/usuario.php +++ b/src/User/resources/i18n/tr_TR/usuario.php @@ -1,21 +1,14 @@ * - * Each array element represents the translation (value) of a message (key). - * If the value is empty, the message is considered as not translated. - * Messages that no longer need translation will have their translations - * enclosed between a pair of '@@' marks. - * - * Message string can be used with plural forms format. Check i18n section - * of the guide for details. - * - * NOTE: this file must be saved in UTF-8 encoding. + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. */ + return [ '(not set)' => '', 'A confirmation message has been sent to your new email address' => '', diff --git a/src/User/resources/i18n/uk/usuario.php b/src/User/resources/i18n/uk/usuario.php index 4328617..dd49916 100644 --- a/src/User/resources/i18n/uk/usuario.php +++ b/src/User/resources/i18n/uk/usuario.php @@ -1,21 +1,14 @@ * - * Each array element represents the translation (value) of a message (key). - * If the value is empty, the message is considered as not translated. - * Messages that no longer need translation will have their translations - * enclosed between a pair of '@@' marks. - * - * Message string can be used with plural forms format. Check i18n section - * of the guide for details. - * - * NOTE: this file must be saved in UTF-8 encoding. + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. */ + return [ '(not set)' => '', 'A confirmation message has been sent to your new email address' => '', diff --git a/src/User/resources/i18n/vi/usuario.php b/src/User/resources/i18n/vi/usuario.php index 4328617..dd49916 100644 --- a/src/User/resources/i18n/vi/usuario.php +++ b/src/User/resources/i18n/vi/usuario.php @@ -1,21 +1,14 @@ * - * Each array element represents the translation (value) of a message (key). - * If the value is empty, the message is considered as not translated. - * Messages that no longer need translation will have their translations - * enclosed between a pair of '@@' marks. - * - * Message string can be used with plural forms format. Check i18n section - * of the guide for details. - * - * NOTE: this file must be saved in UTF-8 encoding. + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. */ + return [ '(not set)' => '', 'A confirmation message has been sent to your new email address' => '', diff --git a/src/User/resources/i18n/zh-CN/usuario.php b/src/User/resources/i18n/zh-CN/usuario.php index 4328617..dd49916 100644 --- a/src/User/resources/i18n/zh-CN/usuario.php +++ b/src/User/resources/i18n/zh-CN/usuario.php @@ -1,21 +1,14 @@ * - * Each array element represents the translation (value) of a message (key). - * If the value is empty, the message is considered as not translated. - * Messages that no longer need translation will have their translations - * enclosed between a pair of '@@' marks. - * - * Message string can be used with plural forms format. Check i18n section - * of the guide for details. - * - * NOTE: this file must be saved in UTF-8 encoding. + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. */ + return [ '(not set)' => '', 'A confirmation message has been sent to your new email address' => '', diff --git a/src/User/resources/views/admin/index.php b/src/User/resources/views/admin/index.php index f5cc5e0..97cee7c 100644 --- a/src/User/resources/views/admin/index.php +++ b/src/User/resources/views/admin/index.php @@ -63,7 +63,7 @@ $module = Yii::$app->getModule('user'); 'value' => function ($model) { if (!$model->last_login_at || $model->last_login_at == 0) { return Yii::t('usuario', 'Never'); - } else if (extension_loaded('intl')) { + } elseif (extension_loaded('intl')) { return Yii::t('usuario', '{0, date, MMMM dd, YYYY HH:mm}', [$model->last_login_at]); } else { return date('Y-m-d G:i:s', $model->last_login_at); diff --git a/src/User/resources/views/settings/account.php b/src/User/resources/views/settings/account.php index 9a9844c..df29662 100644 --- a/src/User/resources/views/settings/account.php +++ b/src/User/resources/views/settings/account.php @@ -14,8 +14,8 @@ use yii\helpers\Url; use yii\widgets\ActiveForm; /** - * @var yii\web\View $this - * @var yii\widgets\ActiveForm $form + * @var yii\web\View $this + * @var yii\widgets\ActiveForm $form * @var \Da\User\Form\SettingsForm $model */