how to implement afterSave method to a specific controller action only? - yii

let's say i have model A..then this model A is being used by many controllers...
now I want to implement the afterSave method, only in one of the controllers that uses
model A . e.g in Controller C it calls the save() function, so I want the afterSave to be called in that function only.how is that ?
protected function afterSave()
{
parent::afterSave();
if($this->isNewRecord)
{
echo "hello";
exit;
}
}
BECAUSE: afterSave() affects all the save() call of all the controllers that uses the Model A

You can try this in you afterSave function :
if (Yii::app()->controller->id!=='yourcontroller')
{
// do what you want
}
If needed, you can also test value of Yii::app()->controller->action->id.
EDIT : or take a look at Jelle de Fries answer.

I don't get why you would need an afterSave() method for this.
In your action you are calling $model->save().
Can't you just do what you have to do after calling this?
like so:
public function actionMyAction(){
$model=new myModel;
$model->attribute = 5;
$model->save();
$model->doLogicAfterSave(); //<-this
$this->render('myView',array(
'model'=>$model,
));
}
Since it's only for 1 controller.

Related

How to invoke a controller method just when condition happens

I want to invoke controller method, in case a specific condition happens.
Can you give me an example how to implement it?
i guess it can intercepted with webapi filters..
Thanks.
I'm assuming that you are talking about invoking a method from a controller/api from another method/controller. It's actually pretty easy.
First, in your startup class you'll need to find the ConfigureServices method and add:
services.AddMvc().AddControllersAsServices();
Then, in whichever controller you need it, just create a new instance of that controller and you can call those methods. Assume you have api1 and you want to call a method from api2. I'd create the api via dependency injection:
public class api1
{
public _api2 {get;set;}
public api1()
{
_api2 = new api2();
}
}
And now you can call your methods however you'd like from api2:
public IActionResult SomeCondition()
{
if(!someCondition)
{
return _api2.YourMethod1();
}
else
{
return _api2.YourMethod2();
}
}

How to Redirect from one view to another view with data - Yii2

i want to pass 1 variables from a view to another view with post method. use this redirect code but its not working
Yii::$app->getResponse()->redirect('home','id'=>$id)->send();
try this
Yii::$app->getResponse()->redirect(['home','id' => $id])->send();
For the sake of completeness in a controller context you may use:
class MyController extends \yii\web\Controller
{
public function actionIndex()
{
return $this->redirect(['home', 'id' => 123]);
}
}
Where the array parameter of redirect() is equal to yii\helpers\Url::to().

Passing array from AuthController to login view in Laravel 5

Am having a problem passing an array from Laravel's AuthController to auth.login view. What am trying to do is retrieve data from News model and send it to the view. I know how to use eloquent to retrieve data, passing from the controller to the view is my problem as I cannot see the how/where Laravel is rendering the view.
Add an array as second parameter to the view method when returning it in the controller.
return view('greetings', ['name' => 'Victoria']); // in controller
Then in your view, you should be able to access the variable $name which should be equal to Victoria
var_dump($name); // in view
More in the documentation
I solved it by passing the variable through the Controller on the redirect method.
I am not entirely sure what the objective is here, but you said:
I cannot see the how/where Laravel is rendering the view.
So to answer that:
Laravel's AuthController pulls in a trait AuthenticatesAndRegistersUsers which itself pulls in a few other traits, one being AuthenticatesUsers and another being RegistersUsers.
In AuthenticatesUsers you will find a method like so:
/**
* Show the application login form.
*
* #return \Illuminate\Http\Response
*/
public function showLoginForm()
{
$view = property_exists($this, 'loginView')
? $this->loginView : 'auth.authenticate';
if (view()->exists($view)) {
return view($view);
}
return view('auth.login');
}
There is likewise a similar method in the RegistersUsers trait.
This is where the AuthController returns its views.
If you need to tweak this behavior, or return the view with some data, you could override these methods in your controller, if this is really the best solution to your given situation.
Meanwhile I found a better way to do that.
You can override the showRegistrationForm() method in AuthController.php and pass along the data you want to use in the view. Ex.:
public function showRegistrationForm()
{
$results = Model::all();
return view('auth.register', ['results' => $results]);
}

Kohana - Best way to pass an ORM object between controllers?

I have Model_Group that extends ORM.
I have Controller_Group that gets a new ORM:
public function before()
{
global $orm_group;
$orm_group = ORM::factory('Group');
}
...and it has various methods that use it to get different subsets of data, such as...
public function action_get_by_type()
{
global $orm_group;
$type = $this->request->param('type');
$result = $orm_group->where('type', '=', $type)->find_all();
}
Then I have another controller (in a separate module) that I want to use to manipulate the object and call the relevant view. Let's call it Controller_Pages.
$orm_object = // Get the $result from Controller_Group somehow!
$this->template->content = View::factory( 'page1' )
->set('orm_object', $orm_object)
What is the best way to pass the ORM object from Controller_Group to Controller_Pages? Is this a good idea? If not, why not, and what better way is there of doing it?
The reason for separating them out into different controllers is because I want to be able to re-use the methods in Controller_Group from other modules. Each module may want to deal with the object in a different way.
This is the way I would do it, but first I would like to note that you shouldn't use global in this context.
If you want to set your ORM model in the before function, just make a variable in your controller and add it like this.
public function before()
{
$this->orm_group = ORM::factory('type');
}
In your Model your should also add the functions to access data and keep the controllers as small as possible. You ORM model could look something like this.
public class Model_Group extends ORM {
//All your other code
public function get_by_type($type)
{
return $this->where('type', '=', $type)->find_all();
}
}
Than in your controllers you can do something like this.
public function action_index()
{
$type = $this->request->param('type');
$result = $this->orm_group->get_by_type($type);
}
I hope this helps.
I always create an helper class for stuff like this
Class Grouphelper{
public static function getGroupByType($type){
return ORM::factory('Group')->where('type','=',$type)->find_all();
}
}
Now you're been able to get the groups by type where you want:
Grouphelper::getGroupByType($type);

Creating a simple controller alias

I'm not sure I am using the proper terminology, so I will describe what I want to achieve.
I have a controller called ControllerA and want a "virtual" controller called ControllerB to function exactly the same as ControllerA.
Basically I just want the url site.com/ControllerB to load up the same page as site.com/ControllerA (but not redirect).
Hope my description is clear enough.
You can achieve what you want with a simple URL rule:
'controllerA/<a>' => 'controllerA/<a>',
'controllerB/<a>' => 'controllerA/<a>',
Read more about URL rules here: http://www.yiiframework.com/doc/guide/1.1/en/topics.url#user-friendly-urls
You can extend ControllerA with ControllerB and provide extended controller name. Next override getViewPath method. Attribute extendedControler give us basic controller name.
class ControllerBController extends ControllerAController
{
private $extendedControler = 'ControllerA';
public function getViewPath() {
$nI = Yii::app()->createController($this->extendedControler);
return $nI[0]->getViewPath();
}
}
Of course you can use some string modification. Like str_ireplace:
class Klient2Controller extends KlientController
{
public function getViewPath() {
//We must extract parent class views directory
$c = get_parent_class($this);
$c = str_ireplace('Controller', '', $c); //Extract only controller name
$nI = Yii::app()->createController($c);
return $nI[0]->getViewPath();
}
}