ObjectManager isn't recognized (Declaration must be compatible with FixtureInterface->load) - php

I have tried to create DataFixtures, I think that my code is correct because if I tried on another project it's worked. So I don't understand why just in that my actual project , the Object Manager isn't working and my IDE is underlying Object Manager.
My error:
Declaration must be compatible with FixtureInterface->load(manager: \Doctrine\Persistence\ObjectManager)
My code:
<?php
namespace App\DataFixtures;
use App\Entity\User;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Common\Persistence\ObjectManager;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
class UserFixtures extends Fixture
{
public function __construct(UserPasswordEncoderInterface $passwordEncoder)
{
$this->passwordEncoder =$passwordEncoder;
}
public function load(ObjectManager $manager)
{
foreach ($this->getUserData() as [$email,$password,$lastname,$firstname,$company,$language,$enabled,$pictures])
{
$user = new User();
$user->setEmail($email);
$user->setPassword($this->passwordEncoder->encodePassword($user,$password));
$user->setLastname($lastname);
$user->setFirstname($firstname);
$user->setCompany($company);
$user->setLanguage($language);
$user->setEnabled($enabled);
$user->setPictures($pictures);
}
$manager->flush();
}
private function getUserData() : array {
return [
['test#gmail.com','test','paul','marc','WKCompany','BE',1,'https://media.istockphoto.com/photos/businessman-silhouette-as-avatar-or-default-profile-picture-picture-id476085198?k=6&m=476085198&s=612x612&w=0&h=5cDQxXHFzgyz8qYeBQu2gCZq1_TN0z40e_8ayzne0X0=']
];
}
}

it looks simple type error. I only changed ObjectManager namespace.
use App\Entity\User;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Persistence\ObjectManager;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
class UserFixtures extends Fixture
{
public function __construct(UserPasswordEncoderInterface $passwordEncoder)
{
$this->passwordEncoder =$passwordEncoder;
}
public function load(ObjectManager $manager)
{
foreach ($this->getUserData() as [$email,$password,$lastname,$firstname,$company,$language,$enabled,$pictures])
{
$user = new User();
$user->setEmail($email);
$user->setPassword($this->passwordEncoder->encodePassword($user,$password));
$user->setLastname($lastname);
$user->setFirstname($firstname);
$user->setCompany($company);
$user->setLanguage($language);
$user->setEnabled($enabled);
$user->setPictures($pictures);
}
$manager->flush();
}
private function getUserData() : array {
return [
['test#gmail.com','test','paul','marc','WKCompany','BE',1,'https://media.istockphoto.com/photos/businessman-silhouette-as-avatar-or-default-profile-picture-picture-id476085198?k=6&m=476085198&s=612x612&w=0&h=5cDQxXHFzgyz8qYeBQu2gCZq1_TN0z40e_8ayzne0X0=']
];
}
}

Related

Problem connecting entitymanager(doctrine) on laminas framework

please tell me how to get entity manager on laminas framework
Controller:
public function signupAction()
{
$user = new Users();
$user->setUsername('Test');
$user->setEmail('test#mail.ru');
$user->setNumber('+79168415532');
// this one i have persist() and flush()
}
To elaborate on #Aleksey Blossom's answer you need to create a factory from which to inject the entity manager.
use Laminas\ServiceManager\Factory\FactoryInterface;
use Interop\Container\ContainerInterface;
use Doctrine\ORM\EntityManager;
use YourModule\Controller\CategoryController;
class CategoryControllerFactory implements FactoryInterface
{
public function __invoke(ContainerInterface $container, $requestedName, ?array $options = null)
{
$entityManger = $container->get(EntityManager::class);
return new CategoryController($entityManger);
}
}
and in your controller
use Laminas\Mvc\Controller\AbstractActionController;
use Doctrine\ORM\EntityManager;
class CategoryController extends AbstractActionController
{
private EntityManager $entityManager;
public function __construct(EntityManager $entityManager)
{
$this->entityManager = $entityManager;
}
public function signupAction()
{
$user = new Users();
$user->setUsername('Test');
$user->setEmail('test#mail.ru');
$user->setNumber('+79168415532');
$this->entityManager->persist($user);
$this->entityManager->flush();
}
}
As a side note I would also consider placing your business logic into models.
Create Factory
class CategoryControllerFactory implements FactoryInterface
{
public function __invoke(\Interop\Container\ContainerInterface $container, $requestedName, ?array $options = null)
{
$entityManger = $container->get(\Doctrine\ORM\EntityManager::class);
return new CategoryController($entityManger);
}
}

Symfony 4 PHP Exception Doctrine\ORM\ORMException: "Unknown Entity namespace ali as 'User'."

Here is my subscriber class. I want to get the user email to him an email.
I use here the EntityManagerInterface
use Doctrine\ORM\EntityManagerInterface;
final class RegisterMailSubscriber implements EventSubscriberInterface
{
private $mailer;
public function __construct(\Swift_Mailer $mailer, EntityManagerInterface $entityManager)
{
$this->mailer = $mailer;
$this->repository= $entityManager->getRepository('AppEntity:User');
}
public static function getSubscribedEvents()
{
return [
KernelEvents::VIEW => ['sendMail', EventPriorities::POST_WRITE],
];
}
public function sendMail(ViewEvent $event): void
{
$user = $event->getControllerResult();
$method = $event->getRequest()->getMethod();
if (!$user instanceof User || Request::METHOD_POST !== $method) {
return;
}
$userInfo = $this->repository->find($user->getId());
}
}
You need to import all the dependencies used as User, Request, ViewEvent, KernelEvent, etc.
By the way, is a good practice to import the repository (UserRepository) and not the entityManager, but you dont need it because you have the $user already. You dont need to find it again.
I think this should be enough if you have the user classes in those namespaces (locations):
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\ViewEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use ApiPlatform\Core\EventListener\EventPriorities;
use App\Entity\User;
final class RegisterMailSubscriber implements EventSubscriberInterface
{
private $mailer;
public function __construct(\Swift_Mailer $mailer)
{
$this->mailer = $mailer;
}
public static function getSubscribedEvents()
{
return [
KernelEvents::VIEW => ['sendMail', EventPriorities::POST_WRITE],
];
}
public function sendMail(ViewEvent $event): void
{
$user = $event->getControllerResult();
$method = $event->getRequest()->getMethod();
if (!$user instanceof User || Request::METHOD_POST !== $method) {
return;
}
$userEmail = $user->getEmail(); //for example. You got the user 5 lines before.
}
}

Symfony 3 unit test form with constructor

I am trying to unit test a form which has 2 dependencies (ObjectManager and EventDispatcher)
I had tried to follow official doc but without success.
My testing file:
<?php
namespace Lch\MediaBundle\Tests\Form;
use Lch\MediaBundle\Form\AddImageType;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Doctrine\Common\Persistence\ObjectManager;
use Symfony\Component\Form\PreloadedExtension;
use Symfony\Component\Form\Test\TypeTestCase;
class AddImageTypeTest extends TypeTestCase
{
private $entityManager;
private $eventDispatcher;
protected function setUp()
{
$this->entityManager = $this->createMock(ObjectManager::class);
$this->eventDispatcher = $this->createMock(EventDispatcher::class);
parent::setUp();
}
protected function getExtensions()
{
$type = new AddImageType($this->entityManager, $this->eventDispatcher);
return array(
new PreloadedExtension(array($type), array()),
);
}
public function testSubmitValidData()
{
$form = $this->factory->create(AddImageType::class);
}
}
I got this error when I execute my test suite:
TypeError: Argument 1 passed to
LCH\MediaBundle\Form\AddImageType::__construct() must implement
interface Doctrine\Common\Persistence\ObjectManager, none given,
called in
/home/matthieu/www/lch/media/src/Lch/MediaBundle/vendor/symfony/symfony/src/Symfony/Component/Form/FormRegistry.php
on line 85
It seems that the job I do in the getExtensions method is not working, but cannot figure it out.
Does anyone have a clue?
ObjectManager is an interface, meaning you can't instantiate or pass it directly to other constructors.
If you are using Doctrine, replace it with Doctrine\ORM\EntityManager which implements ObjectManager interface and can be instantiated, otherwise replace it with your own implementation.
<?php
namespace Lch\MediaBundle\Tests\Form;
use Lch\MediaBundle\Form\AddImageType;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Doctrine\ORM\EntityManager;
use Symfony\Component\Form\PreloadedExtension;
use Symfony\Component\Form\Test\TypeTestCase;
class AddImageTypeTest extends TypeTestCase
{
private $entityManager;
private $eventDispatcher;
protected function setUp()
{
$this->entityManager = $this->createMock(EntityManager::class);
$this->eventDispatcher = $this->createMock(EventDispatcher::class);
parent::setUp();
}
protected function getExtensions()
{
$type = new AddImageType($this->entityManager, $this->eventDispatcher);
return array(
new PreloadedExtension(array($type), array()),
);
}
public function testSubmitValidData()
{
$form = $this->factory->create(AddImageType::class);
}
}

Laravel 5 repository injection

I'm quite new in Laravel 5, what I am trying to do is a simple repository with dependency injection. But I'm stuck with this error:
Argument 1 passed to
App\Http\Controllers\Api\UserController::__construct() must implement
interface App\Repositories\UserInterface, instance of
App\Repositories\UserRepository given
Here is my code:
UserController:
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Response;
use App;
use Auth;
use Crypt;
use Lang;
use Image;
use Storage;
use Config;
use Validator;
use App\User;
use App\Repositories\UserInterface;
class UserController extends Controller
{
protected $config;
protected $users;
public function __construct(UserInterface $users)
{
$this->middleware('api');
$this->middleware('auth', ['except' => 'getInfo']);
$this->users = $users;
$this->config = Config::get('images.avatar');
}
UserInterface:
namespace App\Repositories;
use App\Repositories\BaseInterface;
interface UserInterface extends BaseInterface
{
};
BaseInterface:
namespace App\Repositories;
interface BaseInterface
{
public function all();
public function paginate($count);
public function find($id);
}
BaseRepository
namespace App\Repositories;
use App\Repositories\BaseInterface;
class BaseRepository implements BaseInterface
{
protected $model;
public function __call($name, $args)
{
// $this->getNewInstance()->{$name($args)};
return call_user_func_array([
$this->getNewInstance(),
$method], $args);
}
public function all($relations = [])
{
$instance = $this->getNewInstance();
return $instance->with($relations)->all();
}
public function find($id, $relations = [])
{
$instance = $this->getNewInstance();
return $instance->with($relations)->find($id);
}
public function findOrFail($id, $relations = [])
{
$instance = $this->getNewInstance();
return $instance->with($relations)->findOrFail($id);
}
public function paginate($count)
{
}
protected function getNewInstance()
{
return new $this->model;
}
}
UserRepository
namespace App\Repositories;
use App\Repositories\BaseRepository;
Class UserRepository extends BaseRepository
{
protected $model = 'App\User';
}
RepositoryServiceProvider
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use App;
class RepositoryServiceProvider extends ServiceProvider
{
/**
* Register any error handlers.
*
* #return void
*/
public function boot()
{
}
/**
* Register the service provider.
*
* #return void
*/
public function register()
{
//
App::bind('App\Repositories\UserInterface', 'App\Repositories\UserRepository');
}
}
Of course RepositoryServiceProvider is added under service providers in my config/app.php
Please help, I'm almost sure that I've tried everything whatever I found in Google.
Your UserRepository has to implement UserInterface:
namespace App\Repositories;
use App\Repositories\BaseRepository;
class UserRepository extends BaseRepository implements UserInterface
// ^^^^^^^^^^^^^^^^^^^^^^^^
{
protected $model = 'App\User';
}

Symfony2 $user->setPassword() updates password as plain text [DataFixtures + FOSUserBundle]

I'm trying to pre-populate a database with some User objects, but when I call $user->setPassword('some-password'); and then save the user object, the string 'some-password' is stored directly in the database, instead of the hashed+salted password.
My DataFixture class:
// Acme/SecurityBundle/DataFixtures/ORM/LoadUserData.php
<?php
namespace Acme\SecurityBundle\DataFixtures\ORM;
use Doctrine\Common\DataFixtures\FixtureInterface;
use Doctrine\Common\Persistence\ObjectManager;
use Acme\SecurityBundle\Entity\User;
class LoadUserData implements FixtureInterface
{
public function load(ObjectManager $manager)
{
$userAdmin = new User();
$userAdmin->setUsername('System');
$userAdmin->setEmail('system#example.com');
$userAdmin->setPassword('test');
$manager->persist($userAdmin);
$manager->flush();
}
}
And the relevant database output:
id username email salt password
1 System system#example.com 3f92m2tqa2kg8cookg84s4sow80880g test
Since you are using FOSUserBundle, you can use UserManager to do this. I would use this code (assuming you have $this->container set):
public function load(ObjectManager $manager)
{
$userManager = $this->container->get('fos_user.user_manager');
$userAdmin = $userManager->createUser();
$userAdmin->setUsername('System');
$userAdmin->setEmail('system#example.com');
$userAdmin->setPlainPassword('test');
$userAdmin->setEnabled(true);
$userManager->updateUser($userAdmin, true);
}
Call setPlainPassword instead.
<?php
namespace Acme\SecurityBundle\DataFixtures\ORM;
use Doctrine\Common\DataFixtures\FixtureInterface;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Doctrine\Common\Persistence\ObjectManager;
use Acme\SecurityBundle\Entity\User;
class LoadUserData implements FixtureInterface, ContainerAwareInterface
{
private $container;
public function setContainer(ContainerInterface $container = null)
{
$this->container = $container;
}
public function load(ObjectManager $manager)
{
$userAdmin = new User();
$userAdmin->setUsername('System');
$userAdmin->setEmail('system#example.com');
$userAdmin->setPlainPassword('test');
$userAdmin->setRoles(array('ROLE_SUPER_ADMIN'));
$manager->persist($userAdmin);
$manager->flush();
}
}
Four lines of code and you are done. It will handle everything for you:
$userManager = $this->container->get('fos_user.user_manager');
$user->setPlainPassword($password);
$userManager->updatePassword($user);
This worked for me
public function load(ObjectManager $manager){
$userAdmin = new User();
$userAdmin->setUsername('admin');
$userAdmin->setPlainPassword('admin');
$userAdmin->setEmail('admin#gmail.com');
$userAdmin->setEnabled(true);
$manager->persist($userAdmin);
$manager->flush();
}
Note the difference when setting the password. Querying the database you find
id username username_canonical email email_canonical enabled salt password
2 admin admin admin#gmail.com admin#gmail.com 1 4gm0bx6jzocgksw0wws8kck04kg40o8 m2ZyJM2+oBIzt/NZdnOX4nFvjV/SWTU1qJqe6dWZ0UwLF5gB8N...
$userAdmin->setUsername('System');
$userAdmin->setEmail('system#example.com');
$userAdmin->setPlainPassword('test');
$userAdmin->setEnabled(true);
setPlainPassword works for me.
/**
* 添加用户
* #param $param
* #return int
*/
public function doAdd($param)
{
$entity = new User();
$em = $this->getEntityManager();
$entity->setUsername($param['username'])
->setPlainPassword($param['password'])
->setEmail($param['email'])
->setEnabled(true)
->setRealName($param['realName']);
$em->persist($entity);
$em->flush();
return $entity->getId();
}
Above worked for me, so I got some conclusion:
1. must use the setPlainPassword
2. must setEnabled(true)
Here a sample class to create an admin user via ORM Fixtures:
<?php
namespace Acme\SecurityBundle\DataFixtures\ORM;
use Doctrine\Common\DataFixtures\FixtureInterface;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Doctrine\Common\Persistence\ObjectManager;
use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
use Acme\SecurityBundle\Entity\User;
class LoadFOSAdminUser extends AbstractFixture implements OrderedFixtureInterface, ContainerAwareInterface
{
private $container;
public function setContainer(ContainerInterface $container = null)
{
$this->container = $container;
}
public function load(ObjectManager $manager)
{
$userManager = $this->container->get('fos_user.user_manager');
$userAdmin = $userManager->createUser();
$userAdmin->setUsername('admin');
$userAdmin->setEmail('admin#example.com');
$userAdmin->setPlainPassword('admin');
$userAdmin->setEnabled(true);
$userAdmin->setRoles(array('ROLE_ADMIN'));
$userManager->updateUser($userAdmin, true);
}
public function getOrder()
{
return 1;
}
}

Categories