如何创建自定义功能/格式化Nelmio/Alice v.3



我是Symfony 4的新手,并试图为YML Nelmio/Alice编写自己的功能,但是在我运行bin/console doctrine:fixtures:load之后,我得到了此错误:

在deepcopy.php行177中:

类" ReflectionClass"类不可链式。

这是我的fixtures.yml文件:

AppEntityPost:
post_{1..10}:
    title: <customFunction()>

这是我的appfixture.php文件:

<?php
namespace AppDataFixtures;
use DoctrineBundleFixturesBundleFixture;
use DoctrineCommonPersistenceObjectManager;
use NelmioAliceLoaderNativeLoader;

class AppFixtures extends Fixture
{
    public function load(ObjectManager $manager)
    {
        $loader = new NativeLoader();
        $objectSet = $loader->loadFile(__DIR__.'/Fixtures.yml',
            [
                'providers' => [$this]
            ]
        )->getObjects();
        foreach($objectSet as $object) {
            $manager->persist($object);
        }
        $manager->flush();
    }
    public function customFunction() {
        // Some Calculations
        return 'Yep! I have got my bonus';
    }
}

研究了Nelmio/Alice新版本后,我找到了解决方案:

我们应该首先创建一个提供商,该提供商是包含我们新自定义功能的类。其次,扩展NativeLoader类以注册我们的新提供商。第三,使用我们的新Nativeloader(这是CustomNativeloader(,它允许我们使用新的格式化器。

这是CustomFixtureProvider.php中的提供商:

<?php

namespace AppDataFixtures;
use FakerFactory;
class CustomFixtureProvider
{
    public function title()
    {
        $faker = Factory::create();
        $title = $faker->text($faker->numberBetween(20,100));
        return $title;
    }
}

作为旁注,title函数为您的文章或帖子或帖子等生成了一些虚拟标题,这些标题具有动态长度在20..100字符之间。此功能使用Faker Alice内置格式化。

这是CustomNativeloader.php:

<?php
namespace AppDataFixtures;
use NelmioAliceFakerProviderAliceProvider;
use NelmioAliceLoaderNativeLoader;
use FakerFactory as FakerGeneratorFactory;
use FakerGenerator as FakerGenerator;
class CustomNativeLoader extends NativeLoader
{
    protected function createFakerGenerator(): FakerGenerator
    {
        $generator = FakerGeneratorFactory::create(parent::LOCALE);
        $generator->addProvider(new AliceProvider());
        $generator->addProvider(new CustomFixtureProvider());
        $generator->seed($this->getSeed());
        return $generator;
    }
}

这是LoadFixture.php:

<?php
namespace AppDataFixtures;
use AppDataFixturesCustomNativeLoader;
use DoctrineBundleFixturesBundleFixture;
use DoctrineCommonPersistenceObjectManager;
class LoadFixtures extends Fixture
{
    public function load(ObjectManager $manager)
    {
        $loader = new CustomNativeLoader();
        $objectSet = $loader->loadFile(__DIR__ . '/fixtures.yml')->getObjects();
        foreach($objectSet as $object) {
            $manager->persist($object);
        }
        $manager->flush();
    }
}

,最后是使用我们的新title格式化的示例:

AppEntityPost:
    post_{1..10}:
        title: <title()>

我知道这是编写较小功能的很长的路要走,但是根据我的调查,这是扩展新版本中格式器的标准方法。

您可以以这种简单的方式做到这一点:

1.创建自己的提供商(例如,在/src/datafixtures/faker/customprovider.php(:

 <?php    
    namespace AppDataFixturesFaker;

    class CustomProvider
    {
        public static function customFunction()
        {
            // Some Calculations
            return 'Yep! I have got my bonus';
        }
    }

2.在config/services.yaml中注册提供商:

AppDataFixturesFakerCustomProvider:
    tags: [ { name: nelmio_alice.faker.provider } ]

就是这样。

P.S。您可以在此处查看更多详细信息:https://github.com/hautelook/alicebundle/blob/master/doc/doc/faker-providers.md

也可能喜欢(补充解决方案bellow https://stackoverflow.com/a/54116196/261058(:

EntityServiceProvider.php
<?php
declare(strict_types=1);
namespace AppInfrastructureFixtureProvider;
use DoctrineORMEntityManagerInterface;
use Exception;
use FakerGenerator;
use FakerProviderBase;
class EntityServiceProvider extends Base
{
    public function __construct(Generator $generator, private EntityManagerInterface $entityManager)
    {
        $this->unique(true);
        parent::__construct($generator);
    }
    /**
     * @template T of object
     * @param class-string<T> $class
     * @return T
     * @throws Exception
     */
    public function entityReference(string $class, string $columnName, string|int|bool $columnValue)
    {
        if (!class_exists($class)) {
            throw new Exception(sprintf('Class "%s" does not exist or it isn't loaded', $class));
        }
        $repository = $this->entityManager->getRepository($class);
        $foundEntity = $repository->findOneBy([$columnName => $columnValue]);
        if (!$foundEntity instanceof $class) {
            throw new Exception(sprintf('Entity "%s" with given criteria wasn't found', $class));
        }
        return $foundEntity;
    }
}
服务定义:service.yaml
AppInfrastructureFixtureProviderEntityServiceProvider:
    tags:
        - { name: 'nelmio_alice.faker.provider' }
用法在固定装置中使用yaml
AppDomainLocationAddress:
    address0:
        id: '<numberBetween(3000,99999)>'
        country: '<entityReference(AppDomainLocationCountry, code, DE)>'
从夹具yaml
加载对象
protected function loadObjectsFromFixtures(array $files): array
    {
        return (new NativeLoader($this->getService(FakerGenerator::class)))->loadFiles($files)->getObjects();
    }

相关内容

  • 没有找到相关文章

最新更新