Yii2: Access model value in view - php

I have a variable status declared in model. Status is a column in gridview that is populated using this:
[
'attribute' => 'status',
'contentOptions' => ['class' => 'text-center'],
'value' => function($model){
if($model->nginSum != $model->sapValue){
return 'NOK';
} else {
return 'OK';
}
},
],
I want to count the number os OKs and NOKs to display equal and diferent entries with a counter.
I've tried declaring a function in search model:
public function getStatus()
{
return $this->status;
}
and in view i did this:
$equal = 0;
$different = 0;
$stat = new EtuLojaSearch;
if ($stat->getStatus() == 'OK') {
$equal += 1;
} else {
$different += 1;
}
but it's returning null.
What am i doing wrong?
Edited:
function in model:
public function getStatus()
{
if($this->nginSum != $this->sapValue){
return 'NOK';
} else {
return 'OK';
}
}
In view:
$iguais = 0;
$diferentes = 0;
$stat = new EtuLojaSearch;
if ($stat->status == 'OK') {
$iguais += 1;
} else {
$diferentes += 1;
}
Edit 2:
Status is ot getting bound to model using getStatus() function.
Model
class EtuLoja extends \yii\db\ActiveRecord
{
public $nginSum;
public $sapValue;
public $status;
public $Data_Sap;
/**
* {#inheritdoc}
*/
public static function tableName()
{
return 'etu_loja';
}
public function getStatus()
{
if($this->nginSum != $this->sapValue){
return 'NOK';
} else {
return 'OK';
}
}
/**
* {#inheritdoc}
*/
public function rules()
{
return [
[['id_master', 'nginSum', 'sapValue'], 'integer'],
[['user'], 'required'],
[['user', 'status'], 'string', 'max' => 100],
[['Atendedora', 'Loja', 'Obs'], 'string', 'max' => 255],
[['id_master'], 'exist', 'skipOnError' => true, 'targetClass' => MasterLoja::className(), 'targetAttribute' => ['id_master' => 'id']],
];
}
/**
* {#inheritdoc}
*/
public function attributeLabels()
{
return [
'ID' => 'ETU(Slave)',
'id_master' => 'Master',
'master.regiao' => 'Master/Região',
'user' => 'User',
'Atendedora' => 'Atendedora',
'Loja' => 'Loja',
'Obs' => 'Obs',
'nginValue' => 'Valor Ngin',
'status' => 'Estado',
];
}
/**
* #return \yii\db\ActiveQuery
*/
public function getMaster()
{
return $this->hasOne(MasterLoja::className(), ['id' => 'id_master']);
}
public function getNginAgentDetail()
{
return $this->hasMany(NginAgentDetail::className(),['CLIENT_ID' => 'ID']);
}
public function getSap()
{
return $this->hasMany(Sap::className(),['Criado_por' => 'user']);
}
}
Search Model:
class EtuLojaSearch extends EtuLoja
{
public $regiao;
public $nginValue;
public $sapValue;
public $operationDate;
public $from_date;
public $to_date;
public $Data_Sap;
public function rules()
{
return [
[['ID'], 'integer'],
[['Atendedora', 'Loja', 'Obs', 'id_master', 'regiao', 'user', 'nginValue', 'sapValue', 'operationDate', 'status', 'from_date', 'to_date', 'Data_Sap'], 'safe'],
];
}
/**
* {#inheritdoc}
*/
public function scenarios()
{
// bypass scenarios() implementation in the parent class
return Model::scenarios();
}
/**
* Creates data provider instance with search query applied
*
* #param array $params
*
* #return ActiveDataProvider
*/
public function search($params)
{
$query = EtuLoja::find();
// add conditions that should always apply here
$query->joinWith('master');
// $query->joinWith('nginAgentDetail');
// $query->joinWith('sap');
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
$dataProvider->sort->attributes['Data_Sap'] = [
'asc' => ['Data_Sap' => SORT_ASC],
'desc' => ['Data_Sap' => SORT_DESC],
];
$dataProvider->sort->attributes['regiao'] = [
// The tables are the ones our relation are configured to
// in my case they are prefixed with "tbl_"
'asc' => ['master_loja.regiao' => SORT_ASC],
'desc' => ['master_loja.regiao' => SORT_DESC],
];
$this->load($params);
if (!$this->validate()) {
// uncomment the following line if you do not want to return any records when validation fails
// $query->where('0=1');
return $dataProvider;
}
// grid filtering conditions
$query->andFilterWhere([
'etu_loja.ID' => $this->ID,
// 'id_master' => $this->id_master,
]);
$query->andFilterWhere(['like', 'Atendedora', $this->Atendedora])
->andFilterWhere(['like', 'Loja', $this->Loja])
->andFilterWhere(['like', 'Obs', $this->Obs])
->andFilterWhere(['like', 'user', $this->user]);
if ($this->status === 'OK') {
$query->andWhere('nginSum = sapValue');
} elseif ($this->status === 'NOK') {
$query->andWhere('nginSum <> sapValue');
}
if(" " !== $this->operationDate) {
$query->andFilterWhere(['master_loja.regiao'=>$this->regiao]);
}
return $dataProvider;
}
}

Update your getStatus method with following.
public function getStatus()
{
if($this->nginSum != $this->sapValue){
return 'NOK';
} else {
return 'OK';
}
}
It will bind value (OK, NOK) with status attribute when active record is fetched and later on you can use that value in whatever way you wish eg $model->status. With this approach, your attribute rendering code will be like following.
[
'attribute' => 'status',
'contentOptions' => ['class' => 'text-center'],
'value' => function($model){
return $model->status;
},
],
But to count different values for status, you'll have to loop through all models i-e
$equal = 0;
$different = 0;
foreach($dataProvider->getModels() as $item){
if ($item->status == 'OK') {
$equal += 1;
} else {
$different += 1;
}
}

Related

Multi file upload + textInput - doesn't save in db (yii2)

I am using yii2 basic and wanted to make a gallery, so I made use of multi file upload. All working fine, till I added a text input ('year').
GalleryController.php
public function actionCreate()
{
$model = new MultipleUploadForm();
$year;
if (Yii::$app->request->isPost) {
$model->files = UploadedFile::getInstances($model, 'files');
if ($model->gaUpload()) {
return $this->redirect(['index']);
}
}
return $this->render('create', ['model' => $model]);
}
MultipleUploadForm :
class MultipleUploadForm extends Model
{
/**
* #var UploadedFile[] files uploaded
*/
public $files;
public $year;
public function rules()
{
return [
[['files'], 'file', 'skipOnEmpty' => false, 'maxFiles' => 0],
[['year'], 'string'],
];
}
public function gaUpload()
{
if ($this->validate()) {
foreach ($this->files as $file) {
$model2 = new Gallery();
$model2->img = $file->baseName . '_' . rand(100,999) . '.' . $file->extension;
$model2->save_dir = 'uploads/gallery/';
$model2->year = $this->year;
$file->saveAs($model2->save_dir . $model2->img);
$model2->save();
}
return true;
} else {
return false;
}
}
}
Gallery:
class Gallery extends \yii\db\ActiveRecord
{
/**
* {#inheritdoc}
*/
public static function tableName()
{
return 'cgallery';
}
/**
* {#inheritdoc}
*/
public function rules()
{
return [
[['year', 'img', 'save_dir'], 'required'],
[['img', 'save_dir', 'year'], 'string', 'max' => 1024],
];
}
/**
* {#inheritdoc}
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'year' => 'Year',
'img' => 'Img',
'save_dir' => 'Save Dir',
];
}
}
_form.php:
<?php $form = ActiveForm::begin(['options' => ['enctype' => 'multipart/form-data'], ]); ?>
<?= $form->field($model, 'year')->textInput()?>
<?php
echo '<label class="control-label">Add Pictures</label>';
echo FileInput::widget([
'model' => $model,
'attribute' => 'files[]',
'pluginOptions' => [
'showRemove' => false,
'uploadLabel' => 'Save',
'uploadIcon' => '',
'browseLabel' => '',
'fileExtensions' => 'any',
],
'options' => ['multiple' => true]
]);
?>
<?php ActiveForm::end(); ?>
If I take 'year' out of the process, like : $model2->year = '2010' it work's just fine. I might need to add, that the files get uploaded (into the dir), but it won't get saved to the database.
Has anyone an idea what i did wrong?
EDIT:
Thanks to Wynton Franklin for the help.
The solution was to add the line:
$model->load(\Yii::$app->request->post());
Changed GalleryController.php:
public function actionCreate()
{
$model = new MultipleUploadForm();
$model->load(\Yii::$app->request->post());
if (Yii::$app->request->isPost) {
$model->files = UploadedFile::getInstances($model, 'files');
if ($model->gaUpload()) {
return $this->redirect(['index']);
}
}
return $this->render('create', ['model' => $model]);
}
In your controller year is not begin set. Check that.
if (Yii::$app->request->isPost) {
$model->year = $_POST[][] // or however you do it in yii
$model->files = UploadedFile::getInstances($model, 'files');
if ($model->gaUpload()) {
return $this->redirect(['index']);
}
}

Can't send and find a query in the Class 'app \ models \' not found

I encountered such a problem, a certain query "name", which the user entered, is not stored in the database, and even this stupid error with which I can not cope at all takes off .. apparently I'm more stupid than her .. please tell me what is the catch?
Here is the error in full format:
PHP Fatal Error – yii\base\ErrorException
Class 'app\models\' not found
1. in /var/www/u0598324/public_html/webstels.com/models/ShopPromoItem.php at line 40
return [
'status' => 'Статус',
];
}
public static function get($id)
{
$item = ShopPromoItem::findOne($id);
$class = 'app\\models\\' . $item->class;
return $class::findOne($id);
}
public function getTitle()
{
return Html::encode($this->title);
}
public function getPriceArray()
{
2. yii\base\ErrorHandler::handleFatalError()
$_GET = [
'username' => 'swallowsveta1997',
];
$_POST = [
'_csrf' => '2dWdOMdf_z2HrgmbtpnKKN1f-mQnpLEkeqpEkFg8zj6OoOR-sAa2DrOcQ-GG7otyuxSIXEzn6R0M5jX5Cw2cVw==',
'ShopPromoItemBuyForm' => [
'name' => 'name',
'item_id' => '1',
],
];
$_COOKIE = [
'_identity' => 'd669e918ca5f102ab0802a521e1d3fc241689f04dbb51253b7b8ab7b54713c5ca:2:{i:0;s:9:"_identity";i:1;s:50:"[22727,"gkEvlaqhpnAtz8mz4v9Fk96QOpkIrssI",2592000]";}',
'PHPSESSID' => 'abe468adef98b859d2100b97cb6da127',
'_csrf' => '542d3bc58acd73dd28aadc1e388c74c2697098a4c8d8bb4b855417ada2ebe4ffa:2:{i:0;s:5:"_csrf";i:1;s:32:"WuyFwYI342Jz0wAZfKr8kCX9vLqiS1Ri";}',
];
$_SESSION = [
'__flash' => [],
'__id' => 22727,
'__authKey' => 'gkEvlaqhpnAtz8mz4v9Fk96QOpkIrssI',
'__expire' => 1543857954,
'__captcha/site/captcha' => 'lesafiq',
'__captcha/site/captchacount' => 1,
];
Here is the model ShopPromoItem.php:
<?php
namespace app\models;
use app\helpers\BalanceHelper;
use app\models\User;
use app\models\UserBalance;
use yii\db\ActiveRecord;
use yii\helpers\Html;
use yii\helpers\Json;
class ShopPromoItem extends ActiveRecord
{
const STATUS_ENABLED = 'enabled';
const STATUS_DISABLED = 'disabled';
const STATUS_DELETED = 'deleted';
public static function tableName()
{
return '{{%shop_promo_item}}';
}
public function rules()
{
return [
];
}
public function attributeLabels()
{
return [
'status' => 'Статус',
];
}
public static function get($id)
{
$item = ShopPromoItem::findOne($id);
$class = '#app/models/' . $item->class;
return $class::findOne($id);
}
public function getTitle()
{
return Html::encode($this->title);
}
public function getPriceArray()
{
return Json::decode($this->price);
}
public function getPriceString()
{
$prices = $this->getPriceArray();
$result = '';
foreach ($prices as $currency => $price) {
$result .= '<img src="/images/' . $currency . '.png" style="vertical-align: middle; width: 24px;"> ' . BalanceHelper::convertToDigits($price);
}
return $result;
}
public function giveTo(User $user)
{
}
}
Here is ShopPromoItemBuyForm.php:
<?php
namespace app\models\forms;
use app\helpers\BalanceHelper;
use app\helpers\RefererHelper;
use app\helpers\SettingHelper;
use app\models\ShopPromoItem;
use app\models\User;
use app\models\UserPromo;
use app\models\UserBalance;
use app\models\UserOperation;
use yii\validators\IpValidator;
class ShopPromoItemBuyForm extends UserPromo
{
public $item_id;
public function rules()
{
return [
['item_id', 'required'],
['item_id', 'integer'],
['item_id', 'exist',
'targetClass' => '\app\models\ShopPromoItem',
'targetAttribute' => 'id',
'filter' => ['status' => ShopPromoItem::STATUS_ENABLED]
],
['name', 'multProtect']
];
}
public function scenarios()
{
return [
self::SCENARIO_DEFAULT => ['name']
];
}
public function multProtect()
{
return;
// disable for debug mode
if (YII_DEBUG)
return;
// check evercookie
if (isset($_COOKIE['was_promo']) && $_COOKIE['was_promo'] == "true") {
$this->addError('name', \Yii::t('app', 'Вы уже заказывали сайт с таким названием на проекте, повторный заказ сайта с таким именем запрещён'));
}
$validator = new IpValidator();
if ($validator->validate(\Yii::$app->request->userPromoIP)) {
$ip = \Yii::$app->request->userPromoIP;
$userPromo = UserPromo::find()->where(['id' => $ip])->limit(1)->one();
if ($userPromo !== null) {
$this->addError('name', \Yii::t('app', 'Вы уже заказывали сайт с таким названием на проекте, повторный заказ сайта с таким именем запрещён'));
}
} else {
$this->addError('name', \Yii::t('app', 'Вы уже заказывали сайт с таким названием на проекте, повторный заказ сайта с таким именем запрещён'));
}
}
public function buy(User $user)
{
if (!$this->validate()) {
\Yii::$app->getSession()->setFlash('warning', implode('<br />', $this->getFirstErrors()));
return false;
}
if (\Yii::$app->mutex->acquire('balance_' . $user->id)) {
\Yii::$app->db->transaction(function() use ($user) {
$item = ShopPromoItem::get($this->item_id);
$prices = $item->getPriceArray();
// check balance
foreach ($prices as $currency => $price) {
if (!$user->balance->has($currency, BalanceHelper::convertToDigits($price))) {
\Yii::$app->getSession()->setFlash('warning', \Yii::t('app', 'Недостаточно средств на балансе'));
return false;
}
}
// decrease balance
foreach ($prices as $currency => $price) {
$user->balance->decrease($currency, BalanceHelper::convertToDigits($price));
$user->operation->create(UserOperation::OPERATION_SHOP_PROMO_BUY, $currency, BalanceHelper::convertToDigits($price), [
'ShopPromoItem_id' => $this->item_id
]);
}
$item->giveTo($user);
// give reward to referer
RefererHelper::giveReward($user, UserBalance::CURRENCY_USD, BalanceHelper::convertToDigits($prices['usd']));
$message = '';
foreach ($prices as $currency => $price) {
$message .= \Yii::t('app', '{sum} долларов', ['sum' => BalanceHelper::convertToDigits($price)]);
}
\Yii::$app->getSession()->setFlash('success', \Yii::t('app', 'Вы купили «{title}»', ['title' => \Yii::t('app', $item->getTitle())]) .
'<br />' . \Yii::t('app', 'Потрачено {price}', ['price' => $message]));
return true;
});
}
}
}
UserPromo.php:
<?php
namespace app\models;
use yii\db\ActiveRecord;
use yii\helpers\Html;
class UserPromo extends ActiveRecord
{
const STATUS_ENABLED = 'enabled';
const STATUS_DISABLED = 'disabled';
const STATUS_DELETED = 'deleted';
public static function tableName()
{
return '{{%user_promo}}';
}
public function rules()
{
return [
['id', 'exist'],
['user_id', 'integer'],
['name', 'required'],
['name', 'filter', 'filter' => 'trim'],
['name', 'match', 'pattern' => '#^[\w_-]+$#i'],
['name', 'unique', 'targetClass' => self::className(), 'message' => \Yii::t('app', 'Указанное название для вашего сайта уже занято')],
['name', 'string', 'min' => 2, 'max' => 255],
];
}
public function attributeLabels()
{
return [
'status' => 'Статус',
'name' => \Yii::t('app', 'Название'),
];
}
public static function findIdentity($id)
{
$identity = static::findOne(['id' => $id]);
return $identity;
}
public static function findByName($name)
{
return static::findOne(['name' => $name]);
}
public function getName()
{
return Html::encode($this->name);
}
public function getPromo()
{
return $this->hasOne(Promo::className(), ['id' => 'promo_id']);
}
public function getUser()
{
return $this->hasOne(User::className(), ['id' => 'user_id']);
}
public function getTitle()
{
return $this->promo->getTitle();
}
public function getType()
{
return $this->promo->getType();
}
public function getProfit($type)
{
return $this->promo->{$type . '_profit'};
}
}
PromoSiteShopItem.php:
<?php
namespace app\models;
use app\helpers\BalanceHelper;
use app\helpers\SettingHelper;
class PromoSiteShopItem extends ShopPromoItem
{
public function giveTo(User $user)
{
(new UserPromo([
'user_id' => $user->id,
'promo_id' => 21,
'created_at' => time(),
'status' => UserPromo::STATUS_ENABLED
]))->save(false);
$prices = $this->getPriceArray();
// increase reserve
$value = SettingHelper::get('reserve.promo.sum') + intval(BalanceHelper::convertToDigits($prices['usd']) / 100 * 50);
SettingHelper::set('reserve.promo.sum', $value);
}
}
Promo.php:
<?php
namespace app\models;
use yii\db\ActiveRecord;
use yii\helpers\Html;
class Promo extends ActiveRecord
{
const TYPE_PROMO = 'promo';
const STATUS_ENABLED = 'enabled';
const STATUS_DISABLED = 'disabled';
const STATUS_DELETED = 'deleted';
public static function tableName()
{
return '{{%promo}}';
}
public function rules()
{
return [
['user_id', 'integer'],
];
}
public function attributeLabels()
{
return [
'status' => 'Статус',
];
}
public function getType()
{
return $this->type;
}
public function getTitle()
{
return Html::encode($this->title);
}
}
Controller:
<?php
namespace app\controllers\user\main\services;
use app\components\Controller;
use app\models\ShopPromoItem;
use app\models\forms\ShopPromoItemBuyForm;
use yii\filters\AccessControl;
use yii\web\ForbiddenHttpException;
use yii\filters\VerbFilter;
use yii\helpers\Url;
use app\models\UserPromo;
class PromoController extends Controller
{
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'rules' => [
[
'allow' => true,
'roles' => ['#'],
],
],
],
];
}
public function beforeAction($action)
{
if (\Yii::$app->params['user']['promo']['temporaryDisabled']) {
throw new ForbiddenHttpException('Заказ временно приостановлен');
}
return parent::beforeAction($action);
}
public function actionIndex()
{
$this->layout = 'page';
$items = ShopPromoItem::find()->where([
'status' => ShopPromoItem::STATUS_ENABLED
])->all();
$model = new ShopPromoItemBuyForm();
if ($model->load(\Yii::$app->request->post())) {
$model->buy(\Yii::$app->user->identity);
}
$promo = UserPromo::find()->where([
'user_id' => \Yii::$app->user->identity->id,
'status' => UserPromo::STATUS_ENABLED
])->with('promo')->orderBy('promo_id DESC')->all();
return $this->render('index', [
'items' => $items,
'model' => $model,
'promo' => $promo,
]);
}
}

Integrity constraint violation – yii\db\IntegrityException Yii2

When I signup and input data username, email and password. Field username is null, i don't know why. And then when I input again data username, email and password the result is error. The description error can see in the picture.
Code for models/User.php :
<?php
namespace app\models;
use Yii;
use yii\web\IdentityInterface;
use yii\db\ActiveRecord;
use yii\behaviors\TimestampBehavior;
class User extends ActiveRecord implements IdentityInterface
{
const STATUS_DELETED = 0;
const STATUS_ACTIVE = 10;
public $id;
public $username;
public $password;
public $authKey;
public $accessToken;
public static function tableName()
{
return '{{%user}}';
}
public function behaviors()
{
return
[
TimestampBehavior::className(),
];
}
public function actionLogin()
{
if (!\Yii::$app->user->isGuest) {
return $this->goHome();
}
$model = new LoginForm();
if ($model->load(Yii::$app->request->post()) && $model->login()) {
return $this->goBack();
}
return $this->render('login', [
'model' => $model,
]);
}
public function actionLogout()
{
Yii::$app->user->logout();
return $this->goHome();
}
public function rules()
{
return
[
['status', 'default', 'value' => self::STATUS_ACTIVE],
['status', 'in', 'range' => [self::STATUS_ACTIVE, self::STATUS_DELETED]],
];
}
/**
private static $users = [
'100' => [
'id' => '100',
'username' => 'admin',
'password' => 'admin',
'authKey' => 'test100key',
'accessToken' => '100-token',
],
'101' => [
'id' => '101',
'username' => 'demo',
'password' => 'demo',
'authKey' => 'test101key',
'accessToken' => '101-token',
],
]; */
/**
* #inheritdoc
*/
public static function findIdentity($id)
{
return static::findOne(['id' => $id, 'status' => self::STATUS_ACTIVE]);
}
/**
* #inheritdoc
*/
public static function findIdentityByAccessToken($token, $type = null)
{
}
/**
* Finds user by username
*
* #param string $username
* #return static|null
*/
public static function findByUsername($username)
{
return static::findOne(['username' => $username, 'status' => self::STATUS_ACTIVE]);
}
/**
* #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 password
*
* #param string $password password to validate
* #return boolean if password provided is valid for current user
*/
public function validatePassword($password)
{
return Yii::$app->security->validatePassword($password, $this->password_hash);
}
public function generatePasswordResetToken()
{
$this->password_reset_token = Yii::$app->security->generateRandomString() . '_' . time();
}
public function removePasswordResetToken()
{
$this->password_reset_token = null;
}
public function setPassword($password)
{
$this->password_hash = Yii::$app->security->generatePasswordHash($password);
}
public function generateAuthKey()
{
$this->auth_key = Yii::$app->security->generateRandomString();
}
}
Code for models/SignupForm.php :
<?php
namespace app\models;
use app\models\User;
use yii\base\Model;
use Yii;
class SignupForm extends Model
{
public $username;
public $email;
public $password;
public function rules()
{
return
[
['username', 'filter', 'filter' => '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', 'string', 'max' => 255],
['email', 'unique', 'targetClass' => '\app\models\User', 'message' => 'This email address has already
been taken'],
['password', 'required'],
['password', 'string', 'min' => 6],
];
}
public function signup()
{
if ($this->validate())
{
$user = new user();
$user->username = $this->username;
$user->email = $this->email;
$user->setPassword($this->password);
$user->generateAuthKey();
if ($user->save())
{
return $user;
}
}
return null;
}
}
Code controllers/siteController.php :
<?php
namespace app\controllers;
use Yii;
use yii\filters\AccessControl;
use yii\web\Controller;
use yii\filters\VerbFilter;
use app\models\LoginForm;
use app\models\ContactForm;
use app\components\AuthHandler;
use app\models\UserSocialMedia;
use app\models\User;
use app\helpers\Url;
class SiteController extends Controller
{
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'only' => ['logout'],
'rules' => [
[
'actions' => ['logout'],
'allow' => true,
'roles' => ['#'],
],
],
],
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'logout' => ['post'],
],
],
];
}
public function actions()
{
return [
'error' => [
'class' => 'yii\web\ErrorAction',
],
'captcha' => [
'class' => 'yii\captcha\CaptchaAction',
'fixedVerifyCode' => YII_ENV ? 'testme' : null,
],
'auth' => [
'class' => 'yii\authclient\AuthAction',
'successCallback' => [$this, 'successCallback'],
],
];
}
public function successCallback($client)
{
// call safeAttributes method for properly format data
$attributes = $this->safeAttributes($client);
}
public function safeAttributes($client)
{
// get user data from client
$attributes = $client->getUserAttributes();
// set default value
$safe_attributes = [
'social_media' => '',
'id' => '',
'username' => '',
'name' => '',
'email' => '',
];
// get value from user attributes base on social media
if ($client instanceof \yii\autclient\client\Facebook)
{
$safe_attributes = [
'social_media' => 'facebook',
'id' => $attributes['id'],
'username' => $attributes['email'],
'name' => $attributes['name'],
'email' => $attributes['email'],
];
}
else if ($client instanceof \yii\autclient\client\Google)
{
$safe_attributes = [
'social_media' => 'google',
'id' => $attributes['id'],
'username' => $attributes['emails'] ['0'] ['value'],
'name' => $attributes['displayName'],
'email' => $attributes['emails'] ['0'] ['value'],
];
}
else if ($client instanceof \yii\autclient\client\Twitter)
{
$safe_attributes = [
'social_media' => 'twitter',
'id' => $attributes['id'],
'username' => $attributes['screen_name'],
'name' => $attributes['name'],
'email' => '-',
];
}
else if ($client instanceof \yii\autclient\client\Github)
{
$safe_attributes = [
'social_media' => 'github',
'id' => $attributes['id'],
'username' => $attributes['login'],
'name' => $attributes['name'],
'email' => $attributes['email'],
];
}
return $safe_attributes;
}
public function actionIndex()
{
return $this->render('index');
}
public function actionLogin()
{
if (!\Yii::$app->user->isGuest) {
return $this->goHome();
}
$model = new LoginForm();
if ($model->load(Yii::$app->request->post()) && $model->login()) {
return $this->goBack();
}
return $this->render('login', [
'model' => $model,
]);
}
public function actionLogout()
{
Yii::$app->user->logout();
return $this->goHome();
}
public function actionContact()
{
$model = new ContactForm();
if ($model->load(Yii::$app->request->post()) && $model->contact(Yii::$app->params['adminEmail'])) {
Yii::$app->session->setFlash('contactFormSubmitted');
return $this->refresh();
}
return $this->render('contact', [
'model' => $model,
]);
}
public function actionAbout()
{
return $this->render('about');
}
public function actionCommentary()
{
$model = new \app\models\Commentary();
// return $this->render('commentary',['model' => $model,]);
// Jika form di sumbit dengan method POST
if (Yii::$app->request->post())
{
$model->load(Yii::$app->request->post());
if($model->validate()){
Yii::$app->session->setFlash('success','Thank You');
}
else {
Yii::$app->session->setFlash('error','Sorry, something wrong');
}
return $this->render('result_commentary',['model'=>$model,]);
}
else{
return $this->render('commentary',['model'=>$model,]);
}
}
public function actionQuery()
{
$db = Yii::$app->db;
$command = $db->createCommand('SELECT * FROM employee');
$employees = $command->queryAll();
// Ekstrak data
foreach ($employees as $employee)
{
echo "<br>";
echo $employee['id']." ";
echo $employee['name']." ";
echo $employee['age']." ";
}
}
public function actionQuery2()
{
$db= Yii::$app->db;
// return a single row
$employee = $db->createCommand('SELECT * FROM employee where id=1')
->queryOne();
echo $employee['id']." ";
echo $employee['name']." ";
echo "(".$employee['age'].")";
echo "<hr>";
// return a single column (the first column)
$names = $db->createCommand('SELECT name FROM employee')->
queryColumn();
print_r($names);
echo "<hr>";
// Binding Parameter
$employee = $db->createCommand('SELECT * FROM employee WHERE id=:id'
,['id'=>2])->queryOne();
// INSERT (table name, column values)
//$db->createCommand()->insert('employee',['name'=>'Nur','age'=>'99',
// ])->execute();
// UPDATE (table name, column values, condition)
//$db->createCommand()->update('employee',['age'=>'30'], 'id = 7')
//->execute();
// DELETE (table name, condition)
//$db->createCommand()->delete('employee', 'id = 7')
//->execute();
// table name, column name, column values
$db->createCommand()->batchInsert('employee',
['name', 'age'],
[
['Nur', 25],
['Dani', 32],
['Nurul', 40],
])->execute();
}
public function actionActiveRecord()
{
$employees = \app\models\Employee::find()->all();
foreach($employees as $employee)
{
echo "<br>";
echo $employee->id." ";
echo $employee->name." ";
echo "(".$employee->age.") ";
}
}
public function actionSignup()
{
$model = new \app\models\SignupForm();
// use session
$session = Yii::$app->session;
$attributes = $session['attributes'];
if ($model->load(Yii::$app->request->post()))
{
if ($user = $model->signup())
{
if ($session->has('attributes'))
{
// add data user_social_media
$user_social_media = new UserSocialMedia([
'social_media' => $attributes['social_media'],
'id' => (string)$attributes['id'],
'username' => $attributes['username'],
'user_id' => $user->id,
]);
$user_social_media->save();
}
if (Yii::$app->getUser()->login($user))
{
return $this->goHome();
}
}
}
if ($session->has('attributes'))
{
// set form field with data from social media
$model->username = $attributes['username'];
$model->email = $attributes['email'];
}
return $this->render('signup', ['model' => $model,
]);
}
}
Remove User model attributes' declarations that are present in your database table:
public $id;
public $username;
These will be handled by ActiveRecord and by adding it manually you are preventing this process.

Yii2 Custom Validation function not called

I need to make my custom validation rule to warn the user either email or phone_number field is required , but the custom validation function not called
my code so far :
Model
namespace backend\models;
use Yii;
class Advertisement extends \yii\db\ActiveRecord
{
/**
* #inheritdoc
*/
public static function tableName()
{
return 'advertisement';
}
/**
* #inheritdoc
*/
public function rules()
{
return [
[['position', 'location', 'status'], 'required'],
[['description'], 'string'],
[[ 'phone_number', 'company'], 'integer'],
[['created_at', 'updated_at','date_added'], 'safe'],
[['position', 'email', 'location', ], 'string', 'max' => 255],
[['phone_number','email'], 'myRule'],
];
}
public function myRule($attribute, $params)
{
if (empty($this->email)
&& empty($this->phone_number)
) {
$this->addError($attribute, Yii::t('ap', 'either Phone or Email required'));
return false;
}
return true;
}
/**
* #inheritdoc
*/
public function attributeLabels()
{
return [
'id' => Yii::t('app', 'ID'),
'position' => Yii::t('app', 'Position'),
'description' => Yii::t('app', 'Description'),
'email' => Yii::t('app', 'Email'),
'phone_number' => Yii::t('app', 'Phone Number'),
'created_at' => Yii::t('app', 'Created At'),
'updated_at' => Yii::t('app', 'Updated At'),
'company' => Yii::t('app', 'Company'),
'status' => Yii::t('app', 'Status'),
];
}
/**
* #return \yii\db\ActiveQuery
*/
public function getCompany0()
{
return $this->hasOne(User::className(), ['id' => 'company']);
}
}
controller action
public function actionCreate()
{
$model = new Advertisement();
if ($model->load(Yii::$app->request->post()) ) {
$model->company = Yii::$app->user->identity->id;
$model->created_at = date("Y-m-d H:i:s");
$model->date_added = date("Y-m-d H:i:s");
$model->save();
return $this->redirect(['view', 'id' => $model->id]);
} else {
return $this->render('create', [
'model' => $model,
]);
}
}
any help ?
You need to disable skipOnEmpty property of Validator for it .. For More Info Read
Update your code as
[['phone_number','email'], 'myRule' ,'skipOnEmpty' => false],
I think you hsold use $attribute and not $attribute_name
public function myRule($attribute_name, $params)
{
if (empty($this->email)
&& empty($this->phone_number)
) {
$this->addError($attribute, Yii::t('app', 'either Phone or Email required'));
return false;
}
return true;
}
from yii2 doc
addError() public method Adds an error about the specified attribute
to the model object.
This is a helper method that performs message selection and
internationalization. public void addError ( $model, $attribute,
$message, $params = [] )
Try this action create
public function actionCreate()
{
$model = new Advertisement();
if ($model->load(Yii::$app->request->post()) ) {
if ($model->validate()) {
$model->company = Yii::$app->user->identity->id;
$model->created_at = date("Y-m-d H:i:s");
$model->date_added = date("Y-m-d H:i:s");
$model->save();
return $this->redirect(['view', 'id' => $model->id]);
}
else {
$errors = $model->errors;
return $this->render('create', [
'model' => $model,
]);
}
} else {
return $this->render('create', [
'model' => $model,
]);
}
}

Yii2 Login with database

I have a table in my DB called 'member' where I intend to store username, password and all other related info of a user and I want to use those username/password for login instead yii2's default User.php model. I have been trying for almost a day and modified the Member.php model but can't make it work. Every time I use my custom username/password from db, it says username or password is incorrect.
Can anyone please help me out? Thanks in advance. :)
FYI, I have no such field in member table such as authKey or accessToken. I have tried all the related stackoverflow posts but in vein.
Member.php Model
namespace app\models;
use Yii;
use yii\web\IdentityInterface;
class Member extends \yii\db\ActiveRecord implements IdentityInterface
{
public static function tableName()
{
return 'member';
}
public function rules()
{
return [
[['username', 'password', 'first_name', 'last_name', 'role'], 'required'],
[['created_by_date', 'last_modified_by_date'], 'safe'],
[['username', 'password', 'role', 'created_by_id', 'last_modified_by_id'], 'string', 'max' => 50],
[['first_name', 'last_name', 'middle_name', 'phone', 'mobile'], 'string', 'max' => 100],
[['email'], 'string', 'max' => 250],
[['address_line1', 'address_line2', 'address_line3'], 'string', 'max' => 512]
];
}
public function attributeLabels()
{
return [
'id' => 'ID',
'username' => 'Username',
'password' => 'Password',
'first_name' => 'First Name',
'last_name' => 'Last Name',
'middle_name' => 'Middle Name',
'email' => 'Email',
'phone' => 'Phone',
'mobile' => 'Mobile',
'address_line1' => 'Address Line1',
'address_line2' => 'Address Line2',
'address_line3' => 'Address Line3',
'role' => 'Role',
'created_by_id' => 'Created By ID',
'created_by_date' => 'Created By Date',
'last_modified_by_id' => 'Last Modified By ID',
'last_modified_by_date' => 'Last Modified By Date',
];
}
public static function find()
{
return new MemberQuery(get_called_class());
}
public static function findIdentity($id)
{
$dbUser = self::find()
->where([
"id" => $id
])
->one();
if (!count($dbUser)) {
return null;
}
return new static($dbUser);
}
public static function findIdentityByAccessToken($token, $userType = null)
{
$dbUser = self::find()
->where(["accessToken" => $token])
->one();
if (!count($dbUser)) {
return null;
}
return new static($dbUser);
}
public static function findByUsername($username)
{
$dbUser = self::find()
->where(["username" => $username])
->one();
if (!count($dbUser)) {
return null;
}
return $dbUser;
}
public function getId()
{
return $this->id;
}
public function getAuthKey()
{
return $this->authKey;
}
public function validateAuthKey($authKey)
{
return $this->authKey === $authKey;
}
/**
* Validates password
*
* #param string $password password to validate
* #return boolean if password provided is valid for current user
*/
public function validatePassword($password)
{
return $this->password === $password;
}
}
config/web.php
'user' => [
'identityClass' => 'app\models\Member',
'enableAutoLogin' => true,
],
I didnt change the User.php model. Here it is:
namespace app\models;
class User extends \yii\base\Object implements \yii\web\IdentityInterface
{
private static $users = [
'100' => [
'id' => '100',
'username' => 'admin',
'password' => 'admin',
'authKey' => 'test100key',
'accessToken' => '100-token',
],
'101' => [
'id' => '101',
'username' => 'demo',
'password' => 'demo',
'authKey' => 'test101key',
'accessToken' => '101-token',
],
];
/**
* #inheritdoc
*/
public static function findIdentity($id)
{
return isset(self::$users[$id]) ? new static(self::$users[$id]) : null;
}
/**
* #inheritdoc
*/
public static function findIdentityByAccessToken($token, $type = null)
{
foreach (self::$users as $user) {
if ($user['accessToken'] === $token) {
return new static($user);
}
}
return null;
}
/**
* Finds user by 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 null;
}
/**
* #inheritdoc
*/
public function getId()
{
return $this->id;
}
/**
* #inheritdoc
*/
public function getAuthKey()
{
return $this->authKey;
}
/**
* #inheritdoc
*/
public function validateAuthKey($authKey)
{
return $this->authKey === $authKey;
}
/**
* Validates password
*
* #param string $password password to validate
* #return boolean if password provided is valid for current user
*/
public function validatePassword($password)
{
return $this->password === $password;
}
}
You should make sure you change the getUser() method on models/LoginForm.php to use your Member model class, otherwise it will keep validating against the default User model.
public function getUser() {
if ($this->_user === false) {
$this->_user = Member::findByUsername($this->username);
}
return $this->_user;
}
Also, here is an example of my own User model class
namespace app\models;
use Yii;
class User extends \yii\db\ActiveRecord implements \yii\web\IdentityInterface {
const SCENARIO_LOGIN = 'login';
const SCENARIO_CREATE = 'create';
public static function tableName() {
return 'user';
}
public function scenarios() {
$scenarios = parent::scenarios();
$scenarios[self::SCENARIO_LOGIN] = ['username', 'password'];
$scenarios[self::SCENARIO_CREATE] = ['username', 'password', 'authKey'];
return $scenarios;
}
public function rules() {
return [
[['username', 'email'], 'string', 'max' => 45],
[['email'], 'email'],
[['password'], 'string', 'max' => 60],
[['authKey'], 'string', 'max' => 32],
[['username', 'password', 'email'], 'required', 'on' => self::SCENARIO_CREATE],
[['authKey'], 'default', 'on' => self::SCENARIO_CREATE, 'value' => Yii::$app->getSecurity()->generateRandomString()],
[['password'], 'filter', 'on' => self::SCENARIO_CREATE, 'filter' => function($value) {
return Yii::$app->getSecurity()->generatePasswordHash($value);
}],
[['username', 'password'], 'required', 'on' => self::SCENARIO_LOGIN],
[['username'], 'unique'],
[['email'], 'unique'],
[['authKey'], 'unique'],
];
}
public function attributeLabels() {
return [
'id' => 'Id',
'username' => 'Username',
'password' => 'Password',
'email' => 'Email',
'authKey' => 'authKey',
];
}
public static function findIdentity($id) {
return self::findOne($id);
}
public static function findIdentityByAccessToken($token, $type = null) {
throw new NotSupportedException('"findIdentityByAccessToken" is not implemented.');
}
public static function findByUsername($username) {
return static::findOne(['username' => $username]);
}
public function getId() {
return $this->getPrimaryKey();
}
public function getAuthKey() {
return $this->authKey;
}
public function validateAuthKey($authKey) {
return $this->authKey === $authKey;
}
public function validatePassword($password) {
return Yii::$app->getSecurity()->validatePassword($password, $this->password);
}
}
Make sure the methods from IdentityInterface you implement but don't want to use throw an exception, just like i do on the findIdentityByAccessToken method.
You should extend User class with your Member class and set in main config:
[...]
'modules' => [
'user' => [
'class' => 'member class
'modelMap' => [
'User' => 'app\models\member',
More info: yii 2 : override user model

Categories