teamneusta / pimcore-fixture-bundle
Provide basic functionality to enable installing fixtures in Pimcore
Installs: 957
Dependents: 0
Suggesters: 0
Security: 0
Stars: 1
Watchers: 11
Forks: 0
Open Issues: 1
Type:pimcore-bundle
Requires
- php: ~8.1.0 || ~8.2.0
- pimcore/pimcore: ^10.5 || ^11.0
Requires (Dev)
- ergebnis/composer-normalize: ^2.42
- friendsofphp/php-cs-fixer: ^3.11
- laminas/laminas-zendframework-bridge: ^1.8
- phpspec/prophecy-phpunit: ^2.0
- phpstan/extension-installer: ^1.1
- phpstan/phpstan: ^1.8
- phpstan/phpstan-phpunit: ^1.1
- phpstan/phpstan-symfony: ^1.2
- phpunit/phpunit: ^9.5
- teamneusta/pimcore-testing-framework: ^0.12
Conflicts
- presta/sitemap-bundle: <3.2
- symfony/form: <5.4
- symfony/routing: <5.4
This package is auto-updated.
Last update: 2024-04-25 07:46:28 UTC
README
Provides a way to manage and execute the loading of data fixtures in Pimcore.
It can be useful for testing purposes, or for seeding a database with initial data.
Installation
-
Require the bundle
composer require teamneusta/pimcore-fixture-bundle
-
Enable the bundle
Add the Bundle to your
config/bundles.php
:Neusta\Pimcore\FixtureBundle\NeustaPimcoreFixtureBundle::class => ['test' => true],
Usage
Writing Fixtures
Data fixtures are PHP classes where you create objects and persist them to the database.
Imagine that you want to add some Product
objects to your database.
To do this, create a fixture class and start adding products:
use Neusta\Pimcore\FixtureBundle\Fixture; use Pimcore\Model\DataObject\Product; final class ProductFixture implements Fixture { public function create(): void { for ($i = 1; $i <= 20; $i++) { $product = new Product(); $product->setParentId(0); $product->setPublished(true); $product->setKey("Product {$i}"); // ... $product->save(); } } }
Loading Fixtures
To use fixtures in tests, a few preparations must be made.
Currently, the FixtureFactory
still has to be instantiated manually.
The easiest way to do this is with a project-specific kernel base class.
use Neusta\Pimcore\FixtureBundle\Factory\FixtureFactory; use Neusta\Pimcore\FixtureBundle\Factory\FixtureInstantiator\FixtureInstantiatorForAll; use Neusta\Pimcore\FixtureBundle\Factory\FixtureInstantiator\FixtureInstantiatorForParametrizedConstructors; use Neusta\Pimcore\FixtureBundle\Fixture; use Pimcore\Test\KernelTestCase; abstract class BaseKernelTestCase extends KernelTestCase { protected FixtureFactory $fixtureFactory; /** @param list<class-string<Fixture>> $fixtures */ protected function importFixtures(array $fixtures): void { $this->fixtureFactory ??= (new FixtureFactory([ new FixtureInstantiatorForParametrizedConstructors(static::getContainer()), new FixtureInstantiatorForAll(), ])); $this->fixtureFactory->createFixtures($fixtures); } protected function tearDown(): void { unset($this->fixtureFactory); \Pimcore\Cache::clearAll(); \Pimcore::collectGarbage(); parent::tearDown(); } }
Use the base class as follows:
use Pimcore\Model\DataObject; final class MyCustomTest extends BaseKernelTestCase { /** @test */ public function import_fixtures(): void { $this->importFixtures([ ProductFixture::class, ]); $productFixture = DataObject::getByPath('/product-1'); self::assertNotNull($productFixture); } }
Accessing Services from the Fixtures
Sometimes you may need to access your application's services inside a fixture class. You can use normal dependency injection for this:
Important
You need to create your FixtureFactory
with the FixtureInstantiatorForParametrizedConstructors
for this to work!
final class SomeFixture implements Fixture { public function __construct( private Something $something, ) { } public function create(): void { // ... use $this->something } }
Depending on Other Fixtures
In a fixture, you can depend on other fixtures.
Therefore, you have to reference them in your create()
method as parameters.
Important
All parameters of the create()
method in your fixtures may only reference other fixtures.
Everything else is not allowed!
Referencing other fixtures ensures they are created before this one.
This also allows accessing some state of the other fixtures.
final class SomeFixture implements Fixture { public function create(OtherFixture $otherFixture): void { // do something with $otherFixture->someInformation } } final class OtherFixture implements Fixture { public string $someInformation; public function create(): void { $this->someInformation = 'some information created in this fixture'; } }
The state can also be accessed from the tests:
use Neusta\Pimcore\FixtureBundle\Fixture; use Pimcore\Model\DataObject\Product; final class ProductFixture implements Fixture { public int $productId; public function create(): void { $product = new Product(); $product->setParentId(0); $product->setPublished(true); $product->setKey("Product Fixture"); // ... $product->save(); $this->productId = $product->getId(); } }
use Pimcore\Model\DataObject; final class MyCustomTest extends BaseKernelTestCase { /** @test */ public function some_product_test(): void { $this->importFixtures([ ProductFixture::class, ]); $productFixture = $this->fixtureFactory->getFixture(ProductFixture::class); $product = DataObject::getById($productFixture->productId); self::assertNotNull($product); } }
Contribution
Feel free to open issues for any bug, feature request, or other ideas.
Please remember to create an issue before creating large pull requests.
Local Development
To develop on a local machine, the vendor dependencies are required.
bin/composer install
We use composer scripts for our main quality tools. They can be executed via the bin/composer
file as well.
bin/composer cs:fix bin/composer phpstan bin/composer tests