Symfony 2.4 CRUD please; Controller not found - php

I'm (almost) new to Symfony and I'm using 2.4 but I got a problem that is giving me lots of headaches. For several days I have not been able to fix this issue.
I use the app/console commands to build my base code; from entities to crud:
doctrine:generate:entity (to build the models), then code relations, etc
doctrine:generate: entities (to generate setters, getters, etc)
doctrine:schema:update --force (to update to the database all the models)
generate:doctrine:crud (to make controllers, forms, etc....)
At last, since I choose to declare the routing via annotations, I import into my bundle's routing.yml file all the controller routes like:
AutocondatECRBundle_controllers:
resource: "#AutocondatECRBundle/Controller"
type: annotation
This, as far as I'm aware, makes available all the routes inside the generated controllers at crud generation. However, no matter what route I try to test, Symfony keeps telling me:
FileLoaderLoadException: Cannot import resource "/var/www/autocondat-ecr/src/Autocondat/ECRBundle/Controller" from "/var/www/autocondat-ecr/src/Autocondat/ECRBundle/Resources/config/routing.yml". (Class Autocondat\ECRBundle\Controller\Clasificacion_EstudioController does not exist)
no mater what controller or route I choose to test, always fails to find the controller class, and believe me; those classes are there.
-There are no typos on names or cases
-Classes are there, controllers are there
-Routes are there and can't be loaded even using :
pattern: /whatever
defaults: { _controller: AutocondatECRBundle:ControllerWhatever:index }
This is driving me crazy.
For anyone able to help me, here is the source of all the project:
Link to the project
NOTES:
-There are several bundles inside my project; the one I'm testing is AutocondatECRBundle.
-Security inside security.yml file has been deactivated in order to test it faster.
-Of course, database can be generated fast with the same console commands.
Thanks -A LOT- for your help!

For your class Autocondat\ECRBundle\Controller\Clasificacion_EstudioController
Symfony will resolve both the namespace seperator \ and the underscore _ to a directory seperator, using PSR-0 autoloading standards for the autoloading of classes.
That means it is expecting your class to be located in the file src/Autocondat/ECRBundle/Controller/Clasificacion/EstudioController.php.
Name you class to ClasificacionEstudioController and the file to ClasificacionEstudioController.php.

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!

First "ClassNotFoundException" then "FileLoaderLoadException"

I am trying to create application in Symfony 2, to learn as much as I can, as beginner. First AppBundle which was created by default was easy. Second I created using create:bundle "ResultBundle", was a bit rough and I got "ClassNotFoundException" at first, but after some settings it worked again as expected.
Armed with not so deserved confidence, I tried to create third bundle "ClinicBundle" and then everything fell apart. Although I created routing.yml for new bundle, and set it correctly in AppKernel.php (link goes right to new class ClinicBundle.php), and set app/config/routing.yml correctly (same as for previous ResultBundle) and added the bundle to composer.json autoload, same as in previous bundle, I kept getting "ClassNotFoundException" for this ClinicBundle, like it can't be loaded in AppKernel.php though when I point to link in that row:
new ClinicBundle\ClinicBundle()
It goes smoothly to the right file. Every advice I have found online was already done and set correctly. Everything was in place but "ClassNotFoundException" kept on and it just wasn't working. I tried clear:cache also but same error popped up even then. I checked everything and it was all in place. routing files, paths, composer autoload. AppKernel...
Finally, I followed some ill advice from a forum and run some dump-autoload command which "generated autoload files" and everything after is much much worse. Now, I am getting long long FileLoaderLoadException error with many lines and main is this one:
Cannot load resource "#ClinicBundle/Resources/config/routing.yml". Make sure the "ClinicBundle/Resources/config/routing.yml" bundle is correctly registered and loaded in the application kernel class. If the bundle is registered, make sure the bundle path "#ClinicBundle/Resources/config/routing.yml" is not empty.
I have no idea what is wrong since bundle is registered in AppKernel and this routing file is not empty, it's like this:
clinic_homepage:
path: /clinic
defaults: { _controller: ClinicBundle:Default:index }
app:
resource: '#ClinicBundle/Controller/'
type: annotation
The same structure as previous ResultBundle which worked before all this happened. Also, the ResultBundle does not work anymore too, if I put it on top of routing.yml file in app/config same error happens but for ResultBundle. This is how app/config/rounting.yml file looks like:
clinic:
resource: "#ClinicBundle/Resources/config/routing.yml"
type: annotation
result:
resource: "#ResultBundle/Resources/config/routing.yml"
type: annotation
app:
resource: '#AppBundle/Controller/'
type: annotation
What happened? Does anyone know what is missing here? How do you add new bundle so that it does not report "ClassNotFound"? Thanks!
Just without type: annotation
clinic:
prefix: /some-prefix
resource: '#ClinicBundle/Resources/config/routing.yml'

symfony: how to pass to uploaded bundle its own path

I am using symfony 3.3
I have created a bundle which I install via composer into vendor/ in my application. I have this bundle to require some yml files which I inject to it via dependency injection. So far everything is ok. But I also have one yml file already inside this bundle and this bundle has to know this (his own) file's path.
Currently I have this in one of my bundle's classes
protected const LOCAL_FILE = __DIR__.'/../Resources/translations/ru.yml';
It works just fine but I do not think it is a proper solution. I try to pass to this class a %kernel.root_dir% but from that I still can't guess the whole path.
How ought I to do it the best way?
UPDATE: having made what zerkms suggested I get the result invoking this method the following way:
my.translator:
...
calls:
- method: configure
arguments:
...
- '#kernel'
and the part with locateResource
protected const LOCAL_FILE = '#MyBundle/Resources/translations/ru.yml';
....
....
$this->kernel->locateResource(self::LOCAL_FILE)
You might have used the Symfony\Component\HttpKernel::locateResource() method.
And the kernel object is available through the #kernel id in the container.

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