How can I overwrite a core laravel method? - php

Here is what I'm trying to do:
We are using Laravel 4.2 in our project, and are using the frameworks' Password::remind functionality to send emails for password reset.
The problem is that the team wants all the email templates to be located inside the database instead of the views folder, so I will have to somehow pass a string to the Illuminate\Auth\Reminders\PasswordBroker::sendReminder method.
How can I override this class in Laravel so I can make this thing work? I'm currently a Laravel newbie so I don't yet fully understand how the framework works...

It isn't easy to override the classes simply. Whole laravel mail is based on views. But you can probably create a workaround to achieve you're goal.
For this you've to make the required views. In a service provider or in you're route file you make a view composer. With that view composer you retrieve your data from the database and the only thing you do in the view is printing the value.
View::composer(array('reminders.password','reminders.other'), function($view)
{
$view->with('html', RemindersRepository::getHtml());
});
Or something like that. Now in you're view print {{$html}} and it works!
Edit:
For you're information a view composer is something like a event listener. When the view is loaded, the callback function of the composer is loaded. In that callback function you can pass a extra variable with some contents. In the view you can print this value added in the composer.

Here is a basic guide on how to override/extend core functionality in Laravel:
You can create a folder in app/start/ and then create your own class to override the default behavior like NewReminderServiceProvider.php Then you extend the core functionality in question:
class NewReminderServiceProvider extends Illuminate\Auth\Reminders\ReminderServiceProvider {}
then overwrite or extend the registerPasswordBroker.
In the parent you are extending, you will see where it sets the view:
$view = $app['config']['auth.reminder.email'];
change that to be database driven however you want.
then last of all you have to swap out the ReminderServiceProvider with your NewReminderServiceProvider in your app/config/app.php and you are good to go. This will work with almost any core functionality. Replace or extend blade, auth, etc.

Related

CodeIgniter: where should I put custom utils?

I'm using CodeIgniter and I have a few utils that I want each controller (that is, each controller file) to have access to.
The question is: where to put these?
I thought of helpers, but the CI documentation talks only about extending existing helpers, not making your own. I'm sure that doesn't mean I can't make my own helpers, but it does mean I don't know how they should be built (procedural? Methods of the global CI instance? etc)
I also considered hooks, but this is a poor fit I think as I'm not extending core functionality.
Or is there some other way I'm missing?
It's been a while since I've done this but I believe I used two approaches.
Creating a new, custom helper that goes into /application/helpers, following steps noted from this answer: CodeIgniter: Create new helper?
Creating a new library class into /application/libraries which I also activate in the autoload configuration found in /applications/config/autoload.php. This way it's always available to my controllers when I need it. CI has good documentation on this one (http://ellislab.com/codeigniter/user-guide/general/creating_libraries.html).
I did it simply by adding a file to the application/helpers folder (maybe I created that folder - I can't remember) and then loading them in the usual way.

Where do my non-action/controller classes go in a bundle?

I'm really new to Symfony 2, coming from CI and trying to get me head around where the correct places for everything should go. I've got a bundle that takes care of the few main page types I have, but here's one page element that I use in multiple pages, that can have different configurations for each page.
The logical way around this (as far as I can see) is to have a single class somewhere that all the pages can use... this isn't to be accessed by users so shouldn't go in the controller I'm guessing but where should I put this class?
Make a 'core' type folder within my bundle. Are there naming best practices for this?
Should it go in the vendor folder or is this just for third party bundles?
Make another bundle to somehow use this code... seems a bit overkill for one or two classes?
other?
I guess what you need is to create a service. You can create your own class that has it's own logic and retrieve it using the service container in the controller. The following example is available at Symfony Service Container Docs
$mailer = $this->get('my_mailer');
$mailer->send('ryan#foobar.net', ...);
To make that class available you have to add it in the service.yml file of your bundle like this:
services:
my_mailer:
class: "%my_mailer.class%"
arguments: ["%my_mailer.transport%"]
You can add any other service or parameter to your class via the arguments
More info here: http://symfony.com/doc/current/book/service_container.html

Override Laravel 4 Package view

I want to create my custom CMS and I'd like to create a user package in which I will have a controller with showProfile() function. But the problem is I'd like to easily edit this profile view. So I want to know if there is a way to create cascade view. Like if there is no file in app/views/ then vendor/vendor/package/src/views will be loaded. I hope you got this idea :)
EDIT:
I managed to make it work. I had to register new namespace for views in my ServiceProvider.
I put this code to ServiceProvider:
\View::addNamespace('cmscore',array(app_path()./'views/packages/zaalbarxx/cmscore');
Where zaalbarxx/cmscore is vendor/package and cmscore is a namespace I can use later in controller like View::make('cmscore::index'). I added this code in boot() method BEFORE $this->package() so this way app/views are prioritized over package/views. Works brilliant.
It is already possible, however the structure would be it look into vendor/package-name/src/views by default, but if there is the equivalent in app/views/packages/package-name/ that would be chosen.
As stated, you should be able to load package views already.
However, you can add more view locations in the array found in app/config/view.php.
Additionally view paths can be added at run-time with the addLocation() method found in the FileViewFinder class.
Using that method that in a service provider would look like:
$app['view.finder']->addLocation('/path/to/views');
Or anywhere in your app:
App::make('view.finder')->addLocation('/path/to/views');
Also note, I answered this question on cacheing view output recently, which might help you see how extending some portions of the View package might work if you choose to go down that route.
You don't need to program this behavior in, if you read the laravel code you will see that this is built in...
Packages by default will first look in and
app/views/packages/package-name/ (all in lowercase! even if package or author have caps! goes unnoticed on windows and then on linux you will bump your head against the wall! )
and if the customer app view doesn't exist the package views will load from the package itself inside:
vendor/author/package-name/src/views

CodeIgniter HMVC: extend a library or create a global controller?

I've started using HMVC in Codeigniter with Modular Extension and i want to create a set of methods avalaible in the whole application.
For example i've this three methods:
a method to retrieve te app name
a method for getting the right view folder depending on the user agent
a method to load assets
What's the best way to do this:
I'm using a model inside a module which is then requested from all other modules
I may extend or create a library/helper
now i'm using the first solution but I have come to doubt that it can slow down the application.
I would put this one in a base controller. Like this one: https://github.com/jamierumbelow/codeigniter-base-controller

In an MVC Context, Where Do I Put A Class?

straight to the point :
I am using Kohana, and I am looking at another script written in plain PHP. In the script, I have a class ShoppingCart. If I am to convert the script to Kohana, where am I to put the class, its methods and its properties?
Is it in my existing default controller? Or should I put it in a separate controller? Or as noobie as it may sound, will I put it in the model?
That depends on the specifics of the class I suppose. To be honest I don't know anything about Kohana, but there's probably a place for "vendor files" somewhere. Maybe it's best to place it there and write wrapper functions for it in your controller. If the class already integrates well with Kohana you may instead choose to use it as a controller or model directly. Or you might want to take the time to rewrite it to make it work as a controller...
Only you can evaluate the best place for it, there's no hard and fast rule here.
Kohana has a folder for 3rd party libraries. The main one is under system/vendor, you can put it in you application/ as well.
Many PHP class loaders require details like your filename should be the same as the class name (at least that's what I read in the Kohana documentation) if you want the classes to be automatically loaded.
If you need to use 3rd party code in your app it's recommended that you create a folder in your app / module folder called 'vendor' and place all of that code there.
You can then include the files by calling:
include kohana::find_file('vendor', 'filename');
If needs be you can also create a wrapper for the external library, a good example of this is the email helper which uses the 3rd party Swift email library.
If you're porting your own class to kohana then you need to work out what the class will be doing and categorise it accordingly.
If the class will be fetching items from some kind of database then you should make it a model. Libraries are usually sets of code that you want reuse across controllers / models, such as authentication, calendar generation etc. Controllers are used for passing data from models to your views / libraries.
See the docs for more info
As per kohana convention, you should place custom classes in application/libraries folder. However for this, you need to know how to get the class to work after putting it there. If you can't figure that out, you can do anything like putting it in your controller or making another controller of it, etc.

Categories