Laravel - How to assign relative path for subfolder controller? - rest

I'm using laravel 4.0 for my web service project. I try to assign relative path to controller subfolder but still got the error message.
This is my router looks like
Route::group(array('prefix' => 'merchant'), function()
{
Route::resource('index', 'ProductController#showIndex');
Route::resource('product', 'CategoryController#showIndex');
Route::resource('general', 'GeneralController#showIndex');
});
Current path
/app/controllers/ProductController.php
I want to be like this one
/app/controllers/merchant/ProductController.php
Thanks a lot in advance.

You need a namespace to achieve that.
In your controller folder make a directory called merchant and place your ProductController.php inside Merchant directory.
Then open your ProductController.php and use the following namespace on top of the file.
<?php namespace Merchant;
class ProductController extends /BaseController
{
After that edit your route file:
Route::get('index', 'Merchant\ProductController#showIndex');
Remove the Route::group(array('prefix' => 'merchant'), function(). Prefix used when you have a common url for more than one routes.
For example:
http:://laravel.com/xyz/products
http:://laravel.com/xyz/category
http:://laravel.com/xyz/posts
Here xyz is common in every URL. So, In this case, you can use group routing with prefix xyz
One more thing, I can see, you have used resource controller.
Route::resource('index', 'ProductController#showIndex');
Route::resource('product', 'CategoryController#showIndex');
Route::resource('general', 'GeneralController#showIndex');
Do you know that By default, for resource controller, Laravel will generate 7 routes. So, You don't need to create #showIndex function when using resource controller.
Route::resource('index', 'ProductController');
Route::resource('product', 'CategoryController');
Route::resource('general', 'GeneralController');
More about resource controller:
http://laravel.com/docs/controllers#resource-controllers

Related

Zend Framework 2 Override an existing Service?

I am using a zf2 module called GoalioRememberMe and now I want to override its service by my customized service. Or if it is not possible, I want to override the Module.php with my config. Is it possible?
In the Application module. I wrote this line in module.config.php:
'GoalioRememberMe\Service\RememberMe' => 'Application\Service\RememberMe'
Thanks in advance!
This is exactly the reason it is recommended to name the service as the type of the object that is returned. The object GoalioRememberMe\Service\RememberMe is named goaliorememberme_rememberme_service in the service manager. You can check that here.
So the solution is simple, instead of this:
'GoalioRememberMe\Service\RememberMe' => 'Application\Service\RememberMe'
Write this
'goaliorememberme_rememberme_service' => 'Application\Service\RememberMe'
As Jurian said, the service name is goaliorememberme_rememberme_service and it has been set in the getServiceConfig() method. So I wrote this code in the Module.php file in the Application Module:
$serviceManager->
setAllowOverride(true)->
setInvokableClass('goaliorememberme_rememberme_service', 'Application\Service\CustomRememberMe')->
setAllowOverride(false);
And it replaced successfully with my customized service!
Thanks very much to Jurian for the big help!
Actually the service manager first runs a method "canonicalizeName()" which "normalizes" the names as follows:
All _ / \ and - are stripped out
The key is made lowercase
Thus both "GoalioRememberMe\Service\RememberMe" and "goaliorememberme_rememberme_service" become "goalioremembermeremembermeservice" (i.e. they're both the same), thus the error message.
The quickest way to override an existing service is to create a *local.php or *global.php file in the /config/autoload folder. (That folder is identified in config/application.config.php.) Any override files in this folder are process after modules are loaded. If you have duplicate service manager keys, the last one wins.

Using Zend view helper from admin module with default module layout

I have a view helper being called in my layout that works fine in the default module, but I get an exception when I am in another module.
I have already changed my app.ini to use the default layout across all modules by setting:
resources.layout.layoutPath = APPLICATION_PATH "/layouts/scripts/"
And searching here and google provided me with another app.ini setting to add the view helper path for all modules:
resources.view.helperPath.Zend_View_Helper = APPLICATION_PATH "/views/helpers"
However instead of fixing the problem, that additional setting causes the Zend Exception to become a WSOD.
Without that second app.ini setting, I see the layout and get this exception:
Plugin by name 'AutoScript' was not found in the registry; used paths: Admin_View_Helper_: /Applications/XAMPP/xamppfiles/htdocs/dad/application/modules/admin/views/helpers/ Zend_View_Helper_: Zend/View/Helper/:./views/helpers/
With the helperPath.Zend_View_Helper ini setting I get a WSOD with the following:
Fatal error: Uncaught exception 'Zend_Loader_PluginLoader_Exception' with message 'Plugin by name 'AutoScript' was not found in the registry; used paths: Zend_View_Helper_: Zend/View/Helper/:./views/helpers/'
It appears the plugin loader is looking in public/views/helpers/ for the AutoScript.php file even though it should be using the APPLICATION_PATH value as a prefix.
My layout invocation looks like this
<?php $this->AutoScript(); ?>
My AutoScript.php file's class is defined in application/views/helpers/
class Zend_View_Helper_AutoScript extends Zend_View_Helper_Abstract {
public function AutoScript() {...}
}
My current fix is to copy the AutoScript.php file from application/views/helpers into modules/admin/views/helpers which fixes the issue, but duplicates a file. What am I missing? Do I have to add this view helper path programmatically by creating an _initView function in my bootstrap?
Typically, you would name your custom view helper with your own prefix, not the Zend_ prefix. Beyond that, there are several choices for where to put and name your view helpers.
If this view-helper is really a single-application helper, then I find it natural for it to reside somewhere in the application folder. Within that possibility space, I would ask if the view-helper will be used in a single module or across multiple modules.
If the view-helper is intended for use in a single module, then I depend upon the build-in resource-autoloader mappings and place my view-helper class Mymodule_View_Helper_Myhelper in the file application/modules/mymodule/views/helpers/Myhelper.php.
If the view-helper is intended for use across multiple modules , I might pull it up a little higher than the modules folder, say Application_View_Helper_Myhelper (assuming an appnamespace of Application) stored in
application/views/helpers/Myhelper.php. In this case, we need to tell the view that there are helpers with prefix Application_View_Helper_ in that directory. This can be done at bootstrap:
protected function _initViewHelperPaths()
{
$this->bootstrap('view');
$view = $this->getResource('view');
$view->addHelperPath(APPLICATION_PATH . '/views/helpers', 'Application_View_Helper_');
}
Sometimes, you need a view-helper in one module that exists in another module and you cannot - in practical terms - move the original one around. In that case, one workaround is to define an empty shell of a view-helper in your consuming module extending your unmovable view-helper. In file application/mymodule/views/helpers/MyHelper.php:
class Mymodule_View_Helper_Myhelper extends Othermodule_View_Helper_Myhelper
{
}
This way, the code for the helper implementation is not duplicated. The module-specific resource-autoloader mappings will allow all those classes to be found when they invoked as view-helpers from a view-script.
Finally, if this view helper is to be used in multiple projects, then there is an argument for placing it outside of application scope, out in in the library folder. So perhaps a class MyLibrary_View_Helper_Myhelper stored in the file library/MyLibrary/View/Helper/Myhelper.php. As before, you would need to inform the view - probably at bootstrap or in a front-controller plugin - of the prefix/path mapping:
$view->addHelperPath(APPLICATON_PATH . '/../library/MyLibrary/View/Helper', 'MyLibrary_View_Helper_');
Note that in all cases above, the invocation of the view-helper functionality itself - say, inside a view-script - is:
<?php echo $this->myhelper($params) ?>
Note, in particular, the casing difference between the classname and the invocation.

module specific routes in Zend Framework without specifying module name in route

I need to create some module specific routes, but without explicitly mentioning module name in route. Right now I have separate config file for each module (MODULE/configs/module.ini) and in the module bootstrap I push those routes into Zend Framework. The INI file holds routes information but it mention the module name in the route. e.g.
routes.contents.route = "Contents/(.*)"
routes.contents.defaults.module = Contents
routes.contents.defaults.controller = index
routes.contents.defaults.action = index
+other details regarding the route.
You can see that the module name ("Contents") is explicitly mentioned in the route. What I want is that in the routes I just mention the portion after the module name and it automatically prepend the module name before the route. So later if I rename the module to lets say CMS, I don't ve to change every route into "CMS/xxxx".
The 'route' you specify can be anything you want. If Zend Framework matches it, it will execute the route based on the defaults set below.
resources.router.routes.products.regex = "somethingawesome/(.*)"
resources.router.routes.products.defaults.module = "ModuleName"
resources.router.routes.products.defaults.controller = "awesome"
resources.router.routes.products.defaults.action = "cool"
The above 'route' uses the regex match for - mysite.com/somethingawesome/whatever and will route it to the module: ModuleName, controller AwesomeController.php and run the coolAction()
There are lots of other matches you can do within this regex, but the string 'somethingawesome' is entirely up to you. It's all about what you want to match in the URL and where you want to send it to.

Multiple types were found that match the controller named 'Home'

I've just started using dotnetopenauth for my user registration. It's great, and is working perfectly.
The problem is now I'm getting an error when I try to go to /Home/ which says:
Multiple types were found that match the controller named 'Home'. This can happen if the route that services this request ('{controller}/{action}/{id}') does not specify namespaces to search for a controller that matches the request. If this is the case, register this route by calling an overload of the 'MapRoute' method that takes a 'namespaces' parameter.
The request for 'Home' has found the following matching controllers:
OpenIdRelyingPartyMvc.Controllers.HomeController
YourApp.Controllers.HomeController
The problem is, I have no idea where OpenIdRelyingPartyMvc.Controllers.Homecontroller is coming from. I can't find ANY instance of "OpenIdRelyingPartyMvc" anywhere in my app, save 2 places, both of which occur in the UsersController:
OpenIdRelyingParty openid = new OpenIdRelyingParty();
I've tried deleting the DLL and rebuilding the app - no change. I can't figure out where this other controller would be.
Any ideas?
I had the same error message after changing the name and default namespace of the project.
Finally the solution was to manually delete all the files from debug -folder ("Clean Solution"-function of VS didn't help in this case).
My guess is that you copied the code from the samples into your codebase or you are referencing the DLL from the DotNetOpenAuth sample project. Note, OpenIdRelyingPartyMvc is the namespace of the MVC example.
So my suggestion is to first remove all instances of the DotNetOpenAuth library by starting from the project references.
use this in route.config file
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional },
new[] { "ProjectName.Controllers" }
);
Note: Project Name which you had given while creating the project

Dynamically setting view directory

I am making a customer portal application using ZF. And the portal needs to work for different company brands. So I need to use all of the same backend code/controllers/etc, but dynamically change the view directory based off of the hostname.
Right now my view directory structure looks something like this:
/application/views/scripts/brand1/
/application/views/scripts/brand1/index/index.phtml
/application/views/scripts/brand1/error/error.phtml
/application/views/scripts/brand2/
/application/views/scripts/brand2/index/index.phtml
/application/views/scripts/brand2/error/error.phtml
/application/views/scripts/brand3/
/application/views/scripts/brand3/index/index.phtml
/application/views/scripts/brand3/error/error.phtml
and so on.
I am using the addScriptPath() function in bootstrap.php like so
protected function _initView()
{
$view = new Zend_View();
$view->doctype('XHTML1_STRICT');
$view->env = APPLICATION_ENV;
$view->addScriptPath(APPLICATION_PATH . '/views/scripts/brand1');
$view->addHelperPath(APPLICATION_PATH . '/views/helpers');
...
}
However when this is run, it is looking for all views using /views/scripts/brand1/(action).phtml instead of looking for views using the correct scheme /view/scripts/brand1/(controller)/(action).phtml
tl;dr is it possible to dynamically choose the view directory and have it work like the default /views/scripts/(controller)/(action).phtml behavior?
I knew I would find the answer after I posted here. In case anyone else encounters the same problem, the solution was using:
$view->setBasePath(APPLICATION_PATH . '/views/brand1');
And then modifying the directory structure to:
/application/views/brand1/scripts/...