My problem comes from the fact that i have a relation in my entities that depends on each other. My entity Link has a relation with an entity User. When I try to load the User using UserManagerInterface it returns NULL.
Here is My AppFixtures class:
<?php
namespace App\DataFixtures;
use App\Component\Localization;
use App\Entity\Link;
use App\Entity\LinkClick;
use App\Entity\LinkView;
use App\Entity\Visitor;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Common\Persistence\ObjectManager;
use Faker;
use FOS\UserBundle\Model\UserManagerInterface;
use PUGX\Shortid\Shortid;
class AppFixtures extends Fixture
{
private $userManager;
private $localisation;
public function __construct(UserManagerInterface $userManager, Localization $localization)
{
$this->userManager = $userManager;
$faker = Faker\Factory::create();
$localization->setParameters($localization::GEO_PLUGIN, $faker->ipv4);
$localization->localize();
$this->localisation = $localization->getResult();
}
public function load(ObjectManager $manager): void
{
$faker = Faker\Factory::create();
$user = $this->userManager->createUser();
$user->setUsername('admin');
$user->setEmail('admin#kss.tk');
$user->setPlainPassword('admin');
$user->setEnabled(true);
$user->setRoles(['ROLE_ADMIN']);
$this->userManager->updateUser($user);
$links = [];
$visitors = [];
for ($i = 0; $i < 100; ++$i) {
$link = new Link();
$link->setUrl($faker->url);
$link->setSlug(Shortid::generate(12, 'abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz01', true));
$link->setCreatedAt($faker->dateTime);
$link->setUser($user);
$links[] = $link;
$manager->persist($link);
}
for ($i = 0; $i < 10000; ++$i) {
$visitor = new Visitor();
$visitor->setIp($this->localisation->geoplugin_request);
$visitor->setCountryCode($this->localisation->geoplugin_countryCode);
$visitor->setCountryName($this->localisation->geoplugin_countryName);
$visitors[] = $visitor;
$manager->persist($visitor);
}
for ($i = 0; $i < 10000; ++$i) {
$linkView = new LinkView();
$linkView->setDate($faker->dateTimeBetween('-1 years', 'now'));
$linkView->setVisitor($visitors[rand(0, 999)]);
$linkView->setLink($links[rand(0, 99)]);
$manager->persist($linkView);
}
for ($i = 0; $i < 10000; ++$i) {
$linkClick = new LinkClick();
$linkClick->setDate($faker->dateTimeBetween('-1 years', 'now'));
$linkClick->setVisitor($visitors[rand(0, 999)]);
$linkClick->setLink($links[rand(0, 99)]);
$manager->persist($linkClick);
}
$manager->flush();
}
}
I dont want to flush the database everytime, i want to use and existing user, so i can append fixtures. Right now it throws an error:
SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'admin' for key 'UNIQ_1483A5E992FC23A8'
Related
I want to create a fixture for categories, but I get the error
Could you elaborate on how di works in Symfony. The documentation didn't tell me much.
in config / services.yaml the standard code is already specified which seems to solve the di problem
class CategoryFixtures extends \Doctrine\Bundle\FixturesBundle\Fixture
{
private $category;
public function __construct(
\App\Entity\Category $category
) {
$this->category = $category;
}
public function load(\Doctrine\Persistence\ObjectManager $manager)
{
$this->addMainCategories($manager);
}
private function addMainCategories($manager) {
$mainCategoriesArray = ['111', '222', '333', '444', '555'];
foreach ($mainCategoriesArray as $categoryName) {
$this->category->setName($categoryName);
$manager->persist($this->category);
}
$manager->flush();
}
}
Error
Cannot autowire service "App\DataFixtures\CategoryFixtures": argument "$category" of method "__construct()" references class "App\Entity\Category" but no such service exists.
DI isn't really the issue here.
Untested code to create 5 Category entities:
use App\Entity\Category;
use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Persistence\ObjectManager;
// Creates Category entities Category0, Category1...
class CategoryFixtures extends AbstractFixture
{
private $mainCategoriesArray = ['111', '222', '333', '444', '555'];
public function load(ObjectManager $manager)
{
for ($i = 0; $i < 5; $i++) {
$name = 'Category' . $i;
$$name = new Category();
$$name->setName($this->mainCategoriesArray[$i]);
$manager->persist($$name);
}
$manager->flush();
}
}
I am trying to load fixtures into my database. I have a post entity and a category entity, and a category can have many posts.
In my fixtures file I would like to create some categories and then assign a random category to each post, but I am not sure how to do this.
How can I get a reference to a random category?
<?php
namespace App\DataFixtures;
use App\Entity\Category;
use App\Entity\User;
use App\Entity\Post;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Common\Persistence\ObjectManager;
use Doctrine\ORM\EntityManager;
use Faker\Factory;
use Faker\Generator;
class AppFixtures extends Fixture
{
private $faker;
public function load(ObjectManager $manager)
{
$this->faker = Factory::create();
$this->addUsers($manager);
$this->addCategories($manager);
$this->addPosts($manager);
$manager->flush();
}
private function addUsers(EntityManager $em)
{
for ($i = 1; $i <= 10; $i++) {
$user = new User();
$firstname = $this->faker->firstName;
$lastname = $this->faker->lastName;
$user->setFirstName($firstname);
$user->setLastName($lastname);
$user->setEmail($firstname.'.'.$lastname.'#gmail.com');
$user->setRoles(['ROLE_USER']);
$em->persist($user);
$this->addPosts($user);
}
}
private function addCategories(EntityManager $em)
{
$categoryHome = new Category();
$categoryHome->setName('Home');
$em->persist($categoryHome);
$categoryWork = new Category();
$categoryWork->setName('Work');
$em->persist($categoryWork);
}
public function addPosts(EntityManager $em, User $user){
for ($i = 1; $i <= 10; $i++) {
$post = new Post();
$post->setUser($user);
// How can I assign the category randomly?
$post->setCaterory(????)
$em->persist($post);
}
}
}
If you need to create random data (for example for presentation) I think better choice would be using AliceBundle https://github.com/hautelook/AliceBundle which can do this out of box via relations. Plus it will be same on every load of fixtures.
But to answer your question. You make list of categories you created and then just choose one randomly.
<?php
namespace App\DataFixtures;
use App\Entity\Category;
use App\Entity\User;
use App\Entity\Post;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Common\Persistence\ObjectManager;
use Doctrine\ORM\EntityManager;
use Faker\Factory;
use Faker\Generator;
class AppFixtures extends Fixture
{
private $faker;
private $categories;
public function load(ObjectManager $manager)
{
$this->faker = Factory::create();
$this->addUsers($manager);
$this->addCategories($manager);
$this->addPosts($manager);
$manager->flush();
}
private function addUsers(EntityManager $em)
{
for ($i = 1; $i <= 10; $i++) {
$user = new User();
$firstname = $this->faker->firstName;
$lastname = $this->faker->lastName;
$user->setFirstName($firstname);
$user->setLastName($lastname);
$user->setEmail($firstname.'.'.$lastname.'#gmail.com');
$user->setRoles(['ROLE_USER']);
$em->persist($user);
$this->addPosts($user);
}
}
private function addCategories(EntityManager $em)
{
$categoryHome = new Category();
$categoryHome->setName('Home');
$em->persist($categoryHome);
$this->categories[] = $categoryHome;
$categoryWork = new Category();
$categoryWork->setName('Work');
$em->persist($categoryWork);
$this->categories[] = $categoryWork;
}
public function addPosts(EntityManager $em, User $user){
for ($i = 1; $i <= 10; $i++) {
$post = new Post();
$post->setUser($user);
$post->setCaterory($this->categories[rand(0, count($this->categories))]);
$em->persist($post);
}
}
}
In AddPost Function Add this
public function addPosts(EntityManager $em, User $user){
$categories = $manager->getRepository(Category::class)->findAll();
for ($i = 1; $i <= 10; $i++) {
$post = new Post();
$post->setUser($user);
$category = $categories[array_rand($categories)];
$post->setCategory($category)
$em->persist($post);
}
}
}
I want to create fixture, that generate 10 records in my table (test0-test9), then create migration, wherein I need to rename records, that was created by fixture to (category0-category9).
I have created this fixture:
class AppFixtures extends Fixture
{
public function load(ObjectManager $manager)
{
for ($i = 0; $i < 10; $i++)
{
$product = new Category();
$product->setName('test '.$i);
$id = mt_rand(89,140);
$parent = $manager->getRepository(Category::class)->find($id);
$product->setParent($parent);
$manager->persist($product);
}
$manager->flush();
}
}
But how I can rename this records in doctrine using migration? Any idea?
* I think, I need to create sql queries directly in my migration class...or not
UPDATE
I try to do this, but I think it is bad solution...
public function postUp(Schema $schema)
{
$this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'mysql', 'Migration can only be executed safely on \'mysql\'.');
for ($i = 0; $i < 10; $i++)
{
$category = 'category '.$i;
$test = 'test'.$i;
$this->addSql('UPDATE category SET NAME = '.$category.' WHERE NAME = '.$test );
}
}
You can inject the entity manager inside your migration.
Then you can find the object you want to change and change it.
I hope this answers your question
Example:
public function postUp(Schema $schema)
{
$em = $this->container->get('doctrine.orm.entity_manager');
$products = $em->getRepository(Product::class)
->getProductsCustomQuery();
foreach($product as $products){
$product->setName(Whatever);
}
$em->flush();
}
Check this link
I used DoctrineFixturesBundle to fill my db for 50000 records.I want to have many employee to one boss. But now when I filled my db I have in boss_id only null values
My load function:
public function load(ObjectManager $manager)
{
for ($i = 0; $i <= 50000; $i++) {
$employee = new Employee();
if($i == 0) {
$employee->setPosition('founder');
}
$employee->setFullName('new employee'.$i);
$employee->setSalary(50000 - $i);
$employee->setStartDate(new \DateTime());
if($i > 0) {
$employee->setBoss($manager->find(Employee::class,1));
$employee->setPosition('boss');
} elseif ($i >= 1000) {
$id = rand(2,1000);
$employee->setBoss($manager->find(Employee::class,$id));
$employee->setPosition('top-manager');
} elseif ($i >= 5000) {
$id = rand (1000,4999);
$employee->setBoss($manager->find(Employee::class,$id));
$employee->setPosition('manager');
} elseif ($i >= 10000){
$id = rand(5000,9999);
$employee->setBoss($manager->find(Employee::class,$id));
$employee->setPosition('worker');
}
$manager->persist($employee);
}
$manager->flush();
}
My Entity Employee:
/**
* #var Employee
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\Employee")
*/
private $boss;
public function setBoss(\AppBundle\Entity\Employee $boss = null)
{
$this->boss = $boss;
return $this;
}
how can I do this trick? What I did wrong?
It is because your object is not created when you use it
use the addReferenceas explained in the doc
I have a OneToOne relation between the Article entity and Image entity, the Article entity is the owner , I created the fixtures data files to load the database , I used the " faker " to format the type file, when I run the command:
$ app / console doctrine : fixtures : load
I get this error message :
:[OutOfBoundsException]
Reference to: (image) does not exist
in my fixtures files:
ns\NikahBundle\DataFixtures\ORM\LoadArticleData.php:
<?php
namespace ns\NikahBundle\DataFixtures\ORM;
use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
use Doctrine\Common\Persistence\ObjectManager;
use ns\NikahBundle\Entity\Article;
class LoadArticleData extends AbstractFixture implements OrderedFixtureInterface
{
const MAX_NB_ARTICLES = 10;
public function load(ObjectManager $manager)
{
$faker = \Faker\Factory::create();
for ($i = 0; $i < self::MAX_NB_ARTICLES; ++$i) {
$article = new Article();
$article->setAuteur($faker->text(250));
$article->setTitre($faker->text(250));
$article->setContenu($faker->text(250));
$article->setDeleted($faker->boolean);
$image = $this->getReference('image');
$article->setImage($image);
$manager->persist($article);
}
$manager->flush();
}
public function getOrder(){
return 1;
}
}
in my ns\NikahBundle\DataFixtures\ORM\LoadImageData.php:
<?php
namespace ns\NikahBundle\DataFixtures\ORM;
use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
use Doctrine\Common\Persistence\ObjectManager;
use ns\NikahBundle\Entity\Image;
class LoadImageData extends AbstractFixture implements OrderedFixtureInterface
{
const MAX_NB_IMAGES = 5;
public function load(ObjectManager $manager)
{
$faker = \Faker\Factory::create();
for ($i=0; $i<self::MAX_NB_IMAGES; ++$i){
$image = new Image();
$image->setUrl($faker->imageUrl($width = 640, $height = 480));
$image->setAlt($faker->text);
$manager->persist($image);
$this->addReference('image', $image);
}
$manager->flush();
}
public function getOrder(){
return 2;
}
In my opinion, LoadImageData should be launch before LoadArticleData.
class LoadImageData extends AbstractFixture implements OrderedFixtureInterface
{
/ *** /
public function getOrder(){
return 1;
}
}
and
class LoadArticleData extends AbstractFixture implements OrderedFixtureInterface
{
/ *** /
public function getOrder(){
return 2;
}
}