diff --git a/composer.json b/composer.json index 60798481e..ddde28e1a 100644 --- a/composer.json +++ b/composer.json @@ -6,6 +6,7 @@ "require": { "php": "^7.1.3", "ext-pdo_sqlite": "*", + "doctrine/doctrine-bundle": "^1.8", "doctrine/doctrine-fixtures-bundle": "^2.4", "erusev/parsedown": "^1.6", "ezyang/htmlpurifier": "^4.9", diff --git a/composer.lock b/composer.lock index d13cf617c..514854b3d 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "content-hash": "50f921380572e84d1bdb54e59c3e315e", + "content-hash": "7be12256c45c0323efdcb2415a3d9752", "packages": [ { "name": "composer/ca-bundle", diff --git a/config/services.yaml b/config/services.yaml index a3f2892e8..d2f40e191 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -28,7 +28,7 @@ services: resource: '../src/*' # you can exclude directories or files # but if a service is unused, it's removed anyway - exclude: '../src/{DataFixtures,Entity,Migrations,Repository,Tests}' + exclude: '../src/{DataFixtures,Entity,Migrations,Tests}' # controllers are imported separately to make sure they're public # and have a tag that allows actions to type-hint services diff --git a/src/Command/AddUserCommand.php b/src/Command/AddUserCommand.php index 0e35d3773..fb8169408 100644 --- a/src/Command/AddUserCommand.php +++ b/src/Command/AddUserCommand.php @@ -12,6 +12,7 @@ namespace App\Command; use App\Entity\User; +use App\Repository\UserRepository; use App\Utils\Validator; use Doctrine\ORM\EntityManagerInterface; use Symfony\Component\Console\Command\Command; @@ -57,14 +58,16 @@ class AddUserCommand extends Command private $entityManager; private $passwordEncoder; private $validator; + private $users; - public function __construct(EntityManagerInterface $em, UserPasswordEncoderInterface $encoder, Validator $validator) + public function __construct(EntityManagerInterface $em, UserPasswordEncoderInterface $encoder, Validator $validator, UserRepository $users) { parent::__construct(); $this->entityManager = $em; $this->passwordEncoder = $encoder; $this->validator = $validator; + $this->users = $users; } /** @@ -202,10 +205,8 @@ protected function execute(InputInterface $input, OutputInterface $output) private function validateUserData($username, $plainPassword, $email, $fullName) { - $userRepository = $this->entityManager->getRepository(User::class); - // first check if a user with the same username already exists. - $existingUser = $userRepository->findOneBy(['username' => $username]); + $existingUser = $this->users->findOneBy(['username' => $username]); if (null !== $existingUser) { throw new RuntimeException(sprintf('There is already a user registered with the "%s" username.', $username)); @@ -217,7 +218,7 @@ private function validateUserData($username, $plainPassword, $email, $fullName) $this->validator->validateFullName($fullName); // check if a user with the same email already exists. - $existingEmail = $userRepository->findOneBy(['email' => $email]); + $existingEmail = $this->users->findOneBy(['email' => $email]); if (null !== $existingEmail) { throw new RuntimeException(sprintf('There is already a user registered with the "%s" email.', $email)); diff --git a/src/Command/DeleteUserCommand.php b/src/Command/DeleteUserCommand.php index 88f08f8a5..11e4d4507 100644 --- a/src/Command/DeleteUserCommand.php +++ b/src/Command/DeleteUserCommand.php @@ -12,6 +12,7 @@ namespace App\Command; use App\Entity\User; +use App\Repository\UserRepository; use App\Utils\Validator; use Doctrine\ORM\EntityManagerInterface; use Symfony\Component\Console\Command\Command; @@ -42,16 +43,19 @@ class DeleteUserCommand extends Command { protected static $defaultName = 'app:delete-user'; + /** @var SymfonyStyle */ private $io; private $entityManager; private $validator; + private $users; - public function __construct(EntityManagerInterface $em, Validator $validator) + public function __construct(EntityManagerInterface $em, Validator $validator, UserRepository $users) { parent::__construct(); $this->entityManager = $em; $this->validator = $validator; + $this->users = $users; } /** @@ -108,9 +112,8 @@ protected function execute(InputInterface $input, OutputInterface $output) { $username = $this->validator->validateUsername($input->getArgument('username')); - $repository = $this->entityManager->getRepository(User::class); /** @var User $user */ - $user = $repository->findOneByUsername($username); + $user = $this->users->findOneByUsername($username); if (null === $user) { throw new RuntimeException(sprintf('User with username "%s" not found.', $username)); diff --git a/src/Command/ListUsersCommand.php b/src/Command/ListUsersCommand.php index ac366f8dd..7287144f4 100644 --- a/src/Command/ListUsersCommand.php +++ b/src/Command/ListUsersCommand.php @@ -12,7 +12,7 @@ namespace App\Command; use App\Entity\User; -use Doctrine\ORM\EntityManagerInterface; +use App\Repository\UserRepository; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; @@ -39,17 +39,17 @@ class ListUsersCommand extends Command // a good practice is to use the 'app:' prefix to group all your custom application commands protected static $defaultName = 'app:list-users'; - private $entityManager; private $mailer; private $emailSender; + private $users; - public function __construct(EntityManagerInterface $em, \Swift_Mailer $mailer, $emailSender) + public function __construct(\Swift_Mailer $mailer, $emailSender, UserRepository $users) { parent::__construct(); - $this->entityManager = $em; $this->mailer = $mailer; $this->emailSender = $emailSender; + $this->users = $users; } /** @@ -91,7 +91,7 @@ protected function execute(InputInterface $input, OutputInterface $output) { $maxResults = $input->getOption('max-results'); // Use ->findBy() instead of ->findAll() to allow result sorting and limiting - $users = $this->entityManager->getRepository(User::class)->findBy([], ['id' => 'DESC'], $maxResults); + $allUsers = $this->users->findBy([], ['id' => 'DESC'], $maxResults); // Doctrine query returns an array of objects and we need an array of plain arrays $usersAsPlainArrays = array_map(function (User $user) { @@ -102,7 +102,7 @@ protected function execute(InputInterface $input, OutputInterface $output) $user->getEmail(), implode(', ', $user->getRoles()), ]; - }, $users); + }, $allUsers); // In your console commands you should always use the regular output type, // which outputs contents directly in the console window. However, this diff --git a/src/Controller/Admin/BlogController.php b/src/Controller/Admin/BlogController.php index a2a1a0115..75d3a09d7 100644 --- a/src/Controller/Admin/BlogController.php +++ b/src/Controller/Admin/BlogController.php @@ -13,6 +13,7 @@ use App\Entity\Post; use App\Form\PostType; +use App\Repository\PostRepository; use App\Utils\Slugger; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; @@ -54,12 +55,11 @@ class BlogController extends AbstractController * @Route("/", name="admin_post_index") * @Method("GET") */ - public function index(): Response + public function index(PostRepository $posts): Response { - $em = $this->getDoctrine()->getManager(); - $posts = $em->getRepository(Post::class)->findBy(['author' => $this->getUser()], ['publishedAt' => 'DESC']); + $authorPosts = $posts->findBy(['author' => $this->getUser()], ['publishedAt' => 'DESC']); - return $this->render('admin/blog/index.html.twig', ['posts' => $posts]); + return $this->render('admin/blog/index.html.twig', ['posts' => $authorPosts]); } /** diff --git a/src/Controller/BlogController.php b/src/Controller/BlogController.php index 87f995730..e42466c44 100644 --- a/src/Controller/BlogController.php +++ b/src/Controller/BlogController.php @@ -15,6 +15,7 @@ use App\Entity\Post; use App\Events; use App\Form\CommentType; +use App\Repository\PostRepository; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Cache; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method; use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; @@ -47,15 +48,14 @@ class BlogController extends AbstractController * Content-Type header for the response. * See https://symfony.com/doc/current/quick_tour/the_controller.html#using-formats */ - public function index(int $page, string $_format): Response + public function index(int $page, string $_format, PostRepository $posts): Response { - $em = $this->getDoctrine()->getManager(); - $posts = $em->getRepository(Post::class)->findLatest($page); + $latestPosts = $posts->findLatest($page); // Every template name also has two extensions that specify the format and // engine for that template. // See https://symfony.com/doc/current/templating.html#template-suffix - return $this->render('blog/index.'.$_format.'.twig', ['posts' => $posts]); + return $this->render('blog/index.'.$_format.'.twig', ['posts' => $latestPosts]); } /** @@ -148,7 +148,7 @@ public function commentForm(Post $post): Response * @Route("/search", name="blog_search") * @Method("GET") */ - public function search(Request $request): Response + public function search(Request $request, PostRepository $posts): Response { if (!$request->isXmlHttpRequest()) { return $this->render('blog/search.html.twig'); @@ -156,10 +156,10 @@ public function search(Request $request): Response $query = $request->query->get('q', ''); $limit = $request->query->get('l', 10); - $posts = $this->getDoctrine()->getRepository(Post::class)->findBySearchQuery($query, $limit); + $foundPosts = $posts->findBySearchQuery($query, $limit); $results = []; - foreach ($posts as $post) { + foreach ($foundPosts as $post) { $results[] = [ 'title' => htmlspecialchars($post->getTitle()), 'date' => $post->getPublishedAt()->format('M d, Y'), diff --git a/src/Repository/PostRepository.php b/src/Repository/PostRepository.php index 9addff135..cf9ead871 100644 --- a/src/Repository/PostRepository.php +++ b/src/Repository/PostRepository.php @@ -12,7 +12,8 @@ namespace App\Repository; use App\Entity\Post; -use Doctrine\ORM\EntityRepository; +use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; +use Doctrine\Common\Persistence\ManagerRegistry; use Doctrine\ORM\Query; use Pagerfanta\Adapter\DoctrineORMAdapter; use Pagerfanta\Pagerfanta; @@ -27,8 +28,13 @@ * @author Javier Eguiluz * @author Yonel Ceruto */ -class PostRepository extends EntityRepository +class PostRepository extends ServiceEntityRepository { + public function __construct(ManagerRegistry $registry) + { + parent::__construct($registry, Post::class); + } + public function findLatest(int $page = 1): Pagerfanta { $query = $this->getEntityManager() diff --git a/src/Repository/UserRepository.php b/src/Repository/UserRepository.php index cef9d2419..900815702 100644 --- a/src/Repository/UserRepository.php +++ b/src/Repository/UserRepository.php @@ -11,7 +11,9 @@ namespace App\Repository; -use Doctrine\ORM\EntityRepository; +use App\Entity\User; +use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; +use Doctrine\Common\Persistence\ManagerRegistry; /** * This custom Doctrine repository is empty because so far we don't need any custom @@ -23,6 +25,10 @@ * @author Ryan Weaver * @author Javier Eguiluz */ -class UserRepository extends EntityRepository +class UserRepository extends ServiceEntityRepository { + public function __construct(ManagerRegistry $registry) + { + parent::__construct($registry, User::class); + } } diff --git a/tests/Command/AddUserCommandTest.php b/tests/Command/AddUserCommandTest.php index c1c2828df..d39758f18 100644 --- a/tests/Command/AddUserCommandTest.php +++ b/tests/Command/AddUserCommandTest.php @@ -14,6 +14,7 @@ use App\Command\AddUserCommand; use App\Entity\User; use App\Utils\Validator; +use Doctrine\Bundle\DoctrineBundle\Registry; use Symfony\Bundle\FrameworkBundle\Console\Application; use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; use Symfony\Component\Console\Tester\CommandTester; @@ -117,7 +118,9 @@ private function executeCommand(array $arguments, array $inputs = []) self::bootKernel(); $container = self::$kernel->getContainer(); - $command = new AddUserCommand($container->get('doctrine')->getManager(), $container->get('security.password_encoder'), new Validator()); + /** @var Registry $doctrine */ + $doctrine = $container->get('doctrine'); + $command = new AddUserCommand($doctrine->getManager(), $container->get('security.password_encoder'), new Validator(), $doctrine->getRepository(User::class)); $command->setApplication(new Application(self::$kernel)); $commandTester = new CommandTester($command);