Based on yiisoft/yii2-app-advanced, create a new repository yii2-app-advanced on github, and create a new interface application (implement RESTful-style web service services. API), implement model hierarchy: data layer, logic layer, clarify common directory, application, module inheritance, reference relationship (2)
1. Definition and specification:
Define:
(1) Data layer: Models is used to define automatic verification and automatic completion and data access interfaces related to data;
(2) Logical layer: Logics is used to define the business logic related to data;
Specification:
(1) The model class file in the /common/models directory is only allowed to be generated by the GII tool, which is a common model data layer;
(2) The model class file in the /common/logics directory is business logic-related, which is inherited to the /common/models data layer, which is the common model logic layer;
(3) The model class file needs to be referenced in the /common directory, only the model class file in /common/logics, for example:
public $modelClass =common\logics\user;
(4)/api/models, /backend/models, /frontend/models directory, the model class files are business logic related (only related to each application), inherit to /common/logics public logic layer;
(5) The model file needs to be referenced in the interface, front-end and back-end application directories, and only the corresponding model files in the respective directory are referenced, for example:
use API\models\user;
(6) The model class file in the /API/modules/v1/models directory is business logic related (only related to the module), and inherits to the /api/models application logic layer;
(7) The model class file needs to be referenced in the module directory, and only the corresponding model class file under the respective modules, for example:
public $modelClass =API\modules\v1\models\user;
2. Create a new logics directory in the common directory, which is used for the logical layer of the mysql model, as shown in Figure 1
3. Copy \common\models\loginform.php, \common\models\user.php to \common\logics, as shown in Figure 2
4. The mysql model file in the common/models directory is only generated by the gII tool, delete \common\models\loginform.php, as shown in Figure 3
5. Configure the route, use a beautiful URL, edit \frontend\config\main.php
urlmanager=>[ enablePrettyURL=> true, showscriptname=> false, rules=> [ ]#ATFP_CLOSE_Translate_span#, ],
6. International support, create a new directory \common\messages\en-us\model, \common\messages\zh-cn\model, which are respectively used in American English and Chinese for the data layer of the model; \common\messages\{language}\app.php, \common\messages\{language}\error.p hp, \common\messages\{language}\success.php, which are used to apply global messages, application error messages, and application success messages, as shown in Figure 4
app.php
<?php return[ ]#atfp_close_translate_span#;
error.php
<?php return[ 20000 =>Error, ]#atfp_close_translate_span#;
success.php
<?php return[ 10000 =>succeed, ]#atfp_close_translate_span#;
7. Configure the application language, the source language is American English, and the target language is Simplified Chinese. When the source language and the target language are the same, whether the message translation is forced, the default is false, set to true, edit \common\config\main.php
sourceLanguage=>en-us, Language=>en, components=>[ I18N=> [ translations=> [ ;=> [ class=>yii\i18n\phpMessageSource, ForceTranslation=> true, basepath=>@common/messages, FileMap=> [ app=>app.php, Error=>error.php, succeed=>success.php, ]#ATFP_CLOSE_Translate_span#, ], ], ], cache=>[ class=>Yii\Caching\FileCache, ]#ATFP_CLOSE_Translate_span#, ],
8. Open the URL: http://www.github-shuijingwan-yii2-app-advanced.localhost/gii/model , option, the namespace is common\models, at this time, it is necessary to support internationalization, overwrite \common\models\user.php, as shown in Figure 5
<?php
namespace common\models;
use yii;
/**
* this is the model class for table "{{%user}}".
;
* @property int $id
* @property string $username
* @property string $auth_key
* @property string $password_hash
* @property string $password_reset_token
* @property string $email
* @property int $status
* @property int $created_at
* @property int $updated_at
*/
class user extends \yii\db\ActiveRecord
{
/**
* @InheritDoc
*/
public static function tableName()
{
return{{%user}};
}
/**
* @InheritDoc
*/
public function rules()
{
return[
[[[username,auth_key,password_hash,email,created_at,updated_at]#ATFP_CLOSE_Translate_span#,required],
[['status', 'created_at', 'updated_at'],Integer],
[['username', 'password_hash', 'password_reset_token', 'email'],string,max=> 255],
[['auth_key'],string,max=> 32],
[['username'],unique],
[['email'],unique],
[['password_reset_token'],unique],
];
}
/**
* @InheritDoc
*/
public function attributeLabels()
{
return[
ID=> yii::t(model/user,ID,
username=> yii::t(model/user,username,
auth_key=> yii::t(model/user,auth key,
password_hash=> yii::t(model/user,Password hash,
password_reset_token=> yii::t(model/user,Password reset token,
email=> yii::t(model/user,email,
status=> yii::t(model/user,status,
created_at=> yii::t(model/user,created at,
updated_at=> yii::t(model/user,updated at,
]#atfp_close_translate_span#;
}
}
9. The mysql model file in the common/logics directory is business logic related, inherited to \common\models Data layer, open the URL: http://www.github-shuijingwan-yii2-app-advanced.localhost/gii/model , options, as shown in Figure 6
10. Based on diff, edit \common\logics\user.php, as shown in Figure 7
11. The mysql model file in the common/logics directory is business logic related, inherited to the data layer of \common\models\user
<?php
namespace common\logics;
use yii;
Use Yii\Base\NotSupportedException;
use yii\behaviors\timestampbehavior;
use yii\web\identityinterface;
/**
* this is the model class for table "{{%user}}".
;
* @property int $id
* @property string $username
* @property string $auth_key
* @property string $password_hash
* @property string $password_reset_token
* @property string $email
* @property int $status
* @property int $created_at
* @property int $updated_at
* @property string $password write-only password
*/
class user extends \common\models\user implementations identityinterface
{
const status_deleted = 0;
const status_active = 10;
/**
* @InheritDoc
*/
public function behaviors()
{
return[
TimestampBehavior::ClassName(),
]#atfp_close_translate_span#;
}
/**
* @InheritDoc
*/
public function rules()
{
return[
[[[username,auth_key,password_hash,email]#ATFP_CLOSE_Translate_span#,required],
[['status', 'created_at', 'updated_at'],Integer],
[['username', 'password_hash', 'password_reset_token', 'email'],string,max=> 255],
[['auth_key'],string,max=> 32],
[['username'],unique],
[['email'],unique],
[['password_reset_token'],unique],
['status', 'default', 'value' => self::STATUS_ACTIVE],
['status', 'in', 'range' => [self::STATUS_ACTIVE, self::STATUS_DELETED]],
];
}
/**
* @InheritDoc
*/
public static function findIdentity($id)
{
return static::findone(['id' => $id, 'status' => self::STATUS_ACTIVE]);
}
/**
* @InheritDoc
*/
public static function findIdentityByAccessToken($token, $type = null)
{
Throw New NotsUpportedException("FindIdentityByAccessToken" is not implemented.);
}
/**
* finds user by username
;
* @param string $username
* @return static|null
*/
public static function findByUsername($username)
{
return static::findone(['username' => $username, '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,
]#atfp_close_translate_span#);
}
/**
* Finds out if password reset token is valid
;
* @param string $token password reset token
* @return bool
*/
Public static function isPasswordResetTokenValid($token)
{
if (empty($token)) {
return false;
}
$timestamp = (int) substr($token, strrpos($token,_) + 1);
$expire = yii::$app->params['user.passwordResetTokenExpire'];
return $timestamp + $expire >= time();
}
/**
* @InheritDoc
*/
public function getId()
{
return $this->GetPrimaryKey();
}
/**
* @InheritDoc
*/
public function getAuthKey()
{
return $this->auth_key;
}
/**
* @InheritDoc
*/
public function validateAuthKey($AuthKey)
{
return $this->GetAuthKey() === $AuthKey;
}
/**
* validates passwords
;
* @param string $password password to validate
* @return bool if password provided is valid for current user
*/
public function validatePassword($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);
}
/**
* generate "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->GeneratorAndomString() ._. time();
}
/**
* Removes password reset token
*/
public function removePasswordResetToken()
{
$this->password_reset_token = null;
}
}
12. Create a new \common\messages\en-us\model\user.php, support the message translation when the target language is English and the United States
<?php /** * Created by phpstorm. * user: wangqiang * Date: 2018/04/04 * TIME: 10:34 */ return[ ID=>ID, username=>username, auth key=>auth key, Password hash=>Password hash, Password reset token=>Password reset token, email=>email, status=>status, created at=>created at, updated at=>updated at, ]#atfp_close_translate_span#;
13. Create a new \common\messages\zh-cn\model\user.php, which supports message translation when the target language is simplified Chinese
<?php /** * Created by phpstorm. * user: wangqiang * Date: 2018/04/04 * TIME: 10:39 */ return[ ID=>ID, username=>Username, auth key=>authentication key, Password hash=>Password hashing, Password reset token=>Password reset token, email=>Mailbox, status=>Status, created at=>creation time, updated at=>Update time, ]#atfp_close_translate_span#;
14. Create a new \api\models\user.php, the mysql model file in the api/models directory is business logic related (only related to the API), inherit to \common\logics\user logic layer
<?php
/**
* Created by phpstorm.
* user: wangqiang
* Date: 2018/04/04
* TIME: 10:44
*/
namespace api\models;
class user extends\common\logics\user
{
}
15. Copy \API\models\user.php to \frontend\models\user.php, \backend\models\user.php, and adjust to their respective namespaces
\frontend\models\user.php
<?php
/**
* Created by phpstorm.
* user: wangqiang
* Date: 2018/04/04
* TIME: 10:44
*/
namespace frontend\models;
class user extends\common\logics\user
{
}
\backend\models\user.php
<?php
/**
* Created by phpstorm.
* user: wangqiang
* Date: 2018/04/04
* TIME: 10:44
*/
namespace backend\models;
class user extends\common\logics\user
{
}
16. Search for use common\models\user in the API application, and replace it with: use api\models\user;, the same processing in the foreground and background applications, as shown in Figure 8
17. Search for common\models\user in the API application, replace it with: api\models\user, the same processing in the foreground and background applications, as shown in Figure 9
18. Edit \common\logics\loginform.php to adjust the namespace
<?php
namespace common\logics;
use yii;
use yii\base\model;
/**
* login form
*/
Class Loginform extends model
{
public $username;
public $password;
public $rememberme = true;
private $_user;
/**
* {@inheritdoc}
*/
public function rules()
{
return[
// username and password are both required
[[[username,Password]#ATFP_CLOSE_Translate_span#,required],
// rememberme must be a boolean value
['rememberMe', 'boolean'],
// password is validated by validatePassword()
['password', 'validatePassword'],
];
}
/**
* 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()) {
$user = $this->getUser();
if (!$user || !$user->validatePassword($this->password)) {
$this->addError($attribute,Incorrect username or password.);
}
}
}
/**
* Logs in a user using the provided username and password.
;
* @return bool whether the user is logged in successfully
*/
public function login()
{
if ($this->validate()) {
return yii::$app->user->login($this->getUser(), $this->rememberme ? 3600 * 24 * 30 : 0);
}
return false;
}
/**
* finds user by[[username]]
;
* @return user|null
*/
protected function getUser()
{
if ($this->_user === null) {
$this->_user = user::findByUsername($this->username);
}
return $this->_user;
}
}
19. Create a new \api\models\loginform.php, the mysql model file in the api/models directory is business logic related (only related to the API), inherited to \common\logics\loginform logic layer
<?php
/**
* Created by phpstorm.
* user: wangqiang
* Date: 2018/04/04
* TIME: 11:10
*/
namespace api\models;
class loginform extends \common\logics\loginform
{
}
20. Copy \api\models\loginform.php to \frontend\models\loginform.php, \backend\models\loginform.php, adjust to their respective namespaces
\frontend\models\loginform.php
<?php
/**
* Created by phpstorm.
* user: wangqiang
* Date: 2018/04/04
* TIME: 11:10
*/
namespace frontend\models;
class loginform extends \common\logics\loginform
{
}
\backend\models\loginform.php
<?php
/**
* Created by phpstorm.
* user: wangqiang
* Date: 2018/04/04
* TIME: 11:10
*/
namespace backend\models;
class loginform extends \common\logics\loginform
{
}
21. Search for use common\models\loginform in the API application;, replace with: use api\models\loginform;, the same processing in the foreground and background applications, as shown in Figure 10
22. Search common\models\loginform in the API application, replace it with: api\models\loginform, the same processing in the foreground and background applications, as shown in Figure 11
23. Search for common\models\user in the common directory, replace with: common\logics\user, with the exception of \common\logics\user.php, as shown in Figure 12
24. Search common\models\loginform in the common directory, replace it with: common\logics\loginform, as shown in Figure 13
25. Test the registration function, open the website: http://www.github-shuijingwan-yii2-app-advanced.localhost/site/signup, in line with expectations, as shown in Figure 14
26. Check the database, as shown in Figure 15













