I try to add a event after search onthe var_dump is excuted, but data did
not pass through. Why ?
trigger:
class ContentSearch extends Content
{
const EVENT_AFTER_SEARCH = 'afterSearch';
public function search($params)
{
$e = new ModelEvent;
$e->data = $this;
$this->trigger(self::EVENT_AFTER_SEARCH, $e);
}
}
on:
class ContentController extends Controller
{
public function actionIndex()
{
$searchModel = new ContentSearch();
$searchModel->on($searchModel::EVENT_AFTER_SEARCH, function ($event) {
var_dump($event->data);
die;
});
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
}
}
dump
null
Well, you are wrong about event data usage :
Read this : http://www.yiiframework.com/doc-2.0/yii-base-event.html#$data-detail
The data that is passed to yii\base\Component::on() when attaching an event handler.
And this : http://www.yiiframework.com/doc-2.0/yii-base-component.html#on()-detail
About the third param :
The data to be passed to the event handler when the event is triggered
Anyway, you don't need this, you could simply use $event->sender :
function ($event) {
var_dump($event->sender); // this will dump your ContentSearch model
die;
}
Related
I have a code for checking a session isset or not in Yii2, I added the code inside a function in a controller, this is the code
if(!isset($session['selectedMonth'])){
return $this->redirect(['select-period/month']);
return false;
}
I have over than 50 functions in 10 controllers, I want every function use that code, how do I can make it without put that code in every function one by one?
You could create base controller for your app, and extend all other controllers from it. Then you could add beforeAction() method in this base controller, so it will be used by all controllers that inherit from base controller:
public function beforeAction($action) {
// initialize $session here
if(!isset($session['selectedMonth'])){
Yii::$app->response->redirect(['select-period/month']);
return false;
}
return parent::beforeAction($action);
}
You can create simple behavior that will handle 'before action' event, for example:
use Yii;
use yii\base\Behavior;
use yii\base\Controller;
class RedirectBehavior extends Behavior
{
public function events()
{
return [
Controller::EVENT_BEFORE_ACTION => 'beforeAction',
];
}
public function beforeAction($event)
{
if (Yii::$app->session->has('selectedMonth')){
return;
}
Yii::$app->getResponse()->redirect(['select-period/month'])->send();
}
}
and attach it to your controllers
public function behaviors()
{
return [
'redirect' => [
'class' => RedirectBehavior::className(),
],
];
}
Iam developing a website using codeigniter.I want to pass a particular data to all the controller.I searched and find it can be done by session like below.
$var = $this->session->userdata('passingdata');
But this data loses when history is cleared and when session expires.
Is there any other way to pass variable to all controllers.
You can try this
- create MY_Controller in application/core. it looks like
Class MY_Controller extends CI_Controller {
public function __construct() {
parent::__construct();
$this->load->model('HomeModel');
$this->global_data['settings']= $this->HomeModel->getSettings();
}
function display_view($view, $local_data = array()) {
$data = array_merge($this->global_data, $local_data);
return $this->load->view($view, $data);
}}
then extend this controller in your all controller
your functions in your controller like
Class Home extends MY_Controller {
public function index() {
$data['title'] = 'test';
$this->display_view('home', $data);
}
}
I'm trying to change the $id param in my controller methods on the fly using beforeAction and a behavior. FYI, I'm going to use HashIds and need to convert anywhere I have a $_GET['id'] that may be hashed back into an integer.
How can I use a behavior to automatically modify my $_GET['id'] on the fly using a behavior?
An example action in my controller:
public function actionView($id){
// run code to process $id here back to integer using a behavior
echo $id; //should be an integer
}
My sample url: http://mydomain/posts/view?id=3QhLp
(Alternatively, perhaps the better way to do this is to create a custom url rule?)
you should implement a class that extends from the \yii\base\Behavior like below
<?php
namespace backend\models;
use Yii;
use yii\base\Behavior;
use yii\web\Controller;
class Transformer extends Behavior
{
public $id = '';
public function events()
{
return [Controller::EVENT_BEFORE_ACTION => 'transform']; //mounting the handler to the 'beforeAction' event on the controller.
}
public function transform()
{
$_GET['id'] = $this->id . "transformed"; //mock method here
return true;
}
}
Then in your controller, adding the code as follow:
public function behaviors()
{
return [
'transformer' => [
'class' => \backend\models\Transformer::className(), //Modify the path to your real behavior class.
'id' => Yii::$app->request->get('id'),
],
];
}
then access the Yii::$app->request->get('id') in your action, you will see the transformed url param.
Here is my Behavior's class events() method. When I trigger an event second handler i.e. sendMailHanlder gets called and it ignores anotherOne. I believe, the second one overwrites first one. How do I solve this problem so that both event handlers get called?
// UserBehavior.php
public function events()
{
return [
Users::EVENT_NEW_USER => [$this, 'anotherOne'],
Users::EVENT_NEW_USER => [$this, 'sendMailHanlder'],
];
}
// here are two handlers
public function sendMailHanlder($e)
{
echo ";
}
public function anotherOne($e)
{
echo 'another one';
}
One thing to notice is that I'm attaching this behavior to my Users.php model. I tried adding both handlers using model's init() method. That way both handlers got called. Here is my init code.
public function init()
{
$this->on(self::EVENT_NEW_USER, [$this, 'anotherOne']);
$this->on(self::EVENT_NEW_USER, [$this, 'sendMailHanlder']);
}
You can override Behavior::attach() so you can have something like this in your UserBehavior and no need of your events()
// UserBehavior.php
public function attach($owner)
{
parent::attach($owner);
$owner->on(self::EVENT_NEW_USER, [$this, 'anotherOne']);
$owner->on(self::EVENT_NEW_USER, [$this, 'sendMailHanlder']);
}
You can use anonymous function for attaching handler's in events method :
ActiveRecord::EVENT_AFTER_UPDATE => function ($event) {
$this->deleteRemovalRequestFiles();
$this->uploadFiles();
}
You should not use equal event names. Use this instead:
public function events()
{
return [
Users::EVENT_NEW_USER => [$this, 'sendMailHanlder'],
];
}
// Here are two handlers
public function sendMailHanlder($e)
{
echo '';
$this->anotherOne($e);
}
public function anotherOne($e)
{
echo 'another one';
}
My model: as seen below, very basic
class User extends CI_Model
{
function __construct()
{
parent::__construct();
}
function getAll()
{
$this->db->order_by("lastName", "asc");
$this->db->order_by("firstName", "asc");
$this->db->order_by("userName", "asc");
$query = $this->db->get('user');
// test for result
if($query->num_rows() > 0)
{
return $query->result();
}
return NULL;
}
}
My controller: actually part of my controller, every time loading the users/display function by default route, the error (further down) shows up. Should a model loaded in a controller's contructor be available for all other function in the same controller?
class Users extends CI_Controller
{
function __contruct()
{
parent::__construct();
$this->load->model('user');
}
function display()
{
$data['users'] = $this->user->getAll();
$head['pageTitle'] = 'Users Panel';
$this->load->view('security/redirect');
$this->load->view('template/head', $head);
$this->load->view('user/usersPanel', $data);
$this->load->view('template/foot');
}
}
My error: refering to the line, "$data['users'] = $this->user->getAll()", in above controller
A PHP Error was encountered
Severity: Notice
Message: Undefined property: Users::$user
My environment:
Codeigniter 2.1.0;
Mac Lion;
MAMP 2.0;
Shouldn't this:
class Users extends CI_Controller
{
function __contruct()
{
be like this:
class Users extends CI_Controller
{
function __construct()
{
replace contruct with construct.
Shouldn't this:
$data['users'] = $this->user->getAll();
be this:
$data['users'] = $this->user_model->getAll();
sorry
also the model name:
$this->load->model('user_model');
and class name User_model extends CI_Model
All of my CI projects are set up this way.
http://codeigniter.com/user_guide/general/models.html