Symfony routing resource and Bundle name - php

I an trying to include a file into the Symfony 4 routes, and can't figure out what would be the correct way to put in the Bundle name.
My routes.yml:
icatcher_builder:
# loads routes from the given routing file stored in some bundle
resource: '#ICatcher/Builder/Resources/config/routes.yaml'
My bundles.php:
App\ICatcher\Builder\Builder::class => ['dev' => true, 'test' => true],
And I get this error:
An exception has been thrown during the rendering of a template
("Bundle "ICatcher" does not exist or it is not enabled. Maybe you
forgot to add it in the registerBundles() method of your
App\Kernel.php file? in #ICatcher/Builder/Resources/config/routes.yaml
(which is being imported from "[PATH]\config/routes.yaml"). Make sure
the "ICatcher/Builder/Resources/config/routes.yaml" bundle is
correctly registered and loaded in the application kernel class. If
the bundle is registered, make sure the bundle path
"#ICatcher/Builder/Resources/config/routes.yaml" is not empty.").
If I just copy the routes into the main route.yml file instead of including an external resource - all works fine.

Symfony has strict rules of naming Bundle classes, which I found out here in the documentation:
https://symfony.com/doc/current/bundles/best_practices.html
So my Bundle class is now re-named from App\ICatcher\Builder\Builder to App\ICatcher\Builder\ICatcherBuilder and the file is re-named the same way ICatcherBuilder.php and it works.

Related

Fallback route in Symfony 4 while using annotation routing

I'm currently using routing via controller annotations in a Symfony 4 application.
I am trying to route all requests that don't match an existing annotation (e.g. http://example.com/route-that-isnt-defined) to a specific controller and function (e.g. DefaultController::dynamicPage() which has logic to find if I should be serving content or triggering a NotFoundHttpException).
Defining the route for DefaultController::dynamicPage() as #Route("/{param}") precedes and intercepts all other defined routes, making them inaccesible.
I have tried this solution for Symfony 3, not knowing if it will work but get stuck on what "AppBundle" is supposed to refer to, as it's not something that exists in my project.
Currently, my routes.yaml only has one route in it for the index, as all other named routes are defined via annotations:
index:
path: /
controller: App\Controller\DefaultController::index
I am looking for either the proper way to implement the link Symfony 3 solution in Symfony 4, or an alternative method of achieving the routing I want without doing something convoluted like extending the exceptions controller and inserting routing functionality into cases of NotFoundHttpException.
You could try adding a kernel event listener that would handle the kernel.exception event, and for cases where the exception is a NotFoundHttpException you'd return your custom response instead of the 404 Not Found page.
This could be quite flexible since you can implement any custom logic in such listener.
I haven't moved to sf4 yet, but isn't this problem just related to the order of the routes being evaluated? I.e. you could try by just adding explicit definition to load the DefaultController.php annotations in your routes.yml as the last element? I.e. something like this should do the trick (works in sf2.8 at least):
app_annotations:
resource: '#MyBundle/Controller/'
type: annotation
fallback_annotations:
resource: '#MyBundle/Controller/DefaultController.php'
type: annotation
or if that doesn't work in sf4 (if it loads the controller route annotations with some other logic automatically), another workaround would be to just name this fallback controller so that it will be the last one alphabetically (and thus the routes there should be evaluated the last).
From your comment I "smell" you have some composer packages that are not compatible with the current config of your project. Are you upgrading to SF4 from SF3?
I also had this InvalidArguementException:
"The "App" (from the _controller value "App:Default:index") does not exist
or is not enabled in your kernel...
Turns out that I have a non supported package easycorp/easyadmin-bundle version ^3.1 which I fixed it by
Removing the vendor folder
Removing the composer.lock file.
Explicitly specify the version my project supports ^2.3 in composer.json
Run composer install... et Voila!

laravel 4 create module and put controller , module and view inside module

I have worked on yii framework before and I had possibility to create module folder and inside this put eg: news module which was included controllers, views and module
I'm new in laravel and trying to create same thing MODULE
i tried the following inside routing
Route::get('/news','/modules/news/controllers/NewsController#index');
file exist but i'm getting
ReflectionException
Class /modules/news/controllers/NewsController does not exist
why ? what i'm doing wrong ?
The Route::get() function is looking for a (auto)loaded Class, not for a file on the disk to load, which is why you're getting these errors.
It's more Laravely (Laravelish?) to include:
Controllers in the /app/controllers/ directory
Views in /app/views/ directory
Models in the /app/models/ directory
And if you are starting out with Laravel, this might be the best way to get started. The autoloader knows where to look for your classes then, and everything gets handled automatically for you.
With the NewsController situated in /app/controllers/ you can do this:
// no need to start the route location with a slash:
Route::get('news', array('uses' => 'NewsController#index'));
You can "package" up functionality using Laravel's Packages, but it would be better to check out the excellent docs and then come back with specific questions..
Put your Laravel controllers in app/controllers, since that directory gets autoloaded, and it is where Laravel expects controllers to be.
Then you can use routes like this (example straight from the docs at http://laravel.com/docs/controllers#basic-controllers)
Route::get('user/{id}', 'UserController#showProfile');

ZF2 Default Routing Configuration

I am having trouble with the workflow when creating new modules/controllers to the ZF2 Skeleton Application.
I created a new module test and navigated to mydomain/test. This returns a 404 error until I do the following:
Define my Module in the global config file
Define my route in my module config file
Define my Controller as an invokables in the module config file
Define the path of my view as a view_manager in the module Config file
I am new to ZF2 and trying to better understand the workflow for Application development. This seems like a very cumbersome way to develop, as there is so much configuration needed.
(Rapid application Development??)
Is there a Default means of defining literal routes, controllers, and view rendering in ZF2?
Create your module with zftool, it will add it to your global config.
You will have to create at least one route for each module, take a look at the route in the Application module with this route you're covering allot the comment says:
The following is a route to simplify getting started creating new
controllers and actions without needing to create a new module. Simply
drop new controllers in, and you can access them using the path
/application/:controller/:action
You will have to add controller to the invokables
Use template_path_stack:
'view_manager' => array(
'template_path_stack' => array(
__DIR__ . '/../view',
),
)
i use template_path_stack during development and template_map in production

Symfony2 bundle inheritance losing parent bundles routes

I am trying to create a simple bundle inheritance as instructed in here and ran into a problem with routes. I'm using annotations for routing. When I register my child bundle in AppKernel.php all my parent bundles routes are lost.
For what I understand from the documentation Symfony2 should look all files, including routes, first from the child bundle and then from the parent bundle. Now that is not happening, only child bundles controllers seems to be loaded.
In my child bundles Bundle file I have implemented getParent function as instructed, and in my routing.yml I have:
ParentBundle:
resource: "#Parent/Controller/"
type: annotation
prefix: /admin/
which worked fine before the inheritance.
I have tested that the system works fine if in include all controller files separetely in routing.yml but that seems very cumbersome way to make the inheritance to work as I only want to override few parts of the parent bundle ( not all controllers ).
Profiler is showing both of my bundles as active.
I found the right solution for this issue. Today I was also trying to override a parent bundle configured with annotations routing and also found that parent routes were ignored if the anotation routing imported the whole bundle ("#SomeBundle/Controller").
After a little debugging I found that the explanation for this is that if you use "#" as prefix for the controller this will pass to the kernel resolver which will return ONLY the child resource if the parent resource has been overridden. So the solution is to provide the full path of the bundle, considering that the kernel will try to match the resource from app/Resources so you will have to add a relative directory (../../) before the actual path:
# app/config/routing.yml:
some_parent:
resource: "../../src/Application/ParentBundle/Controller"
type: annotation
# ChildBundle implements getParent() method to inherit from ParentBundle
some_child:
resource: "#ChildBundle/Controller"
type: annotation
This will work as expected: all parent routes will be imported and will be overridden by all routes specified in the child bundle.
In addition to previous answer, I also had to change the name of the routing.yml of the child bundle (e.g. to routing_child.yml) to get it working. I assume this is because Symfony totally ignores the parent bundle routing file if the name is identical.
EDIT:
In many cases it's also practical to import parent bundle routes into the child bundle routing file like this:
# routing_child.yml
_parent:
resource: "#MyParentBundle/Resources/config/routing.yml"
The official documentation says that you shall just copy parent routing file to your child bundle:
The easiest way to "override" a bundle's routing is to never import it at all. Instead of importing a third-party bundle's routing, simply copying that routing file into your application, modify it, and import it instead.
Also, you cannot include parent's bundle routing file using symbolic names "#ParentBundle" because this name is resolved to "#ChildBundle".
If you really want to include parent routes file, then you shall use the absolute path to that file or path relative to current directory, i.e.:
# #YourChildBundle/Resources/routing.yml
YourParentBundle:
resource: "/srv/www/example.com/src/Your/ParentBundle/Resources/routing.yml"
or
# #YourChildBundle/Resources/routing.yml
YourParentBundle:
resource: "../../../../../Your/ParentBundle/Resources/routing.yml"
Another workaround is to symlink your parent routing file into your child bundle and include it with shorter path, i.e.:
cd YourChildBunde
ln -s ../../../../../Your/ParentBundle/Resources/routing.yml parent_routes.yml
and then
# #YourChildBundle/Resources/routing.yml
YourParentBundle:
resource: "parent_routing.yml"
P.S. I hope they'll find some better and less uglier way to override and extend routing from parent bundle, but now we have to se some of those ugly workarounds.
With bundle inheritance, you can override the parent bundle's files.
If you create a routing file in the same location as the parents in your bundle (if the routing of the parent file is at ParentBundle/Resources/config/routing.yml, and you create a routing file at ChildBundle/Resources/config/routing.yml), it will override the parent's routing.yml, and symfony will only use the child's routing.yml.
I haven't tried, but if you import the parent bundle's routing.yml in the child bundle's routing.yml, you can solve your problem. As Symfony router will always choose the first matching route it finds, you can override the specific route you want by writing the relevant routing code on top of the import code.

Symfony 1.4: autoload modules' lib folders

how can I autoload my modules' lib folders in my Symfony 1.4 projects? Probably you know that problem:
If I create plugins, I store base-classes for my modules' actions in the lib folder. Each actions-class stored in actions/actions.class.php inherits from that base-class. This allows overriding the plugin-actions at project level:
myModule
actions
actions.class.php
lib
BasemyModuleActions.class.php
But unfortunately, Symfony doesn't autoload BasemyModuleActions and you have to include the respective file manually:
require_once(dirname(__FILE__) .'/lib/BasemyModuleActions.class.php');
class myModuleActions extends BasemyModuleActions
{
}
This works, but it is really annoying. Moreover I want to put more files in the modules' lib folders, e.g. forms.
Is there a way to add those directories to the autoloader?
Storing forms in their related modules would good for me, since I only reuse the same form for different modules in few cases.
Is your solution also compatible with the Doctrine form-generation task? I.e. is Symfony aware of the existing form, or will it be created again if it is moved out of lib/form/doctrine? (No problem, if you can't answer that. But it would be nice if you know a workaround in this case)
Take a look at this page:
http://www.symfony-project.org/reference/1_4/en/14-Other-Configuration-Files
It describes an autoload.yml file, which configures symfony to look for classes in different directories.
Symfony wouldn't autoload my /apps/app_name/lib/*.* classes, but does so after creating /config/autoload.yml file with the following content:
autoload:
# project
project:
name: project
path: %SF_LIB_DIR%
recursive: true
exclude: [model, symfony]
project_model:
name: project model
path: %SF_LIB_DIR%/model
recursive: true
# application
application:
name: application
path: %SF_APP_LIB_DIR%
recursive: true
modules:
name: module
path: %SF_APP_DIR%/modules/*/lib
prefix: 1
recursive: true
Which the above page describes as the default config.
As i understand it this is a chicken and egg issue with the autoloader and main controller flow.
The prefix: 1 in the default autoload.yml indicates that these classes are only available to be autoloaded if 'in' the current module.
The way the current module is determined is by looking at the actionStack.
The module/action is added to the actionStack after checking to see if it exists.
Unfortunately to determine if an action exists symfony loads the actions.class.php
Hence you need to have the explicit, require_once.
If you get rid of the prefix: 1 and your module is part of your application (not loaded from a plugin) you will not need the require once.
If the module is part of a plugin, you would need to mess with sfPluginConfiguration to have it load the appropriate classes without prefix.
Both methods are problematic as there could be clashes between class names in various modules.

Categories