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?
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.
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.
Related
how to use another controller function without extends in our controller
$this->load->library('../controllers/controllername');
already used
it is giving error =
Unable to locate the specified class: Session.php
Well you are not supposed to do that. If your controller uses repeatable logic, you should make class (Service for example), put the re-usable logic into it and call it in your controllers.
You can't use another controller function inside the controller. You can archive this in these two ways.
Create a Helper class
Create a generic model.
I want to override
vendor\laravel\framework\src\Illuminate\Auth\Password\DatabaseTokenRepository.php
I tried this user model in app folder.. but that is not working.. Can you tell me where to put it?
So see this is a vendor class. If you want to override any functionality of that class you can do so by applying method overriding. Just extends the class that you wan't to override, then redefine the function that you want to override in your class. Now, you can use your own class whenever need instead of the vendor class.
For example:
class TokenRepo extends DatabaseTokenRepository{
//Define the functionality here to ovrride
}
Usages:
$token = new TokenRepo();//instead of original DatabaseTokenRepository
I'm trying to make an application in CodeIgniter where every controller extends a base controller called 'Incyte_Controller.php' and where every model extends a base model called 'Incyte_Model.php'.
I used to import these parent classes in every child class using 'require', but want to change that as it is too redundant for me.
So i moved the base files to 'application/core' and changed the base class prefix in Config.php from 'MY_' to 'Incyte_'.
Now, all controllers can extend 'Incyte_Controller' without the use of 'required'.
But, strangely, when the application tries to load a model it says:
Fatal error: Cannot instantiate abstract class Incyte_Model in
/opt/lampp/htdocs/incyte/system/core/Common.php on line 172
This happens even though i try to extend the base model in the exact same way i extended the base controller.
I checked for spelling errors, including capital letters, but found none.
Also, i must mention that both base classes are abstract classes, because they shouldn't operate on themselves(my teachers would most likely prefer that)
Please understand i KNOW abstract classes themselves cannot be instantiated, but classes that extend abstract classes CAN be instantiated, and that is what i'm trying to do. But it doesn't seem to work in one case, while it does work in another very similar case, which is strange.
I hope any of you can help
A better way to do this would be to extend the core model class to something like MY_Incyte_Model and then extend this in your actual models.
So instead of class AwesomeModel extends CI_Model you can have class AwesomeModel extends MY_Incyte_Model.
Read more here
https://ellislab.com/codeigniter/user-guide/general/core_classes.html
Go to /opt/lampp/htdocs/incyte/system/core/Common.php and you will find a line trying to do something like this:
new Incyte_Model();
The Incyte_Model class is abstract (which means that it can't be used directly - it has to be sub-classed).
Look into how PHP handles Object Oriented (OO) code.
In particular, look at class abstractions.
I'm trying to figure out how to add a method to a class in a Laravel package, so that all controllers and models that call that class can access the new method. How do I replace this class in the IoC?
This is the package in question, Angel CMS. The package is my creation, so I can modify it if we need to add aliases or anything to accomplish this.
Let's say I want to add a method to this class:
vendor/angel/core/src/models/PageModule.php
Okay, so I copy the class file to here:
app/models/PageModule.php
And then I modify the copied file, adding a namespace and the desired custom_function method:
<?php namespace MyModels;
use Eloquent;
class PageModule extends Eloquent {
protected $table = 'pages_modules';
public static function custom_function()
{
return 'It works!';
}
}
As you can see, I am using the MyModels namespace here.
Then, I run a composer dump-autoload.
Next, I open up my app/routes.php and register the binding and set up a test route:
App::bind('PageModule', function($app) {
return new \MyModels\PageModule;
});
Route::get('test-binding', function() {
return PageModule::custom_function();
});
But, when visiting the test route, I always receive the same error that the method is undefined.
What am I doing wrong here? Thank you in advance for any help.
To Clarify:
I am attempting to replace the class application-wide so that all other classes (controllers/models/etc.) that call PageModule will have access to the custom_function method. Thanks.
To be honest, I'm pretty new to all this IoC, dependency inversion/injection concept too. But I think I've gone through the same struggle before. What I would do, as much as my knowledge allows, is...
Add a constructor to src/controllers/admin/AdminPageController.php:
protected $pageModule;
public function __construct(PageModule $pageModule)
{
$this->pageModule = $pageModule;
}
Then where you did $module = new PageModule in the same file. You replace it with:
$module = $this->pageModule;
The two modifications above makes use of Laravel's IoC to allow injecting a different PageModule object into your controller, instead of strictly creating PageModule in your code.
Now at this point Laravel should know that when it constructs the AdminPageController, it should create a PageModule and inject into the controller for you.
Since your controller now expects a PageModule class, you can no longer do class PageModule extends Eloquent in your app anymore, because even though the name is the same, PHP does not think that it is! You'll need to extend it:
So let's rename your app/models/PageModule.php to app/models/CustomPageModule.php, and in the file change the class to:
class CustomPageModule extends \PageModule {
Up to this point, you also have a CustomPageModule class that is a child of your package's PageModule. All you need to do now is to let Laravel knows that if any controllers ask for PageModule, it should serve the controller with your MyModels\CustomPageModule instead.
So at the top of your app's routes.php file:
App::bind('PageModule', 'MyModels\CustomPageModule');
Your AdminPageController should now be using your CustomPageModule and can use whatever public methods that are in there!
I'm expecting to be editing this answer heavily since this will be quite a long discussion. My first try at answering above isn't the best code you can write, but I hope it takes the least amount of edit to the original code, and then we can work up from there.
Or fast track by reading up articles like http://culttt.com/2013/07/08/creating-flexible-controllers-in-laravel-4-using-repositories
You probably have a alias for the PageModule facade, you should override this alias using your class \MyModels\PageModule in your app/config/app.php file.
Be careful, it seems like you are overwriting the PageModule class instead of extending it. You should probably extend the parent class instead of Eloquent.
I want to make something like this:
Main_Controller -> {
child1_controller
child2_controller
child3_controller
}
the purpose is to execute the constructor of the Main class everytime the child classes have been executed, it looks like some kind of multi extending, for example if i want to check in the main constructor wheter is admin or not, but the problem is when i do that
child1_controller extends Main_Controller
i get an error Class 'Main_Controller' not found
Use the built in core class extending mechanism, if you name your base controller class appropriately (with the default prefix MY_) and put it under application/core CI should pick it up.
Once you got your MY_Controller set up, you can make your child controllers under application/controllers/ extend that, and call for parent::__construct() in their __construct.