I have advanced app. I create CRUD for User model. So i got update action. I tried to update password by adding
<?= $form->field($model, 'password')->passwordInput() ?>
But it call error, something like "password is write-only variable"
I tried to use field
<?= $form->field($model, 'new_password')->passwordInput() ?>
With adding in actionUpdate model->setPassword($this->new_password); and it throw Getting unknown property: common\modules\user\controllers\DefaultController::new_password.
But model->setPassword('123456'); successfully setting pussword 123456.
How can i get new_password field from view, to put it in model->setPassword('there');
Or maybe exist best way to do it?
UPD
I tried do it. Is not work.
public function beforeSave($insert)
{
if (parent::beforeSave($insert)) {
if ($this->new_password) {
$this->setPassword($this->new_password);
}
return true;
} else {
return false;
}
}
UPD2
public function setPassword($password) {
$this->password_hash = Yii::$app->security->generatePasswordHash($password);
}
And password_hash writing in database. I can easy change hash, via generated CRUD, but don't know how to use setPassword() in updateAction.
You can try write updatePassword function like setPassword with another variable
public function updatePassword($new_password) {
$this->password_hash = Yii::$app->security->generatePasswordHash($new_password);
}
declare a variable
public $new_password;
And add it in rules()
public function rules() {
return [
//...
['new_password', 'required'],
['new_password', 'string', 'min' => 6],
];
}
And at actionUpdate in your controller add
$model->updatePassword($model->new_password);
This should help
Here "$this" is your Controller which of course, doesn't have 'new_password' property. You'd better not set new password in controller, but do it in model, for example in beforeSave method:
if ($this->new_password) {
$this->setPassword($this->new_password);
}
Related
I'm new to Laravel and I'm writing a user management System on my own.
At this time,
I can CRUD permissions, roles and users,
I can check the permissions by the AuthServiceProvider#boot method like this:
public function boot()
{
Gate::before( function (User $user , $permission) {
// App administrator
if($user->getPermissions()->contains('appAll'))
{
return true;
}
// Permission check
return $user->getPermissions()->contains($permission);
});
}
In my AdminUserController, I can check the permissions like that:
public function index()
{
if( Gate::check('createUser') || Gate::check('readUser') || Gate::check('updateUser') || Gate::check('deleteUser')) {
return view('userMgmt/users/index', [
'users' => User::getUsersWithRolesWithTexts()
]);
}
else
{
return redirect(route('home'))->withErrors('You do not have required permission');
}
}
That is working well.
BUT
Is this the right way to wrap each controller method with:
if( Gate::check(...) ...) {
//Do what the method is supposed to do
}
else
{
return redirect(route('SOME.ROUTE'))->withErrors('SOME ERROR OCCURRED');
}
It would be nice if someone can give me some ideas.
Tank you
There is a controller helper function named authorize that you can call from any method in a controller that extends App\Http\Controllers\Controller. This method accepts the action name and the model, and it will throw an exception if the user is not authorized. So instead of the if...else statement, it will be one line:
public function update(Request $request, Post $post)
{
$this->authorize('update', $post);
// The current user can update the blog post...
}
I have a model Printer, a model Category, and a model for the relation between the two models CategoryPrinterRel
In the CategoryPrinterRel model I need a unique validator between the $category_id, and the client of the printer $printer->client_id
Up till now I have tried
public function rules()
{
[['category_id', $this->printer->client_id], 'unique', 'targetAttribute' => ['category_id']]
}
Is there any other way to do this though?
The problem with the method I'm using is that when the printer object is empty, trying $this->printer->client_id gives an error
I was looking for something more elegant, or built in. For now I have opted for a custom validator however. In the model:
public function rules()
{
return [
[['category_id', 'printer_id'], 'integer'],
[['printer_id', 'category_id'], 'required'],
[['cat_id'],'validateUniquenessOnClient']
];
}
public function validateUniquenessOnClient($attribute, $params, $validator)
{
$isPrinterUniqueOnClient = DbPrinterRepository::IsPrinterCatRelUniqueOnClient($this->category_id, $this->printer_id);
if(!$isPrinterGroupUniqueOnClient)
{
$this->addError($attribute, "There is already a printer using that category ({$this->cat->name}).");
}
}
I've use BlameableBehavior but in some of my controller I want to manually set the user created value but it can't work.
public function behaviors()
{
return [
BlameableBehavior::className(),
];
}
this not work.
$model->createdBy = 1;
$model->save();
it try to use the BlameableBehavior.
how can I manually add it.
Thanks.
Try to use named behavior and detach it before saving model:
public function behaviors()
{
return [
'blameable' => BlameableBehavior::className(),
];
}
And then:
$model->detachBehavior('blameable');
$model->createdBy = 1;
$model->save();
I am trying to save user's last logout time into a DB in Yii framework.
I have WebUser as:
<?php
// this file must be stored in:
// protected/components/WebUser.php
class WebUser extends CWebUser {
public function afterLogout()
{
$user=user::Model();
$user->logOutDateTime='TEST';
$user->saveAttributes(array('logOutDateTime'));
parent::afterLogout();
}
}
?>
and in config\main.php I have these lines
// application components
'components'=>array(
'user'=>array(
// enable cookie-based authentication
'class'=>'WebUser',
'allowAutoLogin'=>true,
)
For now I have set logOutDateTime datatype to varchar, to test, and I assume every time user logs out, it should write 'TEST' into database but it does nothing.
Where did I go wrong?
I don't think the afterLogout() still has the Yii::app()->user set, so I would do something like (untested):
public function beforeLogout()
{
if (parent::beforeLogout()) {
$user = User::model()->findByPk(Yii::app()->user->id); // assuming you have getId() mapped to id column
$user->logOutDateTime='TEST';
$user->saveAttributes(array('logOutDateTime'));
return true;
} else {
return false;
}
}
$user = user::Model();
should be:
$user = user::Model()->find(/* model_conditions */);
I am using PHP Yii Framework with MongoDB(yiimongodbsuite). I have created a Model which extends from EMongoDocument.
<?php
class MyModel extends EMongoDocument
{
public $attr1;
public $attr2;
// rules, custom validations and other functions....
public function setAttributes($values, $safeOnly=true)
{
if(!is_array($values))
return;
if($this->hasEmbeddedDocuments())
{
$attributes=array_flip($safeOnly ? $this->getSafeAttributeNames() : $this->attributeNames());
foreach($this->embeddedDocuments() as $fieldName => $className)
if(isset($values[$fieldName]) && isset($attributes[$fieldName]))
{
$this->$fieldName->setAttributes($values[$fieldName], $safeOnly);
unset($values[$fieldName]);
}
}
parent::setAttributes($values, $safeOnly);
}
}
In Controller,
$dataModel = new MyModel();
$dataModel->setAttributes($_POST['MyModel']);
if($dataModel->validate()){
$dataModel->save();
}
the above code is not setting the attribute value.
Please let me know if there is any mistake.
You need to make sure that the 'safe' validation rules is used on each level.
To understand more read this http://www.yiiframework.com/wiki/161/understanding-safe-validation-rules/
Try to determine which valdation errors you have:
if(!$model->validate()) {
die( print_r($model->getErrors()) );
}