I am using Advanced Template in Yii 2. I want to create behavior for user id, so I made folder in common\components\behavior and created one class,
class UidBehavior extends Behavior
{
public function encryptUid($id)
{
$id = md5($id);
return $this->$id;
}
}
then in user.php =>
'mybehavior' => [
'class' => 'common\components\behavior\UidBehavior',
'encryptUid' => 'id'
],
but error has occurred which is
Setting unknown property: common\components\behavior\UidBehavior::encryptUid
can any one help me ?
You try to init encryptUid property on User.php, Where that is not exist, You can rewrite code like this then all thing work fine:
class UidBehavior extends Behavior
{
public $encryptUid;
public function encryptUid($id)
{
$encryptUid = md5($encryptUid);
return $this->$encryptUid;
}
}
Check Refer Link
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(),
],
];
}
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.
In my application I'm using an extension (which I own and may modify). This extension has an ActiveRecord based class that I want to extend in the application with another property. Can I do this somehow? Can a Factory help anyhow or Yii behaviour?
Class in extension:
namespace extension;
/**
* #property integer $id
* #property string $name
*/
class Product extends ActiveRecord {
public static function tableName() {
return 'product';
}
/**
* #inheritdoc
*/
public function rules() {
return [
[['id', 'name'], 'required'],
[['id'], 'integer'],
[['name'], 'string'],
];
}
}
There is also a ProductController and the corresponding view files (index, create, update, view, _form) in the extension which were regularly produced with gii. I just would like to add another property $description (string, required) to the Product. A migration in order to add the required column is available.
Do I have to overwrite the model and controller class and the view files? Or is the a more elegant solution?
E.g., consider the standard object creation that takes place within the extension:
public function actionCreate() {
$model = new Product();
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['view', 'language' => $model->language]);
} else {
return $this->render('create', [
'model' => $model,
]);
}
}
From my understanding I cannot influence the creation. Or am I wrong?
My impression is that I have to override everything (also the view files since the property has to be displayed) and then change controllerNamespace.
As far as extending a class, just go ahead and add the property. Your new class will have inherited everything from the parent class plus have your new property.
Concerning overwriting the generated files, there is a diff option in gii when you generate the files, so you can preview and decide what to keep and what to overwrite. Be aware that you have to merge any changes manually however.
I have installed the Bootstrap-UI plugin with composer and loaded the plugin in the bootstrap.php.
When I add the necessary code to the ViewApp.php I get an error.
Strict (2048): Declaration of App\View\AppView::initialize() should be compatible with Cake\View\View::initialize() [APP/View/AppView.php, line 22]
Code Context
*/
class AppView extends View
{
The code I added is:
class AppView extends View
{
public $layout = 'BootstrapUI.default';
public function initialize(array $config)
{
$this->loadHelper('Html', ['className' => 'BootstrapUI.Html']);
$this->loadHelper('Form', ['className' => 'BootstrapUI.Form']);
$this->loadHelper('Flash', ['className' => 'BootstrapUI.Flash']);
$this->loadHelper('Paginator', ['className' => 'BootstrapUI.Paginator']);
}
I had the same problem and I deleted the 'array $config' in the initialize function.
public function initialize()
{
// Code from Plugin
}
You also need to add <?php $this->extend('../Layout/TwitterBootstrap/dashboard'); ?> to your views to get the bootstrap look.
I am creating tables on the fly. If I created the tables Schools and Classes. How can I create the models for them and specify relationships among them.
I searched but did not get anything on this topic. Any help would be appreciated. Thank you.
The only way I can figure out is to use "global variables" for tables - e.g. in Yii::$app->params['ar_tables'] and redefine them dynamically:
In config:
[
....
'params' => [
'ar_tables' => [
'Parent' => 'parent',
'Child' => 'table2'
]
]
....
]
Parent class:
class Parent extends \yii\db\ActiveRecord
{
public static function tableName()
{
return Yii::$app->params['ar_tables']['Parent'];
}
public function getChildren
{
return self::hasMany(Child::className(), ['parent_id' => 'id']);
}
}
Child class:
class Child extends \yii\db\ActiveRecord
{
public static function tableName()
{
return Yii::$app->params['ar_tables']['Child'];
}
public function getParent
{
return self::hasOne(Parent::className(), ['id' => 'parent_id']);
}
}
After that you can dynamically change Yii::$app->params['ar_tables'] values for getting what you want. I have already tried this. And didn't like :)