diff --git a/README.md b/README.md index 3bc44a785..b63d3475f 100644 --- a/README.md +++ b/README.md @@ -1,208 +1,23 @@ -Yii 2 Basic Project Template -============================ -Yii 2 Basic Project Template is a skeleton [Yii 2](http://www.yiiframework.com/) application best for -rapidly creating small projects. -The template contains the basic features including user login/logout and a contact page. -It includes all commonly used configurations that would allow you to focus on adding new -features to your application. -[![Latest Stable Version](https://poser.pugx.org/yiisoft/yii2-app-basic/v/stable.png)](https://packagist.org/packages/yiisoft/yii2-app-basic) -[![Total Downloads](https://poser.pugx.org/yiisoft/yii2-app-basic/downloads.png)](https://packagist.org/packages/yiisoft/yii2-app-basic) -[![Build Status](https://travis-ci.org/yiisoft/yii2-app-basic.svg?branch=master)](https://travis-ci.org/yiisoft/yii2-app-basic) - -DIRECTORY STRUCTURE -------------------- - - assets/ contains assets definition - commands/ contains console commands (controllers) - config/ contains application configurations - controllers/ contains Web controller classes - mail/ contains view files for e-mails - models/ contains model classes - runtime/ contains files generated during runtime - tests/ contains various tests for the basic application - vendor/ contains dependent 3rd-party packages - views/ contains view files for the Web application - web/ contains the entry script and Web resources - - - -REQUIREMENTS ------------- - -The minimum requirement by this project template that your Web server supports PHP 5.4.0. - - -INSTALLATION ------------- - -### Install via Composer - -If you do not have [Composer](http://getcomposer.org/), you may install it by following the instructions -at [getcomposer.org](http://getcomposer.org/doc/00-intro.md#installation-nix). - -You can then install this project template using the following command: - -~~~ -php composer.phar global require "fxp/composer-asset-plugin:^1.2.0" -php composer.phar create-project --prefer-dist --stability=dev yiisoft/yii2-app-basic basic -~~~ - -Now you should be able to access the application through the following URL, assuming `basic` is the directory -directly under the Web root. - -~~~ -http://localhost/basic/web/ -~~~ - - -### Install from an Archive File - -Extract the archive file downloaded from [yiiframework.com](http://www.yiiframework.com/download/) to -a directory named `basic` that is directly under the Web root. - -Set cookie validation key in `config/web.php` file to some random secret string: - -```php -'request' => [ - // !!! insert a secret key in the following (if it is empty) - this is required by cookie validation - 'cookieValidationKey' => '', -], -``` - -You can then access the application through the following URL: - -~~~ -http://localhost/basic/web/ -~~~ - - -CONFIGURATION -------------- - -### Database - -Edit the file `config/db.php` with real data, for example: +## Configurazione RBAC ```php -return [ - 'class' => 'yii\db\Connection', - 'dsn' => 'mysql:host=localhost;dbname=yii2basic', - 'username' => 'root', - 'password' => '1234', - 'charset' => 'utf8', -]; + return [ + // ... + 'controllerMap' => [ + 'mongodb-migrate' => 'yii\mongodb\console\controllers\MigrateController' + ], + ]; ``` -**NOTES:** -- Yii won't create the database for you, this has to be done manually before you can access it. -- Check and edit the other files in the `config/` directory to customize your application as required. -- Refer to the README in the `tests` directory for information specific to basic application tests. - - - -TESTING -------- - -Tests are located in `tests` directory. They are developed with [Codeception PHP Testing Framework](http://codeception.com/). -By default there are 3 test suites: - -- `unit` -- `functional` -- `acceptance` - -Tests can be executed by running - -``` -vendor/bin/codecept run -``` - -The command above will execute unit and functional tests. Unit tests are testing the system components, while functional -tests are for testing user interaction. Acceptance tests are disabled by default as they require additional setup since -they perform testing in real browser. - - -### Running acceptance tests - -To execute acceptance tests do the following: - -1. Rename `tests/acceptance.suite.yml.example` to `tests/acceptance.suite.yml` to enable suite configuration - -2. Replace `codeception/base` package in `composer.json` with `codeception/codeception` to install full featured - version of Codeception - -3. Update dependencies with Composer - - ``` - composer update - ``` - -4. Download [Selenium Server](http://www.seleniumhq.org/download/) and launch it: - - ``` - java -jar ~/selenium-server-standalone-x.xx.x.jar - ``` - - In case of using Selenium Server 3.0 with Firefox browser since v48 or Google Chrome since v53 you must download [GeckoDriver](https://github.com/mozilla/geckodriver/releases) or [ChromeDriver](https://sites.google.com/a/chromium.org/chromedriver/downloads) and launch Selenium with it: - - ``` - # for Firefox - java -jar -Dwebdriver.gecko.driver=~/geckodriver ~/selenium-server-standalone-3.xx.x.jar - - # for Google Chrome - java -jar -Dwebdriver.chrome.driver=~/chromedriver ~/selenium-server-standalone-3.xx.x.jar - ``` - - As an alternative way you can use already configured Docker container with older versions of Selenium and Firefox: - - ``` - docker run --net=host selenium/standalone-firefox:2.53.0 - ``` - -5. (Optional) Create `yii2_basic_tests` database and update it by applying migrations if you have them. - - ``` - tests/bin/yii migrate - ``` - - The database configuration can be found at `config/test_db.php`. - - -6. Start web server: - - ``` - tests/bin/yii serve - ``` - -7. Now you can run all available tests - - ``` - # run all available tests - vendor/bin/codecept run - - # run acceptance tests - vendor/bin/codecept run acceptance - - # run only unit and functional tests - vendor/bin/codecept run unit,functional - ``` - -### Code coverage support - -By default, code coverage is disabled in `codeception.yml` configuration file, you should uncomment needed rows to be able -to collect code coverage. You can run your tests and collect coverage with the following command: - -``` -#collect coverage for all tests -vendor/bin/codecept run -- --coverage-html --coverage-xml - -#collect coverage only for unit tests -vendor/bin/codecept run unit -- --coverage-html --coverage-xml - -#collect coverage for unit and functional tests -vendor/bin/codecept run functional,unit -- --coverage-html --coverage-xml +```bash +yii mongodb-migrate/create create_user_collection +yii mongodb-migrate ``` -You can see code coverage output under the `tests/_output` directory. +```bash +# reverts the last applied migration +yii mongodb-migrate/down +``` \ No newline at end of file diff --git a/composer.json b/composer.json index e31abe055..c49ea9b52 100644 --- a/composer.json +++ b/composer.json @@ -12,17 +12,38 @@ "irc": "irc://irc.freenode.net/yii", "source": "https://github.com/yiisoft/yii2" }, - "minimum-stability": "dev", + "minimum-stability": "stable", "require": { "php": ">=5.4.0", "yiisoft/yii2": "~2.0.5", + "yiisoft/yii2-apidoc": "~2.1.0", + "yiisoft/yii2-jui": "^2.0", + "yiisoft/yii2-imagine": "*", "yiisoft/yii2-bootstrap": "~2.0.0", - "yiisoft/yii2-swiftmailer": "~2.0.0" + "yiisoft/yii2-swiftmailer": "~2.0.0", + "yiisoft/yii2-mongodb": "~2.1.0", + "rmrevin/yii2-fontawesome": "~2.17", + "kartik-v/yii2-nav-x": "dev-master", + "kartik-v/yii2-dropdown-x": "dev-master", + "kartik-v/yii2-icons": "@stable", + "kartik-v/yii2-widget-depdrop": "^1.0", + "kartik-v/yii2-popover-x": "dev-master", + "miloschuman/yii2-highcharts-widget": "*", + "mongosoft/yii2-mongodate-behavior": "*", + "fedemotta/yii2-widget-datatables": "*", + "bower-asset/jquery": "2.2.*@stable", + "bower-asset/jquery-ui": "~1.11@stable", + "dmstr/yii2-adminlte-asset": "2.*", + "johnitvn/yii2-ajaxcrud": "*" }, "require-dev": { "yiisoft/yii2-debug": "~2.0.0", "yiisoft/yii2-gii": "~2.0.0", "yiisoft/yii2-faker": "~2.0.0", + "kartik-v/yii2-icons": "@dev", + "kartik-v/yii2-tree-manager": "@dev", + "kartik-v/yii2-detail-view": "@dev", + "kartik-v/yii2-editable": "@dev", "codeception/base": "^2.2.3", "codeception/verify": "~0.3.1", @@ -38,13 +59,11 @@ }, "extra": { "yii\\composer\\Installer::postCreateProject": { - "setPermission": [ - { - "runtime": "0777", - "web/assets": "0777", - "yii": "0755" - } - ], + "setPermission": [{ + "runtime": "0777", + "web/assets": "0777", + "yii": "0755" + }], "generateCookieValidationKey": [ "config/web.php" ] @@ -54,4 +73,4 @@ "bower-asset-library": "vendor/bower" } } -} +} \ No newline at end of file diff --git a/config/console.php b/config/console.php index 3945d9eb2..4e636bef7 100644 --- a/config/console.php +++ b/config/console.php @@ -20,16 +20,12 @@ ], ], ], - 'db' => $db, + 'mongodb' => $db, ], 'params' => $params, - /* 'controllerMap' => [ - 'fixture' => [ // Fixture generation command line. - 'class' => 'yii\faker\FixtureController', - ], + 'mongodb-migrate' => 'yii\mongodb\console\controllers\MigrateController' ], - */ ]; if (YII_ENV_DEV) { diff --git a/config/db.php b/config/db.php index c4c12529c..8cd92bcc8 100644 --- a/config/db.php +++ b/config/db.php @@ -1,9 +1,6 @@ 'yii\db\Connection', - 'dsn' => 'mysql:host=localhost;dbname=yii2basic', - 'username' => 'root', - 'password' => '', - 'charset' => 'utf8', + 'class' => '\yii\mongodb\Connection', + 'dsn' => 'mongodb://developer:password@localhost:27017/mydatabase', ]; diff --git a/config/web.php b/config/web.php index 2bc8561fb..bc75d1fc3 100644 --- a/config/web.php +++ b/config/web.php @@ -37,17 +37,27 @@ ], ], ], - 'db' => require(__DIR__ . '/db.php'), - /* + 'mongodb' => require(__DIR__ . '/db.php'), + 'authManager' => [ + 'class' => 'yii\mongodb\rbac\MongoDbManager', + ], 'urlManager' => [ 'enablePrettyUrl' => true, 'showScriptName' => false, 'rules' => [ ], ], - */ + ], 'params' => $params, + 'modules' => [ + 'gridview' => [ + 'class' => '\kartik\grid\Module' + ], + 'api' => [ + 'class' => 'app\modules\api\v1', + ], + ], ]; if (YII_ENV_DEV) { @@ -56,14 +66,19 @@ $config['modules']['debug'] = [ 'class' => 'yii\debug\Module', // uncomment the following to add your IP if you are not connecting from localhost. - //'allowedIPs' => ['127.0.0.1', '::1'], + 'allowedIPs' => ['*'], ]; $config['bootstrap'][] = 'gii'; $config['modules']['gii'] = [ 'class' => 'yii\gii\Module', // uncomment the following to add your IP if you are not connecting from localhost. - //'allowedIPs' => ['127.0.0.1', '::1'], + 'allowedIPs' => ['*'], + 'generators' => [ + 'mongoDbModel' => [ + 'class' => 'yii\mongodb\gii\model\Generator' + ] + ], ]; } diff --git a/controllers/BaseController.php b/controllers/BaseController.php new file mode 100644 index 000000000..9c3cad2d6 --- /dev/null +++ b/controllers/BaseController.php @@ -0,0 +1,23 @@ + [ + 'class' => AccessControl::className(), + 'rules' => [ + [ + 'allow' => true, + 'roles' => ['@'], + ], + ], + ], + ]; + } +} \ No newline at end of file diff --git a/controllers/SiteController.php b/controllers/SiteController.php index 36dc9591b..ede31f719 100644 --- a/controllers/SiteController.php +++ b/controllers/SiteController.php @@ -7,6 +7,7 @@ use yii\web\Controller; use yii\filters\VerbFilter; use app\models\LoginForm; +use app\models\SignupForm; use app\models\ContactForm; class SiteController extends Controller @@ -19,10 +20,14 @@ public function behaviors() return [ 'access' => [ 'class' => AccessControl::className(), - 'only' => ['logout'], + 'only' => ['logout', 'signup'], 'rules' => [ [ - 'actions' => ['logout'], + 'actions' => ['signup','login', 'request-password-reset'], + 'allow' => true, + ], + [ + 'actions' => ['logout', 'index'], 'allow' => true, 'roles' => ['@'], ], @@ -95,6 +100,59 @@ public function actionLogout() return $this->goHome(); } + public function actionSignup() + { + $model = new SignupForm(); + if ($model->load(Yii::$app->request->post())) { + if ($user = $model->signup()) { + if (Yii::$app->getUser()->login($user)) { + return $this->goHome(); + } + } + } + + return $this->render('signup', [ + 'model' => $model, + ]); + } + + public function actionRequestPasswordReset() + { + $model = new PasswordResetRequestForm(); + if ($model->load(Yii::$app->request->post()) && $model->validate()) { + if ($model->sendEmail()) { + Yii::$app->getSession()->setFlash('success', 'Check your email for further instructions.'); + + return $this->goHome(); + } else { + Yii::$app->getSession()->setFlash('error', 'Sorry, we are unable to reset password for email provided.'); + } + } + + return $this->render('requestPasswordResetToken', [ + 'model' => $model, + ]); + } + + public function actionResetPassword($token) + { + try { + $model = new ResetPasswordForm($token); + } catch (InvalidParamException $e) { + throw new BadRequestHttpException($e->getMessage()); + } + + if ($model->load(Yii::$app->request->post()) && $model->validate() && $model->resetPassword()) { + Yii::$app->getSession()->setFlash('success', 'New password was saved.'); + + return $this->goHome(); + } + + return $this->render('resetPassword', [ + 'model' => $model, + ]); + } + /** * Displays contact page. * diff --git a/models/LoginForm.php b/models/LoginForm.php index cc6af264c..2186b5f81 100644 --- a/models/LoginForm.php +++ b/models/LoginForm.php @@ -14,6 +14,7 @@ class LoginForm extends Model { public $username; + public $email; public $password; public $rememberMe = true; diff --git a/models/PasswordResetRequestForm.php b/models/PasswordResetRequestForm.php new file mode 100644 index 000000000..358629224 --- /dev/null +++ b/models/PasswordResetRequestForm.php @@ -0,0 +1,60 @@ + 'trim'], + ['email', 'required'], + ['email', 'email'], + ['email', 'exist', + 'targetClass' => '\app\models\User', + 'filter' => ['status' => User::STATUS_ACTIVE], + 'message' => 'There is no user with such email.' + ], + ]; + } + + /** + * Sends an email with a link, for resetting the password. + * + * @return boolean whether the email was send + */ + public function sendEmail() + { + /** @var User $user */ + $user = User::findOne([ + 'status' => User::STATUS_ACTIVE, + 'email' => $this->email, + ]); + + if ($user) { + if (!User::isPasswordResetTokenValid($user->password_reset_token)) { + $user->generatePasswordResetToken(); + } + + if ($user->save()) { + return \Yii::$app->mail->compose('passwordResetToken', ['user' => $user]) + ->setFrom([\Yii::$app->params['supportEmail'] => \Yii::$app->name . ' robot']) + ->setTo($this->email) + ->setSubject('Password reset for ' . \Yii::$app->name) + ->send(); + } + } + + return false; + } +} \ No newline at end of file diff --git a/models/ResetPasswordForm.php b/models/ResetPasswordForm.php new file mode 100644 index 000000000..f9cb32ea8 --- /dev/null +++ b/models/ResetPasswordForm.php @@ -0,0 +1,64 @@ +_user = User::findByPasswordResetToken($token); + if (!$this->_user) { + throw new InvalidParamException('Wrong password reset token.'); + } + parent::__construct($config); + } + + /** + * @inheritdoc + */ + public function rules() + { + return [ + ['password', 'required'], + ['password', 'string', 'min' => 6], + ]; + } + + /** + * Resets password. + * + * @return boolean if password was reset. + */ + public function resetPassword() + { + $user = $this->_user; + $user->password = $this->password; + $user->removePasswordResetToken(); + + return $user->save(); + } +} \ No newline at end of file diff --git a/models/SignupForm.php b/models/SignupForm.php new file mode 100644 index 000000000..a21178e15 --- /dev/null +++ b/models/SignupForm.php @@ -0,0 +1,61 @@ + 'trim'], + ['username', 'required'], + ['username', 'unique', 'targetClass' => '\app\models\User', 'message' => 'This username has already been taken.'], + ['username', 'string', 'min' => 2, 'max' => 255], + + ['email', 'filter', 'filter' => 'trim'], + ['email', 'required'], + ['email', 'email'], + ['email', 'unique', 'targetClass' => '\app\models\User', 'message' => 'This email address has already been taken.'], + + ['password', 'required'], + ['password', 'string', 'min' => 6], + ]; + } + + /** + * Signs user up. + * + * @return User|null the saved model or null if saving fails + */ + public function signup() + { + if ($this->validate()) { + $user = new User(); + $user->username = $this->username; + $user->email = $this->email; + $user->role = $this->role; + $user->setPassword($this->password); + $user->generateAuthKey(); + $user->save(); + + return $user; + } + + return null; + } +} \ No newline at end of file diff --git a/models/User.php b/models/User.php index 250fb3962..d6fc5fec1 100644 --- a/models/User.php +++ b/models/User.php @@ -1,39 +1,82 @@ [ - 'id' => '100', - 'username' => 'admin', - 'password' => 'admin', - 'authKey' => 'test100key', - 'accessToken' => '100-token', - ], - '101' => [ - 'id' => '101', - 'username' => 'demo', - 'password' => 'demo', - 'authKey' => 'test101key', - 'accessToken' => '101-token', - ], - ]; + const STATUS_DELETED = 0; + const STATUS_ACTIVE = 10; + + /** + * @inheritdoc + */ + public function behaviors() + { + + return [ + 'timestamp' => [ + 'class' => 'yii\behaviors\TimestampBehavior', + 'attributes' => [ + ActiveRecord::EVENT_BEFORE_INSERT => ['created_at', 'updated_at'], + ActiveRecord::EVENT_BEFORE_UPDATE => ['updated_at'], + ], + ], + ]; + } + /** + * @inheritdoc + */ + public function rules() + { + return [ + ['status', 'default', 'value' => self::STATUS_ACTIVE], + ['status', 'in', 'range' => [self::STATUS_ACTIVE, self::STATUS_DELETED]], + ]; + } + + public function attributes() + { + return [ + '_id', + 'username', + 'password_hash', + 'password_reset_token', + 'email', + 'auth_key', + 'role', + 'status', + 'created_at', + 'updated_at', + ]; + } /** * @inheritdoc */ public static function findIdentity($id) { - return isset(self::$users[$id]) ? new static(self::$users[$id]) : null; + return static::findOne($id); } /** @@ -41,38 +84,63 @@ public static function findIdentity($id) */ public static function findIdentityByAccessToken($token, $type = null) { - foreach (self::$users as $user) { - if ($user['accessToken'] === $token) { - return new static($user); - } - } - - return null; + return static::findOne(['auth_key' => $token]); } /** * Finds user by username * - * @param string $username + * @param string $username * @return static|null */ public static function findByUsername($username) { - foreach (self::$users as $user) { - if (strcasecmp($user['username'], $username) === 0) { - return new static($user); - } - } + return static::findOne(['username' => $username, 'status' => self::STATUS_ACTIVE]); + } - return null; + public static function findByEmail($email) + { + return static::findOne(['email' => $email, 'status' => self::STATUS_ACTIVE]); } + /** + * Finds user by password reset token + * + * @param string $token password reset token + * @return static null + */ + public static function findByPasswordResetToken($token) { + if (! static::isPasswordResetTokenValid($token)) { + return null; + } + return static::findOne([ + 'password_reset_token' => $token, + 'status' => self::STATUS_ACTIVE + ]); + } + + /** + * Finds out if password reset token is valid + * + * @param string $token password reset token + * @return boolean + */ + public static function isPasswordResetTokenValid($token) { + if (empty($token)){ + return false; + } + $expire = Yii::$app->params['user.passwordResetTokenExpire']; + $parts = explode( '_', $token ); + $timestamp = (int)end($parts); + return $timestamp + $expire >= time(); + } + /** * @inheritdoc */ public function getId() { - return $this->id; + return $this->getPrimaryKey(); } /** @@ -80,7 +148,7 @@ public function getId() */ public function getAuthKey() { - return $this->authKey; + return $this->auth_key; } /** @@ -88,17 +156,52 @@ public function getAuthKey() */ public function validateAuthKey($authKey) { - return $this->authKey === $authKey; + return $this->getAuthKey() === $authKey; } /** * Validates password * - * @param string $password password to validate - * @return bool if password provided is valid for current user + * @param string $password password to validate + * @return boolean if password provided is valid for current user */ public function validatePassword($password) { - return $this->password === $password; + return \Yii::$app->security->validatePassword($password, $this->password_hash); + } + + /** + * Generates password hash from password and sets it to the model + * + * @param string $password + */ + public function setPassword($password) + { + $this->password_hash = \Yii::$app->security->generatePasswordHash($password); + } + + /** + * Generates "remember me" authentication key + */ + public function generateAuthKey() + { + $this->auth_key = \Yii::$app->security->generateRandomString(); + } + + /** + * Generates new password reset token + */ + public function generatePasswordResetToken() + { + $this->password_reset_token = \Yii::$app->security->generateRandomString() . '_' . time(); + } + + /** + * Removes password reset token + */ + public function removePasswordResetToken() + { + $this->password_reset_token = null; } -} + +} \ No newline at end of file diff --git a/modules/api/controllers/DefaultController.php b/modules/api/controllers/DefaultController.php new file mode 100644 index 000000000..b7f708291 --- /dev/null +++ b/modules/api/controllers/DefaultController.php @@ -0,0 +1,34 @@ + CompositeAuth::className(), + 'authMethods' => [ + HttpBasicAuth::className(), + HttpBearerAuth::className(), + QueryParamAuth::className(), + ], + ]; + + return $behaviors; + } +} diff --git a/modules/api/v1.php b/modules/api/v1.php new file mode 100644 index 000000000..31d3f1b9c --- /dev/null +++ b/modules/api/v1.php @@ -0,0 +1,24 @@ + +beginPage() ?> + + + + + + + <?= Html::encode($this->title) ?> + head() ?> + + +beginBody() ?> + +
+ 'My Company', + 'brandUrl' => Yii::$app->homeUrl, + 'options' => [ + 'class' => 'navbar-inverse navbar-fixed-top', + ], + ]); + echo NavX::widget([ + 'options' => ['class' => 'navbar-nav navbar-right'], + 'items' => [ + ['label' => 'Home', 'url' => ['/site/index']], + ['label' => 'About', 'url' => ['/site/about']], + ['label' => 'Contact', 'url' => ['/site/contact']], + Yii::$app->user->isGuest ? ( + ['label' => 'Login', 'url' => ['/site/login']] + ) : ( + '
  • ' + . Html::beginForm(['/site/logout'], 'post') + . Html::submitButton( + 'Logout (' . Yii::$app->user->identity->username . ')', + ['class' => 'btn btn-link logout'] + ) + . Html::endForm() + . '
  • ' + ) + ], + ]); + NavBar::end(); + ?> + +
    + isset($this->params['breadcrumbs']) ? $this->params['breadcrumbs'] : [], + ]) ?> + +
    +
    + + + +endBody() ?> + + +endPage() ?> diff --git a/views/layouts/content.php b/views/layouts/content.php new file mode 100644 index 000000000..38c9442e7 --- /dev/null +++ b/views/layouts/content.php @@ -0,0 +1,235 @@ + +
    +
    + blocks['content-header'])) { ?> +

    blocks['content-header'] ?>

    + +

    + title !== null) { + echo \yii\helpers\Html::encode($this->title); + } else { + echo \yii\helpers\Inflector::camel2words( + \yii\helpers\Inflector::id2camel($this->context->module->id) + ); + echo ($this->context->module->id !== \Yii::$app->id) ? 'Module' : ''; + } ?> +

    + + + isset($this->params['breadcrumbs']) ? $this->params['breadcrumbs'] : [], + ] + ) ?> +
    + +
    + + +
    +
    + + + + + + +
    \ No newline at end of file diff --git a/views/layouts/header.php b/views/layouts/header.php new file mode 100644 index 000000000..63b0a4553 --- /dev/null +++ b/views/layouts/header.php @@ -0,0 +1,271 @@ + + +
    + + APP' . Yii::$app->name . '', Yii::$app->homeUrl, ['class' => 'logo']) ?> + + +
    diff --git a/views/layouts/left.php b/views/layouts/left.php new file mode 100644 index 000000000..981578d03 --- /dev/null +++ b/views/layouts/left.php @@ -0,0 +1,71 @@ + diff --git a/views/layouts/main-login.php b/views/layouts/main-login.php new file mode 100644 index 000000000..c6525db90 --- /dev/null +++ b/views/layouts/main-login.php @@ -0,0 +1,29 @@ + +beginPage() ?> + + + + + + + <?= Html::encode($this->title) ?> + head() ?> + + + +beginBody() ?> + + + +endBody() ?> + + +endPage() ?> diff --git a/views/layouts/main.php b/views/layouts/main.php index 4d256e45b..329db7ae1 100644 --- a/views/layouts/main.php +++ b/views/layouts/main.php @@ -1,78 +1,65 @@ -beginPage() ?> - - - - - - - <?= Html::encode($this->title) ?> - head() ?> - - -beginBody() ?> +if (Yii::$app->controller->action->id === 'login') { +/** + * Do not use this code in your template. Remove it. + * Instead, use the code $this->layout = '//main-login'; in your controller. + */ + echo $this->render( + 'main-login', + ['content' => $content] + ); +} else { + + if (class_exists('backend\assets\AppAsset')) { + backend\assets\AppAsset::register($this); + } else { + app\assets\AppAsset::register($this); + } -
    - 'My Company', - 'brandUrl' => Yii::$app->homeUrl, - 'options' => [ - 'class' => 'navbar-inverse navbar-fixed-top', - ], - ]); - echo Nav::widget([ - 'options' => ['class' => 'navbar-nav navbar-right'], - 'items' => [ - ['label' => 'Home', 'url' => ['/site/index']], - ['label' => 'About', 'url' => ['/site/about']], - ['label' => 'Contact', 'url' => ['/site/contact']], - Yii::$app->user->isGuest ? ( - ['label' => 'Login', 'url' => ['/site/login']] - ) : ( - '
  • ' - . Html::beginForm(['/site/logout'], 'post') - . Html::submitButton( - 'Logout (' . Yii::$app->user->identity->username . ')', - ['class' => 'btn btn-link logout'] - ) - . Html::endForm() - . '
  • ' - ) - ], - ]); - NavBar::end(); + dmstr\web\AdminLteAsset::register($this); + + $directoryAsset = Yii::$app->assetManager->getPublishedUrl('@vendor/almasaeed2010/adminlte/dist'); ?> + beginPage() ?> + + + + + + + <?= Html::encode($this->title) ?> + head() ?> + + + beginBody() ?> +
    -
    - isset($this->params['breadcrumbs']) ? $this->params['breadcrumbs'] : [], - ]) ?> - -
    -
    + render( + 'header.php', + ['directoryAsset' => $directoryAsset] + ) ?> + + render( + 'left.php', + ['directoryAsset' => $directoryAsset] + ) + ?> -
    -
    -

    © My Company

    + render( + 'content.php', + ['content' => $content, 'directoryAsset' => $directoryAsset] + ) ?> -

    -
    -endBody() ?> - - -endPage() ?> + endBody() ?> + + + endPage() ?> + diff --git a/views/site/confirmLogin.php b/views/site/confirmLogin.php new file mode 100644 index 000000000..144c52818 --- /dev/null +++ b/views/site/confirmLogin.php @@ -0,0 +1,36 @@ +title = 'Please confirm your login'; +echo Alert::widget(); +?> + \ No newline at end of file diff --git a/views/site/login.php b/views/site/login.php index 0944d37e4..54d675b69 100644 --- a/views/site/login.php +++ b/views/site/login.php @@ -1,47 +1,85 @@ -title = 'Login'; +$this->title = Yii::t('app', 'Login'); $this->params['breadcrumbs'][] = $this->title; ?> -