SOLVED: Problem with attribute routing in symfony 5.4 - php

There's a solution via RFE for this in RFE; solve problem with bin commands and php versions
I'm dealing with a new app in symfony 5.4 and php 7.4 to test the new additions and changes in symfony 6. I've used the entity maker from the console to create the entity and the crud, and the db was created perfectly. However, the generator uses the new "attributes" (according to the convention in https://symfony.com/doc/5.4/routing.html) instead of the "classic" annotations. Debugging via console to see the resulting paths, none of the routes defined in the controllers is shown (of course, a 404 error was shown when accessing the url in dev mode). I decided to replace the attributes with classic annotations, and the paths are shown and the 404 error is gone. But now, I find that the logic the generator uses is via the repository to use the Entity Manager, and when accessing to the index to start from scratch, I get:
Could not find the entity manager for class "App\Entity\Room". Check your Doctrine configuration to make sure it is configured to load this entity’s metadata.
The portion of code shown in the debugger is this:
class RoomRepository extends ServiceEntityRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, Room::class); // Here is the error
}
And the entity starts with this:
namespace App\Entity;
use App\Repository\RoomRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity(repositoryClass: RoomRepository::class)]
class Room
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column()]
private ?int $id = null;
...
My biggest concern is that I guess I can't rewrite the full crud reverting to annotations, which is a lot of work (just what I wanted to avoid by using the generator), so there must be something about the attributes that I'm missing. Here's a controller whose crud I haven't modified yet, so anyone can take a look and find out why the router can't find the defined paths with this kind of annotation.
namespace App\Controller;
use App\Entity\RoomFeature;
use App\Form\RoomFeatureType;
use App\Repository\RoomFeatureRepository;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
#[Route('/admin/feature')]
class RoomFeatureController extends AbstractController
{
#[Route('/', name: 'admin_room_feature_index', methods: ['GET'])]
public function index(RoomFeatureRepository $roomFeatureRepository): Response
{
return $this->render('room_feature/index.html.twig', [
'room_features' => $roomFeatureRepository->findAll(),
]);
}
...
What is the problem with all this? Thanks in advance.

As stated in the first comment, forcing every bin/console (for make: commnds) and composer commands to be run especifically by prepending php7.4 to the command, everything works but with "classic" annotations, I've found no way to use attributes in controllers with php7.4. The .php-version file seems to be used only by the symfony-cli to launch the dev webserver. I hope this helps anyone who can face this scenario in the future.

I had a similar situation and on my case it was related to an incorrect namespace on a Trait (under src/Entity/Traits).
The trait wasn't even being used but apparently it will still cause this error.

Regarding your second comment:
the resulting code using annotations via attributes should be
compatible with whatever version of php is supported with symfony 5.4
This assumption is wrong, since symfony 5.4 supports php 7.2.5 and up. Although 7.2 is sunsetted officially, there are plenty of installations out there or with extended support from distros so that's besides the point: Symfony will happilly run in 7.2 or 7.3.
In any case, it's maker bundle who determines whether or not to use attributes based on the php version that is used to execute the maker commands, not the available installed versions. You can force it to use specific version features by executing composer config platform.php 7.4.x.
And be aware that maker bundle 1.44 has dropped annotation support altogether, so pin your version to an older one.

Related

Adjust Seeders integration for Package Development in Laravel 8

I developed a package for an api in laravel.7.x. That api is delivered as an package for laravel. Now I want to upgrade it to laravel 8. Unfortunately I cannot get the seeders to work.
all package Seeders should executed after the
php artisan migrate:fresh --seed
command.
Appearantly the Seeder classes are not found. for Example Target class [PostSeeder] does not exist.
But it does exist, it's even in the same namespace.
Now I'm trying to start in with a DatabaseSeeder and this one IS found. But from there the other Seeders can't be triggered.
Does anyone has an Idea what can be tried or has a hint or code snippet for this problem?
Many thanks in advance.
alright, the issue is solved.
Use the new way of including factories in laravel 8 i.e Models have this new function:
use Acme\YourPackage\Database\Factories\PostFactory;
use Illuminate\Database\Eloquent\Factories\HasFactory;
protected static function newFactory()
{
return PostFactory::new();
}
and make sure to call it like:
enter $this->call('Acme\YourPackage\Database\Seeders\PostSeeder');
after that make your sure your namespace and class paths are set correctly.

How to fix that symfony dd function shows a blank page?

Symfony version 4.1.
Problem: when I use dd I see only a blank page. body tag does not contain anything. Doing I little dubugging I found that there are different types of debugging output: cli, html, server. And in my case var_dumper.server_dumper service was used as a debugger class. I do not know symfony so good to make some further steps. I guessed that there is service config file where I can pass html_dumper. But I did not find any related files. Symfony docs also show nothing about the configuration. Strange, but google also does not show any relevant results.
Want to add that I installed symfony 4.1 when it was not stable and then I usage of dd/dump gave the same result. But I have run composer update recently and now I should have a fresh symfony version. For long time I used xdebug but sometimes it is much easier to dump a var.
Update:
My code:
namespace App\Controller\SuperAdmin;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class HomeController extends Controller
{
/**
* #Route("/", name="home")
* #return Response
*/
public function index()
{
dd(1);
return $this->render('super-admin/home/index.html.twig');
}
}
Update: Just verified that Symfony 4.1.1 has fixed this problem. dd now works as expected out of the box.
Some of this is discussed here: https://symfony.com/blog/new-in-symfony-4-1-vardumper-server
Basically, out of the box, Symfony 4.1 has:
# config/packages/dev/debug.yaml
debug:
# Forwards VarDumper Data clones to a centralized server allowing to inspect dumps on CLI or in your browser.
# See the "server:dump" command to start a new server.
dump_destination: "tcp://%env(VAR_DUMPER_SERVER)%"
The intent (I think) is to intercept debug strings and print them to a console using:
bin/console server:dump
So dd(1); will result in an output in the console as well as a blank web page in the browser. Not entirely sure the Symfony folks intended this to be the default behavior or not.
If you want dd(1) to appear in your html page then change the destination to null.
# config/packages/dev/debug.yaml
debug:
dump_destination: null
In any case, dump() continues to work as expected.
Look like this was in fact a bug: https://github.com/symfony/symfony/issues/27622
Should be fixed in the next 4.1.x release.

why do I have to support every "use" keyword by "require"?

Example:
namespace MyApp\Api;
use Mautic\Auth\AuthInterface;
use Psr\Log\LoggerAwareInterface;
use Psr\Log\LoggerInterface;
use Psr\Log\NullLogger;
/**
* Base API class
*/
class Api implements LoggerAwareInterface
{
//do Api stuff here
If I upload this to my hosting, I am getting "Class Not found" exception. But i I do simple update:
namespace MyApp\Api;
use Mautic\Auth\AuthInterface;
use Psr\Log\LoggerAwareInterface;
use Psr\Log\LoggerInterface;
use Psr\Log\NullLogger;
/**
* Base API class
*/
require_once('Psr/Log/LoggerAwareInterface.php');
require_once('Psr/Log/LoggerInterface.php');
require_once('Psr/Log/NullLogger.php');
class Api implements LoggerAwareInterface
{
//do stuff
Adding keywords require_once solves the problem and it seems that everything is usable.
Now, some of the packages I use in my PHP projects are done by someone else. So I hate the idea of changing files of someone else. Now, what should I check or change on my hosting?
Basic info of my hosting:
-- Webserver Configuration
PHP Version: 5.3.29
MySQL Version: 5.5.5
Webserver Info: Apache
Whad do I have to change on my hosting so the files work on themselves without need to add require keywords?
EDIT I am still bit newbie in PHP programming, so I am using only Notepad++ to develop and usual FTP tool to upload files on my hosting

ClassNotFoundException: Attempted to load class "Mongo" from... (with persist) symfony2

I am having some issue integrating mongodb with Symfony (version 2.5.0-DEV) using the doctrine mongodb cookbook on http://symfony.com/doc/current/bundles/DoctrineMongoDBBundle/index.html.
Everything is okay up to the 'Persisting Objects to MongoDB' stage. When I add the line "$dm->persist($script);", nothing happens to my remote database and I get the error message:
ClassNotFoundException: Attempted to load class "Mongo" from the global namespace in /var/www/Symfony/vendor/doctrine/mongodb/lib/Doctrine/MongoDB/Connection.php line 283. Did you forget a use statement for this class?
But without the persist line, the script parses without errors (but nothing happens at the remote database).
Is this particular to my Symfony version (2.5.0) and is there a workaround? I have pasted my entire script below including the use statements. Any help would be appreciated :).
namespace Atlas\MpBundle\Controller;
use Atlas\MpBundle\Document\Scripts;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\JsonResponse;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class UserjsonController extends Controller
{
public function showuserjsonAction()
{
$script = new Scripts();
$script->setName('kingstest');
$script->setDescription('just a desc test');
$script->setGroup('SMS');
$dm = $this->get('doctrine_mongodb')->getManager();
$dm->persist($script);
$dm->flush();
return new Response('Created New Document in scripts with script id '.$script->getId());
}
}
Thanks guys. Works now.
the extension mongo.so has to be loaded in php.ini and I edited the wrong php.ini file. Added extension=mongo.so to php.ini located in /etc/php5/apache2/ and now it works :)
Hopefully this can help someone in the future.

Cannot use X as Y because the name is already in use, even though it's not

I'm using PHP 5.4, and have a PSR-0 class structure similar to the following.
A\Library\Session.php:
namespace A\Library;
class Session { ... }
My\Application\Session.php:
namespace My\Application;
class Session { ... }
My\Application\Facebook.php:
namespace My\Application;
use A\Library\Session;
class Facebook { ... }
When I try to run the application, I get the following error:
Cannot use A\Library\Session as Session because the name is already in use in My\Application\Facebook.php
Even though it's not, at least not in this file. The Facebook.php file declares only the Facebook class, and imports exactly one Session class, the A\Library one.
The only problem I can see is that another Session class exists in the same namespace as the Facebook class, but as it was never imported in the Facebook.php file, I thought it did not matter at all.
Am I wrong (in that case please point to the relevant documentation), or is this a bug?
There is a bug confirmed in PHP that may affect the behavior you see. It is supposed to fatal error, but with opcache enabled, it may still execute flawlessly.
https://bugs.php.net/bug.php?id=66773
If it still concerns you, please vote for the bug.
No, this is not a bug. As mentioned in Using namespaces: Aliasing/Importing
use A\Library\Session;
is the same as:
use A\Library\Session as Session;
So try using something like:
use A\Library\Session as AnotherSessionClassName;
The only problem I can see is that another Session class exists in the
same namespace as the Facebook class, but as it was never imported in
the Facebook.php file, I thought it did not matter at all.
Yes, it does matter. This is why you don't need to "import" classes from the same namespace. If you have conflicting names from different namespaces, you need to alias the class.
namespace My\Application;
use A\Library\Session as ASession; // choose a proper alias name here
class Facebook { ... }
I've read the thread about the issue, but I tested on many PHP versions (php 5.5, 5.6, 7.*, x32, x64, vc11, vc14, vc5). I'm using Laravel with Laragon. But, when I build up the server with php artisan serve (and open the server at http://localhost:8000) I have the problem of "the namespace that some Class was already used" and stuff.
I tested with and without opcache extension and nothing works, then I tested the virtual domain that Laragon provides and... voila, the error just disappeared and now I can work OK. I don't know what was happening, my namespaces were OK, I had an alias but the same code works in many machine without problem (AWS, local, prod, dev, etc) but only in my machine I had the problem just as I described it.
So, if someone is working with Laravel (5.1) and is having this issue, try the virtual host of Laragon.

Categories