├── .github
├── scripts
│ └── build-documentation.sh
└── workflows
│ ├── ci.yml
│ └── documentation.yml
├── .php-cs-fixer.php
├── CHANGELOG.md
├── LICENSE
├── README.md
├── bench
├── README.md
├── composer.json
├── composer.lock
└── src
│ ├── CreateObjectBench.php
│ └── IsInitializedBench.php
├── castor.composer.json
├── castor.composer.lock
├── castor.php
├── composer.json
├── docs
├── _nav.md
├── assets
│ ├── favicon.png
│ ├── javascripts
│ │ └── highlight.min.js
│ └── stylesheets
│ │ └── highlight-github.min.css
├── bundle
│ ├── api-platform.md
│ ├── cache-warmup.md
│ ├── configuration.md
│ ├── debugging.md
│ ├── expression-language.md
│ ├── index.md
│ ├── installation.md
│ └── migrate.md
├── contributing.md
├── getting-started
│ ├── cache.md
│ ├── configuration.md
│ ├── context.md
│ ├── index.md
│ └── source-and-target.md
├── images
│ ├── debug-cli.png
│ ├── debug-profiler-1.png
│ └── debug-profiler-2.png
├── index.md
├── mapping
│ ├── attributes.md
│ ├── conditional-mapping.md
│ ├── date-time.md
│ ├── groups.md
│ ├── ignoring-properties.md
│ ├── index.md
│ ├── inheritance.md
│ ├── map-collection.md
│ ├── mapper-attribute.md
│ ├── provider.md
│ ├── serializer.md
│ └── transformer.md
├── overrides
│ └── main.html
└── upgrading-9.0.md
├── mkdocs.yaml
├── phpstan-baseline.neon
├── phpstan.neon
├── poetry.lock
├── pyproject.toml
├── src
├── Attribute
│ ├── MapFrom.php
│ ├── MapProvider.php
│ ├── MapTo.php
│ ├── MapToContext.php
│ └── Mapper.php
├── AutoMapper.php
├── AutoMapperInterface.php
├── AutoMapperRegistryInterface.php
├── Configuration.php
├── ConstructorStrategy.php
├── Event
│ ├── GenerateMapperEvent.php
│ ├── PropertyMetadataEvent.php
│ ├── SourcePropertyMetadata.php
│ └── TargetPropertyMetadata.php
├── EventListener
│ ├── ApiPlatform
│ │ └── JsonLdListener.php
│ ├── MapFromListener.php
│ ├── MapListener.php
│ ├── MapProviderListener.php
│ ├── MapToContextListener.php
│ ├── MapToListener.php
│ ├── MapperListener.php
│ └── Symfony
│ │ ├── AdvancedNameConverterListener.php
│ │ ├── ClassDiscriminatorListener.php
│ │ ├── SerializerGroupListener.php
│ │ ├── SerializerIgnoreListener.php
│ │ └── SerializerMaxDepthListener.php
├── Exception
│ ├── AutoMapperException.php
│ ├── BadMapDefinitionException.php
│ ├── CannotCreateTargetException.php
│ ├── CircularReferenceException.php
│ ├── CompileException.php
│ ├── InvalidArgumentException.php
│ ├── InvalidMappingException.php
│ ├── LogicException.php
│ ├── MetadataException.php
│ ├── MissingConstructorArgumentsException.php
│ ├── ReadOnlyTargetException.php
│ └── RuntimeException.php
├── Extractor
│ ├── FromSourceMappingExtractor.php
│ ├── FromTargetMappingExtractor.php
│ ├── GetTypeTrait.php
│ ├── MappingExtractor.php
│ ├── MappingExtractorInterface.php
│ ├── ReadAccessor.php
│ ├── ReadWriteTypeExtractor.php
│ ├── SourceTargetMappingExtractor.php
│ └── WriteMutator.php
├── GeneratedMapper.php
├── Generator
│ ├── CreateTargetStatementsGenerator.php
│ ├── InjectMapperMethodStatementsGenerator.php
│ ├── MapMethodStatementsGenerator.php
│ ├── MapperConstructorGenerator.php
│ ├── MapperGenerator.php
│ ├── PropertyConditionsGenerator.php
│ ├── PropertyStatementsGenerator.php
│ ├── Shared
│ │ ├── CachedReflectionStatementsGenerator.php
│ │ ├── ClassDiscriminatorResolver.php
│ │ └── DiscriminatorStatementsGenerator.php
│ ├── UniqueVariableScope.php
│ └── VariableRegistry.php
├── Loader
│ ├── ClassLoaderInterface.php
│ ├── EvalLoader.php
│ ├── FileLoader.php
│ └── FileReloadStrategy.php
├── MapperContext.php
├── MapperInterface.php
├── Metadata
│ ├── Dependency.php
│ ├── GeneratorMetadata.php
│ ├── MapperMetadata.php
│ ├── MetadataFactory.php
│ ├── MetadataRegistry.php
│ ├── PropertyMetadata.php
│ ├── SourcePropertyMetadata.php
│ ├── TargetPropertyMetadata.php
│ └── TypesMatching.php
├── Normalizer
│ └── AutoMapperNormalizer.php
├── Provider
│ ├── ApiPlatform
│ │ └── IriProvider.php
│ ├── EarlyReturn.php
│ ├── ProviderInterface.php
│ └── ProviderRegistry.php
├── Symfony
│ ├── Attribute
│ │ └── AsAutoMapperExpressionService.php
│ ├── Bundle
│ │ ├── AutoMapperBundle.php
│ │ ├── CacheWarmup
│ │ │ └── CacheWarmer.php
│ │ ├── Command
│ │ │ └── DebugMapperCommand.php
│ │ ├── DataCollector
│ │ │ └── MetadataCollector.php
│ │ ├── DependencyInjection
│ │ │ ├── AutoMapperExtension.php
│ │ │ ├── Compiler
│ │ │ │ └── TransformerFactoryPass.php
│ │ │ └── Configuration.php
│ │ ├── ReflectionClassRecursiveIterator.php
│ │ └── Resources
│ │ │ ├── config
│ │ │ ├── api_platform.php
│ │ │ ├── automapper.php
│ │ │ ├── custom_transformers.php
│ │ │ ├── event.php
│ │ │ ├── event_serializer.php
│ │ │ ├── expression_language.php
│ │ │ ├── generator.php
│ │ │ ├── metadata.php
│ │ │ ├── normalizer.php
│ │ │ ├── property_info.php
│ │ │ ├── provider.php
│ │ │ ├── symfony.php
│ │ │ └── transformers.php
│ │ │ └── views
│ │ │ └── DataCollector
│ │ │ ├── icon.svg
│ │ │ └── metadata.html.twig
│ └── ExpressionLanguageProvider.php
├── Transformer
│ ├── AbstractArrayTransformer.php
│ ├── AbstractUniqueTypeTransformerFactory.php
│ ├── AllowNullValueTransformerInterface.php
│ ├── ApiPlatform
│ │ ├── JsonLdContextTransformer.php
│ │ └── JsonLdIdTransformer.php
│ ├── ArrayToDoctrineCollectionTransformer.php
│ ├── ArrayTransformer.php
│ ├── ArrayTransformerFactory.php
│ ├── AssignedByReferenceTransformerInterface.php
│ ├── BuiltinTransformer.php
│ ├── BuiltinTransformerFactory.php
│ ├── CallableTransformer.php
│ ├── ChainTransformerFactory.php
│ ├── ChainTransformerFactoryAwareInterface.php
│ ├── ChainTransformerFactoryAwareTrait.php
│ ├── CheckTypeInterface.php
│ ├── CopyEnumTransformer.php
│ ├── CopyTransformer.php
│ ├── CopyTransformerFactory.php
│ ├── DateTimeInterfaceToImmutableTransformer.php
│ ├── DateTimeInterfaceToMutableTransformer.php
│ ├── DateTimeToStringTransformer.php
│ ├── DateTimeTransformerFactory.php
│ ├── DependentTransformerInterface.php
│ ├── DictionaryTransformer.php
│ ├── DoctrineCollectionTransformerFactory.php
│ ├── EnumTransformerFactory.php
│ ├── ExpressionLanguageTransformer.php
│ ├── FixedValueTransformer.php
│ ├── MapperDependency.php
│ ├── MultipleTransformer.php
│ ├── MultipleTransformerFactory.php
│ ├── NullableTransformer.php
│ ├── NullableTransformerFactory.php
│ ├── ObjectTransformer.php
│ ├── ObjectTransformerFactory.php
│ ├── PrioritizedTransformerFactoryInterface.php
│ ├── PropertyTransformer
│ │ ├── PrioritizedPropertyTransformerInterface.php
│ │ ├── PropertyTransformer.php
│ │ ├── PropertyTransformerFactory.php
│ │ ├── PropertyTransformerInterface.php
│ │ ├── PropertyTransformerRegistry.php
│ │ └── PropertyTransformerSupportInterface.php
│ ├── SourceEnumTransformer.php
│ ├── StringToDateTimeTransformer.php
│ ├── StringToSymfonyUidTransformer.php
│ ├── SymfonyUidCopyTransformer.php
│ ├── SymfonyUidToStringTransformer.php
│ ├── SymfonyUidTransformerFactory.php
│ ├── TargetEnumTransformer.php
│ ├── TransformerFactoryInterface.php
│ ├── TransformerInterface.php
│ ├── UniqueTypeTransformerFactory.php
│ └── VoidTransformer.php
└── php-parser.php
└── tests
├── AutoMapperBuilder.php
├── AutoMapperMapToTest.php
├── AutoMapperTest.php
├── AutoMapperTest
├── ArrayAccess
│ ├── expected.1.data
│ ├── expected.data
│ └── map.php
├── ArrayConsistency
│ ├── expected.to.data
│ ├── expected.toAdder.data
│ ├── expected.toAdderCollection.data
│ ├── expected.toCollection.data
│ └── map.php
├── ArrayNested
│ ├── expected.array.data
│ └── map.php
├── BuiltinClass
│ ├── expected.data
│ └── map.php
├── CircularReferenceDeep
│ ├── expected.data
│ └── map.php
├── ConstructorPropertyPromoted
│ ├── expected.data
│ └── map.php
├── ConstructorWithRelation
│ ├── expected.constructor-and-relation-missing.data
│ ├── expected.constructor-arguments.data
│ ├── expected.ok.data
│ └── map.php
├── ConstructorWithSerializedName
│ ├── expected.from_array.data
│ ├── expected.to_array.data
│ └── map.php
├── Covariance
│ ├── expected.data
│ └── map.php
├── DeepPopulateWithArrayCollection
│ ├── expected.array.data
│ ├── expected.collection.data
│ └── map.php
├── DifferentSetterGetterType
│ ├── expected.data
│ └── map.php
├── DiscriminatorMapAndInterface
│ ├── expected.to-array.data
│ ├── expected.to-class.data
│ └── map.php
├── DiscriminatorMapBadConfiguration
│ ├── expected.data
│ └── map.php
├── DiscriminatorPopulate
│ ├── expected.data
│ └── map.php
├── DoctrineCollections
│ ├── expected.from-array.data
│ ├── expected.to-array.data
│ └── map.php
├── GroupOverride
│ ├── expected.data
│ └── map.php
├── Ignore
│ ├── expected.ignore-in-source.data
│ ├── expected.ignore-in-target.data
│ └── map.php
├── Issue111
│ ├── expected.data
│ └── map.php
├── Issue425
│ ├── expected.data
│ └── map.php
├── IssueParamDocBlock
│ ├── expected.data
│ └── map.php
├── MaxDepth
│ ├── expected.data
│ └── map.php
├── NoProperties
│ ├── expected.data
│ └── map.php
├── NoTypes
│ ├── expected.data
│ └── map.php
├── ObjectWithPropertyAsUnknownArray
│ ├── expected.object-to-object-with-property-as-unknown-array.data
│ ├── expected.object-with-property-as-unknown-array-to-object.data
│ └── map.php
├── Paramters
│ ├── expected.int.data
│ ├── expected.mixed.data
│ ├── expected.string.data
│ └── map.php
├── Private
│ ├── expected.data
│ └── map.php
├── PrivatePropertyInConstructors
│ ├── expected.from-array.data
│ ├── expected.from-class.data
│ └── map.php
├── Provider
│ ├── expected.bar-foo.data
│ ├── expected.bar.data
│ ├── expected.early-return.data
│ └── map.php
├── README.md
├── SkipNullValues
│ ├── expected.data
│ └── map.php
├── StdObject
│ ├── expected.data
│ └── map.php
├── SymfonyUId
│ ├── expected.array-to-object-v1.data
│ ├── expected.array-to-object-v3.data
│ ├── expected.array-to-object-v4.data
│ ├── expected.array-to-object.data
│ ├── expected.object-to-array.data
│ ├── expected.object-to-object.data
│ └── map.php
├── TargetToPopulate
│ ├── expected.data
│ └── map.php
├── UninitializedProperties
│ ├── expected.data
│ └── map.php
└── UnionProperty
│ ├── expected.bar.data
│ ├── expected.foo.data
│ └── map.php
├── AutoMapperTestCase.php
├── AutoMapperWithCustomTransformerTest.php
├── Bundle
├── ApiPlatformTest.php
├── DependencyInjection
│ └── AutoMapperExtensionTest.php
├── NormalizerTest.php
├── Resources
│ ├── App
│ │ ├── Api
│ │ │ ├── Entity
│ │ │ │ ├── Book.php
│ │ │ │ └── Review.php
│ │ │ ├── Processor
│ │ │ │ └── BookProcessor.php
│ │ │ └── Provider
│ │ │ │ └── BookProvider.php
│ │ ├── AppKernel.php
│ │ ├── Controller
│ │ │ └── HomeController.php
│ │ ├── Entity
│ │ │ ├── Address.php
│ │ │ ├── AddressDTO.php
│ │ │ ├── BaseUser.php
│ │ │ ├── Cat.php
│ │ │ ├── ClassWithMapToContextAttribute.php
│ │ │ ├── ClassWithPrivateProperty.php
│ │ │ ├── DTOWithEnum.php
│ │ │ ├── Dog.php
│ │ │ ├── FooMapTo.php
│ │ │ ├── NestedObject.php
│ │ │ ├── Order.php
│ │ │ ├── Pet.php
│ │ │ ├── SomeEnum.php
│ │ │ ├── User.php
│ │ │ └── UserDTO.php
│ │ ├── Normalizer
│ │ │ ├── AddressDTONormalizer.php
│ │ │ ├── OrderNormalizer.php
│ │ │ ├── UserDTODenormalizer.php
│ │ │ └── UserNormalizer.php
│ │ └── Service
│ │ │ ├── CatProvider.php
│ │ │ ├── FooService.php
│ │ │ ├── IdNameConverter.php
│ │ │ └── YearOfBirthTransformer.php
│ ├── bin
│ │ └── console
│ ├── config
│ │ ├── bundles.php
│ │ ├── packages
│ │ │ ├── api_platform.yaml
│ │ │ ├── automapper.yaml
│ │ │ ├── dev
│ │ │ │ └── web_profiler.yaml
│ │ │ └── framework.yaml
│ │ ├── routes
│ │ │ ├── dev
│ │ │ │ └── profiler.yaml
│ │ │ └── routes.yaml
│ │ ├── services.yaml
│ │ └── with-private-properties.yml
│ └── public
│ │ ├── dev.php
│ │ └── index.php
└── ServiceInstantiationTest.php
├── Extractor
├── Fixtures
│ ├── Foo.php
│ └── FooCustomMapper.php
├── FromSourceMappingExtractorTest.php
└── FromTargetMappingExtractorTest.php
├── Fixtures
├── Address.php
├── AddressBar.php
├── AddressDTO.php
├── AddressDTOReadonlyClass.php
├── AddressDTOSecondReadonlyClass.php
├── AddressDTOWithReadonly.php
├── AddressDTOWithReadonlyPromotedProperty.php
├── AddressFoo.php
├── AddressNotWritable.php
├── AddressType.php
├── AddressWithEnum.php
├── Bar.php
├── BarGenerator.php
├── BirthDateDateTime.php
├── BirthDateExploded.php
├── Cat.php
├── CityFoo.php
├── ClassWithMapToContextAttribute.php
├── ClassWithNullablePropertyInConstructor.php
├── ClassWithPrivateProperty.php
├── ConstructorWithDefaultValues.php
├── ConstructorWithDefaultValuesAsObjects.php
├── Dog.php
├── Empty_.php
├── Fish.php
├── Foo.php
├── FooGenerator.php
├── GroupOverride.php
├── HasDateTime.php
├── HasDateTimeImmutable.php
├── HasDateTimeImmutableWithNullValue.php
├── HasDateTimeInterfaceWithImmutableInstance.php
├── HasDateTimeInterfaceWithMutableInstance.php
├── HasDateTimeInterfaceWithNullValue.php
├── HasDateTimeWithNullValue.php
├── IntDTO.php
├── IntDTOWithMapper.php
├── MapTo
│ ├── BadMapToTransformer.php
│ ├── Bar.php
│ ├── DateTimeFormatMapTo.php
│ ├── FooMapTo.php
│ ├── MapperDateTimeFormatMapTo.php
│ └── PriorityMapTo.php
├── Node.php
├── Normalizer
│ ├── ChildOfGroupsAnnotationDummy.php
│ ├── DeepObjectPopulateChildDummy.php
│ ├── DeepObjectPopulateParentDummy.php
│ ├── GroupDummy.php
│ ├── GroupDummyInterface.php
│ ├── GroupDummyParent.php
│ ├── MaxDepthDummy.php
│ ├── ProxyDummy.php
│ └── ToBeProxyfiedDummy.php
├── ObjectWithDateTime.php
├── Order.php
├── Pet.php
├── PetOwner.php
├── PetOwnerWithConstructorArguments.php
├── Private_.php
├── Proxy.php
├── ReflectionExtractorTestFixture.php
├── SourceForConstructorWithDefaultValues.php
├── Transformer
│ ├── ArrayToMoneyTransformer.php
│ ├── CustomTransformer
│ │ ├── FooDependency.php
│ │ ├── FromSourceCustomModelTransformer.php
│ │ ├── FromSourceCustomPropertyTransformer.php
│ │ ├── FromTargetCustomModelTransformer.php
│ │ ├── FromTargetCustomPropertyTransformer.php
│ │ ├── PrioritizedFromSourcePropertyPriorityTransformer.php
│ │ ├── SourceTargetCustomModelTransformer.php
│ │ ├── SourceTargetCustomPropertyTransformer.php
│ │ ├── SourceTargetMultiFieldsCustomPropertyTransformer.php
│ │ └── TransformerWithDependency.php
│ ├── MoneyToArrayTransformer.php
│ ├── MoneyToMoneyTransformer.php
│ └── MoneyTransformerFactory.php
├── Uninitialized.php
├── User.php
├── UserConstructorDTO.php
├── UserDTO.php
├── UserDTOMerged.php
├── UserDTONoAge.php
├── UserDTONoName.php
├── UserDTOProperties.php
├── UserPartialConstructor.php
├── UserWithYearOfBirth.php
├── WrongParameters.php
└── proxies.php
├── Generator
└── UniqueVariableScopeTest.php
├── MapperContextTest.php
├── Metadata
└── MetadataFactoryTest.php
├── Normalizer
├── AutoMapperNormalizerTest.php
└── Features
│ ├── AttributesTestTrait.php
│ ├── CallbacksObject.php
│ ├── CallbacksTestTrait.php
│ ├── CircularReferenceDummy.php
│ ├── CircularReferenceTestTrait.php
│ ├── ConstructorArgumentsObject.php
│ ├── ConstructorArgumentsTestTrait.php
│ ├── ContextMetadataTestTrait.php
│ ├── DummyContextChild.php
│ ├── GroupsTestTrait.php
│ ├── IgnoredAttributesTestTrait.php
│ ├── MaxDepthTestTrait.php
│ ├── ObjectDummy.php
│ ├── ObjectDummyWithContextAttribute.php
│ ├── ObjectInner.php
│ ├── ObjectOuter.php
│ ├── ObjectToPopulateTestTrait.php
│ ├── SkipNullValuesTestTrait.php
│ ├── SkipUninitializedValuesTestTrait.php
│ ├── TypeEnforcementNumberObject.php
│ ├── TypeEnforcementTestTrait.php
│ ├── TypedPropertiesObject.php
│ └── TypedPropertiesObjectWithGetters.php
└── Transformer
├── ArrayTransformerFactoryTest.php
├── ArrayTransformerTest.php
├── BuiltinTransformerFactoryTest.php
├── BuiltinTransformerTest.php
├── ChainTransformerFactoryTest.php
├── CopyTransformerTest.php
├── DateTimeInterfaceToImmutableTransformerTest.php
├── DateTimeInterfaceToMutableTransformerTest.php
├── DateTimeToStringTransformerTest.php
├── DateTimeTransformerFactoryTest.php
├── EvalTransformerTrait.php
├── MultipleTransformerFactoryTest.php
├── MultipleTransformerTest.php
├── NullableTransformerFactoryTest.php
├── NullableTransformerTest.php
├── ObjectTransformerFactoryTest.php
├── ObjectTransformerTest.php
├── StringToDateTimeTransformerTest.php
├── SymfonyUidTransformerFactoryTest.php
└── UniqueTypeTransformerFactoryTest.php
/.github/scripts/build-documentation.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # preparing fake remote
4 | mkdir .build
5 | git config user.name ci-bot
6 | git config user.email ci-bot@example.org
7 | git remote add gh-pages ./.build
8 | cd ./.build
9 | git init
10 | git checkout -b gh-pages
11 | git config receive.denyCurrentBranch ignore
12 | cd -
13 |
14 | # build documentation for main branch
15 | poetry run mike deploy --push --remote gh-pages dev
16 |
17 | # build documentation for 8.x
18 | git checkout tags/8.2.2
19 | poetry run mike deploy --push --remote gh-pages --update-aliases 8.2.2
20 |
21 | # build documentation for 9.x
22 | git checkout tags/9.2.0
23 | poetry run mike deploy --push --remote gh-pages 9.2.0 latest
24 | poetry run mike set-default --push latest
25 |
26 | # clean fake remote
27 | cd ./.build
28 | git reset --hard gh-pages
29 | cd -
30 |
--------------------------------------------------------------------------------
/.php-cs-fixer.php:
--------------------------------------------------------------------------------
1 | in(__DIR__ . '/src')
5 | ->in(__DIR__ . '/tests')
6 | ->append([__DIR__ . '/castor.php'])
7 | ->exclude(['cache', 'Bundle/Resources/var'])
8 | ;
9 |
10 | return (new PhpCsFixer\Config())
11 | ->setRiskyAllowed(true)
12 | ->registerCustomFixers((new PhpCsFixerCustomFixers\Fixers()))
13 | ->setRules([
14 | '@Symfony' => true,
15 | '@Symfony:risky' => true,
16 | 'array_syntax' => ['syntax' => 'short'],
17 | 'concat_space' => ['spacing' => 'one'],
18 | 'yoda_style' => false,
19 | 'native_constant_invocation' => false,
20 | 'no_superfluous_phpdoc_tags' => [
21 | 'remove_inheritdoc' => false,
22 | ],
23 | 'declare_strict_types' => true,
24 | 'no_trailing_comma_in_singleline' => false,
25 | 'function_declaration' => ['trailing_comma_single_line' => true],
26 | 'phpdoc_to_comment' => ['allow_before_return_statement' => true],
27 | 'psr_autoloading' => false, // Does not work well with "map.php" files in tests
28 | PhpCsFixerCustomFixers\Fixer\MultilinePromotedPropertiesFixer::name() => true,
29 | ])
30 | ->setFinder($finder)
31 | ;
32 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (C) 2016-present Baptiste Leduc
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is furnished
8 | to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in all
11 | copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
20 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # AutoMapper
2 |
3 | The AutoMapper solves a simple problem: removing all the code you need to map one object to another. A boring code to
4 | write and often replaced by less-performant alternatives like Symfony's Serializer.
5 | ## Quick Start 🚀
6 |
7 | ```shell
8 | composer require jolicode/automapper
9 | ```
10 |
11 | You can read more about this library and how to use it on the [documentation](https://jolicode.github.io/automapper/).
12 | ## Support
13 |
14 | For support, please create an issue on [Github tracker](https://github.com/jolicode/automapper/issues)
15 |
--------------------------------------------------------------------------------
/bench/README.md:
--------------------------------------------------------------------------------
1 | # Bench package
2 |
3 | This package benchmarks performance of some PHP operations that allow us to take decision on which one to use.
4 |
--------------------------------------------------------------------------------
/bench/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "automapper/bench",
3 | "require": {
4 | "phpbench/phpbench": "^1.2"
5 | },
6 | "autoload": {
7 | "psr-4": {
8 | "Automapper\\Bench\\": "src/"
9 | }
10 | },
11 | "authors": [
12 | {
13 | "name": "Joel Wurtz",
14 | "email": "jwurtz@jolicode.com"
15 | }
16 | ]
17 | }
18 |
--------------------------------------------------------------------------------
/castor.composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "require": {
3 | "castor-php/php-qa": "0.1.0"
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/docs/_nav.md:
--------------------------------------------------------------------------------
1 | - [Home](index.md)
2 | - [Getting started](getting-started/index.md)
3 | - [Understanding the `source` and `target`](getting-started/source-and-target.md)
4 | - [Using the context](getting-started/context.md)
5 | - [Configuration](getting-started/configuration.md)
6 | - [Cache](getting-started/cache.md)
7 | - [Mapping](mapping/index.md)
8 | - [MapTo and MapFrom attributes](mapping/attributes.md)
9 | - [Symfony Serializer](mapping/serializer.md)
10 | - [Mapping Collections](mapping/map-collection.md)
11 | - [Ignoring properties](mapping/ignoring-properties.md)
12 | - [Conditional mapping](mapping/conditional-mapping.md)
13 | - [Groups](mapping/groups.md)
14 | - [Transformer](mapping/transformer.md)
15 | - [Provider](mapping/provider.md)
16 | - [Mapping inheritance](mapping/inheritance.md)
17 | - [DateTime format](mapping/date-time.md)
18 | - [Symfony Bundle](bundle/index.md)
19 | - [Installation](bundle/installation.md)
20 | - [Configuration](bundle/configuration.md)
21 | - [Cache Warmup](bundle/cache-warmup.md)
22 | - [Expression Language](bundle/expression-language.md)
23 | - [Api Platform](bundle/api-platform.md)
24 | - [Migrate existing application](bundle/migrate.md)
25 | - [Debugging](bundle/debugging.md)
26 | - [Upgrading to 9.0](upgrading-9.0.md)
27 | - [Contributing](contributing.md)
28 |
--------------------------------------------------------------------------------
/docs/assets/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jolicode/automapper/26f9739cc05aa1bd7ade4ccc6117b01029762297/docs/assets/favicon.png
--------------------------------------------------------------------------------
/docs/bundle/api-platform.md:
--------------------------------------------------------------------------------
1 | # Api Platform integration
2 |
3 | > [!WARNING]
4 | > The api platform integration is in a experimental state, and may change in the future.
5 | > Some behavior may not be handled correctly, and some features may not be implemented.
6 | >
7 | > If you find a bug or missing feature, please report it on the [issue tracker](https://github.com/jolicode/automapper/issues).
8 |
9 | This bundle provides a way to integrate with [Api Platform](https://api-platform.com/) by generating the mappers for you.
10 |
11 | It injects extra data in the mappers when we map a Resource class to or from an array.
12 |
13 | You have to enable the `api_platform` option in the configuration to use this feature.
14 |
15 | If you have custom normalizer with some logic inside you will have to convert this logic with our library way of doing things.
16 | [See our migrate guide](migrate.md) for more information.
17 |
--------------------------------------------------------------------------------
/docs/bundle/debugging.md:
--------------------------------------------------------------------------------
1 | # Debug a Mapper
2 |
3 | AutoMapper provides 2 ways to debug what's going on with a mapper when using the Symfony bundle:
4 |
5 | ## The `debug:mapper` Command
6 |
7 | The `debug:mapper` command will display the mapping information for a specific mapper.
8 | This can be useful to understand how AutoMapper is mapping your objects and why some properties are not mapped.
9 |
10 | ```bash
11 | php bin/console debug:mapper User UserDTO
12 | ```
13 |
14 | 
15 |
16 | ## Using the symfony profiler
17 |
18 | AutoMapper provides a panel in the Symfony profiler that will display the mapping information for each request.
19 | Please note that this only display Mapper that has been generated during the request, if you have a mapper that was not
20 | generated during the request it will not be displayed.
21 |
22 | You can find the panel in the Symfony profiler under the `AutoMapper` tab.
23 |
24 | 
25 | 
--------------------------------------------------------------------------------
/docs/bundle/index.md:
--------------------------------------------------------------------------------
1 | # Symfony Bundle
2 |
3 | To make Symfony's users life easier, we made a bundle that will make all DependencyInjection for you and offer extra
4 | features linked to Symfony way of doing things.
5 |
6 | - [Installation](installation.md)
7 | - [Configuration](configuration.md)
8 | - [Cache Warmup](cache-warmup.md)
9 | - [Expression Language](expression-language.md)
10 | - [Api Platform](api-platform.md)
11 | - [Migrate existing application](migrate.md)
12 | - [Debugging](debugging.md)
13 |
--------------------------------------------------------------------------------
/docs/bundle/installation.md:
--------------------------------------------------------------------------------
1 | # Installing the Symfony Bundle
2 |
3 | The bundle is already available on the `jolicode/automapper` package, you don't need to add any packages to your composer.json file.
4 |
5 | ## Registering the bundle
6 |
7 | To use it, you have to register the main bundle class in your `config/bundles.php` file.
8 |
9 | ```php
10 | return [
11 | // ...
12 | AutoMapper\Symfony\Bundle\AutoMapperBundle::class => ['all' => true],
13 | ];
14 | ```
15 |
16 | ## Usage
17 |
18 | Once the bundle is registered, you can use the `AutoMapperInterface` service to map your objects.
19 |
20 | ```php
21 | use AutoMapper\AutoMapperInterface;
22 |
23 | class MyController
24 | {
25 | public function __construct(private AutoMapperInterface $autoMapper)
26 | {
27 | }
28 |
29 | #[Route('/my-route', name: 'my_route')]
30 | public function index()
31 | {
32 | $source = new Source();
33 | $target = $this->autoMapper->map($source, 'array');
34 |
35 | return new JsonResponse($target);
36 | }
37 | }
38 | ```
--------------------------------------------------------------------------------
/docs/contributing.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | ## Releasing
4 |
5 | Whenever you're doing a release you need to do some updates in order for the project to keep history on what was done
6 | and some other stuff.
7 |
8 | ### Changelog
9 |
10 | First you'll need to update the CHANGELOG file (`./CHANGELOG.md`), take everything under the `Unreleased` section and
11 | create a new section for your new tag with the today's date.
12 |
13 | ### Version
14 |
15 | When a new version is tagged, you have to update the version constants within the `AutoMapper/AutoMapper` so
16 | transformers can be updated with last AutoMapper version.
17 |
--------------------------------------------------------------------------------
/docs/getting-started/cache.md:
--------------------------------------------------------------------------------
1 | # Cache
2 |
3 | AutoMapper can uses a cache system to store each Mapper generated for a specific `source` and `target` class.
4 | This way, the Mapper is generated only once and reused for each mapping.
5 |
6 | By default, it will evaluate the generated Mapper, new call inside the same request or cli command will not regenerate the Mapper.
7 |
8 | However, next request or cli command will regenerate the Mapper.
9 |
10 | To avoid regenerating the Mapper, you can use the `cacheDirectory` option in the `AutoMapper::create()` method.
11 |
12 | ```php
13 | use AutoMapper\AutoMapper;
14 |
15 | $autoMapper = AutoMapper::create(cacheDirectory: '/path/to/cache');
16 | ```
17 |
18 | This way, the Mapper will be stored in the `/path/to/cache` directory and reused for each mapping. However, if you change
19 | the `source` or `target` class, the Mapper will be regenerated.
20 |
21 | > [!WARNING]
22 | > Some changes may not be detected by the cache system, like changing a dependency used by the source or target class.
23 | > You may need to clean it manually.
24 | >
25 | > However, we try our best to detect those changes, if you encounter a problem, please open an issue on the GitHub repository.
26 |
--------------------------------------------------------------------------------
/docs/getting-started/index.md:
--------------------------------------------------------------------------------
1 | # Getting started
2 |
3 | - [Understanding the `source` and `target`](source-and-target.md)
4 | - [Using the context](context.md)
5 | - [Configuration](configuration.md)
6 | - [Cache](cache.md)
7 |
--------------------------------------------------------------------------------
/docs/images/debug-cli.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jolicode/automapper/26f9739cc05aa1bd7ade4ccc6117b01029762297/docs/images/debug-cli.png
--------------------------------------------------------------------------------
/docs/images/debug-profiler-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jolicode/automapper/26f9739cc05aa1bd7ade4ccc6117b01029762297/docs/images/debug-profiler-1.png
--------------------------------------------------------------------------------
/docs/images/debug-profiler-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jolicode/automapper/26f9739cc05aa1bd7ade4ccc6117b01029762297/docs/images/debug-profiler-2.png
--------------------------------------------------------------------------------
/docs/mapping/groups.md:
--------------------------------------------------------------------------------
1 | # Groups
2 |
3 | In addition to use the Symfony Serializer `#[Groups]` attribute, you can also use the `#[MapTo]` and `#[MapFrom]`
4 | attributes to define groups of properties that should be mapped.
5 |
6 | ```php
7 | class Source
8 | {
9 | #[MapTo(target: 'array', groups: ['group1', 'group2'])]
10 | public $groupedProperty;
11 | }
12 | ```
13 |
14 | When doing so the property will be mapped only if the context contains at least one group defined in the `groups` argument.
15 |
16 | ### Cumulative groups
17 |
18 | When using both groups from the Symfony Serializer `#[Groups]` attribute and the `groups` argument from the `#[MapTo]`
19 | or `#[MapFrom]` attributes, the latter groups will override the former groups.
20 |
21 | ```php
22 | use Symfony\Component\Serializer\Attribute\Groups;
23 |
24 | class Source
25 | {
26 | #[Groups(['group1', 'group2'])]
27 | #[MapTo(target: 'array', groups: ['group3'])]
28 | public $groupedProperty;
29 | }
30 | ```
31 |
32 | In this case the property will be mapped only if the context contains the `group3` group.
33 |
--------------------------------------------------------------------------------
/docs/mapping/ignoring-properties.md:
--------------------------------------------------------------------------------
1 | # Ignoring properties
2 |
3 | Sometimes you may want to ignore a property during the mapping process. This can be done using the `#[MapTo]` or `#[MapFrom]` attributes
4 | with the `ignore` argument set to `true`.
5 |
6 | ```php
7 | class Source
8 | {
9 | #[MapTo(target: SourceDTO::class, ignore: true)]
10 | #[MapTo(target: 'array', ignore: false)]
11 | public $ignoredProperty;
12 | }
13 | ```
14 |
15 | Setting `ignore` to `false` may be useful when used in conjunction with the `#[Ignore]` attribute from the Symfony Serializer.
16 |
17 | ```php
18 | use Symfony\Component\Serializer\Attribute\Ignore;
19 |
20 | class Source
21 | {
22 | #[Ignore]
23 | #[MapTo(target: SourceDTO::class, ignore: false)]
24 | public $ignoredProperty;
25 | }
26 | ```
27 |
28 | In this case the property will be mapped to the `SourceDTO` class, but will be ignored when using the Symfony Serializer.
29 |
--------------------------------------------------------------------------------
/docs/mapping/index.md:
--------------------------------------------------------------------------------
1 | # Mapping
2 |
3 | Despite doing its best to map objects automatically, AutoMapper provides a lot of ways to customize the mapping between
4 | a `source` and a `target`.
5 |
6 | - [MapTo and MapFrom attributes](attributes.md)
7 | - [Symfony Serializer attributes](serializer.md)
8 | - [Ignoring properties](ignoring-properties.md)
9 | - [Conditional mapping](conditional-mapping.md)
10 | - [Groups](groups.md)
11 | - [Transformer](transformer.md)
12 | - [Provider](provider.md)
13 | - [Mapping inheritance](inheritance.md)
14 | - [DateTime format](date-time.md)
15 |
--------------------------------------------------------------------------------
/docs/mapping/inheritance.md:
--------------------------------------------------------------------------------
1 | # Inheritance Mapping
2 |
3 | A `source` or `target` class may inherit from another class.
4 |
5 | When creating the mapping, AutoMapper can determine the correct mapping by using the inheritance information from
6 | the Symfony Serializer `#[DiscriminatorMap]` attribute.
7 |
8 | ```php
9 | #[DiscriminatorMap(typeProperty: 'type', mapping: [
10 | 'cat' => Cat::class,
11 | 'dog' => Dog::class,
12 | 'fish' => Fish::class,
13 | ])]
14 | abstract class Pet
15 | {
16 | /** @var string */
17 | public $type;
18 |
19 | /** @var string */
20 | public $name;
21 |
22 | /** @var PetOwner */
23 | public $owner;
24 | }
25 | ```
26 |
27 | When mapping a `Pet` object, AutoMapper will automatically determine the correct class to instantiate based on the `type` property.
28 |
29 | [Learn more about the Symfony Serializer inheritance mapping](https://symfony.com/doc/current/components/serializer.html#serializing-interfaces-and-abstract-classes)
30 |
31 | > [!NOTE]
32 | > If you don't use the Symfony Serializer we do not provide, yet, any way to determine the correct class to instantiate.
33 |
--------------------------------------------------------------------------------
/docs/overrides/main.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 |
3 | {% block htmltitle %}
4 | {% if page.meta and page.meta.title %}
5 |
{{ page.meta.title }} - AutoMapper
6 | {% elif page.title and not page.is_homepage %}
7 | {{ page.title | striptags }} - AutoMapper
8 | {% else %}
9 | {{ config.site_name }}
10 | {% endif %}
11 | {% endblock %}
--------------------------------------------------------------------------------
/docs/upgrading-9.0.md:
--------------------------------------------------------------------------------
1 | # Upgrading from 8.x to 9.0
2 |
3 | 9.0 is major release of AutoMapper. It brings a lot of new features and improvements. We recommend first [to check
4 | the new documentation](./index.md) to see if the new features are useful for your project.
5 |
6 | If you upgrade from 8.x to 9.0, you will need to make some changes to your code, but most of existing behavior should
7 | still work.
8 |
9 | ## Bundle
10 |
11 | If you use the bundle, it is now integrated in the main package. You can remove the `jolicode/automapper-bundle` package from your
12 | `composer.json` file.
13 |
14 | Then you have to use the new namespace for the bundle:
15 |
16 | ```php
17 | use AutoMapper\Symfony\Bundle\AutoMapperBundle;
18 | ```
19 |
20 | You will also need to update the bundle configuration, see the [bundle documentation](./bundle/configuration.md) for more
21 | information.
22 |
23 | ## Custom Transformers
24 |
25 | The `CustomPropertyTransformerInterface` and `CustomModelTransformerInterface` have been removed in favor of the
26 | `PropertyTransformerInterface` interface handling both case.
27 |
28 | See the [transformers documentation](./mapping/transformer.md#creating-a-custom-transformer) for more information.
29 |
--------------------------------------------------------------------------------
/phpstan.neon:
--------------------------------------------------------------------------------
1 | includes:
2 | - phpstan-baseline.neon
3 |
4 | parameters:
5 | level: max
6 | paths:
7 | - src/
8 |
9 | tmpDir: cache
10 |
11 | ignoreErrors:
12 | - "#Instantiated class fromIteratorToArray not found#"
13 | - "#Instantiated class toArray not found#"
14 |
15 | -
16 | message: "#^Method Symfony\\\\Component\\\\Serializer\\\\NameConverter\\\\NameConverterInterface\\:\\:normalize\\(\\) invoked with 2 parameters, 1 required\\.$#"
17 | count: 2
18 | path: src/EventListener/Symfony/AdvancedNameConverterListener.php
19 |
--------------------------------------------------------------------------------
/pyproject.toml:
--------------------------------------------------------------------------------
1 | [tool.poetry]
2 | name = "automapper-doc"
3 | version = "0.1.0"
4 | description = "Documentation for jolicode/automapper"
5 | authors = ["Joel Wurtz "]
6 | license = "MIT"
7 | readme = "README.md"
8 | package-mode = false
9 |
10 | [tool.poetry.dependencies]
11 | python = "^3.11"
12 | mkdocs = "^1.5.3"
13 | mkdocs-material = "^9.5.13"
14 | markdown-callouts = "^0.4.0"
15 | mkdocs-literate-nav = "^0.6.1"
16 | mike = "^2.0.0"
17 |
18 |
19 | [build-system]
20 | requires = ["poetry-core"]
21 | build-backend = "poetry.core.masonry.api"
22 |
--------------------------------------------------------------------------------
/src/Attribute/MapProvider.php:
--------------------------------------------------------------------------------
1 | |'array'|array|'array'>|null $source The source class or classes
17 | * @param class-string