Good evening everyone! Help please, on the site created with the help of yii2 I want to make a personal money account of the user .. But when a user is authorized, this will crash:

Call to a member function get() on null 

Link to website: coinfactory.pw

I have a module from the yii2-user dextrium on my site

I redefined the two User.php and RegistrationForm.php models:

User.php

 <?php namespace app\models; use dektrium\user\models\User as BaseUser; class User extends BaseUser { public function getBalance() { return $this->hasOne(UserBalance::className(), ['user_id' => 'id']); } 

}

RegistrationForm.php

 <?php namespace app\models; use dektrium\user\models\RegistrationForm as BaseRegistrationForm; class RegistrationForm extends BaseRegistrationForm { public function signup() { \Yii::$app->db->transaction(function() { (new UserBalance([ 'user_id' => $this->id, 'silver_in' => 100 ]))->save(); // increase setting $value = SettingHelper::get('user.count') + rand(1, 10); SettingHelper::set('user.count', $value); }); } } 

Configuration site where web.php models are redefined:

 'modules' => [ 'rbac' => 'dektrium\rbac\RbacWebModule', 'user' => [ 'class' => \dektrium\user\Module::className(), // 'identityClass' => 'dektrium\user\models\User', // 'identityClass' => 'dektrium\user\models\RegistrationForm', 'mailer' => [ //'sender' => 'no-reply@myhost.com', // or ['no-reply@myhost.com' => 'Sender name'] 'sender' => 'example@yandex.ru', 'welcomeSubject' => 'Welcome subject', 'confirmationSubject' => 'Confirmation subject', 'reconfirmationSubject' => 'Email change subject', 'recoverySubject' => 'Recovery subject', ], 'controllerMap' => [ 'registration' => [ 'class' => \dektrium\user\controllers\RegistrationController::className(), 'on ' . \dektrium\user\controllers\RegistrationController::EVENT_AFTER_REGISTER => function ($e) { Yii::$app->response->redirect(array('/user/security/login'))->send(); Yii::$app->end(); } ], ], 'modelMap' => [ 'User' => 'app\models\User', 'RegistrationForm' => 'app\models\RegistrationForm', ], 'enableUnconfirmedLogin' => true, 'enableFlashMessages' => true, 'enableRegistration' => true, 'enableGeneratingPassword' => true, 'enableUnconfirmedLogin' => false, 'enablePasswordRecovery' => true, 'enableAccountDelete' => false, 'emailChangeStrategy' => '\dektrium\user\Module::STRATEGY_DEFAULT', 'recoverWithin' => 21600, 'confirmWithin' => 21600, 'cost' => 12, 'admins' => ['admin'] ], ], 

UserBalance.php

 <?php namespace app\models; use app\helpers\BalanceHelper; use yii\base\InvalidParamException; use yii\db\ActiveRecord; class UserBalance extends ActiveRecord { const CURRENCY_SILVER_IN = 'silver_in'; const CURRENCY_SILVER_OUT = 'silver_out'; const CURRENCY_GOLD_IN = 'gold_in'; const CURRENCY_GOLD_OUT = 'gold_out'; const CURRENCY_FACTORY_ONE = 'factory_one'; const CURRENCY_FACTORY_TWO = 'factory_two'; public static function tableName() { return '{{%user_balance}}'; } public function rules() { return [ ['user_id', 'integer'], ]; } public function attributeLabels() { return [ 'silver_in' => \Yii::t('app', 'Серебро'), 'silver_out' => \Yii::t('app', 'Серебро на вывод'), 'gold_in' => \Yii::t('app', 'Золото'), 'gold_out' => \Yii::t('app', 'Золото на вывод'), 'factory_one' => \Yii::t('app', 'Фабрика 1'), 'factory_two' => \Yii::t('app', 'Фабрика 2'), ]; } public function getUser() { return $this->hasOne(User::className(), ['id' => 'user_id']); } public function get($currency) { $currentSum = \Yii::$app->db->createCommand(' SELECT `'.$currency.'` FROM {{%user_balance}} WHERE `user_id` = :user_id', [ ':user_id' => $this->user_id ])->queryScalar(); return BalanceHelper::toDigits($currency, $currentSum); } public function has($currency, $sum) { $currentSum = \Yii::$app->db->createCommand(' SELECT `'.$currency.'` FROM {{%user_balance}} WHERE `user_id` = :user_id', [ ':user_id' => $this->user_id ])->queryScalar(); return $currentSum >= BalanceHelper::toCoins($currency, $sum); } public function decrease($currency, $sum) { if ($this->has($currency, $sum)) { $sum = BalanceHelper::toCoins($currency, $sum); $rows = \Yii::$app->db->createCommand(' UPDATE {{%user_balance}} SET `' . $currency . '` = `' . $currency . '` - :sum WHERE `' . $currency . '` >= :sum AND `user_id` = :user_id', [ ':sum' => $sum, ':user_id' => $this->user_id ])->execute(); return $rows > 0; } return false; } public function increase($currency, $sum) { $sum = BalanceHelper::toCoins($currency, $sum); $rows = \Yii::$app->db->createCommand(' UPDATE {{%user_balance}} SET `' . $currency . '` = `' . $currency . '` + :sum WHERE `user_id` = :user_id', [ ':sum' => $sum, ':user_id' => $this->user_id ])->execute(); return $rows > 0; } public static function getCurrencyArray() { return [ self::CURRENCY_SILVER_IN => \Yii::t('app', 'Серебро'), self::CURRENCY_SILVER_OUT => \Yii::t('app', 'Серебро на вывод'), self::CURRENCY_GOLD_IN => \Yii::t('app', 'Золото'), self::CURRENCY_GOLD_OUT => \Yii::t('app', 'Золото на вывод'), self::CURRENCY_FACTORY_ONE => \Yii::t('app', 'Фабрика 1'), self::CURRENCY_FACTORY_TWO => \Yii::t('app', 'Фабрика 2'), ]; } public function getCurrencyString() { $currencies = self::getCurrencyArray(); return isset($currencies[$this->currency]) ? $currencies[$this->currency] : ''; } } 

But actually the file where the error is shown

main.php:

 <?php if (!\Yii::$app->user->isGuest) { ?> <div class="main-p"> <p><a href="#"><i class="fa fa-home" aria-hidden="true"></i>Серебро</a> <?= \Yii::$app->user->identity->balance->get(UserBalance::CURRENCY_SILVER_IN) ?> <p><a href="#"><i class="fa fa-home" aria-hidden="true"></i>Серебро на вывод</a></li> <?= \Yii::$app->user->identity->balance->get(UserBalance::CURRENCY_SILVER_OUT) ?> <p><a href="#"><i class="fa fa-home" aria-hidden="true"></i>Золото</a></li> <?= \Yii::$app->user->identity->balance->get(UserBalance::CURRENCY_GOLD_IN) ?> <p><a href="#"><i class="fa fa-home" aria-hidden="true"></i>Золото на вывод</a></li> <?= \Yii::$app->user->identity->balance->get(UserBalance::CURRENCY_GOLD_OUT) ?> <p><a href="#"><i class="fa fa-home" aria-hidden="true"></i>Фабрика 1</a></li> <?= \Yii::$app->user->identity->balance->get(UserBalance::CURRENCY_FACTORY_ONE) ?> <p><a href="#"><i class="fa fa-home" aria-hidden="true"></i>Фабрика 2</a></li> <?= \Yii::$app->user->identity->balance->get(UserBalance::CURRENCY_FACTORY_TWO) ?> </div> <?php } ?> 

Maybe something is missing? Thanks in advance for your help.

  • Eh, and precisely because of this “code” many people spit on yii, although he has nothing to do with it :( - Peresada
  • @Peresada Good evening, what did I write wrong? I'm new to this business and just learning .. So for now, probably there are a lot of jambs .. - GaLana

1 answer 1

Probably there is no entry in the user_balance table for the current user, so Yii::$app->user->identity->balance returns null. We must do a preliminary check. And the UserBalance model, I would thoroughly refactor. For example, how does attributeLabels () differ from getCurrencyArray ()?

get and has redundant methods, and I would make save () the standard options, because this is a regular update. When it comes time to keep statistics on changes in balances, then there will be some problems with this approach.