@@ -384,12 +384,179 @@ class CustomFieldFixture implements FixtureInterface
384384}
385385```
386386
387+ ## Customer Fixtures
388+
389+ The FixtureBundle provides comprehensive customer management through fixtures using ` CustomerFixtureLoader ` and ` CustomerFixtureDefinition ` classes for creating test customers with addresses, custom fields, and relationships.
390+
391+ ### Basic Customer Fixture
392+
393+ ``` php
394+ <?php
395+
396+ declare(strict_types=1);
397+
398+ namespace Acme\Fixture;
399+
400+ use Shopware\FixtureBundle\Attribute\Fixture;
401+ use Shopware\FixtureBundle\FixtureInterface;
402+ use Shopware\FixtureBundle\Helper\Customer\CustomerFixtureDefinition;
403+ use Shopware\FixtureBundle\Helper\Customer\CustomerFixtureLoader;
404+
405+ #[Fixture]
406+ class CustomerFixture implements FixtureInterface
407+ {
408+ public function __construct(
409+ private readonly CustomerFixtureLoader $customerFixtureLoader
410+ ) {
411+ }
412+
413+ public function load(): void
414+ {
415+ $this->customerFixtureLoader->apply(
416+ (new CustomerFixtureDefinition('john.doe@example.com'))
417+ ->firstName('John')
418+ ->lastName('Doe')
419+ ->salutation('mr')
420+ ->password('password123')
421+ ->company('ACME Corporation')
422+ ->department('IT Department')
423+ );
424+ }
425+ }
426+ ```
427+
428+ ### Customer with Complete Information
429+
430+ ``` php
431+ #[Fixture(groups: ['customers', 'test-data'])]
432+ class DetailedCustomerFixture implements FixtureInterface
433+ {
434+ public function __construct(
435+ private readonly CustomerFixtureLoader $customerFixtureLoader
436+ ) {
437+ }
438+
439+ public function load(): void
440+ {
441+ $this->customerFixtureLoader->apply(
442+ (new CustomerFixtureDefinition('jane.smith@example.com'))
443+ ->firstName('Jane')
444+ ->lastName('Smith')
445+ ->salutation('mrs')
446+ ->title('Dr.')
447+ ->birthday('1990-05-15')
448+ ->company('Tech Solutions Ltd')
449+ ->department('Marketing')
450+ ->vatId('DE123456789')
451+ ->password('secure123')
452+ ->customerNumber('CUST-001')
453+ ->affiliateCode('PARTNER-123')
454+ ->campaignCode('SUMMER2024')
455+ ->active(true)
456+ ->guest(false)
457+ ->customFields([
458+ 'vip_level' => 'gold',
459+ 'newsletter_subscription' => true,
460+ 'preferred_contact' => 'email'
461+ ])
462+ );
463+ }
464+ }
465+ ```
466+
467+ ### Customer with Addresses
468+
469+ ``` php
470+ #[Fixture(groups: ['customers', 'addresses'])]
471+ class CustomerWithAddressesFixture implements FixtureInterface
472+ {
473+ public function __construct(
474+ private readonly CustomerFixtureLoader $customerFixtureLoader
475+ ) {
476+ }
477+
478+ public function load(): void
479+ {
480+ $this->customerFixtureLoader->apply(
481+ (new CustomerFixtureDefinition('customer@example.com'))
482+ ->firstName('Max')
483+ ->lastName('Mustermann')
484+ ->salutation('mr')
485+ ->password('password')
486+ ->defaultBillingAddress([
487+ 'firstName' => 'Max',
488+ 'lastName' => 'Mustermann',
489+ 'street' => 'Musterstraße 123',
490+ 'zipcode' => '12345',
491+ 'city' => 'Musterstadt',
492+ 'country' => 'DEU',
493+ 'company' => 'Musterfirma GmbH',
494+ 'phoneNumber' => '+49 123 456789',
495+ 'salutation' => 'mr'
496+ ])
497+ ->defaultShippingAddress([
498+ 'firstName' => 'Max',
499+ 'lastName' => 'Mustermann',
500+ 'street' => 'Lieferadresse 456',
501+ 'zipcode' => '67890',
502+ 'city' => 'Lieferstadt',
503+ 'country' => 'DEU',
504+ 'additionalAddressLine1' => 'Building B',
505+ 'additionalAddressLine2' => '3rd Floor'
506+ ])
507+ ->addAddress('work', [
508+ 'firstName' => 'Max',
509+ 'lastName' => 'Mustermann',
510+ 'street' => 'Office Street 789',
511+ 'zipcode' => '11111',
512+ 'city' => 'Business City',
513+ 'country' => 'DEU',
514+ 'company' => 'Work Corporation'
515+ ])
516+ );
517+ }
518+ }
519+ ```
520+
521+ ### Guest Customer Fixture
522+
523+ ``` php
524+ #[Fixture(groups: ['customers', 'guest-orders'])]
525+ class GuestCustomerFixture implements FixtureInterface
526+ {
527+ public function __construct(
528+ private readonly CustomerFixtureLoader $customerFixtureLoader
529+ ) {
530+ }
531+
532+ public function load(): void
533+ {
534+ $this->customerFixtureLoader->apply(
535+ (new CustomerFixtureDefinition('guest@example.com'))
536+ ->firstName('Guest')
537+ ->lastName('User')
538+ ->guest(true)
539+ ->active(false)
540+ ->defaultBillingAddress([
541+ 'firstName' => 'Guest',
542+ 'lastName' => 'User',
543+ 'street' => 'Guest Street 1',
544+ 'zipcode' => '99999',
545+ 'city' => 'Guest City',
546+ 'country' => 'DEU'
547+ ])
548+ );
549+ }
550+ }
551+ ```
552+
387553## Best Practices
388554
3895551 . ** Use meaningful names** : Name your fixtures clearly to indicate what data they create
390- 2 . ** Organize with groups** : Use groups to categorize fixtures (e.g., 'test-data', 'demo-data', 'performance-test', 'theme-config')
556+ 2 . ** Organize with groups** : Use groups to categorize fixtures (e.g., 'test-data', 'demo-data', 'performance-test', 'theme-config', 'customers' )
3915573 . ** Declare dependencies explicitly** : Always declare dependencies to ensure correct execution order
3925584 . ** Keep fixtures focused** : Each fixture should have a single responsibility
3935595 . ** Make fixtures idempotent** : Fixtures should be able to run multiple times without errors
3945606 . ** Use dependency injection** : Inject the services you need rather than accessing the container directly
3955617 . ** Handle theme errors gracefully** : Use try-catch blocks when configuring optional themes
562+ 8 . ** Use email as unique identifier** : Customer fixtures use email as the primary identifier for updates vs. creation
0 commit comments