Use glob pattern to include controllers annotations routing with Symfony 4 - php

I want to include all controllers for route annotation, giving a routes/annotations.yaml:
controllers:
resource: ../../src/{Site,Dashboard}/Controller/
type: annotation
The glob component is not giving folders but null (whereas files exist).
How can I use glob pattern in such way?

Related

How to add prefix to some controllers using annotations?

I have at the moment two controllers.
GitlabAuthController
UserController
I need to add the path prefix api to UserController only.
Before I was trying following at annotations.yaml file:
controllers:
resource: ../../src/Controller/
type: annotation
prefix: api
But this adds the prefix to all my controllers.
Is there any way I can add the exception for the GitlabAuthController?
Just create different directories/namespaces for the different types of controllers.
Then you can do:
controllers:
resource: ../../src/Controller/
type: annotation
api_controllers:
resource: ../../src/Controller/Api
type: annotation
prefix: api
Routes defined on the Api namespace would get the /api/ prefix, while the other routes would remain unaffected.
You can check the generated routes are fine by executing bin/console debug:router.

What Does the `type:` Configuration in a Symfony Route Configuration Control?

What does the type: configuration in a Symfony routing file control? What are its valid values?
I can't find this configuration field explicitly documented anywhere. It's referenced indirectly in Symfony's routing documentation.
app_directory:
resource: '../legacy/routing/'
type: directory
and seems related to loading in additional routes. However, its behavior (or all its allowed values) doesn't seem to be explicatly defined anywhere. I can make a guess that it somehow tells Symfony how to load the external routes, but I'd love to know
Is my guess correct?
Are there valid values other than directory or annotation?
Is this formally documented anywhere?
Is there a spot in the Symfony internals that would be a good place to start finding these answers for myself?
You can find how the type works in the Symfony documentation, see code below. It controls if the routes should be loaded from the PHP annotations or the YAML or XML files found in that (bundle) directory.
app_file:
# loads routes from the given routing file stored in some bundle
resource: '#AcmeOtherBundle/Resources/config/routing.yaml'
app_annotations:
# loads routes from the PHP annotations of the controllers found in that directory
resource: '../src/Controller/'
type: annotation
app_directory:
# loads routes from the YAML or XML files found in that directory
resource: '../legacy/routing/'
type: directory
app_bundle:
# loads routes from the YAML or XML files found in some bundle directory
resource: '#AppBundle/Resources/config/routing/public/'
type: directory

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!

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