5

Is it possible to change the action class Yii2 uses somehow, similar to how you can set the class of many other components within the config file?

I want to extend this class so I can add another member variable to it.

I guess I could just add one to it anyway dynamically, but would prefer to do it in a proper fashion.

Edit: Looking at the list of core application components it isn't listed, so not sure if it's possible?

Brett
  • 19,449
  • 54
  • 157
  • 290
  • I guess you'll have to extend the yii\base\Controller and rewrite createAction function to be able to use your custom InlineAction wrapper, as it is hardcoded there. – apoq Aug 07 '15 at 13:41

2 Answers2

1

It can be done with class map

Yii::$classMap['yii\base\InlineAction'] = '@common/InlineAction.php';

and should be placed into index.php, before the app is launched.

Regardless of its location, common/InlineAction.php should have the same yii\base namespace as the original class.

Estus Flask
  • 206,104
  • 70
  • 425
  • 565
  • Shouldn't this be set in the *bootstrapping process* and not in the *index.php* file as indicated within the docs? Also, if you give it the same `namespace` then you won't be able to give it the same class name? – Brett Aug 07 '15 at 15:11
  • index.php *is* the part of bootstrapping process, you may call it entry script if it sounds better. You need to give it the same class name, that's the point. Copy yii's InlineAction.php to new location and modify it. The side effect is that it leaves no opportunity to extend the original class. – Estus Flask Aug 07 '15 at 15:17
  • Sorry, I meant the bootstrap location within the config file. I don't think I want to go to those measures of having to move around core files, I just want a way to extend it. If there isn't a way, then I guess I will have to stick with setting the member variable dynamically. – Brett Aug 07 '15 at 15:30
  • This class is being instantiated [directly](https://github.com/yiisoft/yii2/blob/2.0.5/framework/base/Controller.php#L225), so there's no other way. There's nothing criminal, it's the way Yii offers to modify core classes, but yes, it is a hack, avoid it unless it is necessary. – Estus Flask Aug 07 '15 at 15:40
1

The proper way to solve this problem is to extend both controller and action classes. If you look at the source code, yii\base\Controller has a createAction method that, if no class action is found, will create an instance of InlineAction.

Since you're extending some kind of controller class every time you make your own controller (class MyController extends Controller), you can just override the original createAction method and in it use your own implementation of the InlineAction class.

Beowulfenator
  • 2,262
  • 16
  • 26
  • Thanks for the idea. I guess I'd prefer to not have to override any methods at all as it has the caveat of missing out on future updates to these methods (as you will be using your own method), but I guess this would currently be the best way to handle it. – Brett Aug 10 '15 at 16:56
  • It's a bit odd that you need to extend `InlineAction`. What is this attribute you're adding to it? – Beowulfenator Aug 10 '15 at 21:59
  • I've decided to handle it a different way now and avoid adding the extra attribute, but it was going to simply be a *unique* name for the action over the entire application, because different controllers can obviously have identical named actions. – Brett Aug 11 '15 at 06:57