How to pass variable from controller to model after function execution Yii2 - php

I have a function in a controller that when executed, check for existence of a record in a table and returns that record. This function is used as validation of a model inside the same controller. For example:
public function somethingValidate() {
$someVariable = SomeTable::find()->where(['some_id' => $someVariable])->one();
if ($model) {
return $model;
} else {
return false;
Here is the validation part of controller:
public function actionSave() {
$model = new TestModel() {
if ($this->somethingValidate()) {
try {
--- REST OF THE CODE ---
How can i now, pass $someVariable variable into a TestModel and manipulate the data either on save or beforeSave.
Any assistance is greatly appreciated.

For example, an Investment amount should be more or equal with the Proposal's min_investment value. Below is the beforeValidate() function in Investment model.
public function beforeValidate()
{
parent::beforeValidate();
$proposal = Proposal::findOne($this->proposal_id);
if ($this->amount < $proposal->min_investment)
{
$this->addError('amount', Yii::t('app', 'Minimum amount should be ' . $proposal->min_investment));
return FALSE;
}
return TRUE;
}
Is that what you're trying to achieve?

Related

Laravel 5 return redirect is not working as it should

I'm having a controller with some functions. In every function I get user data by sharing it from the Contoller.php
In controller.php
public function share_user_data() {
$user = Auth::user();
$this->checkValidation($user);
$this->user = $user;
View::share('user', $user);
}
public function checkValidation($user){
if($user->email_activated == 0){
var_dump($user->email_activated); // I get: int(0)
return redirect('/verifyEmail');
}
}
In the other controller
public function viewCategory(Category $category){
$this->share_user_data(); // here's the check
$this->get_site_lang();
$products = $category->products;
return view('category', compact('category','products'));
}
But I get the category view and not redirected to the verifyEmail route. How to fix this and why it's happening?
The controller function called by the route is the one responsible for the response. I guess it is viewCategory() in your example?
Your viewCategory() function is always returning view(). It must return redirect() instead. I think the main function should be responsible for picking the output of the request.
private function checkValidation($user) {
return $user->email_activated == 0;
}
public function viewCategory(Category $category) {
$user = Auth::user();
/* ... call to share_user_data() or whatever ... */
if ($this->checkValidation($user)) {
return redirect('/verifyEmail');
}
return view('category', compact('category','products'));
}

(Phalcon) How to redirect (Phalcon\Http\Response) from static method in model

I'm trying to create a reusable static function which redirects if true.
This function will be in a model.
public function checkEmtpy(ResultsetInterface $resultset)
{
$di = \Phalcon\DI::getDefault();
if (empty($resultset->toArray())) {
$di->get('flash')->error('Page not found.');
return $di->get('response')->redirect('content');
} else {
return false;
}
}
I tried several ways to redirect but I can't get it to redirect from the model.
What can I change to make this work or isn't this possible at all?
It is against MVC principle to do redirects in models. The redirect has to be done in the Controller. What you should do is return only the status from your model only. Something like this:
// Model
public function checkEmtpy(ResultsetInterface $resultset)
{
return empty($resultset->toArray());
}
// Controller
public action someAction()
{
$isEmpty = (new YourModelName)->checkEmtpy($someVariable);
if ($isEmpty === true) {
return $this->response->redirect(...);
}
}

Is that possible to have multiple rules function in single Request class?

I have request class like below.
class CategoryRequest extends Request
{
public function response(array $errors){
return \Redirect::back()->withErrors($errors)->withInput();
}
public function authorize()
{
return false;
}
public function rules()
{
return [
'Category' => 'required|unique:tblcategory|max:25|min:5'
];
}
}
There is rules function.
In the controller, there are multiple methods that have Request as a Parameter. Most of them vary in the validation point of view. I mean, if I am admin,. I can update 4 fields. If I am manager, I can update 3 and if I am normal user, I can update 2. So validation will change according to roles.
Is that possible to have multiple rules function in Request class ?
You can use here any conditions you want, so you you could do something like this:
public function rules()
{
$rules = [];
if (Auth::user()->isAdmin()) {
$rules['Category'] = '...';
}
elseif (Auth::user()->isManager()) {
$rules['Category'] = '...';
}
return $rules;
}
Of course you need to create isAdmin and isManager in your User model

Extend model get/build method in Laravel

I need to update my person object every time i retrieve it from the database and then save it again .. But how to do it?
My object, Person, with a bool-attribute seen_by_organization which is 0 when its created.
First time the Person is retrieve from the database i want to set the seen_by_organization to 1.
Ive tried put into the constructor, but it seems not to work
public function __construct(array $attributes = array())
{
parent::__construct($attributes);
if($this->seen_by_organization == 0)
{
$this->seen_by_organization = 1;
$this->save();
}
}
I know a method to bind code to "on save", but not "before get" or "after get".
protected static function boot()
{
parent::boot();
//This is on saving
static::saving(function($model)
{
});
//Is there something like this ?
static::getting(function($model)
{
}
}
I hope that you can help me
Thanks !
There is no built-in event for this. Also created is not the one you need - it is fired when a new model is inserted to the storage.
You need something like this:
// This is called after fetching data from db
// override it in order to fire the event you need
public function setRawAttributes(array $attributes, $sync = false)
{
parent::setRawAttributes($attributes, $sync);
$this->fireModelEvent('loaded', false);
}
// add handler for new event
public static function loaded($callback)
{
static::registerModelEvent('loaded', $callback);
}
// do the job
public static function boot()
{
parent::boot();
static::loaded(function ($user) {
if($user->exists && $user->seen_by_organization == 0)
{
$user->seen_by_organization = 1;
$user->save();
}
});
}
Mind that it will be called for each model that you retrieve using get() or first() etc. so there might be multiple inserts.
I got it !
The name of the event is created
protected static function boot()
{
parent::boot();
static::created(function($model)
{
if($model->seen_by_organization == 0)
{
$model->seen_by_organization = 1;
$model->save();
}
});
}

laravel hook into Eloquent pre and post save for every model

I'm new to Laravel and ORM's in general. How could i hook into Eloquent to fire code before and after a save of any model? I know i can do the following for specific models but i'm looking at figuring out how to do this for every model.
class Page extends Eloquent {
public function save()
{
// before save code
parent::save();
// after save code
}
}
Using laravel models own life cycle events may solve this easy
/**
* model life cycle event listeners
*/
public static function boot(){
parent::boot();
static::creating(function ($instance){
//
});
static::created(function ($instance){
//
});
}
There's even a better way of accomplishing this! Create an observer for, lets say a model called House:
class HouseObserver {
public function saving(House $house) {
// Code before save
}
public function saved(House $house) {
// Code after save
}
}
Now register the observer with the House model by adding the line House::observe(new HouseObserver) somewhere. The line can be added in the boot method of the model:
class House extends Eloquent {
// Lots of model code
public static function boot() {
parent::boot();
self::observe(new HouseObserver);
}
}
More info can be found here.
You can create a BaseModel class that extends eloquent and then have all your models extend BaseModel. Here's an example:
abstract class Elegant extends Eloquent{
/* Save ****************************/
public function preNew() {}
public function postNew() {}
public function preSave() { return true; }
public function postSave() {}
public function save($validate=true, $preSave=null, $postSave=null)
{
$newRecord = !$this->exists;
if ($validate)
if (!$this->valid()) return false;
if($newRecord)
$this->preNew();
$before = is_null($preSave) ? $this->preSave() : $preSave($this);
// check before & valid, then pass to parent
$success = ($before) ? parent::save() : false;
if ($success)
is_null($postSave) ? $this->postSave() : $postSave($this);
if($newRecord)
$this->postNew();
return $success;
}
public function onForceSave(){}
public function forceSave($validate=true, $rules=array(), $messages=array(), $onForceSave=null)
{
if ($validate)
$this->valid($rules, $messages);
$before = is_null($onForceSave) ? $this->onForceSave() : $onForceSave($this); // execute onForceSave
return $before ? parent::save() : false; // save regardless of the result of validation
}
/** Soft Delete ****************************/
public function preSoftDelete() { return true; }
public function postSoftDelete() { }
public function softDelete($val = true, $preSoftDelete=null, $postSoftDelete=null)
{
if ($this->exists)
{
$before = is_null($preSoftDelete) ? $this->preSoftDelete() : $preSoftDelete($this);
$success = null;
if($before) {
$this->set_attribute(static::$softDelete, $val);
$success = $this->save(false);
}
else
$success = false;
if ($success)
{
is_null($postSoftDelete) ? $this->postSoftDelete() : $postSoftDelete($this);
}
return $success;
}
}
/** Hard Delete ****************************/
public function preDelete() { return true;}
public function postDelete(){}
public function delete( $preDelete=null, $postDelete=null)
{
if ($this->exists)
{
$before = is_null($preDelete) ? $this->preDelete() : $preDelete($this);
$success = ($before) ? parent::delete() : false;
if ($success)
{
is_null($postDelete) ? $this->postDelete() : $postDelete($this);
}
return $success;
}
}
}

Categories