I'm new to Symfony and can't seem to find a way to fix my issue.
I have done an earlier project in which I didn't have this problem but it seems that the method getDoctrine is considered undefined.
enter image description here
here is the 1st route of my controller
<?php
namespace App\Controller;
use Doctrine\Persistence\ObjectManager;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\Persistence\ManagerRegistry;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Form\Extension\HttpFoundation\HttpFoundationExtension;
use Symfony\Component\Form\Forms;
use Symfony\Component\HttpFoundation\Request;
use App\Entity\Accueil;
use App\Entity\Actualite;
use App\Entity\Admin;
use App\Entity\Artistique;
use App\Entity\Avis;
use App\Entity\Equipe;
use App\Entity\Fonction;
use App\Entity\Image;
use App\Entity\Partenaire;
use App\Entity\TypeArtistique;
class SiteValdinguController extends AbstractController
{
/**
* #Route("/", name="app_site_valdingu")
*/
public function index(Request $request, ManagerRegistry $entityManager): Response
{
unset($_POST['triArtNom']);
unset($_POST['triArtNbRepres']);
unset($_POST['triArtTypeArt']);
unset($_POST['triActuNom']);
unset($_POST['triActuDate']);
unset($_POST['triActuTypeArt']);
unset($_POST['triActuTime']);
$repos = $this->getRepository(Accueil::class);
$LesAccueils = $repos->findAll();
$repos = $this->getRepository(Actualite::class);
$LesActualites = $repos->findAll();
$repos = $this->getRepository(Image::class);
$LesImages = $repos->findAll();
return $this->render('site_valdingu/index.html.twig', [
'controller_name' => 'SiteValdinguController',
'LesAccueils'=>$LesAccueils,
'LesActualite'=>$LesActualites
]);
}
Here is the relevant part of my Entity
namespace App\Entity;
use App\Repository\AccueilRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity(repositoryClass: AccueilRepository::class)]
class Accueil
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
private ?int $id = null;
#[ORM\Column(length: 255)]
private ?string $Label = null;
#[ORM\Column(length: 255)]
private ?string $Texte = null;
#[ORM\OneToMany(mappedBy: 'Acc_id', targetEntity: Image::class)]
private Collection $img;
`
and here is the relevant part of my Repository
`namespace App\Repository;
use App\Entity\Accueil;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
/**
* #extends ServiceEntityRepository<Accueil>
*
* #method Accueil|null find($id, $lockMode = null, $lockVersion = null)
* #method Accueil|null findOneBy(array $criteria, array $orderBy = null)
* #method Accueil[] findAll()
* #method Accueil[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/
class AccueilRepository extends ServiceEntityRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, Accueil::class);
}
public function save(Accueil $entity, bool $flush = false): void
{
$this->getEntityManager()->persist($entity);
if ($flush) {
$this->getEntityManager()->flush();
}
}
public function remove(Accueil $entity, bool $flush = false): void
{
$this->getEntityManager()->remove($entity);
if ($flush) {
$this->getEntityManager()->flush();
}
}
I used Symfony 6 for my last project, and I thought about not having done the right translation in some places but I didn't notice anything myself.
I also have weird things like no automatic annotations.yaml file created so maybe some routing stuff is messing up but I didn't have do worry about it last time so it feels weird + it seems that it's not the annotations routes that cause the problem since I'm technically on the right page, it just doesn't work and can't extract data from the db.
Both when I use the old getDoctrine()->getRepository() method with the EntityManagerInterface and the immediate getRepository() method with the ManagerRegistry give me the same result
The migrations work so it's not a connexion to db problem.
You are calling $this->getRepository(), so it's trying to use a method that does not exist in SiteValdinguController. What you are trying to achieve is getting each repository using the entity manager. So you need to call $managerRegistry->getRepository() instead.
The correct code would be:
/**
* #Route("/", name="app_site_valdingu")
*/
public function index(Request $request, ManagerRegistry $entityManager): Response
{
unset($_POST['triArtNom']);
unset($_POST['triArtNbRepres']);
unset($_POST['triArtTypeArt']);
unset($_POST['triActuNom']);
unset($_POST['triActuDate']);
unset($_POST['triActuTypeArt']);
unset($_POST['triActuTime']);
$repos = $entityManager->getRepository(Accueil::class);
$LesAccueils = $repos->findAll();
$repos = $entityManager->getRepository(Actualite::class);
$LesActualites = $repos->findAll();
$repos = $entityManager->getRepository(Image::class);
$LesImages = $repos->findAll();
return $this->render('site_valdingu/index.html.twig', [
'controller_name' => 'SiteValdinguController',
'LesAccueils'=>$LesAccueils,
'LesActualite'=>$LesActualites
]);
}
Related
This question already has an answer here:
Class does not exist in getRepository doctrine
(1 answer)
Closed 1 year ago.
I created a new symfony project with an entity Company and a contoller CompanyController. I want to get the results from a database but I keep getting this error: The class 'App\Repository\CompanyRepository' was not found in the chain configured namespaces App\Entity and I don't know why.
I searched the internet but I read only answers that are solving errors when the namespace is not App\Entity. Please help me.
The files are all stored in the src folder as it is when creating a new symfony project. I didn't change any configuration files so every configuration is on default.
Here is my entity:
<?php
namespace App\Entity;
use App\Repository\CompanyRepository;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity(repositoryClass=CompanyRepository::class)
*/
class Company
After that there are just getter and setter.
Here is my controller:
<?php
namespace App\Controller;
use App\Repository\CompanyRepository;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
#[Route('/api/company', name: 'company')]
class CompanyController extends AbstractController
{
#[Route(name: 'company.get', methods: ["GET"])]
public function getCompanies(): Response
{
$entityManager = $this->getDoctrine()->getManager();
$repository = $entityManager->getRepository(CompanyRepository::class);
$companies = $repository->findAll();
$data = [];
foreach ($companies as $company) {
$data[] = $company->toArray();
}
return $this->json([
'data' => $data
]);
}
}
Here is my Company Repository:
<?php
namespace App\Repository;
use App\Entity\Company;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
/**
* #method Company|null find($id, $lockMode = null, $lockVersion = null)
* #method Company|null findOneBy(array $criteria, array $orderBy = null)
* #method Company[] findAll()
* #method Company[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/
class CompanyRepository extends ServiceEntityRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, Company::class);
}
// /**
// * #return Company[] Returns an array of Company objects
// */
/*
public function findByExampleField($value)
{
return $this->createQueryBuilder('c')
->andWhere('c.exampleField = :val')
->setParameter('val', $value)
->orderBy('c.id', 'ASC')
->setMaxResults(10)
->getQuery()
->getResult()
;
}
*/
/*
public function findOneBySomeField($value): ?Company
{
return $this->createQueryBuilder('c')
->andWhere('c.exampleField = :val')
->setParameter('val', $value)
->getQuery()
->getOneOrNullResult()
;
}
*/
}
In the controller, replace $repository = $entityManager->getRepository(CompanyRepository::class); with
$repository = $entityManager->getRepository(Company::class);
And replace use App\Repository\CompanyRepository; with use App\Entity\Company;
Because getRepository() expects the Entity class, instead of the Repository class.
<?php
namespace App\Controller;
use App\Entity\Company;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
#[Route('/api/company', name: 'company')]
class CompanyController extends AbstractController
{
#[Route(name: 'company.get', methods: ["GET"])]
public function getCompanies(): Response
{
$entityManager = $this->getDoctrine()->getManager();
$repository = $entityManager->getRepository(Company::class);
$companies = $repository->findAll();
$data = [];
foreach ($companies as $company) {
$data[] = $company->toArray();
}
return $this->json([
'data' => $data
]);
}
}
hi im trying to encode My password for My app user So i tried to encrypted in my setPassword function
unfortunately i get this error that i don't understand: Call to a member function encodePassword() on null error pic
<?php
namespace App\Entity;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use Gedmo\Mapping\Annotation as Gedmo;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
use Symfony\Component\HttpFoundation\File\File;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\UserInterface;
/**
* Admin
*#Vich\Uploadable
* #ORM\Table(name="admin")
* #ORM\Entity
*/
class Admin implements UserInterface
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* Undocumented variable
*
* #var UserPasswordEncoderInterface
*/
private $passwordEncoder ;
/**
* #see UserInterface
*/
public function getPassword(): string
{
return (string) $this->password;
}
public function setPassword(string $password): self
{
$hash= $this->passwordEncoder->encodePassword($this,$password);
$this->password=$hash;
return $this ;
}
.......
whats wrong, and how can i fix it ! thnx
but this one work
<?php
namespace App\Controller\Admin;
use App\Entity\User;
use EasyCorp\Bundle\EasyAdminBundle\Config\KeyValueStore;
use EasyCorp\Bundle\EasyAdminBundle\Context\AdminContext;
use EasyCorp\Bundle\EasyAdminBundle\Dto\EntityDto;
use EasyCorp\Bundle\EasyAdminBundle\Field\Field;
use EasyCorp\Bundle\EasyAdminBundle\Field\FormField;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\RepeatedType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
class UserCrudController extends AbstractCrudController
{
/** #var UserPasswordEncoderInterface */
private $passwordEncoder;
public static function getEntityFqcn(): string
{
return User::class;
}
public function configureFields(string $pageName): iterable
{
return [
FormField::addPanel('Change password')->setIcon('fa fa-key'),
Field::new('plainPassword', 'New password')->onlyOnForms()
->setFormType(RepeatedType::class)
->setFormTypeOptions([
'type' => PasswordType::class,
'first_options' => ['label' => 'New password'],
'second_options' => ['label' => 'Repeat password'],
]),
];
}
public function createEditFormBuilder(EntityDto $entityDto, KeyValueStore $formOptions, AdminContext $context): FormBuilderInterface
{
$formBuilder = parent::createEditFormBuilder($entityDto, $formOptions, $context);
$this->addEncodePasswordEventListener($formBuilder);
return $formBuilder;
}
public function createNewFormBuilder(EntityDto $entityDto, KeyValueStore $formOptions, AdminContext $context): FormBuilderInterface
{
$formBuilder = parent::createNewFormBuilder($entityDto, $formOptions, $context);
$this->addEncodePasswordEventListener($formBuilder);
return $formBuilder;
}
/**
* #required
*/
public function setEncoder(UserPasswordEncoderInterface $passwordEncoder): void
{
$this->passwordEncoder = $passwordEncoder;
}
protected function addEncodePasswordEventListener(FormBuilderInterface $formBuilder)
{
$formBuilder->addEventListener(FormEvents::SUBMIT, function (FormEvent $event) {
/** #var User $user */
$user = $event->getData();
if ($user->getPlainPassword()) {
$user->setPassword($this->passwordEncoder->encodePassword($user, $user->getPlainPassword()));
}
});
}
}
i tried to add an Event listener so i create this class
<?php
namespace App\Controller\Admin;
use App\Entity\Admin;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use EasyCorp\Bundle\EasyAdminBundle\EventListener\AdminContextListener;
class AdminController extends AdminContextListener
{
/**
* #var UserPasswordEncoderInterface
*/
private $encoder ;
public function __construct(UserPasswordEncoderInterface $encoder)
{
$this->encoder=$encoder;
}
public static function getSetPasswordEvent()
{
return [
BeforeEntityPersistedEvent::class => ['setPassword'],
];
}
public function setPassword(BeforeEntityPersistedEvent $event)
{
$entity = $event->getEntityInstance();
if (!($entity instanceof Admin)) {
return;
}
$encoded = $this->encoder->encodePassword($entity, $entity->getPassword());
$entity->setPassword($encoded);
}
}
and it didn't work too
You should do that when User register, so add this before doing flush(); for new user:
$user = new UserEntity();
$user->setEmail($request->getEmail());
if ($request->getPassword())
{
$createUser->setPassword($this->encoder->encodePassword($user, $request->getPassword()));
}
$this->entityManager->persist($createUser);
$this->entityManager->flush();
$this->entityManager->clear();
Notice: $request containe payload comes form frontend {"email": "", "passwprd": ""}.
Notice: $createUser is a user object to flush.
I wanted to build my own __construct for calling my TaskListRepository but it doesn't work:
<?php
namespace App\Controller;
use Doctrine\ORM\Mapping as ORM;
use App\Repository\TaskListRepository;
use Symfony\Component\HttpFoundation\Request;
use FOS\RestBundle\Controller\AbstractFOSRestController;
class ListController extends AbstractFOSRestController
{
/**
* #var string $taskListRepository
*/
private $taskListRepository;
public function __construct(TaskListRepository $taskListRepository)
{
$this->taskListRepository = $taskListRepository;
}
public function getListsAction()
{
return $this->taskListRepository->findAll();
}
}
<?php
namespace App\Repository;
use App\Entity\TaskList;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Symfony\Bridge\Doctrine\RegistryInterface;
/**
* #method TaskList|null find($id, $lockMode = null, $lockVersion = null)
* #method TaskList|null findOneBy(array $criteria, array $orderBy = null)
* #method TaskList[] findAll()
* #method TaskList[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/
class TaskListRepository extends ServiceEntityRepository
{
public function __construct(RegistryInterface $registry)
{
parent::__construct($registry, TaskList::class);
}
//commented lines removed for readability
}
Error:
Type error: Argument 1 passed to App\Controller\ListController::__construct() must be an instance of
App\Repository\TaskListRepository, none given, called in /data/
applis/GIE/var/cache/dev/ContainerAfvn1yx/getListControllerService.php
on line 14
You should have enabled autowiring for you controllers or configure controller as service explicitly. In your case TaskListRepository should be a service too.
Thats the code from the docu
// https://api-platform.com/docs/core/security/#security
itemOperations={
"get"={"access_control"="is_granted('ROLE_USER') and object.owner == user"}
}
how can i get that realized with many to many, i tried many different expressions but everytime i get a error.
<?php
// api/src/Entity/Book.php
use ApiPlatform\Core\Annotation\ApiResource;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* Secured resource.
*
* #ApiResource(
* itemOperations={
* "get"={"access_control"="is_granted('ROLE_USER') and object.users == user"}
* }
* )
* #ORM\Entity
*/
class Book
{
// ...
/**
* #var User The owner
*
* #ORM\ManyToMany(targetEntity="App\Entity\User", mappedBy="book", cascade={"persist"})
*/
public $users;
// ...
}
nYou cant in those cases where the target relation is a collection. In this case, users collection.
For these cases, you should create a subscriber with PRE_SERIALIZE event and throw Access Denied exception there.
You have to do something like this. As you say you have a ManyToMany relation, I guess that you have an intermediate entity between book and user, so you should use that repository for find user <-> book then.
<?php
namespace App\EventSubscriber;
use ApiPlatform\Core\EventListener\EventPriorities;
use App\Entity\User;
use App\Entity\Book;
use App\Repository\UserRepository;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
class ChatMessagePreSerializeSubscriber implements EventSubscriberInterface
{
private $tokenStorage;
private $userRepository;
private $authorizationChecker;
public function __construct(
TokenStorageInterface $tokenStorage,
UserRepository $userRepository,
AuthorizationCheckerInterface $authorizationChecker
) {
$this->tokenStorage = $tokenStorage;
$this->userRepository = $userRepository;
$this->authorizationChecker = $authorizationChecker;
}
/**
* {#inheritdoc}
*/
public static function getSubscribedEvents()
{
return [
KernelEvents::VIEW => ['bookPreSerialize', EventPriorities::PRE_SERIALIZE],
];
}
public function bookPreSerialize(GetResponseForControllerResultEvent $event)
{
$book = $event->getControllerResult();
$method = $event->getRequest()->getMethod();
if (!$book instanceof Book || (Request::METHOD_GET !== $method)) {
return;
}
$currentUser = $this->tokenStorage->getToken()->getUser();
if (!$currentUser instanceof User)
return;
$user = $this->userRepository->findOneBy(['id' => $currentUser->getId(), 'book' => $book]);
if (!$user instanceof User)
throw new AccessDeniedHttpException();
}
}
Here is something I did for a resource that is ManytoOne related to intermediate entity Events ManytoOne related to one Organizer, with Users ManyToMany related to Organizers (collection).
I transform the collection to Array and use "in" operator to compare data. For a more sophisticated operation you should look at Doctrine Extension as it's describe in API Platform doc.
#[ApiResource(
operations: [
new GetCollection(),
new Post(),
new Get(security: "object.getEvent().getOrganizer() in user.getOrganizers().toArray()"),
new Patch(),
new Delete()
]
)]
I want to make some operations before controller load and I have problem with include interfaces or classes into function.
My question is how should I do it to start working?
There is a code:
~/src/Controller/ControllerListener.php
<?php
namespace App\EventListener;
use App\Controller\DailyWinController;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
class ControllerListener implements DailyWinController
{
public function onKernelController(FilterControllerEvent $event, LoggerInterface $logger) {
$logger->alert('Working');
}
}
~/src/Controller/DailyWinController.php
<?php
namespace App\Controller;
interface DailyWinController {
// maybe there something?
}
~/src/Controller/UserController.php
<?php
namespace App\Controller;
use App\Entity\User;
use App\Entity\DailyWin;
use Psr\Log\LoggerInterface;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
class UserController extends Controller implements DailyWinController
{
/**
* #Route("/user", name="user")
* #param AuthorizationCheckerInterface $authChecker
* #param UserInterface $user
* #return \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response
*/
public function user(AuthorizationCheckerInterface $authChecker, UserInterface $user = null, LoggerInterface $logger) {
if ($authChecker->isGranted('ROLE_USER') === false) {
return $this->redirectToRoute('logowanie');
}
$logger->warning('Logger is working');
$em = $this->getDoctrine()->getManager();
$DWrep = $em->getRepository(DailyWin::class);
$userId = $user->getId();
$dailyWin = $DWrep->findOneBy(['userId' => $userId]);
return $this->render('andprize/user/index.html.twig', array(
'dailyWin' => $dailyWin,
'userId' => $userId
));
}
}
I have the following problem:
FatalThrowableError Type error: Argument 2 passed to
App\EventListener\ControllerListener::onKernelController() must
implement interface Psr\Log\LoggerInterface, string given
You have to inject the logger to the listener.
<?php
namespace App\EventListener;
use App\Controller\DailyWinController;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
class ControllerListener implements DailyWinController
{
protected $logger;
public function __construct(LoggerInterface $logger)
{
$this->logger=$logger;
}
public function onKernelController(FilterControllerEvent $event) {
$this->logger->alert('Working');
}
}