Skip to content
This repository has been archived by the owner on Dec 11, 2020. It is now read-only.

Doctrine entity populator type error #2010

Open
ScottA38 opened this issue Jun 6, 2020 · 1 comment
Open

Doctrine entity populator type error #2010

ScottA38 opened this issue Jun 6, 2020 · 1 comment

Comments

@ScottA38
Copy link

ScottA38 commented Jun 6, 2020

Summary

Cannot use Doctrine EntityManager with ORM EntityManager

Versions

Version
PHP 7.4.4
fzaninotto/faker 1.9.0

Self-enclosed code snippet for reproduction

<?php

declare(strict_types=1);

namespace WebApp\Util;

use Doctrine\ORM\EntityManager;
use Faker\ORM\Doctrine\Populator;
use Faker\Factory;
use WebApp\Models\Product;
use Faker\Generator;

class ProductPopulator
{
    private EntityManager $em;
    private Generator $generator;

    public function __construct(EntityManager $em)
    {
        $this->em = $em;
        $this->generator = Factory::create();
    }

    private function getspecialInstructions()
    {
        $nameReducer = function ($carry, $lChar) {
            if (!in_array($lChar, ["a", "e", "i", "o", "u"])) {
                $carry++;
            }
            return $carry;
        };
        return [
            'price' => function () {
                return $this->generator->randomFloat(2, 0, 10000);
            },
            'name' => function () use ($nameReducer) {
                $name = $this->generator->unique()->company;
                while (array_reduce(str_split(strtolower($name)), $nameReducer) < 3) {
                    $name = $this->generator->unique()->company;
                }
                return $name;
            },
            'dimensions' => function () {
                return [
                    $this->generator->randomNumber(3),
                    $this->generator->randomNumber(3),
                    $this->generator->randomNumber(3)
                ];
            }
        ];
    }

    public function getEntityManager(): EntityManager
    {
        return $this->em;
    }


    /**
     * Populate the database with a given amount of DBAL entity. Returns PK of each popluated element
     * @param Product $entity
     * @param int $amount
     * @return array
     */
    public function populate(string $className, int $amount)
    {
        $metadata = $this->em->getClassMetadata($className);
        $fieldNames = array_keys($metadata->fieldMappings);
        $specialInstructions = $this->getspecialInstructions();
        $instructionKeys = array_keys($specialInstructions);
        foreach ($instructionKeys as &$instructionKey) {
            if (!in_array($instructionKey, $fieldNames)) {
                unset($specialInstructions[$instructionKey]);
            }
        }
        $populator = new Populator($this->generator, null, 1);
        $populator->addEntity($className, $amount, $specialInstructions, [], false);
        return $populator->execute();
    }
}

Expected output

SELECT * FROM Furniture

records display

Actual output

>>> main()
$pop = new ProductPopulator($em);
$pop->populate('WebApp\models\Furniture', 1);
>>> error output (from PHPUnit tests)
TypeError: Argument 2 passed to Faker\ORM\Doctrine\Populator::__construct() must be an instance of Doctrine\Common\Persistence\ObjectManager or null, instance of Doctrine\ORM\EntityManager given, called in /Users/ScottAnderson/Documents/Tech/commissions/shopping_app_test/src/Util/ProductPopulator.php on line 76
@ScottA38
Copy link
Author

ScottA38 commented Jun 6, 2020

To anyone who encounters this, this is a doctrine version issue
(maybe it will be patched in a future minor release, I don't know).

The specific minimum version of doctrine/orm that seems to be compatible with Faker at the time of writing is 2.7.2, 2.7.3 will break it as shown in the original error report.

So constrain your composer version as so:

"require": {
		"doctrine/orm": "2.7.2"
	},

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant