├── Tests ├── Fixture │ ├── EmptyDirectory │ │ └── .gitkeep │ ├── NonEmptyDirectory │ │ ├── SubDir1 │ │ │ ├── NonPhpFile.txt │ │ │ └── Service2.php │ │ ├── DummyFile.php │ │ ├── Service1.php │ │ ├── SubDir2 │ │ │ └── Service3.php │ │ └── Service4.php │ ├── NullLogger.php │ ├── Validator │ │ └── Validator.php │ ├── LoginController.php │ └── RequestListener.php ├── DependencyInjection │ ├── Compiler │ │ ├── Fixtures │ │ │ ├── a │ │ │ │ └── b │ │ │ │ │ └── .gitkeep │ │ │ └── c │ │ │ │ └── .gitkeep │ │ ├── ResourceOptimizationPassTest.php │ │ ├── LazyServiceSequencePassTest.php │ │ ├── LazyServiceMapPassTest.php │ │ └── AnnotationConfigurationPassTest.php │ └── Collection │ │ ├── LazyServiceSequenceTest.php │ │ └── LazyServiceMapTest.php ├── Functional │ ├── config │ │ ├── traits.yml │ │ ├── twig.yml │ │ ├── doctrine.yml │ │ ├── routing.yml │ │ ├── automatic_controller_injections.yml │ │ ├── bc_automatic_controller_injections.yml │ │ ├── security.yml │ │ ├── framework.yml │ │ └── default.yml │ ├── Bundle │ │ ├── TestBundle │ │ │ ├── Factory │ │ │ │ └── MyFactory.php │ │ │ ├── JMSDiExtraTestBundle.php │ │ │ ├── Controller │ │ │ │ ├── ServiceController.php │ │ │ │ ├── InvokableServiceController.php │ │ │ │ ├── ExtendedServiceController.php │ │ │ │ ├── AnotherSecuredController.php │ │ │ │ ├── SecuredController.php │ │ │ │ ├── RegisterController.php │ │ │ │ └── AutomaticallyInjectedController.php │ │ │ ├── Mailer │ │ │ │ └── TestMailer.php │ │ │ └── Inheritance │ │ │ │ ├── AbstractClass.php │ │ │ │ └── ConcreteClass.php │ │ └── LegacyTestBundle │ │ │ ├── JMSDiExtraTestBundle.php │ │ │ ├── Controller │ │ │ ├── ServiceController.php │ │ │ ├── InvokableServiceController.php │ │ │ ├── ExtendedServiceController.php │ │ │ ├── AnotherSecuredController.php │ │ │ ├── SecuredController.php │ │ │ ├── RegisterController.php │ │ │ └── AutomaticallyInjectedController.php │ │ │ ├── Mailer │ │ │ └── TestMailer.php │ │ │ └── Inheritance │ │ │ ├── AbstractClass.php │ │ │ └── ConcreteClass.php │ ├── FactoryTest.php │ ├── Traits │ │ ├── ConcreteClassWithTrait.php │ │ └── TemplatableTrait.php │ ├── TraitTest.php │ ├── Issue11Test.php │ ├── Issue48Test.php │ ├── BaseTestCase.php │ ├── AutomaticControllerInjectionsTest.php │ ├── ControllerResolverTest.php │ └── AppKernel.php ├── Metadata │ ├── Driver │ │ ├── Fixture │ │ │ ├── ClassMetaProcessor.php │ │ │ ├── MethodMetaProcessor.php │ │ │ ├── SignUpType.php │ │ │ ├── CustomAnnotation.php │ │ │ ├── Service.php │ │ │ └── LoginType.php │ │ ├── AnnotationDriverTest.php │ │ └── ConfiguredControllerInjectionsDriverTest.php │ └── ClassMetadataTest.php ├── bootstrap.php ├── BaseTestCase.php ├── Finder │ ├── PhpPatternFinderTest.php │ ├── FindstrPatternFinderTest.php │ ├── AbstractPatternFinderTest.php │ └── GrepPatternFinderTest.php └── PerformanceTest.php ├── .gitignore ├── phpunit ├── README.md ├── CHANGELOG.md ├── phpunit.xml.dist ├── Exception ├── InvalidAnnotationException.php ├── Exception.php ├── RuntimeException.php ├── InvalidArgumentException.php └── InvalidTypeException.php ├── Annotation ├── LookupMethod.php ├── Inject.php ├── Validator.php ├── AfterSetup.php ├── InjectParams.php ├── FormType.php ├── Reference.php ├── Observe.php ├── Tag.php ├── DoctrineListener.php ├── DoctrineMongoDBListener.php ├── SecurityFunction.php ├── MetadataProcessorInterface.php ├── AbstractDoctrineListener.php └── Service.php ├── DependencyInjection ├── LookupMethodClassInterface.php ├── Collection │ ├── LazySequenceIterator.php │ ├── LazyServiceSequence.php │ └── LazyServiceMap.php └── Compiler │ ├── LazyServiceSequencePass.php │ ├── ResourceOptimizationPass.php │ ├── IntegrationPass.php │ └── LazyServiceMapPass.php ├── Metadata ├── NamingStrategy.php ├── DefaultNamingStrategy.php ├── Driver │ └── ConfiguredControllerInjectionsDriver.php └── ClassMetadata.php ├── .php_cs.dist ├── Resources ├── doc │ ├── index.rst │ ├── installation.rst │ ├── doctrine.rst │ ├── usage.rst │ ├── configuration.rst │ └── lazy_service_collections.rst └── config │ └── services.xml ├── Config ├── InternalResource.php ├── ServiceFilesResource.php └── FastDirectoriesResource.php ├── .travis.yml ├── JMSDiExtraBundle.php ├── composer.json ├── Generator ├── NameGenerator.php ├── LookupMethodClassGenerator.php └── RepositoryInjectionGenerator.php └── HttpKernel └── ControllerInjectorsWarmer.php /Tests/Fixture/EmptyDirectory/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Tests/DependencyInjection/Compiler/Fixtures/a/b/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Tests/DependencyInjection/Compiler/Fixtures/c/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | vendor 2 | composer.lock 3 | .phpunit 4 | .php_cs.cache 5 | -------------------------------------------------------------------------------- /Tests/Functional/config/traits.yml: -------------------------------------------------------------------------------- 1 | jms_di_extra: 2 | locations: 3 | directories: ["%kernel.root_dir%/Traits"] 4 | -------------------------------------------------------------------------------- /Tests/Functional/config/twig.yml: -------------------------------------------------------------------------------- 1 | framework: 2 | templating: 3 | engines: [twig, php] 4 | 5 | twig: 6 | debug: "%kernel.debug%" 7 | strict_variables: "%kernel.debug%" 8 | -------------------------------------------------------------------------------- /Tests/Fixture/NonEmptyDirectory/SubDir1/NonPhpFile.txt: -------------------------------------------------------------------------------- 1 | markTestSkipped('Requires PHP 7.0'); 13 | } 14 | 15 | $this->createClient(); 16 | $container = self::$kernel->getContainer(); 17 | 18 | $service = $container->get('factory_generic_service'); 19 | $this->assertInstanceOf('stdClass', $service); 20 | } 21 | } -------------------------------------------------------------------------------- /Tests/Fixture/NonEmptyDirectory/DummyFile.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | -------------------------------------------------------------------------------- /phpunit.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 14 | 15 | 16 | 17 | ./Tests 18 | 19 | 20 | 21 | 22 | 23 | performance 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Exception/InvalidAnnotationException.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Exception; 20 | 21 | class InvalidAnnotationException extends \InvalidArgumentException implements Exception 22 | { 23 | } 24 | -------------------------------------------------------------------------------- /Annotation/LookupMethod.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Annotation; 20 | 21 | /** 22 | * @Annotation 23 | * @Target("METHOD") 24 | */ 25 | final class LookupMethod extends Reference 26 | { 27 | } 28 | -------------------------------------------------------------------------------- /Annotation/Inject.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Annotation; 20 | 21 | /** 22 | * @Annotation 23 | * @Target({"PROPERTY", "ANNOTATION"}) 24 | */ 25 | final class Inject extends Reference 26 | { 27 | } 28 | -------------------------------------------------------------------------------- /Tests/Fixture/NonEmptyDirectory/Service1.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Tests\Fixture\NonEmptyDirectory; 20 | 21 | use JMS\DiExtraBundle\Annotation as DI; 22 | 23 | /** @DI\Service */ 24 | class Service1 25 | { 26 | } 27 | -------------------------------------------------------------------------------- /Tests/Metadata/Driver/Fixture/ClassMetaProcessor.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Tests\Metadata\Driver\Fixture; 20 | 21 | /** 22 | * @CustomAnnotation(value="works") 23 | */ 24 | class ClassMetaProcessor 25 | { 26 | } 27 | -------------------------------------------------------------------------------- /DependencyInjection/LookupMethodClassInterface.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\DependencyInjection; 20 | 21 | interface LookupMethodClassInterface 22 | { 23 | public function __jmsDiExtra_getOriginalClassName(); 24 | } 25 | -------------------------------------------------------------------------------- /Annotation/Validator.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Annotation; 20 | 21 | /** 22 | * @Annotation 23 | * @Target("CLASS") 24 | */ 25 | final class Validator 26 | { 27 | /** @var string @Required */ 28 | public $alias; 29 | } 30 | -------------------------------------------------------------------------------- /Tests/Fixture/NonEmptyDirectory/SubDir1/Service2.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Tests\Fixture\NonEmptyDirectory\SubDir1; 20 | 21 | use JMS\DiExtraBundle\Annotation\Service; 22 | 23 | /** @Service */ 24 | class Service2 25 | { 26 | } 27 | -------------------------------------------------------------------------------- /Tests/Fixture/NonEmptyDirectory/SubDir2/Service3.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Tests\Fixture\NonEmptyDirectory\SubDir2; 20 | 21 | use JMS\DiExtraBundle\Annotation as DI; 22 | 23 | /** @DI\Service */ 24 | class Service1 25 | { 26 | } 27 | -------------------------------------------------------------------------------- /Exception/Exception.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Exception; 20 | 21 | /** 22 | * Base exception for the DiExtraBundle. 23 | * 24 | * @author Johannes M. Schmitt 25 | */ 26 | interface Exception 27 | { 28 | } 29 | -------------------------------------------------------------------------------- /Tests/Fixture/NonEmptyDirectory/Service4.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Tests\Fixture\NonEmptyDirectory { 20 | use JMS\DiExtraBundle\Annotation as DI; 21 | 22 | /** @DI\Service */ 23 | class Service4 24 | { 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Annotation/AfterSetup.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Annotation; 20 | 21 | /** 22 | * @Annotation 23 | * @Target("METHOD") 24 | * 25 | * @author Johannes M. Schmitt 26 | */ 27 | final class AfterSetup 28 | { 29 | } 30 | -------------------------------------------------------------------------------- /Tests/Functional/Bundle/TestBundle/JMSDiExtraTestBundle.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Tests\Functional\Bundle\TestBundle; 20 | 21 | use Symfony\Component\HttpKernel\Bundle\Bundle; 22 | 23 | class JMSDiExtraTestBundle extends Bundle 24 | { 25 | } 26 | -------------------------------------------------------------------------------- /Tests/Functional/Bundle/LegacyTestBundle/JMSDiExtraTestBundle.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Tests\Functional\Bundle\LegacyTestBundle; 20 | 21 | use Symfony\Component\HttpKernel\Bundle\Bundle; 22 | 23 | class JMSDiExtraTestBundle extends Bundle 24 | { 25 | } 26 | -------------------------------------------------------------------------------- /Annotation/InjectParams.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Annotation; 20 | 21 | /** 22 | * @Annotation 23 | * @Target("METHOD") 24 | */ 25 | final class InjectParams 26 | { 27 | /** @var array */ 28 | public $params = array(); 29 | } 30 | -------------------------------------------------------------------------------- /Annotation/FormType.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Annotation; 20 | 21 | /** 22 | * @Annotation 23 | * @Target("CLASS") 24 | * 25 | * @author Johannes M. Schmitt 26 | */ 27 | final class FormType 28 | { 29 | /** @var string */ 30 | public $alias; 31 | } 32 | -------------------------------------------------------------------------------- /Annotation/Reference.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Annotation; 20 | 21 | abstract class Reference 22 | { 23 | /** @var string */ 24 | public $value; 25 | 26 | /** @var bool */ 27 | public $required; 28 | 29 | /** @var bool */ 30 | public $strict = true; 31 | } 32 | -------------------------------------------------------------------------------- /Annotation/Observe.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Annotation; 20 | 21 | /** 22 | * @Annotation 23 | * @Target("METHOD") 24 | */ 25 | final class Observe 26 | { 27 | /** @var string @Required */ 28 | public $event; 29 | 30 | /** @var int */ 31 | public $priority = 0; 32 | } 33 | -------------------------------------------------------------------------------- /Annotation/Tag.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Annotation; 20 | 21 | /** 22 | * @Annotation 23 | * @Target("CLASS") 24 | */ 25 | final class Tag 26 | { 27 | /** @var string @Required */ 28 | public $name; 29 | 30 | /** @var array */ 31 | public $attributes = array(); 32 | } 33 | -------------------------------------------------------------------------------- /Exception/RuntimeException.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Exception; 20 | 21 | /** 22 | * RuntimeException for the DiExtraBundle. 23 | * 24 | * @author Johannes M. Schmitt 25 | */ 26 | class RuntimeException extends \RuntimeException implements Exception 27 | { 28 | } 29 | -------------------------------------------------------------------------------- /Tests/Metadata/Driver/Fixture/MethodMetaProcessor.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Tests\Metadata\Driver\Fixture; 20 | 21 | class MethodMetaProcessor 22 | { 23 | /** 24 | * @CustomAnnotation(key="omg", value="fancy") 25 | */ 26 | public function test() 27 | { 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Tests/Functional/Traits/ConcreteClassWithTrait.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Tests\Functional\Traits; 20 | 21 | use JMS\DiExtraBundle\Annotation as DI; 22 | 23 | /** 24 | * @DI\Service("concrete_class_with_trait") 25 | */ 26 | class ConcreteClassWithTrait 27 | { 28 | use TemplatableTrait; 29 | } 30 | -------------------------------------------------------------------------------- /Annotation/DoctrineListener.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Annotation; 20 | 21 | /** 22 | * @Annotation 23 | * @Target("CLASS") 24 | */ 25 | class DoctrineListener extends AbstractDoctrineListener 26 | { 27 | public function getTag() 28 | { 29 | return 'doctrine.event_listener'; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Exception/InvalidArgumentException.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Exception; 20 | 21 | /** 22 | * InvalidArgumentException for the DiExtraBundle. 23 | * 24 | * @author Johannes M. Schmitt 25 | */ 26 | class InvalidArgumentException extends \InvalidArgumentException implements Exception 27 | { 28 | } 29 | -------------------------------------------------------------------------------- /Annotation/DoctrineMongoDBListener.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Annotation; 20 | 21 | /** 22 | * @Annotation 23 | * @Target("CLASS") 24 | */ 25 | class DoctrineMongoDBListener extends AbstractDoctrineListener 26 | { 27 | public function getTag() 28 | { 29 | return 'doctrine_mongodb.odm.event_listener'; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Annotation/SecurityFunction.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Annotation; 20 | 21 | /** 22 | * @Annotation 23 | * @Target("METHOD") 24 | * 25 | * @author Johannes M. Schmitt 26 | */ 27 | final class SecurityFunction 28 | { 29 | /** 30 | * @Required 31 | * 32 | * @var string 33 | */ 34 | public $function; 35 | } 36 | -------------------------------------------------------------------------------- /Metadata/NamingStrategy.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Metadata; 20 | 21 | interface NamingStrategy 22 | { 23 | /** 24 | * Returns a service name for an annotated class. 25 | * 26 | * @param string $className the fully-qualified class name 27 | * 28 | * @return string a service name 29 | */ 30 | public function classToServiceName($className); 31 | } 32 | -------------------------------------------------------------------------------- /.php_cs.dist: -------------------------------------------------------------------------------- 1 | in(__DIR__) 5 | ->exclude('Tests/Functional/cache') 6 | ; 7 | 8 | return PhpCsFixer\Config::create() 9 | ->setRules([ 10 | '@Symfony' => true, 11 | 'ordered_imports' => true, 12 | 'phpdoc_order' => true, 13 | 'header_comment' => [ 14 | 'header' => <<
16 | 17 | Licensed under the Apache License, Version 2.0 (the "License"); 18 | you may not use this file except in compliance with the License. 19 | You may obtain a copy of the License at 20 | 21 | http://www.apache.org/licenses/LICENSE-2.0 22 | 23 | Unless required by applicable law or agreed to in writing, software 24 | distributed under the License is distributed on an "AS IS" BASIS, 25 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 26 | See the License for the specific language governing permissions and 27 | limitations under the License. 28 | HEADER 29 | ], 30 | ]) 31 | ->setFinder($finder) 32 | ; 33 | -------------------------------------------------------------------------------- /Tests/Functional/Bundle/TestBundle/Controller/ServiceController.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Tests\Functional\Bundle\TestBundle\Controller; 20 | 21 | use Symfony\Component\Routing\RouterInterface; 22 | 23 | abstract class ServiceController 24 | { 25 | public function __construct(RouterInterface $router) 26 | { 27 | // Dummy constructor injection, to make sure inheritance works 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Tests/Functional/Bundle/LegacyTestBundle/Controller/ServiceController.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Tests\Functional\Bundle\LegacyTestBundle\Controller; 20 | 21 | use Symfony\Component\Routing\RouterInterface; 22 | 23 | abstract class ServiceController 24 | { 25 | public function __construct(RouterInterface $router) 26 | { 27 | // Dummy constructor injection, to make sure inheritance works 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Tests/bootstrap.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | use Doctrine\Common\Annotations\AnnotationRegistry; 20 | 21 | // Composer 22 | if (file_exists(__DIR__.'/../vendor/autoload.php')) { 23 | $loader = require_once __DIR__.'/../vendor/autoload.php'; 24 | 25 | AnnotationRegistry::registerLoader('class_exists'); 26 | 27 | return $loader; 28 | } 29 | 30 | throw new \RuntimeException('Could not find vendor/autoload.php, make sure you ran composer.'); 31 | -------------------------------------------------------------------------------- /Tests/BaseTestCase.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Tests; 20 | 21 | use PHPUnit\Framework\TestCase; 22 | 23 | abstract class BaseTestCase extends TestCase 24 | { 25 | final protected function createMock($class) 26 | { 27 | if (method_exists('PHPUnit\Framework\TestCase', 'createMock')) { 28 | return parent::createMock($class); 29 | } 30 | return $this->getMock($class); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Tests/Functional/Bundle/TestBundle/Mailer/TestMailer.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Tests\Functional\Bundle\TestBundle\Mailer; 20 | 21 | use JMS\DiExtraBundle\Annotation as DI; 22 | 23 | /** 24 | * @DI\Service("test_mailer") 25 | * 26 | * @author Johannes M. Schmitt 27 | */ 28 | class TestMailer 29 | { 30 | public function getFromMail() 31 | { 32 | return 'foo@bar.de'; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Tests/Functional/Bundle/LegacyTestBundle/Mailer/TestMailer.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Tests\Functional\Bundle\LegacyTestBundle\Mailer; 20 | 21 | use JMS\DiExtraBundle\Annotation as DI; 22 | 23 | /** 24 | * @DI\Service("test_mailer") 25 | * 26 | * @author Johannes M. Schmitt 27 | */ 28 | class TestMailer 29 | { 30 | public function getFromMail() 31 | { 32 | return 'foo@bar.de'; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Tests/Fixture/NullLogger.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Tests\Fixture; 20 | 21 | use Psr\Log\NullLogger as PsrNullLogger; 22 | use Symfony\Component\HttpKernel\Log\NullLogger as SfNullLogger; 23 | 24 | if (class_exists('JMS\SecurityExtraBundle\DependencyInjection\Compiler\SecurityCompatibilityPass')) { 25 | class NullLogger extends PsrNullLogger 26 | { 27 | } 28 | } else { 29 | class NullLogger extends SfNullLogger 30 | { 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Exception/InvalidTypeException.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Exception; 20 | 21 | class InvalidTypeException extends InvalidArgumentException 22 | { 23 | public function __construct($annotName, $attrName, $expected, $actual) 24 | { 25 | $msg = sprintf('The attribute "%s" on annotation "@%s" is expected to be of type %s, but got %s.', $attrName, $annotName, $expected, gettype($actual)); 26 | 27 | parent::__construct($msg); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Tests/Functional/Bundle/TestBundle/Controller/InvokableServiceController.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Tests\Functional\Bundle\TestBundle\Controller; 20 | 21 | use JMS\DiExtraBundle\Annotation as DI; 22 | use Symfony\Component\HttpFoundation\Response; 23 | 24 | /** 25 | * @DI\Service("controller.invokable") 26 | */ 27 | class InvokableServiceController 28 | { 29 | public function __invoke() 30 | { 31 | return new Response('invoked'); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Tests/Functional/Bundle/LegacyTestBundle/Controller/InvokableServiceController.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Tests\Functional\Bundle\LegacyTestBundle\Controller; 20 | 21 | use JMS\DiExtraBundle\Annotation as DI; 22 | use Symfony\Component\HttpFoundation\Response; 23 | 24 | /** 25 | * @DI\Service("controller.invokable") 26 | */ 27 | class InvokableServiceController 28 | { 29 | public function __invoke() 30 | { 31 | return new Response('invoked'); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Tests/Functional/Bundle/TestBundle/Controller/ExtendedServiceController.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Tests\Functional\Bundle\TestBundle\Controller; 20 | 21 | use JMS\DiExtraBundle\Annotation as DI; 22 | use Symfony\Component\HttpFoundation\Response; 23 | 24 | /** 25 | * @DI\Service("controller.extended_hello", parent = "controller.hello") 26 | */ 27 | class ExtendedServiceController extends ServiceController 28 | { 29 | public function helloAction() 30 | { 31 | return new Response('hello'); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Resources/doc/index.rst: -------------------------------------------------------------------------------- 1 | JMSDiExtraBundle 2 | ================ 3 | 4 | Introduction 5 | ------------ 6 | 7 | JMSDiExtraBundle adds more powerful dependency injection features to Symfony2: 8 | 9 | - configure dependency injection via annotations 10 | - convention-based dependency injection in controllers 11 | - aspect-oriented programming capabilities for controllers 12 | 13 | Documentation 14 | ------------- 15 | 16 | .. toctree :: 17 | :hidden: 18 | 19 | installation 20 | configuration 21 | usage 22 | doctrine 23 | annotations 24 | 25 | - :doc:`Installation ` 26 | - :doc:`Configuration ` 27 | - :doc:`Usage ` 28 | - :doc:`Doctrine Integration ` 29 | - :doc:`Annotations ` 30 | - :doc:`Lazy Service Collections ` 31 | 32 | License 33 | ------- 34 | 35 | The code is released under the business-friendly `Apache2 license`_. 36 | 37 | Documentation is subject to the `Attribution-NonCommercial-NoDerivs 3.0 Unported 38 | license`_. 39 | 40 | .. _Apache2 license: http://www.apache.org/licenses/LICENSE-2.0.html 41 | .. _Attribution-NonCommercial-NoDerivs 3.0 Unported license: http://creativecommons.org/licenses/by-nc-nd/3.0/ 42 | 43 | -------------------------------------------------------------------------------- /Tests/Metadata/Driver/Fixture/SignUpType.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Tests\Metadata\Driver\Fixture; 20 | 21 | use JMS\DiExtraBundle as DI; 22 | use Symfony\Component\Form\AbstractType; 23 | 24 | /** 25 | * @DI\Annotation\FormType("foo") 26 | * 27 | * @author johannes 28 | */ 29 | class SignUpType extends AbstractType 30 | { 31 | public function getName() 32 | { 33 | return $this->getBlockPrefix(); 34 | } 35 | 36 | public function getBlockPrefix() 37 | { 38 | return 'sign_up'; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Annotation/MetadataProcessorInterface.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Annotation; 20 | 21 | use JMS\DiExtraBundle\Metadata\ClassMetadata; 22 | 23 | /** 24 | * enable custom annotations for dependency injection. 25 | * 26 | * this can be used for both method and class annotations 27 | */ 28 | interface MetadataProcessorInterface 29 | { 30 | /** 31 | * handle custom metadata for annotation. 32 | * 33 | * @param ClassMetadata $metadata 34 | */ 35 | public function processMetadata(ClassMetadata $metadata); 36 | } 37 | -------------------------------------------------------------------------------- /Tests/Functional/Bundle/LegacyTestBundle/Controller/ExtendedServiceController.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Tests\Functional\Bundle\LegacyTestBundle\Controller; 20 | 21 | use JMS\DiExtraBundle\Annotation as DI; 22 | use Symfony\Component\HttpFoundation\Response; 23 | 24 | /** 25 | * @DI\Service("controller.extended_hello", parent = "controller.hello") 26 | */ 27 | class ExtendedServiceController extends ServiceController 28 | { 29 | public function helloAction() 30 | { 31 | return new Response('hello'); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Annotation/AbstractDoctrineListener.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Annotation; 20 | 21 | abstract class AbstractDoctrineListener 22 | { 23 | /** @var array @Required */ 24 | public $events; 25 | 26 | /** @var string */ 27 | public $connection = 'default'; 28 | 29 | /** @var bool */ 30 | public $lazy = true; 31 | 32 | /** @var int */ 33 | public $priority = 0; 34 | 35 | /** 36 | * Returns the DI tag name. 37 | * 38 | * @return string 39 | */ 40 | abstract public function getTag(); 41 | } 42 | -------------------------------------------------------------------------------- /Tests/Finder/PhpPatternFinderTest.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Tests\Finder; 20 | 21 | use JMS\DiExtraBundle\Finder\PatternFinder; 22 | 23 | class PhpPatternFinderTest extends AbstractPatternFinderTest 24 | { 25 | protected function getFinder() 26 | { 27 | $finder = new PatternFinder('JMS\DiExtraBundle\Annotation'); 28 | $ref = new \ReflectionProperty($finder, 'method'); 29 | $ref->setAccessible(true); 30 | $ref->setValue($finder, PatternFinder::METHOD_FINDER); 31 | 32 | return $finder; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Metadata/DefaultNamingStrategy.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Metadata; 20 | 21 | class DefaultNamingStrategy implements NamingStrategy 22 | { 23 | /** 24 | * Returns a service name for an annotated class. 25 | * 26 | * @param string $name the fully-qualified class name 27 | * 28 | * @return string a service name 29 | */ 30 | public function classToServiceName($name) 31 | { 32 | $name = preg_replace('/(?<=[a-zA-Z0-9])[A-Z]/', '_\\0', $name); 33 | 34 | return strtolower(strtr($name, '\\', '.')); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Tests/Functional/TraitTest.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Tests\Functional; 20 | 21 | class TraitTest extends BaseTestCase 22 | { 23 | /** 24 | * @requires PHP 5.4.0 25 | * @runInSeparateProcess 26 | */ 27 | public function testInjectionFromTrait() 28 | { 29 | $this->createClient(); 30 | 31 | $container = self::$kernel->getContainer(); 32 | $classWithTrait = $container->get('concrete_class_with_trait'); 33 | $templating = $container->get('templating'); 34 | 35 | $this->assertSame($templating, $classWithTrait->getTemplating()); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Tests/Functional/Traits/TemplatableTrait.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Tests\Functional\Traits; 20 | 21 | use JMS\DiExtraBundle\Annotation as DI; 22 | use Symfony\Component\Templating\EngineInterface; 23 | 24 | trait TemplatableTrait 25 | { 26 | private $templating; 27 | 28 | /** 29 | * @DI\InjectParams 30 | * 31 | * @param EngineInterface $templating 32 | */ 33 | public function setTemplating(EngineInterface $templating) 34 | { 35 | $this->templating = $templating; 36 | } 37 | 38 | public function getTemplating() 39 | { 40 | return $this->templating; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Tests/Functional/Bundle/TestBundle/Controller/AnotherSecuredController.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Tests\Functional\Bundle\TestBundle\Controller; 20 | 21 | use JMS\SecurityExtraBundle\Annotation\Secure; 22 | use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; 23 | 24 | /** 25 | * Secured Controller. 26 | * 27 | * @author Johannes M. Schmitt 28 | */ 29 | class AnotherSecuredController 30 | { 31 | /** 32 | * @Route("/secure-action") 33 | * @Secure("ROLE_FOO") 34 | */ 35 | public function secureAction() 36 | { 37 | throw new \Exception('Should never be called'); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Tests/Functional/Bundle/LegacyTestBundle/Controller/AnotherSecuredController.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Tests\Functional\Bundle\LegacyTestBundle\Controller; 20 | 21 | use JMS\SecurityExtraBundle\Annotation\Secure; 22 | use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; 23 | 24 | /** 25 | * Secured Controller. 26 | * 27 | * @author Johannes M. Schmitt 28 | */ 29 | class AnotherSecuredController 30 | { 31 | /** 32 | * @Route("/secure-action") 33 | * @Secure("ROLE_FOO") 34 | */ 35 | public function secureAction() 36 | { 37 | throw new \Exception('Should never be called'); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Tests/Metadata/Driver/Fixture/CustomAnnotation.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Tests\Metadata\Driver\Fixture; 20 | 21 | use JMS\DiExtraBundle\Annotation\MetadataProcessorInterface; 22 | use JMS\DiExtraBundle\Metadata\ClassMetadata; 23 | 24 | /** 25 | * @Annotation 26 | */ 27 | class CustomAnnotation implements MetadataProcessorInterface 28 | { 29 | public $key = 'custom'; 30 | public $value; 31 | 32 | /** 33 | * handle custom metadata for annotation. 34 | * 35 | * @param ClassMetadata $metadata 36 | */ 37 | public function processMetadata(ClassMetadata $metadata) 38 | { 39 | $metadata->tags[$this->key] = $this->value; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Config/InternalResource.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Config; 20 | 21 | use Symfony\Component\Config\Resource\ResourceInterface; 22 | use Symfony\Component\Config\Resource\SelfCheckingResourceInterface; 23 | 24 | // BC for sf < 2.8 25 | if (interface_exists('Symfony\Component\Config\Resource\SelfCheckingResourceInterface')) { 26 | /** 27 | * @internal do not use this class 28 | */ 29 | abstract class InternalResource implements ResourceInterface, SelfCheckingResourceInterface 30 | { 31 | } 32 | } else { 33 | /** 34 | * @internal do not use this class 35 | */ 36 | abstract class InternalResource implements ResourceInterface 37 | { 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Tests/Metadata/Driver/Fixture/Service.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Tests\Metadata\Driver\Fixture; 20 | 21 | use JMS\DiExtraBundle\Annotation as DI; // Use this alias in order to not have this class picked up by the finder 22 | 23 | /** 24 | * @DI\Service( 25 | * id="test.service", 26 | * environments={"dev", "test"}, 27 | * decorates="test.service", 28 | * decorationInnerName="original.test.service", 29 | * deprecated="use new.test.service instead", 30 | * public=false, 31 | * autowire=false, 32 | * autowiringTypes={"JMS\DiExtraBundle\Tests\Metadata\Driver\Fixture\Service"} 33 | * ) 34 | * 35 | * @author wodka 36 | */ 37 | class Service 38 | { 39 | } 40 | -------------------------------------------------------------------------------- /Tests/Finder/FindstrPatternFinderTest.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Tests\Finder; 20 | 21 | use JMS\DiExtraBundle\Finder\PatternFinder; 22 | 23 | class FindstrPatternFinderTest extends AbstractPatternFinderTest 24 | { 25 | protected function getFinder() 26 | { 27 | if (0 !== stripos(PHP_OS, 'win')) { 28 | $this->markTestSkipped('FINDSTR is only available on Windows.'); 29 | } 30 | 31 | $finder = new PatternFinder('JMS\DiExtraBundle\Annotation'); 32 | $ref = new \ReflectionProperty($finder, 'method'); 33 | $ref->setAccessible(true); 34 | $ref->setValue($finder, PatternFinder::METHOD_FINDSTR); 35 | 36 | return $finder; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Tests/Functional/Bundle/TestBundle/Controller/SecuredController.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Tests\Functional\Bundle\TestBundle\Controller; 20 | 21 | use JMS\DiExtraBundle\Annotation as DI; 22 | use JMS\SecurityExtraBundle\Annotation\Secure; 23 | use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; 24 | 25 | /** 26 | * @author Johannes M. Schmitt 27 | */ 28 | class SecuredController 29 | { 30 | /** 31 | * @Route("/lookup-method-and-aop") 32 | * @Secure("ROLE_FOO") 33 | */ 34 | public function secureAction() 35 | { 36 | throw new \Exception('Should never be called'); 37 | } 38 | 39 | /** @DI\LookupMethod */ 40 | protected function getTestMailer() 41 | { 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Tests/Functional/Bundle/LegacyTestBundle/Controller/SecuredController.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Tests\Functional\Bundle\LegacyTestBundle\Controller; 20 | 21 | use JMS\DiExtraBundle\Annotation as DI; 22 | use JMS\SecurityExtraBundle\Annotation\Secure; 23 | use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; 24 | 25 | /** 26 | * @author Johannes M. Schmitt 27 | */ 28 | class SecuredController 29 | { 30 | /** 31 | * @Route("/lookup-method-and-aop") 32 | * @Secure("ROLE_FOO") 33 | */ 34 | public function secureAction() 35 | { 36 | throw new \Exception('Should never be called'); 37 | } 38 | 39 | /** @DI\LookupMethod */ 40 | protected function getTestMailer() 41 | { 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Tests/Functional/Bundle/TestBundle/Inheritance/AbstractClass.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Tests\Functional\Bundle\TestBundle\Inheritance; 20 | 21 | use JMS\DiExtraBundle\Annotation as DI; 22 | use Symfony\Component\Templating\EngineInterface; 23 | 24 | /** 25 | * @DI\Service("abstract_class") 26 | * 27 | * @author johannes 28 | */ 29 | abstract class AbstractClass 30 | { 31 | private $templating; 32 | 33 | /** 34 | * @DI\InjectParams 35 | * 36 | * @param EngineInterface $templating 37 | */ 38 | public function setTemplating(EngineInterface $templating) 39 | { 40 | $this->templating = $templating; 41 | } 42 | 43 | public function getTemplating() 44 | { 45 | return $this->templating; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Tests/Functional/Bundle/LegacyTestBundle/Inheritance/AbstractClass.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Tests\Functional\Bundle\LegacyTestBundle\Inheritance; 20 | 21 | use JMS\DiExtraBundle\Annotation as DI; 22 | use Symfony\Component\Templating\EngineInterface; 23 | 24 | /** 25 | * @DI\Service("abstract_class") 26 | * 27 | * @author johannes 28 | */ 29 | abstract class AbstractClass 30 | { 31 | private $templating; 32 | 33 | /** 34 | * @DI\InjectParams 35 | * 36 | * @param EngineInterface $templating 37 | */ 38 | public function setTemplating(EngineInterface $templating) 39 | { 40 | $this->templating = $templating; 41 | } 42 | 43 | public function getTemplating() 44 | { 45 | return $this->templating; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Tests/Functional/Issue11Test.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Tests\Functional; 20 | 21 | class Issue11Test extends BaseTestCase 22 | { 23 | /** 24 | * @runInSeparateProcess 25 | */ 26 | public function testConstructorInjectionWithInheritance() 27 | { 28 | $this->createClient(); 29 | 30 | $container = self::$kernel->getContainer(); 31 | $foo = $container->get('foo'); 32 | $bar = $container->get('bar'); 33 | $templating = $container->get('templating'); 34 | 35 | $concreteService = $container->get('concrete_class'); 36 | $this->assertSame($templating, $concreteService->getTemplating()); 37 | $this->assertSame($foo, $concreteService->getFoo()); 38 | $this->assertSame($bar, $concreteService->getBar()); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Resources/doc/installation.rst: -------------------------------------------------------------------------------- 1 | Installation 2 | ============ 3 | 4 | .. note :: 5 | 6 | This version is not compatible with Symfony 2.0.x anymore. Please use an 7 | older version of this bundle if you are still on the 2.0 series. 8 | 9 | JMSDiExtraBundle can be conveniently installed via Composer. Just add the 10 | following to your `composer.json` file: 11 | 12 | .. code-block :: js 13 | 14 | // composer.json 15 | { 16 | // ... 17 | require: { 18 | // ... 19 | "jms/di-extra-bundle": "dev-master" 20 | } 21 | } 22 | 23 | .. note :: 24 | 25 | Please replace `dev-master` in the snippet above with the latest stable 26 | branch, for example ``1.0.*``. Please check the tags on Github for which 27 | versions are available. 28 | 29 | Then, you can install the new dependencies by running Composer's ``update`` 30 | command from the directory where your ``composer.json`` file is located: 31 | 32 | .. code-block :: bash 33 | 34 | php composer.phar update 35 | 36 | Now, Composer will automatically download all required files, and install them 37 | for you. All that is left to do is to update your ``AppKernel.php`` file, and 38 | register the new bundle: 39 | 40 | .. code-block :: php 41 | 42 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Tests\Functional\Bundle\TestBundle\Controller; 20 | 21 | use JMS\DiExtraBundle\Annotation as DI; 22 | use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; 23 | use Symfony\Component\HttpFoundation\Response; 24 | 25 | /** 26 | * @author Johannes M. Schmitt 27 | */ 28 | class RegisterController 29 | { 30 | /** 31 | * @Route("/register") 32 | */ 33 | public function registerAction() 34 | { 35 | $mailer = $this->getMailer(); 36 | 37 | return new Response($mailer->getFromMail(), 200, array('Content-Type' => 'text/plain')); 38 | } 39 | 40 | /** @DI\LookupMethod("test_mailer") */ 41 | protected function getMailer() 42 | { 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Tests/Fixture/Validator/Validator.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Tests\Fixture\Validator; 20 | 21 | use JMS\DiExtraBundle\Annotation\InjectParams; 22 | use JMS\DiExtraBundle\Annotation\Validator as ValidatorAnnot; 23 | use Symfony\Component\Validator\Constraint; 24 | use Symfony\Component\Validator\ConstraintValidator; 25 | 26 | /** 27 | * @ValidatorAnnot("foobar") 28 | */ 29 | class Validator extends ConstraintValidator 30 | { 31 | private $foo; 32 | 33 | /** 34 | * @InjectParams 35 | */ 36 | public function __construct($foo) 37 | { 38 | $this->foo = $foo; 39 | } 40 | 41 | public function isValid($value, Constraint $constraint) 42 | { 43 | return true; 44 | } 45 | 46 | public function validate($value, Constraint $constraint) 47 | { 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Tests/Functional/Issue48Test.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Tests\Functional; 20 | 21 | class Issue48Test extends BaseTestCase 22 | { 23 | /** 24 | * @runInSeparateProcess 25 | */ 26 | public function testCreatingMultipleKernelsInATest() 27 | { 28 | $kernelA = static::createKernel(array('debug' => false, 'config' => 'doctrine.yml')); 29 | $kernelA->boot(); 30 | 31 | $kernelB = static::createKernel(array('debug' => true, 'config' => 'doctrine.yml')); 32 | $kernelB->boot(); 33 | 34 | $this->assertInstanceOf('Doctrine\ORM\EntityManager', $kernelA->getContainer()->get('doctrine.orm.default_entity_manager')); 35 | $this->assertInstanceOf('Doctrine\ORM\EntityManager', $kernelB->getContainer()->get('doctrine.orm.default_entity_manager')); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Tests/Functional/Bundle/LegacyTestBundle/Controller/RegisterController.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Tests\Functional\Bundle\LegacyTestBundle\Controller; 20 | 21 | use JMS\DiExtraBundle\Annotation as DI; 22 | use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; 23 | use Symfony\Component\HttpFoundation\Response; 24 | 25 | /** 26 | * @author Johannes M. Schmitt 27 | */ 28 | class RegisterController 29 | { 30 | /** 31 | * @Route("/register") 32 | */ 33 | public function registerAction() 34 | { 35 | $mailer = $this->getMailer(); 36 | 37 | return new Response($mailer->getFromMail(), 200, array('Content-Type' => 'text/plain')); 38 | } 39 | 40 | /** @DI\LookupMethod("test_mailer") */ 41 | protected function getMailer() 42 | { 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Tests/Metadata/Driver/Fixture/LoginType.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Tests\Metadata\Driver\Fixture; 20 | 21 | use JMS\DiExtraBundle as DI; 22 | use Security\SecurityContext; 23 | use Symfony\Component\Form\AbstractType; // Use this alias in order to not have this class picked up by the finder 24 | 25 | /** 26 | * @DI\Annotation\FormType 27 | * 28 | * @author Johannes M. Schmitt 29 | */ 30 | class LoginType extends AbstractType 31 | { 32 | private $securityContext; 33 | 34 | public function __construct(SecurityContext $context) 35 | { 36 | $this->securityContext = $context; 37 | } 38 | 39 | public function getName() 40 | { 41 | return $this->getBlockPrefix(); 42 | } 43 | 44 | public function getBlockPrefix() 45 | { 46 | return 'login'; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Resources/doc/doctrine.rst: -------------------------------------------------------------------------------- 1 | Doctrine Integration 2 | ==================== 3 | 4 | .. versionadded : 1.1 5 | Doctrine Integration was added. 6 | 7 | Configuration 8 | ------------- 9 | Doctrine integration is enabled by default. However, you can easily disable it 10 | in your configuration: 11 | 12 | .. configuration-block :: 13 | 14 | .. code-block :: yaml 15 | 16 | jms_di_extra: 17 | doctrine_integration: false 18 | 19 | .. code-block :: xml 20 | 21 | 22 | 23 | 24 | Injecting Dependencies Into Repositories 25 | ---------------------------------------- 26 | If you have enabled Doctrine integration, you can now inject dependencies into 27 | repositories using annotations: 28 | 29 | .. code-block :: php 30 | 31 | use JMS\DiExtraBundle\Annotation as DI; 32 | 33 | class MyRepository extends EntityRepository 34 | { 35 | private $uuidGenerator; 36 | 37 | /** 38 | * @DI\InjectParams({ 39 | * "uuidGenerator" = @DI\Inject("my_uuid_generator"), 40 | * }) 41 | */ 42 | public function setUuidGenerator(UUidGenerator $uuidGenerator) 43 | { 44 | $this->uuidGenerator = $uuidGenerator; 45 | } 46 | 47 | // ... 48 | } 49 | 50 | .. note :: 51 | 52 | If you do not want to use annotations, you can also implement 53 | ``Symfony\Component\DependencyInjection\ContainerAwareInterface`` in your 54 | repositories to receive the entire service container. -------------------------------------------------------------------------------- /Tests/Functional/Bundle/TestBundle/Inheritance/ConcreteClass.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Tests\Functional\Bundle\TestBundle\Inheritance; 20 | 21 | use JMS\DiExtraBundle\Annotation as DI; 22 | 23 | /** 24 | * @DI\Service("concrete_class") 25 | * 26 | * @author Johannes M. Schmitt 27 | */ 28 | class ConcreteClass extends AbstractClass 29 | { 30 | private $foo; 31 | private $bar; 32 | 33 | /** 34 | * @DI\InjectParams 35 | * 36 | * @param stdClass $foo 37 | * @param stdClass $bar 38 | */ 39 | public function __construct($foo, $bar) 40 | { 41 | $this->foo = $foo; 42 | $this->bar = $bar; 43 | } 44 | 45 | public function getFoo() 46 | { 47 | return $this->foo; 48 | } 49 | 50 | public function getBar() 51 | { 52 | return $this->bar; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Tests/Functional/Bundle/LegacyTestBundle/Inheritance/ConcreteClass.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Tests\Functional\Bundle\LegacyTestBundle\Inheritance; 20 | 21 | use JMS\DiExtraBundle\Annotation as DI; 22 | 23 | /** 24 | * @DI\Service("concrete_class") 25 | * 26 | * @author Johannes M. Schmitt 27 | */ 28 | class ConcreteClass extends AbstractClass 29 | { 30 | private $foo; 31 | private $bar; 32 | 33 | /** 34 | * @DI\InjectParams 35 | * 36 | * @param stdClass $foo 37 | * @param stdClass $bar 38 | */ 39 | public function __construct($foo, $bar) 40 | { 41 | $this->foo = $foo; 42 | $this->bar = $bar; 43 | } 44 | 45 | public function getFoo() 46 | { 47 | return $this->foo; 48 | } 49 | 50 | public function getBar() 51 | { 52 | return $this->bar; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Tests/Functional/BaseTestCase.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Tests\Functional; 20 | 21 | use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; 22 | use Symfony\Component\Filesystem\Filesystem; 23 | 24 | class BaseTestCase extends WebTestCase 25 | { 26 | protected static function createKernel(array $options = array()) 27 | { 28 | return new AppKernel( 29 | isset($options['config']) ? $options['config'] : 'default.yml', 30 | isset($options['debug']) ? (bool) $options['debug'] : true 31 | ); 32 | } 33 | 34 | protected function tearDown() 35 | { 36 | $this->cleanTmpDir(); 37 | } 38 | 39 | protected function setUp() 40 | { 41 | $this->cleanTmpDir(); 42 | } 43 | 44 | private function cleanTmpDir() 45 | { 46 | $fs = new Filesystem(); 47 | $fs->remove(sys_get_temp_dir().'/JMSDiExtraBundle'); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /DependencyInjection/Collection/LazySequenceIterator.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\DependencyInjection\Collection; 20 | 21 | use ArrayIterator; 22 | use Symfony\Component\DependencyInjection\ContainerInterface; 23 | 24 | class LazySequenceIterator extends ArrayIterator 25 | { 26 | private $container; 27 | private $seq; 28 | 29 | public function __construct(ContainerInterface $container, LazyServiceSequence $seq, array $elements) 30 | { 31 | parent::__construct($elements); 32 | 33 | $this->container = $container; 34 | $this->seq = $seq; 35 | } 36 | 37 | public function current() 38 | { 39 | $elem = parent::current(); 40 | 41 | if (is_string($elem)) { 42 | $service = $this->container->get($elem); 43 | $this->seq->update($this->key(), $service); 44 | 45 | return $service; 46 | } 47 | 48 | return $elem; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Tests/Functional/AutomaticControllerInjectionsTest.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Tests\Functional; 20 | 21 | class AutomaticControllerInjectionsTest extends BaseTestCase 22 | { 23 | /** 24 | * @runInSeparateProcess 25 | */ 26 | public function testInjections() 27 | { 28 | $client = $this->createClient(array( 29 | 'config' => class_exists('Symfony\Component\Security\Core\Authorization\AuthorizationChecker') ? 'automatic_controller_injections.yml' : 'bc_automatic_controller_injections.yml', 30 | )); 31 | $client->request('GET', '/automatic-controller-injection-test'); 32 | 33 | $expected = ''; 34 | $expected .= "\$context injection: OK\n"; 35 | $expected .= "\$templating injection: OK\n"; 36 | $expected .= "\$router injection: OK\n"; 37 | $expected .= "\$foo injection: OK\n"; 38 | 39 | $this->assertEquals($expected, $client->getResponse()->getContent()); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Tests/Fixture/LoginController.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Tests\Fixture; 20 | 21 | use JMS\DiExtraBundle\Annotation\Inject; 22 | 23 | /** 24 | * Login Controller. 25 | * 26 | * @author Johannes M. Schmitt 27 | */ 28 | class LoginController 29 | { 30 | /** 31 | * @Inject("form.csrf_provider") 32 | */ 33 | private $csrfProvider; 34 | 35 | /** 36 | * @Inject 37 | */ 38 | private $rememberMeServices; 39 | 40 | /** 41 | * @Inject("security.authentication.trust_resolver") 42 | */ 43 | private $trustResolver; 44 | 45 | public function loginAction() 46 | { 47 | } 48 | 49 | public function getCsrfProvider() 50 | { 51 | return $this->csrfProvider; 52 | } 53 | 54 | public function getRememberMeServices() 55 | { 56 | return $this->rememberMeServices; 57 | } 58 | 59 | public function getTrustResolver() 60 | { 61 | return $this->trustResolver; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /Tests/Fixture/RequestListener.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Tests\Fixture; 20 | 21 | use JMS\DiExtraBundle\Annotation as DI; 22 | 23 | /** 24 | * @DI\Service 25 | * 26 | * @author Johannes M. Schmitt 27 | */ 28 | class RequestListener 29 | { 30 | private $router; 31 | private $session; 32 | private $em; 33 | private $con; 34 | private $table; 35 | 36 | /** 37 | * @DI\InjectParams({ 38 | * "em" = @DI\Inject("doctrine.entity_manager") 39 | * }) 40 | */ 41 | public function __construct($router, $session, $em) 42 | { 43 | $this->router = $router; 44 | $this->session = $session; 45 | $this->em = $em; 46 | } 47 | 48 | /** 49 | * @DI\InjectParams({ 50 | * "table" = @DI\Inject("%table_name%") 51 | * }) 52 | */ 53 | public function setConnection($databaseConnection, $table) 54 | { 55 | $this->con = $databaseConnection; 56 | $this->table = $table; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /Tests/Metadata/ClassMetadataTest.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Tests\Metadata; 20 | 21 | use JMS\DiExtraBundle\Metadata\ClassMetadata; 22 | use PHPUnit\Framework\TestCase; 23 | 24 | class ClassMetadataTest extends TestCase 25 | { 26 | public function testSerializeUnserialize() 27 | { 28 | $classMetadata = new ClassMetadata('JMS\DiExtraBundle\Tests\Fixture\LoginController'); 29 | $classMetadata->arguments = array('foo', 'bar'); 30 | $classMetadata->abstract = true; 31 | $classMetadata->public = false; 32 | $classMetadata->id = 'foo'; 33 | $classMetadata->deprecated = true; 34 | $classMetadata->decorates = 'test.service'; 35 | $classMetadata->decoration_inner_name = 'old.test.service'; 36 | $classMetadata->autowire = true; 37 | $classMetadata->autowiringTypes = array('JMS\DiExtraBundle\Tests\Fixture\LoginController'); 38 | 39 | $this->assertEquals($classMetadata, unserialize(serialize($classMetadata))); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | dist: trusty 3 | 4 | php: 5 | - 5.5 6 | - 5.6 7 | - 7.0 8 | - 7.1 9 | - 7.2 10 | 11 | branches: 12 | only: 13 | - master 14 | - /^\d+\.\d+$/ 15 | 16 | env: SYMFONY_DEPRECATIONS_HELPER=weak_vendors 17 | 18 | sudo: false 19 | 20 | cache: 21 | directories: 22 | - .phpunit 23 | - $HOME/.composer/cache 24 | 25 | matrix: 26 | fast_finish: true 27 | include: 28 | - php: 5.3 29 | dist: precise 30 | - php: 5.3 31 | dist: precise 32 | env: SYMFONY_DEPRECATIONS_HELPER COMPOSER_FLAGS="--prefer-lowest" 33 | - php: 5.4 34 | - php: 7.0 35 | env: SYMFONY_DEPRECATIONS_HELPER=weak_vendors SYMFONY_VERSION=2.7.* 36 | - php: 7.0 37 | env: SYMFONY_DEPRECATIONS_HELPER=weak_vendors SYMFONY_VERSION=2.8.* COVERAGE=true 38 | - php: 7.0 39 | env: SYMFONY_DEPRECATIONS_HELPER=weak_vendors SYMFONY_VERSION=3.2.* 40 | - php: 7.1 41 | env: ~ 42 | allow_failures: 43 | - php: 7.1 44 | env: ~ 45 | 46 | before_script: 47 | - if [ "$COVERAGE" != "true" ]; then phpenv config-rm xdebug.ini; fi 48 | - composer self-update 49 | - if [ "$SYMFONY_VERSION" != "" ]; then composer require --dev --no-update symfony/symfony=$SYMFONY_VERSION; fi 50 | - echo "memory_limit=-1" >> ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini 51 | - composer update $COMPOSER_FLAGS --prefer-dist --no-interaction 52 | 53 | script: if [ "$COVERAGE" == "true" ]; then vendor/bin/phpunit --coverage-clover=clover; else vendor/bin/phpunit; fi 54 | 55 | after_success: 56 | - if [ "$COVERAGE" == "true" ]; then curl -sL https://bit.ly/artifact-uploader | php; fi 57 | -------------------------------------------------------------------------------- /Annotation/Service.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Annotation; 20 | 21 | /** 22 | * @Annotation 23 | * @Target({"CLASS", "METHOD"}) 24 | */ 25 | final class Service 26 | { 27 | /** @var string */ 28 | public $id; 29 | 30 | /** @var string */ 31 | public $parent; 32 | 33 | /** @var bool */ 34 | public $public; 35 | 36 | /** @var string */ 37 | public $scope; 38 | 39 | /** @var bool */ 40 | public $shared; 41 | 42 | /** @var string */ 43 | public $deprecated; 44 | 45 | /** @var string */ 46 | public $decorates; 47 | 48 | /** 49 | * @var string 50 | * 51 | * @deprecated since version 1.8, to be removed in 2.0. Use $decorationInnerName instead. 52 | */ 53 | public $decoration_inner_name; 54 | 55 | /** @var string */ 56 | public $decorationInnerName; 57 | 58 | /** @var bool */ 59 | public $abstract; 60 | 61 | /** @var array */ 62 | public $environments = array(); 63 | 64 | /** @var bool */ 65 | public $autowire; 66 | 67 | /** @var array */ 68 | public $autowiringTypes; 69 | } 70 | -------------------------------------------------------------------------------- /DependencyInjection/Collection/LazyServiceSequence.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\DependencyInjection\Collection; 20 | 21 | use PhpCollection\Sequence; 22 | use Symfony\Component\DependencyInjection\ContainerInterface; 23 | 24 | class LazyServiceSequence extends Sequence 25 | { 26 | private $container; 27 | 28 | public function __construct(ContainerInterface $container, array $serviceIds = array()) 29 | { 30 | parent::__construct($serviceIds); 31 | 32 | $this->container = $container; 33 | } 34 | 35 | public function get($index) 36 | { 37 | $this->initialize($index); 38 | 39 | return parent::get($index); 40 | } 41 | 42 | public function getIterator() 43 | { 44 | return new LazySequenceIterator($this->container, $this, $this->elements); 45 | } 46 | 47 | private function initialize($index) 48 | { 49 | if (!isset($this->elements[$index]) || !is_string($this->elements[$index])) { 50 | return; 51 | } 52 | 53 | $this->elements[$index] = $this->container->get($this->elements[$index]); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Config/ServiceFilesResource.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Config; 20 | 21 | use JMS\DiExtraBundle\Finder\PatternFinder; 22 | 23 | class ServiceFilesResource extends InternalResource 24 | { 25 | private $files; 26 | private $dirs; 27 | private $disableGrep; 28 | private $pattern; 29 | 30 | public function __construct(array $files, array $dirs, $disableGrep, $pattern = 'JMS\DiExtraBundle\Annotation') 31 | { 32 | $this->files = $files; 33 | $this->dirs = $dirs; 34 | $this->disableGrep = $disableGrep; 35 | $this->pattern = $pattern; 36 | } 37 | 38 | public function isFresh($timestamp) 39 | { 40 | $finder = new PatternFinder($this->pattern, '*.php', $this->disableGrep); 41 | $files = $finder->findFiles($this->dirs); 42 | 43 | return !array_diff($files, $this->files) && !array_diff($this->files, $files); 44 | } 45 | 46 | public function __toString() 47 | { 48 | return implode(', ', $this->files); 49 | } 50 | 51 | public function getResource() 52 | { 53 | return array($this->files, $this->dirs); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /JMSDiExtraBundle.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle; 20 | 21 | use JMS\DiExtraBundle\DependencyInjection\Compiler\AnnotationConfigurationPass; 22 | use JMS\DiExtraBundle\DependencyInjection\Compiler\IntegrationPass; 23 | use JMS\DiExtraBundle\DependencyInjection\Compiler\ResourceOptimizationPass; 24 | use Symfony\Component\DependencyInjection\Compiler\PassConfig; 25 | use Symfony\Component\DependencyInjection\ContainerBuilder; 26 | use Symfony\Component\HttpKernel\Bundle\Bundle; 27 | 28 | /** 29 | * Builder. 30 | */ 31 | class JMSDiExtraBundle extends Bundle 32 | { 33 | /** 34 | * @param ContainerBuilder $container 35 | */ 36 | public function build(ContainerBuilder $container) 37 | { 38 | $config = $container->getCompiler()->getPassConfig(); 39 | $passes = $config->getBeforeOptimizationPasses(); 40 | array_unshift($passes, new AnnotationConfigurationPass()); 41 | $config->setBeforeOptimizationPasses($passes); 42 | 43 | $container->addCompilerPass(new IntegrationPass()); 44 | $container->addCompilerPass(new ResourceOptimizationPass(), PassConfig::TYPE_AFTER_REMOVING); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jms/di-extra-bundle", 3 | "type": "symfony-bundle", 4 | "description": "Allows to configure dependency injection using annotations", 5 | "keywords": ["annotations","dependency injection"], 6 | "homepage": "http://jmsyst.com/bundles/JMSDiExtraBundle", 7 | "license": "Apache-2.0", 8 | "authors": [ 9 | { 10 | "name": "Johannes M. Schmitt", 11 | "email": "schmittjoh@gmail.com" 12 | } 13 | ], 14 | "require": { 15 | "php": "~5.3|~7.0", 16 | "symfony/framework-bundle": "~2.3|~3.0", 17 | "symfony/routing": "~2.3|~3.0", 18 | "symfony/http-kernel": "^2.3.24|~3.0", 19 | "symfony/dependency-injection": "~2.3|~3.0", 20 | "symfony/process": "~2.3|~3.0", 21 | "symfony/finder": "~2.3|~3.0", 22 | "jms/aop-bundle": "~1.1", 23 | "jms/metadata": "~1.0" 24 | }, 25 | "require-dev": { 26 | "symfony/validator": "~2.3|~3.0", 27 | "symfony/form": "~2.3|~3.0", 28 | "symfony/class-loader": "~2.3|~3.0", 29 | "symfony/yaml": "~2.3|~3.0", 30 | "symfony/browser-kit": "~2.3|~3.0", 31 | "symfony/security-bundle": "~2.3|^3.0", 32 | "symfony/expression-language": "~2.6|~3.0", 33 | "symfony/twig-bundle": "~2.3|~3.0", 34 | "sensio/framework-extra-bundle": "~2.0|~3.0", 35 | "jms/security-extra-bundle": "~1.0", 36 | "doctrine/doctrine-bundle": "~1.5", 37 | "doctrine/orm": "~2.3", 38 | "phpcollection/phpcollection": ">=0.2,<0.3-dev", 39 | "symfony/phpunit-bridge": "~3.3", 40 | "phpunit/phpunit": "^4.8.35|^5.4.4|^6.0.0", 41 | "symfony/asset": "~2.3|^3.3", 42 | "symfony/templating": "~2.3|^3.3" 43 | }, 44 | "autoload": { 45 | "psr-4": { "JMS\\DiExtraBundle\\": "" } 46 | }, 47 | "extra": { 48 | "branch-alias": { 49 | "dev-master": "1.8-dev" 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Tests/Finder/AbstractPatternFinderTest.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Tests\Finder; 20 | 21 | use PHPUnit\Framework\TestCase; 22 | 23 | abstract class AbstractPatternFinderTest extends TestCase 24 | { 25 | public function testFindFiles() 26 | { 27 | $finder = $this->getFinder(); 28 | 29 | $expectedFiles = array( 30 | realpath(__DIR__.'/../Fixture/NonEmptyDirectory/Service1.php'), 31 | realpath(__DIR__.'/../Fixture/NonEmptyDirectory/Service4.php'), 32 | realpath(__DIR__.'/../Fixture/NonEmptyDirectory/SubDir1/Service2.php'), 33 | realpath(__DIR__.'/../Fixture/NonEmptyDirectory/SubDir2/Service3.php'), 34 | ); 35 | 36 | $foundFiles = $finder->findFiles(array(__DIR__.'/../Fixture/NonEmptyDirectory')); 37 | 38 | $this->assertEquals(array(), array_diff($expectedFiles, $foundFiles)); 39 | $this->assertEquals(array(), array_diff($foundFiles, $expectedFiles)); 40 | } 41 | 42 | public function testFindFilesUsingGrepReturnsEmptyArrayWhenNoMatchesAreFound() 43 | { 44 | $finder = $this->getFinder(); 45 | $this->assertEquals(array(), $finder->findFiles(array(__DIR__.'/../Fixture/EmptyDirectory'))); 46 | } 47 | 48 | abstract protected function getFinder(); 49 | } 50 | -------------------------------------------------------------------------------- /Tests/DependencyInjection/Compiler/ResourceOptimizationPassTest.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Tests\DependencyInjection\Compiler; 20 | 21 | use JMS\DiExtraBundle\DependencyInjection\Compiler\ResourceOptimizationPass; 22 | use PHPUnit\Framework\TestCase; 23 | use Symfony\Component\Config\Resource\DirectoryResource; 24 | use Symfony\Component\DependencyInjection\ContainerBuilder; 25 | 26 | class ResourceOptimizationPassTest extends TestCase 27 | { 28 | public function testProcess() 29 | { 30 | $container = new ContainerBuilder(); 31 | $container->setParameter('jms_di_extra.disable_grep', false); 32 | $container->addResource(new DirectoryResource(__DIR__.'/Fixtures/a')); 33 | $container->addResource(new DirectoryResource(__DIR__.'/Fixtures/a/b')); 34 | $container->addResource(new DirectoryResource(__DIR__.'/Fixtures/c')); 35 | $this->process($container); 36 | 37 | $resources = $container->getResources(); 38 | $this->assertEquals(1, count($resources)); 39 | $this->assertInstanceOf('JMS\DiExtraBundle\Config\FastDirectoriesResource', $resources[0]); 40 | $this->assertEquals(array( 41 | __DIR__.'/Fixtures/a', 42 | __DIR__.'/Fixtures/c', 43 | ), $resources[0]->getResource()); 44 | $this->assertAttributeEquals('*', 'filePattern', $resources[0]); 45 | } 46 | 47 | private function process(ContainerBuilder $container) 48 | { 49 | $pass = new ResourceOptimizationPass(); 50 | $pass->process($container); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Tests/Finder/GrepPatternFinderTest.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Tests\Finder; 20 | 21 | use JMS\DiExtraBundle\Finder\PatternFinder; 22 | 23 | class GrepPatternFinderTest extends AbstractPatternFinderTest 24 | { 25 | protected $disableGrep = false; 26 | protected $forceMethodReload = false; 27 | 28 | protected function getFinder() 29 | { 30 | $finder = new PatternFinder( 31 | 'JMS\DiExtraBundle\Annotation', 32 | '*.php', 33 | $this->disableGrep, 34 | $this->forceMethodReload 35 | ); 36 | 37 | if (!$this->disableGrep) { 38 | $ref = new \ReflectionProperty($finder, 'grepPath'); 39 | $ref->setAccessible(true); 40 | if (null === $v = $ref->getValue($finder)) { 41 | $this->markTestSkipped('grep is not available on your system.'); 42 | } 43 | } 44 | 45 | return $finder; 46 | } 47 | 48 | public function testFinderMethodIsNotGrepIfDisableGrepParameterIsSetToTrue() 49 | { 50 | // Change the flag to disable grep 51 | $this->disableGrep = true; 52 | $this->forceMethodReload = true; 53 | 54 | // Get the finder and a reflection object on its method property 55 | $finder = $this->getFinder(); 56 | $ref = new \ReflectionProperty($finder, 'method'); 57 | $ref->setAccessible(true); 58 | 59 | // Ensure the method is not grep 60 | $this->assertNotEquals(PatternFinder::METHOD_GREP, $ref->getValue($finder)); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /Tests/Functional/Bundle/TestBundle/Controller/AutomaticallyInjectedController.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Tests\Functional\Bundle\TestBundle\Controller; 20 | 21 | use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; 22 | use Symfony\Component\HttpFoundation\Response; 23 | use Symfony\Component\Routing\RouterInterface; 24 | use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface; 25 | use Symfony\Component\Security\Core\SecurityContextInterface; 26 | use Symfony\Component\Templating\EngineInterface; 27 | 28 | class AutomaticallyInjectedController 29 | { 30 | private $context; 31 | private $templating; 32 | private $router; 33 | private $foo; 34 | 35 | public function setRouter(RouterInterface $router) 36 | { 37 | $this->router = $router; 38 | } 39 | 40 | /** 41 | * @Route("/automatic-controller-injection-test") 42 | */ 43 | public function testAction() 44 | { 45 | $content = ''; 46 | 47 | $content .= sprintf("\$context injection: %s\n", $this->context instanceof SecurityContextInterface || $this->context instanceof AuthorizationCheckerInterface ? 'OK' : 'FAILED'); 48 | $content .= sprintf("\$templating injection: %s\n", $this->templating instanceof EngineInterface ? 'OK' : 'FAILED'); 49 | $content .= sprintf("\$router injection: %s\n", $this->router instanceof RouterInterface ? 'OK' : 'FAILED'); 50 | $content .= sprintf("\$foo injection: %s\n", 'bar' === $this->foo ? 'OK' : 'FAILED'); 51 | 52 | return new Response($content); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Tests/DependencyInjection/Compiler/LazyServiceSequencePassTest.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Tests\DependencyInjection\Compiler; 20 | 21 | use JMS\DiExtraBundle\DependencyInjection\Compiler\LazyServiceSequencePass; 22 | use PHPUnit\Framework\TestCase; 23 | use Symfony\Component\DependencyInjection\ContainerBuilder; 24 | use Symfony\Component\DependencyInjection\Definition; 25 | use Symfony\Component\DependencyInjection\Reference; 26 | 27 | class LazyServiceSequencePassTest extends TestCase 28 | { 29 | public function testProcess() 30 | { 31 | $called = false; 32 | $self = $this; 33 | 34 | $pass = new LazyServiceSequencePass('tag', function (ContainerBuilder $container, Definition $def) use (&$called, $self) { 35 | $self->assertFalse($called); 36 | $called = true; 37 | 38 | $self->assertEquals(new Reference('service_container'), $def->getArgument(0)); 39 | $self->assertEquals(array('foo', 'bar'), $def->getArgument(1)); 40 | }); 41 | 42 | $container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder') 43 | ->disableOriginalConstructor() 44 | ->setMethods(array('findTaggedServiceIds')) 45 | ->getMock(); 46 | 47 | $container->expects($this->once()) 48 | ->method('findTaggedServiceIds') 49 | ->with('tag') 50 | ->will($this->returnValue(array('foo' => array(), 'bar' => array()))); 51 | 52 | $pass->process($container); 53 | $this->assertTrue($called); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Config/FastDirectoriesResource.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Config; 20 | 21 | use JMS\DiExtraBundle\Finder\PatternFinder; 22 | 23 | class FastDirectoriesResource extends InternalResource 24 | { 25 | private $finder; 26 | 27 | private $directories; 28 | private $filePattern; 29 | private $files = array(); 30 | 31 | public function __construct(array $directories, $filePattern = null, $disableGrep = false) 32 | { 33 | $this->finder = new PatternFinder('.*', '*.php', $disableGrep); 34 | $this->finder->setRegexPattern(true); 35 | 36 | $this->directories = $directories; 37 | $this->filePattern = $filePattern ?: '*'; 38 | } 39 | 40 | public function __toString() 41 | { 42 | return implode(', ', $this->directories); 43 | } 44 | 45 | public function getResource() 46 | { 47 | return $this->directories; 48 | } 49 | 50 | public function update() 51 | { 52 | $this->files = $this->getFiles(); 53 | } 54 | 55 | public function isFresh($timestamp) 56 | { 57 | $files = $this->getFiles(); 58 | 59 | if (array_diff($this->files, $files) || array_diff($files, $this->files)) { 60 | return false; 61 | } 62 | 63 | foreach ($files as $file) { 64 | if (filemtime($file) > $timestamp) { 65 | return false; 66 | } 67 | } 68 | 69 | return true; 70 | } 71 | 72 | private function getFiles() 73 | { 74 | return $this->finder->findFiles($this->directories); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /Tests/Functional/Bundle/LegacyTestBundle/Controller/AutomaticallyInjectedController.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Tests\Functional\Bundle\LegacyTestBundle\Controller; 20 | 21 | use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; 22 | use Symfony\Component\HttpFoundation\Response; 23 | use Symfony\Component\Routing\RouterInterface; 24 | use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface; 25 | use Symfony\Component\Security\Core\SecurityContextInterface; 26 | use Symfony\Component\Templating\EngineInterface; 27 | 28 | class AutomaticallyInjectedController 29 | { 30 | private $context; 31 | private $templating; 32 | private $router; 33 | private $foo; 34 | 35 | public function setRouter(RouterInterface $router) 36 | { 37 | $this->router = $router; 38 | } 39 | 40 | /** 41 | * @Route("/automatic-controller-injection-test") 42 | */ 43 | public function testAction() 44 | { 45 | $content = ''; 46 | 47 | $content .= sprintf("\$context injection: %s\n", $this->context instanceof SecurityContextInterface || $this->context instanceof AuthorizationCheckerInterface ? 'OK' : 'FAILED'); 48 | $content .= sprintf("\$templating injection: %s\n", $this->templating instanceof EngineInterface ? 'OK' : 'FAILED'); 49 | $content .= sprintf("\$router injection: %s\n", $this->router instanceof RouterInterface ? 'OK' : 'FAILED'); 50 | $content .= sprintf("\$foo injection: %s\n", 'bar' === $this->foo ? 'OK' : 'FAILED'); 51 | 52 | return new Response($content); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Tests/DependencyInjection/Compiler/LazyServiceMapPassTest.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Tests\DependencyInjection\Compiler; 20 | 21 | use JMS\DiExtraBundle\DependencyInjection\Compiler\LazyServiceMapPass; 22 | use PHPUnit\Framework\TestCase; 23 | use Symfony\Component\DependencyInjection\ContainerBuilder; 24 | use Symfony\Component\DependencyInjection\Definition; 25 | use Symfony\Component\DependencyInjection\Reference; 26 | 27 | class LazyServiceMapPassTest extends TestCase 28 | { 29 | public function testProcess() 30 | { 31 | $called = false; 32 | $self = $this; 33 | 34 | $pass = new LazyServiceMapPass('tag', 'key', function (ContainerBuilder $container, Definition $def) use (&$called, $self) { 35 | $self->assertFalse($called); 36 | $called = true; 37 | 38 | $self->assertEquals(new Reference('service_container'), $def->getArgument(0)); 39 | $self->assertEquals(array('json' => 'foo', 'xml' => 'bar', 'atom' => 'bar'), $def->getArgument(1)); 40 | }); 41 | 42 | $container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder') 43 | ->disableOriginalConstructor() 44 | ->setMethods(array('findTaggedServiceIds')) 45 | ->getMock(); 46 | 47 | $container->expects($this->once()) 48 | ->method('findTaggedServiceIds') 49 | ->with('tag') 50 | ->will($this->returnValue(array('foo' => array(array('key' => 'json')), 'bar' => array(array('key' => 'xml'), array('key' => 'atom'))))); 51 | 52 | $pass->process($container); 53 | $this->assertTrue($called); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /DependencyInjection/Compiler/LazyServiceSequencePass.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\DependencyInjection\Compiler; 20 | 21 | use Serializable; 22 | use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; 23 | use Symfony\Component\DependencyInjection\ContainerBuilder; 24 | use Symfony\Component\DependencyInjection\Definition; 25 | use Symfony\Component\DependencyInjection\Reference; 26 | 27 | class LazyServiceSequencePass implements CompilerPassInterface, Serializable 28 | { 29 | private $tagName; 30 | private $callable; 31 | 32 | public function __construct($tagName, $callable) 33 | { 34 | $this->tagName = $tagName; 35 | $this->callable = $callable; 36 | } 37 | 38 | public function process(ContainerBuilder $container) 39 | { 40 | if (!is_callable($this->callable)) { 41 | throw new \RuntimeException('The callable is invalid. If you had serialized this pass, the original callable might not be available anymore.'); 42 | } 43 | 44 | $serviceIds = array(); 45 | foreach ($container->findTaggedServiceIds($this->tagName) as $id => $attrs) { 46 | $serviceIds[] = $id; 47 | } 48 | 49 | $seqDef = new Definition('JMS\DiExtraBundle\DependencyInjection\Collection\LazyServiceSequence'); 50 | $seqDef->addArgument(new Reference('service_container')); 51 | $seqDef->addArgument($serviceIds); 52 | 53 | call_user_func($this->callable, $container, $seqDef); 54 | } 55 | 56 | public function serialize() 57 | { 58 | return $this->tagName; 59 | } 60 | 61 | public function unserialize($tagName) 62 | { 63 | $this->tagName = $tagName; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /Generator/NameGenerator.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Generator; 20 | 21 | class NameGenerator 22 | { 23 | private $count = 0; 24 | private $firstChars = 'abcdefghijklmnopqrstuvwxyz'; 25 | private $firstCharsLength = 26; 26 | private $nonFirstChars = 'abcdefghijklmnopqrstuvwxyz0123456789_'; 27 | private $nonFirstCharsLength = 37; 28 | private $reservedNames = array(); 29 | 30 | public function addReservedName($name) 31 | { 32 | $this->reservedNames[$name] = true; 33 | } 34 | 35 | public function setFirstChars($chars) 36 | { 37 | $this->firstChars = $chars; 38 | $this->firstCharsLength = strlen($chars); 39 | } 40 | 41 | public function setNonFirstChars($chars) 42 | { 43 | $this->nonFirstChars = $chars; 44 | $this->nonFirstCharsLength = strlen($chars); 45 | } 46 | 47 | public function reset() 48 | { 49 | $this->count = 0; 50 | } 51 | 52 | public function nextName() 53 | { 54 | while (true) { 55 | $name = ''; 56 | $i = $this->count; 57 | 58 | if ('' === $name) { 59 | $name .= $this->firstChars[$i % $this->firstCharsLength]; 60 | $i = intval($i / $this->firstCharsLength); 61 | } 62 | 63 | while ($i > 0) { 64 | $i -= 1; 65 | $name .= $this->nonFirstChars[$i % $this->nonFirstCharsLength]; 66 | $i = intval($i / $this->nonFirstCharsLength); 67 | } 68 | 69 | $this->count += 1; 70 | 71 | // check that the name is not reserved 72 | if (isset($this->reservedNames[$name])) { 73 | continue; 74 | } 75 | 76 | return $name; 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /DependencyInjection/Collection/LazyServiceMap.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\DependencyInjection\Collection; 20 | 21 | use PhpCollection\Map; 22 | use Symfony\Component\DependencyInjection\ContainerInterface; 23 | 24 | /** 25 | * A map of services which may be initialized lazily. 26 | * 27 | * This is useful if you have a list of services which implement a common interface, and where you only need selected 28 | * services during a request. The map then automatically lazily initializes these services upon first access. 29 | * 30 | * @author Johannes M. Schmitt 31 | */ 32 | class LazyServiceMap extends Map 33 | { 34 | private $container; 35 | private $serviceIds; 36 | 37 | public function __construct(ContainerInterface $container, array $serviceIds) 38 | { 39 | $this->container = $container; 40 | $this->serviceIds = $serviceIds; 41 | } 42 | 43 | public function get($key) 44 | { 45 | $this->initialize($key); 46 | 47 | return parent::get($key); 48 | } 49 | 50 | public function containsKey($key) 51 | { 52 | return isset($this->serviceIds[$key]) || parent::containsKey($key); 53 | } 54 | 55 | public function remove($key) 56 | { 57 | $this->initialize($key); 58 | 59 | return parent::remove($key); 60 | } 61 | 62 | public function getIterator() 63 | { 64 | foreach ($this->serviceIds as $key => $id) { 65 | $this->set($key, $this->container->get($id)); 66 | unset($this->serviceIds[$key]); 67 | } 68 | 69 | return parent::getIterator(); 70 | } 71 | 72 | private function initialize($key) 73 | { 74 | if (!isset($this->serviceIds[$key])) { 75 | return; 76 | } 77 | 78 | $this->set($key, $this->container->get($this->serviceIds[$key])); 79 | unset($this->serviceIds[$key]); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /Tests/Functional/ControllerResolverTest.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Tests\Functional; 20 | 21 | class ControllerResolverTest extends BaseTestCase 22 | { 23 | /** 24 | * @runInSeparateProcess 25 | */ 26 | public function testLookupMethodIsCorrectlyImplemented() 27 | { 28 | $client = $this->createClient(); 29 | $client->request('GET', '/register'); 30 | 31 | $this->assertEquals('foo@bar.de', $client->getResponse()->getContent()); 32 | } 33 | 34 | /** 35 | * @runInSeparateProcess 36 | */ 37 | public function testLookupMethodAndAopProxy() 38 | { 39 | $client = $this->createClient(); 40 | $client->request('GET', '/lookup-method-and-aop'); 41 | 42 | $this->assertTrue($client->getResponse()->isRedirect('http://localhost/login'), substr((string) $client->getResponse(), 0, 1024)); 43 | 44 | $client->insulate(); 45 | $client->request('GET', '/lookup-method-and-aop'); 46 | $this->assertTrue($client->getResponse()->isRedirect('http://localhost/login'), substr((string) $client->getResponse(), 0, 512)); 47 | } 48 | 49 | /** 50 | * @runInSeparateProcess 51 | */ 52 | public function testAopProxyWhenNoDiMetadata() 53 | { 54 | $client = $this->createClient(); 55 | $client->request('GET', '/secure-action'); 56 | 57 | $this->assertTrue($client->getResponse()->isRedirect('http://localhost/login')); 58 | } 59 | 60 | /** 61 | * @runInSeparateProcess 62 | */ 63 | public function testAnnotationControllerServiceExtendingClassicService() 64 | { 65 | $client = $this->createClient(); 66 | $client->request('GET', '/hello'); 67 | 68 | $this->assertEquals('hello', $client->getResponse()->getContent()); 69 | } 70 | 71 | /** 72 | * @runInSeparateProcess 73 | */ 74 | public function testInvokableControllerAsService() 75 | { 76 | $client = $this->createClient(); 77 | $client->request('GET', '/invoke'); 78 | 79 | $this->assertEquals('invoked', $client->getResponse()->getContent()); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /Tests/DependencyInjection/Collection/LazyServiceSequenceTest.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Tests\DependencyInjection\Collection; 20 | 21 | use JMS\DiExtraBundle\DependencyInjection\Collection\LazyServiceSequence; 22 | use JMS\DiExtraBundle\Tests\BaseTestCase; 23 | 24 | class LazyServiceSequenceTest extends BaseTestCase 25 | { 26 | private $container; 27 | private $seq; 28 | 29 | public function testPartialIteration() 30 | { 31 | $this->container->expects($this->once()) 32 | ->method('get') 33 | ->with('foo') 34 | ->will($this->returnValue($foo = new \stdClass())); 35 | 36 | foreach ($this->seq as $service) { 37 | $this->assertSame($foo, $service); 38 | break; 39 | } 40 | 41 | foreach ($this->seq as $service) { 42 | $this->assertSame($foo, $service); 43 | break; 44 | } 45 | } 46 | 47 | public function testFullIteration() 48 | { 49 | $this->container->expects($this->at(0)) 50 | ->method('get') 51 | ->with('foo') 52 | ->will($this->returnValue('service.foo')); 53 | $this->container->expects($this->at(1)) 54 | ->method('get') 55 | ->with('bar') 56 | ->will($this->returnValue('service.bar')); 57 | $this->container->expects($this->at(2)) 58 | ->method('get') 59 | ->with('baz') 60 | ->will($this->returnValue('service.baz')); 61 | 62 | $services = iterator_to_array($this->seq); 63 | $this->assertSame(array('service.foo', 'service.bar', 'service.baz'), $services); 64 | } 65 | 66 | public function testGet() 67 | { 68 | $this->container->expects($this->once()) 69 | ->method('get') 70 | ->with('baz') 71 | ->will($this->returnValue($baz = new \stdClass())); 72 | 73 | $this->assertEquals($baz, $this->seq->get(2)); 74 | $this->assertEquals($baz, $this->seq->get(2)); 75 | } 76 | 77 | protected function setUp() 78 | { 79 | $this->container = $this->createMock('Symfony\Component\DependencyInjection\ContainerInterface'); 80 | $this->seq = new LazyServiceSequence($this->container, array('foo', 'bar', 'baz')); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /DependencyInjection/Compiler/ResourceOptimizationPass.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\DependencyInjection\Compiler; 20 | 21 | use JMS\DiExtraBundle\Config\FastDirectoriesResource; 22 | use Symfony\Component\Config\Resource\DirectoryResource; 23 | use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; 24 | use Symfony\Component\DependencyInjection\ContainerBuilder; 25 | 26 | class ResourceOptimizationPass implements CompilerPassInterface 27 | { 28 | public function process(ContainerBuilder $container) 29 | { 30 | $resources = $directories = array(); 31 | 32 | $ref = new \ReflectionProperty('Symfony\Component\Config\Resource\DirectoryResource', 'pattern'); 33 | $ref->setAccessible(true); 34 | 35 | foreach ($container->getResources() as $resource) { 36 | if ($resource instanceof DirectoryResource) { 37 | if (null === $pattern = $ref->getValue($resource)) { 38 | $pattern = '*'; 39 | } 40 | 41 | $directories[$pattern][] = $resource->getResource(); 42 | 43 | continue; 44 | } 45 | 46 | $resources[] = $resource; 47 | } 48 | 49 | $sortFunc = function ($a, $b) { 50 | return strlen($a) - strlen($b); 51 | }; 52 | 53 | foreach ($directories as $pattern => $pDirectories) { 54 | $newResources = array(); 55 | 56 | usort($pDirectories, $sortFunc); 57 | foreach ($pDirectories as $a) { 58 | foreach ($newResources as $b) { 59 | if (0 === strpos($a, $b)) { 60 | continue 2; 61 | } 62 | } 63 | 64 | $newResources[] = $a; 65 | } 66 | 67 | $directories[$pattern] = $newResources; 68 | } 69 | 70 | $disableGrep = $container->getParameter('jms_di_extra.disable_grep'); 71 | 72 | foreach ($directories as $pattern => $pDirectories) { 73 | $newResource = new FastDirectoriesResource($pDirectories, $pattern, $disableGrep); 74 | $newResource->update(); 75 | $resources[] = $newResource; 76 | } 77 | 78 | $ref = new \ReflectionProperty('Symfony\Component\DependencyInjection\ContainerBuilder', 'resources'); 79 | $ref->setAccessible(true); 80 | $ref->setValue($container, $resources); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /Tests/DependencyInjection/Collection/LazyServiceMapTest.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Tests\DependencyInjection\Collection; 20 | 21 | use JMS\DiExtraBundle\DependencyInjection\Collection\LazyServiceMap; 22 | use JMS\DiExtraBundle\Tests\BaseTestCase; 23 | use PHPUnit_Framework_MockObject_MockObject; 24 | use Symfony\Component\DependencyInjection\ContainerInterface; 25 | 26 | class LazyServiceMapTest extends BaseTestCase 27 | { 28 | /** 29 | * @var LazyServiceMap 30 | */ 31 | private $map; 32 | 33 | /** 34 | * @var PHPUnit_Framework_MockObject_MockObject|ContainerInterface 35 | */ 36 | private $container; 37 | 38 | public function testGet() 39 | { 40 | $this->container->expects($this->once()) 41 | ->method('get') 42 | ->with('bar_service') 43 | ->will($this->returnValue($a = new \stdClass())); 44 | 45 | $this->assertSame($a, $this->map->get('foo')->get()); 46 | $this->assertSame($a, $this->map->get('foo')->get()); 47 | } 48 | 49 | public function testRemove() 50 | { 51 | $this->container->expects($this->once()) 52 | ->method('get') 53 | ->with('bar_service') 54 | ->will($this->returnValue($a = new \stdClass())); 55 | 56 | $this->assertSame($a, $this->map->remove('foo')); 57 | $this->assertFalse($this->map->contains($a)); 58 | $this->assertFalse($this->map->containsKey('foo')); 59 | } 60 | 61 | public function testIterator() 62 | { 63 | $this->container->expects($this->at(0)) 64 | ->method('get') 65 | ->with('bar_service') 66 | ->will($this->returnValue($a = new \stdClass())); 67 | 68 | $this->container->expects($this->at(1)) 69 | ->method('get') 70 | ->with('baz_service') 71 | ->will($this->returnValue($b = new \stdClass())); 72 | 73 | $iterator = $this->map->getIterator(); 74 | 75 | $this->assertSame($a, $iterator->current()); 76 | 77 | $iterator->next(); 78 | $this->assertSame($b, $iterator->current()); 79 | } 80 | 81 | protected function setUp() 82 | { 83 | $this->container = $this->createMock('Symfony\Component\DependencyInjection\ContainerInterface'); 84 | 85 | $this->map = new LazyServiceMap($this->container, array( 86 | 'foo' => 'bar_service', 87 | 'bar' => 'baz_service', 88 | )); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /Resources/doc/usage.rst: -------------------------------------------------------------------------------- 1 | Usage 2 | ===== 3 | 4 | Non-Controller Classes 5 | ---------------------- 6 | Non-controller classes are configured, and managed by Symfony's DIC just like any 7 | other service that you configure using YML, XML, or PHP. The only difference is 8 | that you can do it via annotations which is a lot more convenient. 9 | 10 | You can use these annotations on services (for examples, see below): 11 | @Service, @Inject, @InjectParams, @Observe, @Tag 12 | 13 | Note that you cannot use the @Inject annotation on private, or protected properties. 14 | Likewise, the @InjectParams annotation does not work on protected, or private methods. 15 | 16 | Controllers 17 | ----------- 18 | Controllers are a special type of class which is also treated specially by this 19 | bundle. The most notable difference is that you do not need to define these 20 | classes as services. Yes, no services, but don't worry you can still use all of 21 | the DIC's features, and even some more. 22 | 23 | Constructor/Setter Injection 24 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 25 | 26 | .. code-block :: php 27 | 28 | em = $em; 46 | $this->session = $session; 47 | } 48 | // ... some actions 49 | } 50 | 51 | .. note :: 52 | 53 | Constructor Injection is not possible when a parent definition 54 | also defines a constructor which is configured for injection. 55 | 56 | Property Injection 57 | ~~~~~~~~~~~~~~~~~~ 58 | 59 | .. code-block :: php 60 | 61 | getMailer(); 94 | } 95 | } 96 | 97 | /** @DI\LookupMethod("mailer") */ 98 | protected function getMailer() { /* empty body here */ } 99 | } 100 | 101 | You can use this type of injection if you have a dependency that you do not 102 | always need in the controller, and which is costly to initialize, like the 103 | mailer in the example above. 104 | -------------------------------------------------------------------------------- /Metadata/Driver/ConfiguredControllerInjectionsDriver.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Metadata\Driver; 20 | 21 | use JMS\DiExtraBundle\Metadata\ClassMetadata; 22 | use Metadata\Driver\DriverInterface; 23 | 24 | class ConfiguredControllerInjectionsDriver implements DriverInterface 25 | { 26 | private $delegate; 27 | private $propertyInjections; 28 | private $methodInjections; 29 | 30 | public function __construct(DriverInterface $driver, array $propertyInjections, array $methodInjections) 31 | { 32 | $this->delegate = $driver; 33 | $this->propertyInjections = $propertyInjections; 34 | $this->methodInjections = $methodInjections; 35 | } 36 | 37 | public function loadMetadataForClass(\ReflectionClass $class) 38 | { 39 | $metadata = $this->delegate->loadMetadataForClass($class); 40 | 41 | if (!preg_match('/Controller\\\(.+)Controller$/', $class->name)) { 42 | return $metadata; 43 | } 44 | 45 | if (null === $metadata) { 46 | $metadata = new ClassMetadata($class->name); 47 | } 48 | 49 | foreach ($metadata->reflection->getProperties() as $property) { 50 | // explicit injection configured? 51 | if (isset($metadata->properties[$property->name])) { 52 | continue; 53 | } 54 | 55 | // automatic injection configured? 56 | if (!isset($this->propertyInjections[$property->name])) { 57 | continue; 58 | } 59 | 60 | if ($property->getDeclaringClass()->name !== $class->name) { 61 | continue; 62 | } 63 | 64 | $metadata->properties[$property->name] = $this->propertyInjections[$property->name]; 65 | } 66 | 67 | foreach ($metadata->reflection->getMethods(\ReflectionMethod::IS_PUBLIC) as $method) { 68 | // explicit injection configured? 69 | foreach ($metadata->methodCalls as $call) { 70 | if ($call[0] === $method->name) { 71 | continue 2; 72 | } 73 | } 74 | 75 | // automatic injection configured? 76 | if (!isset($this->methodInjections[$method->name])) { 77 | continue; 78 | } 79 | 80 | if ($method->getDeclaringClass()->name !== $class->name) { 81 | continue; 82 | } 83 | 84 | $metadata->methodCalls[] = array($method->name, $this->methodInjections[$method->name]); 85 | } 86 | 87 | return $metadata->properties || $metadata->methodCalls || $metadata->lookupMethods ? $metadata : null; 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /DependencyInjection/Compiler/IntegrationPass.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\DependencyInjection\Compiler; 20 | 21 | use Symfony\Component\DependencyInjection\Alias; 22 | use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; 23 | use Symfony\Component\DependencyInjection\ContainerBuilder; 24 | use Symfony\Component\DependencyInjection\DefinitionDecorator; 25 | use Symfony\Component\DependencyInjection\Reference; 26 | 27 | /** 28 | * Integrates the bundle with external code. 29 | * 30 | * @author Johannes M. Schmitt 31 | */ 32 | class IntegrationPass implements CompilerPassInterface 33 | { 34 | public function process(ContainerBuilder $container) 35 | { 36 | // replace Symfony2's default controller resolver 37 | $container->setAlias('controller_resolver', new Alias('jms_di_extra.controller_resolver', false)); 38 | 39 | if (true === $container->getParameter('jms_di_extra.doctrine_integration')) { 40 | $this->integrateWithDoctrine($container); 41 | } 42 | } 43 | 44 | /** 45 | * Integrates the DiAwareObjectManager with Doctrine. 46 | * 47 | * This is a bit trickier... mostly because Doctrine uses many factories, 48 | * and we cannot directly inject the EntityManager. We circumvent this 49 | * problem by renaming the original entity manager definition, and then 50 | * placing our definition in its place. 51 | * 52 | * Note that this also currently only supports the ORM, for the ODM flavors 53 | * a similar integration should be possible. 54 | * 55 | * @param ContainerBuilder $container 56 | */ 57 | private function integrateWithDoctrine($container) 58 | { 59 | foreach ($container->getDefinitions() as $id => $definition) { 60 | if (!$definition instanceof DefinitionDecorator) { 61 | continue; 62 | } 63 | 64 | if ('doctrine.orm.entity_manager.abstract' !== $definition->getParent()) { 65 | continue; 66 | } 67 | 68 | $public = $definition->isPublic(); 69 | $definition->setPublic(false); 70 | 71 | $container->setDefinition($id.'.delegate', $definition); 72 | 73 | $container->register($id, $container->getParameter('jms_di_extra.doctrine_integration.entity_manager.class')) 74 | ->setFile($container->getParameter('jms_di_extra.doctrine_integration.entity_manager.file')) 75 | ->addArgument(new Reference($id.'.delegate')) 76 | ->addArgument(new Reference('service_container')) 77 | ->setPublic($public); 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /DependencyInjection/Compiler/LazyServiceMapPass.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\DependencyInjection\Compiler; 20 | 21 | use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; 22 | use Symfony\Component\DependencyInjection\ContainerBuilder; 23 | use Symfony\Component\DependencyInjection\Definition; 24 | use Symfony\Component\DependencyInjection\Reference; 25 | 26 | /** 27 | * This pass allows you to easily create lazy-loading service maps. 28 | * 29 | * ```php 30 | * $container->addCompilerPass(new LazyServiceMapPass( 31 | * 'jms_serializer.visitor', 32 | * 'format', 33 | * function(ContainerBuilder $container, Definition $def) { 34 | * $container->getDefinition('jms_serializer') 35 | * ->addArgument($def); 36 | * } 37 | * )); 38 | * ``` 39 | * 40 | * In the example above, we make the definition of visitors lazy-loading. 41 | * 42 | * @author Johannes M. Schmitt 43 | */ 44 | class LazyServiceMapPass implements CompilerPassInterface, \Serializable 45 | { 46 | private $tagName; 47 | private $keyAttributeName; 48 | private $callable; 49 | 50 | public function __construct($tagName, $keyAttributeName, $callable) 51 | { 52 | $this->tagName = $tagName; 53 | $this->keyAttributeName = $keyAttributeName; 54 | $this->callable = $callable; 55 | } 56 | 57 | public function process(ContainerBuilder $container) 58 | { 59 | if (!is_callable($this->callable)) { 60 | throw new \RuntimeException('The callable is invalid. If you had serialized this pass, the original callable might not be available anymore.'); 61 | } 62 | 63 | $serviceMap = array(); 64 | foreach ($container->findTaggedServiceIds($this->tagName) as $id => $tags) { 65 | foreach ($tags as $tag) { 66 | if (!isset($tag[$this->keyAttributeName])) { 67 | throw new \RuntimeException(sprintf('The attribute "%s" must be set for service "%s" and tag "%s".', $this->keyAttributeName, $id, $this->tagName)); 68 | } 69 | 70 | $serviceMap[$tag[$this->keyAttributeName]] = $id; 71 | } 72 | } 73 | 74 | $def = new Definition('JMS\DiExtraBundle\DependencyInjection\Collection\LazyServiceMap'); 75 | $def->addArgument(new Reference('service_container')); 76 | $def->addArgument($serviceMap); 77 | 78 | call_user_func($this->callable, $container, $def); 79 | } 80 | 81 | public function serialize() 82 | { 83 | return serialize(array($this->tagName, $this->keyAttributeName)); 84 | } 85 | 86 | public function unserialize($str) 87 | { 88 | list($this->tagName, $this->keyAttributeName) = unserialize($str); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /Tests/Metadata/Driver/AnnotationDriverTest.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Tests\Metadata\Driver; 20 | 21 | use Doctrine\Common\Annotations\AnnotationReader; 22 | use JMS\DiExtraBundle\Metadata\DefaultNamingStrategy; 23 | use JMS\DiExtraBundle\Metadata\Driver\AnnotationDriver; 24 | use PHPUnit\Framework\TestCase; 25 | 26 | class AnnotationDriverTest extends TestCase 27 | { 28 | public function testFormType() 29 | { 30 | $metadata = $this->getDriver()->loadMetadataForClass(new \ReflectionClass('JMS\DiExtraBundle\Tests\Metadata\Driver\Fixture\LoginType')); 31 | 32 | $this->assertEquals('j_m_s.di_extra_bundle.tests.metadata.driver.fixture.login_type', $metadata->id); 33 | $this->assertEquals(array( 34 | 'form.type' => array( 35 | array('alias' => 'login'), 36 | ), 37 | ), $metadata->tags); 38 | } 39 | 40 | public function testFormTypeWithExplicitAlias() 41 | { 42 | $metadata = $this->getDriver()->loadMetadataForClass(new \ReflectionClass('JMS\DiExtraBundle\Tests\Metadata\Driver\Fixture\SignUpType')); 43 | 44 | $this->assertEquals(array( 45 | 'form.type' => array( 46 | array('alias' => 'foo'), 47 | ), 48 | ), $metadata->tags); 49 | } 50 | 51 | public function testCustomAnnotationOnClass() 52 | { 53 | $metadata = $this->getDriver()->loadMetadataForClass(new \ReflectionClass('JMS\DiExtraBundle\Tests\Metadata\Driver\Fixture\ClassMetaProcessor')); 54 | $this->assertEquals('works', @$metadata->tags['custom'], 'check value of custom annotation'); 55 | } 56 | 57 | public function testServiceAnnotations() 58 | { 59 | $metadata = $this->getDriver()->loadMetadataForClass(new \ReflectionClass('JMS\DiExtraBundle\Tests\Metadata\Driver\Fixture\Service')); 60 | $this->assertEquals('test.service', $metadata->id); 61 | $this->assertEquals(array('dev', 'test'), $metadata->environments); 62 | $this->assertEquals('test.service', $metadata->decorates); 63 | $this->assertEquals('original.test.service', $metadata->decorationInnerName); 64 | $this->assertEquals('use new.test.service instead', $metadata->deprecated); 65 | $this->assertEquals(false, $metadata->public); 66 | $this->assertEquals(array('JMS\DiExtraBundle\Tests\Metadata\Driver\Fixture\Service'), $metadata->autowiringTypes); 67 | } 68 | 69 | public function testCustomAnnotationOnMethod() 70 | { 71 | $metadata = $this->getDriver()->loadMetadataForClass(new \ReflectionClass('JMS\DiExtraBundle\Tests\Metadata\Driver\Fixture\MethodMetaProcessor')); 72 | $this->assertEquals('fancy', @$metadata->tags['omg'], 'check key and value of custom annotation'); 73 | } 74 | 75 | private function getDriver() 76 | { 77 | return new AnnotationDriver(new AnnotationReader(), new DefaultNamingStrategy()); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /Tests/PerformanceTest.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Tests; 20 | 21 | use JMS\DiExtraBundle\Finder\ServiceFinder; 22 | use JMS\SecurityExtraBundle\JMSSecurityExtraBundle; 23 | use PHPUnit\Framework\TestCase; 24 | use Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle; 25 | use Symfony\Bundle\AsseticBundle\AsseticBundle; 26 | use Symfony\Bundle\DoctrineBundle\DoctrineBundle; 27 | use Symfony\Bundle\FrameworkBundle\FrameworkBundle; 28 | use Symfony\Bundle\MonologBundle\MonologBundle; 29 | use Symfony\Bundle\SecurityBundle\SecurityBundle; 30 | use Symfony\Bundle\TwigBundle\TwigBundle; 31 | 32 | /** 33 | * @group performance 34 | */ 35 | class PerformanceTest extends TestCase 36 | { 37 | /** 38 | * @dataProvider getFinderMethods 39 | */ 40 | public function testServiceFinder($method) 41 | { 42 | $finder = new ServiceFinder(); 43 | $ref = new \ReflectionMethod($finder, $method); 44 | $ref->setAccessible(true); 45 | 46 | $bundles = array( 47 | new FrameworkBundle(), 48 | new SecurityBundle(), 49 | new MonologBundle(), 50 | new AsseticBundle(), 51 | new DoctrineBundle(), 52 | new TwigBundle(), 53 | new SensioFrameworkExtraBundle(), 54 | new JMSSecurityExtraBundle(), 55 | ); 56 | $bundles = array_map(function ($v) { 57 | return $v->getPath(); 58 | }, $bundles); 59 | 60 | $bundles[] = __DIR__.'/../'; 61 | 62 | $time = microtime(true); 63 | for ($i = 0, $c = 5; $i < $c; ++$i) { 64 | $ref->invoke($finder, $bundles); 65 | } 66 | $time = microtime(true) - $time; 67 | $this->printResults('service finder ('.$method.')', $time, $c); 68 | } 69 | 70 | public function getFinderMethods() 71 | { 72 | return array( 73 | array('findUsingGrep'), 74 | array('findUsingFinder'), 75 | ); 76 | } 77 | 78 | private function printResults($test, $time, $iterations) 79 | { 80 | if (0 == $iterations) { 81 | throw new InvalidArgumentException('$iterations cannot be zero.'); 82 | } 83 | 84 | $title = $test." results:\n"; 85 | $iterationsText = sprintf("Iterations: %d\n", $iterations); 86 | $totalTime = sprintf("Total Time: %.3f s\n", $time); 87 | $iterationTime = sprintf("Time per iteration: %.3f ms\n", $time / $iterations * 1000); 88 | 89 | $max = max(strlen($title), strlen($iterationTime)) - 1; 90 | 91 | echo "\n".str_repeat('-', $max)."\n"; 92 | echo $title; 93 | echo str_repeat('=', $max)."\n"; 94 | echo $iterationsText; 95 | echo $totalTime; 96 | echo $iterationTime; 97 | echo str_repeat('-', $max)."\n"; 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /Tests/Functional/AppKernel.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Tests\Functional; 20 | 21 | // get the autoload file 22 | $dir = __DIR__; 23 | $lastDir = null; 24 | while ($dir !== $lastDir) { 25 | $lastDir = $dir; 26 | 27 | if (file_exists($dir.'/autoload.php')) { 28 | require_once $dir.'/autoload.php'; 29 | break; 30 | } 31 | 32 | if (file_exists($dir.'/autoload.php.dist')) { 33 | require_once $dir.'/autoload.php.dist'; 34 | break; 35 | } 36 | 37 | if (file_exists($dir.'/vendor/autoload.php')) { 38 | require_once $dir.'/vendor/autoload.php'; 39 | break; 40 | } 41 | 42 | $dir = dirname($dir); 43 | } 44 | 45 | use Symfony\Component\Config\Loader\LoaderInterface; 46 | use Symfony\Component\Filesystem\Filesystem; 47 | use Symfony\Component\HttpKernel\Kernel; 48 | 49 | class AppKernel extends Kernel 50 | { 51 | private $config; 52 | 53 | public function __construct($config, $debug = true) 54 | { 55 | parent::__construct('test', $debug); 56 | 57 | $fs = new Filesystem(); 58 | if (!$fs->isAbsolutePath($config)) { 59 | $config = __DIR__.'/config/'.$config; 60 | } 61 | 62 | if (!file_exists($config)) { 63 | throw new \RuntimeException(sprintf('The config file "%s" does not exist.', $config)); 64 | } 65 | 66 | $this->config = $config; 67 | } 68 | 69 | public function registerBundles() 70 | { 71 | return array( 72 | new \Symfony\Bundle\FrameworkBundle\FrameworkBundle(), 73 | new \Symfony\Bundle\SecurityBundle\SecurityBundle(), 74 | new \Symfony\Bundle\TwigBundle\TwigBundle(), 75 | new \Doctrine\Bundle\DoctrineBundle\DoctrineBundle(), 76 | new \Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle(), 77 | new \JMS\AopBundle\JMSAopBundle(), 78 | version_compare(PHP_VERSION, '7.0.0', '<')? 79 | new \JMS\DiExtraBundle\Tests\Functional\Bundle\LegacyTestBundle\JMSDiExtraTestBundle(): 80 | new \JMS\DiExtraBundle\Tests\Functional\Bundle\TestBundle\JMSDiExtraTestBundle(), 81 | new \JMS\DiExtraBundle\JMSDiExtraBundle(), 82 | new \JMS\SecurityExtraBundle\JMSSecurityExtraBundle(), 83 | ); 84 | } 85 | 86 | public function registerContainerConfiguration(LoaderInterface $loader) 87 | { 88 | $loader->load($this->config); 89 | if (PHP_VERSION_ID > 50400) { 90 | $loader->load(__DIR__.'/config/traits.yml'); 91 | } 92 | } 93 | 94 | public function getCacheDir() 95 | { 96 | return sys_get_temp_dir().'/JMSDiExtraBundle/'.substr(sha1($this->config), 0, 6); 97 | } 98 | 99 | public function serialize() 100 | { 101 | return serialize(array($this->config, $this->isDebug())); 102 | } 103 | 104 | public function unserialize($str) 105 | { 106 | call_user_func_array(array($this, '__construct'), unserialize($str)); 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /HttpKernel/ControllerInjectorsWarmer.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\HttpKernel; 20 | 21 | use Symfony\Component\Finder\Finder; 22 | use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerAggregate; 23 | use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerInterface; 24 | use Symfony\Component\HttpKernel\KernelInterface; 25 | 26 | class ControllerInjectorsWarmer implements CacheWarmerInterface 27 | { 28 | private $kernel; 29 | private $controllerResolver; 30 | private $blackListedControllerFiles; 31 | private $scanAllBundles; 32 | private $scanBundles; 33 | 34 | public function __construct( 35 | KernelInterface $kernel, 36 | ControllerResolver $resolver, 37 | array $blackListedControllerFiles, 38 | $scanAllBundles = true, 39 | array $scanBundles = array() 40 | ) { 41 | $this->kernel = $kernel; 42 | $this->controllerResolver = $resolver; 43 | $this->blackListedControllerFiles = $blackListedControllerFiles; 44 | $this->scanAllBundles = $scanAllBundles; 45 | $this->scanBundles = $scanBundles; 46 | } 47 | 48 | public function warmUp($cacheDir) 49 | { 50 | // This avoids class-being-declared twice errors when the cache:clear 51 | // command is called. The controllers are not pre-generated in that case. 52 | $suffix = defined('Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerAggregate::NEW_CACHE_FOLDER_SUFFIX') 53 | ? CacheWarmerAggregate::NEW_CACHE_FOLDER_SUFFIX 54 | : '_new'; 55 | 56 | if (basename($cacheDir) === $this->kernel->getEnvironment().$suffix) { 57 | return; 58 | } 59 | 60 | $classes = $this->findControllerClasses(); 61 | foreach ($classes as $class) { 62 | $this->controllerResolver->createInjector($class); 63 | } 64 | } 65 | 66 | public function isOptional() 67 | { 68 | return false; 69 | } 70 | 71 | private function findControllerClasses() 72 | { 73 | $dirs = array(); 74 | foreach ($this->kernel->getBundles() as $bundle) { 75 | if (!$this->scanAllBundles && !in_array($bundle->getName(), $this->scanBundles, true)) { 76 | continue; 77 | } 78 | 79 | if (!is_dir($controllerDir = $bundle->getPath().'/Controller')) { 80 | continue; 81 | } 82 | 83 | $dirs[] = $controllerDir; 84 | } 85 | 86 | // Combination of scanAllBundles/scanBundles can lead to empty dirs. 87 | // Only search for controllers if we have at least one directory, 88 | // otherwise the finder will throw an exception. 89 | if (!empty($dirs)) { 90 | foreach (Finder::create()->name('*Controller.php')->in($dirs)->files() as $file) { 91 | $filename = $file->getRealPath(); 92 | if (!in_array($filename, $this->blackListedControllerFiles)) { 93 | require_once $filename; 94 | } 95 | } 96 | } 97 | 98 | // It is not so important if these controllers never can be reached with 99 | // the current configuration nor whether they are actually controllers. 100 | // Important is only that we do not miss any classes. 101 | return array_filter(get_declared_classes(), function ($name) { 102 | return preg_match('/Controller\\\(.+)Controller$/', $name) > 0; 103 | }); 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /Resources/doc/configuration.rst: -------------------------------------------------------------------------------- 1 | Configuration 2 | ============= 3 | 4 | Introduction 5 | ------------ 6 | By default, you can only use the provided :doc:`annotations ` on your 7 | non-service controllers; no other directories are scanned. 8 | 9 | However, if you also would like to use annotations to configure your regular services, 10 | you can configure more locations as demonstrated below. 11 | 12 | Configuration Locations 13 | ----------------------- 14 | If you would like to configure services in a bundle of yours via annotations, or 15 | have some services outside of any bundles structure such as in your ``src/`` directory, 16 | you can make use of the following configuration options, so that the bundle will pick 17 | them up, and add them to your dependency injection container: 18 | 19 | .. configuration-block :: 20 | 21 | .. code-block :: yaml 22 | 23 | jms_di_extra: 24 | locations: 25 | all_bundles: false 26 | bundles: [FooBundle, AcmeBlogBundle] 27 | directories: ["%kernel.root_dir%/../src"] 28 | 29 | .. code-block :: xml 30 | 31 | 32 | 33 | FooBundle 34 | AcmeBlogBundle 35 | 36 | %kernel.root_dir%/../src 37 | 38 | 39 | 40 | .. tip :: 41 | 42 | For optimal development performance (in production there is no difference either way), 43 | it is recommended to explicitly configure the directories which should be scanned for 44 | service classes, and not rely on the ``all_bundles`` configuration option. 45 | 46 | Automatic Controller Injections 47 | ------------------------------- 48 | This bundle allows you to configure injection for certain properties, and methods 49 | of controllers automatically. This is most useful for commonly needed services 50 | which then do not need to be annotated explicitly anymore. 51 | 52 | .. configuration-block :: 53 | 54 | .. code-block :: yaml 55 | 56 | jms_di_extra: 57 | automatic_controller_injections: 58 | properties: 59 | request: "@request" 60 | router: "@router" 61 | 62 | method_calls: 63 | setRouter: ["@router"] 64 | 65 | .. code-block :: xml 66 | 67 | 68 | 69 | @request 70 | @router 71 | 72 | @router 73 | 74 | 75 | 76 | If your controller has any of the above properties, or methods, then you do not need 77 | to add an @Inject annotation anymore, but we will automatically inject the configured 78 | services for you. However, if you do declare an @Inject annotation it will automatically 79 | overwrite whatever you have configured in the above section. 80 | 81 | Disabling the usage of ``grep`` 82 | ------------------------------- 83 | The bundle uses different methods to find the annotations in your files, depending on 84 | your Operating System and available software. If you are using a Linux distribution 85 | with ``grep`` installed, ``grep`` will be used by default instead of the Symfony Finder 86 | to increase performance. 87 | 88 | Sometimes, you might not want to let the bundle use ``grep``, for example if your 89 | version of grep is too old and therefore does not support some of the more recent options. 90 | In this case, you can disable the usage of ``grep`` with the following configuration. 91 | 92 | .. configuration-block :: 93 | 94 | .. code-block :: yaml 95 | 96 | jms_di_extra: 97 | disable_grep: true 98 | 99 | .. code-block :: xml 100 | 101 | 102 | ... 103 | 104 | -------------------------------------------------------------------------------- /Metadata/ClassMetadata.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Metadata; 20 | 21 | use Metadata\ClassMetadata as BaseClassMetadata; 22 | 23 | /** 24 | * class metadata. 25 | */ 26 | class ClassMetadata extends BaseClassMetadata 27 | { 28 | public $id; 29 | public $parent; 30 | public $scope; 31 | public $shared; 32 | public $public; 33 | public $abstract; 34 | public $tags = array(); 35 | public $arguments; 36 | public $methodCalls = array(); 37 | public $lookupMethods = array(); 38 | public $properties = array(); 39 | /** 40 | * @deprecated since version 1.7, to be removed in 2.0. Use $initMethods instead. 41 | */ 42 | public $initMethod; 43 | public $initMethods = array(); 44 | public $environments = array(); 45 | public $decorates; 46 | public $decorationInnerName; 47 | /** 48 | * @deprecated since version 1.8, to be removed in 2.0. Use $initMethods instead. 49 | */ 50 | public $decoration_inner_name; 51 | public $deprecated; 52 | 53 | public $autowire; 54 | public $autowiringTypes; 55 | 56 | public $factoryMethods = array(); 57 | 58 | /** 59 | * @param string $env 60 | * 61 | * @return bool 62 | */ 63 | public function isLoadedInEnvironment($env) 64 | { 65 | if (empty($this->environments)) { 66 | return true; 67 | } 68 | 69 | return in_array($env, $this->environments, true); 70 | } 71 | 72 | /** 73 | * @return string 74 | */ 75 | public function serialize() 76 | { 77 | return serialize(array( 78 | $this->id, 79 | $this->parent, 80 | $this->scope, 81 | $this->shared, 82 | $this->public, 83 | $this->abstract, 84 | $this->autowire, 85 | $this->tags, 86 | $this->arguments, 87 | $this->methodCalls, 88 | $this->lookupMethods, 89 | $this->properties, 90 | $this->initMethod, 91 | $this->autowiringTypes, 92 | parent::serialize(), 93 | $this->environments, 94 | $this->decorates, 95 | $this->decoration_inner_name, 96 | $this->decorationInnerName, 97 | $this->deprecated, 98 | $this->initMethods, 99 | $this->factoryMethods, 100 | )); 101 | } 102 | 103 | /** 104 | * @param string $str 105 | */ 106 | public function unserialize($str) 107 | { 108 | $data = unserialize($str); 109 | 110 | // prevent errors if not all key's are set 111 | @list( 112 | $this->id, 113 | $this->parent, 114 | $this->scope, 115 | $this->shared, 116 | $this->public, 117 | $this->abstract, 118 | $this->autowire, 119 | $this->tags, 120 | $this->arguments, 121 | $this->methodCalls, 122 | $this->lookupMethods, 123 | $this->properties, 124 | $this->initMethod, 125 | $this->autowiringTypes, 126 | $parentStr, 127 | $this->environments, 128 | $this->decorates, 129 | $this->decoration_inner_name, 130 | $this->decorationInnerName, 131 | $this->deprecated, 132 | $this->initMethods, 133 | $this->factoryMethods) = $data; 134 | 135 | parent::unserialize($parentStr); 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /Tests/Metadata/Driver/ConfiguredControllerInjectionsDriverTest.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Tests\Metadata\Driver; 20 | 21 | use JMS\DiExtraBundle\Metadata\ClassMetadata; 22 | use JMS\DiExtraBundle\Metadata\Driver\ConfiguredControllerInjectionsDriver; 23 | use JMS\DiExtraBundle\Tests\BaseTestCase; 24 | use Symfony\Component\DependencyInjection\Reference; 25 | 26 | class ConfiguredControllerInjectionsDriverTest extends BaseTestCase 27 | { 28 | public function testIgnoresNonControllers() 29 | { 30 | $class = new \ReflectionClass('JMS\DiExtraBundle\Tests\Metadata\Driver\NonControllerClass'); 31 | $this->delegateReturnsEmptyMetadata(); 32 | $metadata = $this->getDriver(array('foo' => new Reference('foo')))->loadMetadataForClass($class); 33 | 34 | $this->assertArrayNotHasKey('foo', $metadata->properties); 35 | } 36 | 37 | public function testLoadMetadataForClass() 38 | { 39 | $class = new \ReflectionClass('JMS\DiExtraBundle\Tests\Metadata\Driver\Controller\MyTestController'); 40 | $this->delegateReturnsEmptyMetadata(); 41 | $metadata = $this->getDriver(array('foo' => $ref = new Reference('foo')), 42 | array('setFoo' => array('foo')))->loadMetadataForClass($class); 43 | 44 | $this->assertArrayHasKey('foo', $metadata->properties); 45 | $this->assertSame($ref, $metadata->properties['foo']); 46 | 47 | $this->assertSame('setFoo', $metadata->methodCalls[0][0]); 48 | $this->assertSame(array('foo'), $metadata->methodCalls[0][1]); 49 | } 50 | 51 | public function testExplicitConfigurationWins() 52 | { 53 | $class = new \ReflectionClass('JMS\DiExtraBundle\Tests\Metadata\Driver\Controller\MyTestController'); 54 | $this->delegate->expects($this->once()) 55 | ->method('loadMetadataForClass') 56 | ->with($class) 57 | ->will($this->returnCallback(function () use ($class) { 58 | $metadata = new ClassMetadata($class->name); 59 | $metadata->properties['foo'] = new Reference('bar'); 60 | $metadata->methodCalls[] = array('setFoo', array('foo')); 61 | 62 | return $metadata; 63 | })) 64 | ; 65 | 66 | $metadata = $this->getDriver(array('foo' => new Reference('baz'), array('setFoo' => array('bar'), 'setBar' => array('bar'))))->loadMetadataForClass($class); 67 | $this->assertArrayHasKey('foo', $metadata->properties); 68 | $this->assertEquals('bar', (string) $metadata->properties['foo']); 69 | 70 | $this->assertSame('setFoo', $metadata->methodCalls[0][0]); 71 | $this->assertEquals(1, count($metadata->methodCalls)); 72 | $this->assertSame(array('foo'), $metadata->methodCalls[0][1]); 73 | } 74 | 75 | protected function setUp() 76 | { 77 | $this->delegate = $this->createMock('Metadata\Driver\DriverInterface'); 78 | } 79 | 80 | private function delegateReturnsEmptyMetadata() 81 | { 82 | $this->delegate 83 | ->expects($this->any()) 84 | ->method('loadMetadataForClass') 85 | ->will($this->returnCallback(function ($v) { 86 | return new ClassMetadata($v->name); 87 | })) 88 | ; 89 | } 90 | 91 | private function getDriver(array $propertyInjections = array(), array $methodInjections = array()) 92 | { 93 | return new ConfiguredControllerInjectionsDriver($this->delegate, $propertyInjections, $methodInjections); 94 | } 95 | } 96 | 97 | class NonControllerClass 98 | { 99 | private $foo; 100 | } 101 | 102 | namespace JMS\DiExtraBundle\Tests\Metadata\Driver\Controller; 103 | 104 | class MyTestController 105 | { 106 | private $foo; 107 | 108 | public function setFoo() 109 | { 110 | } 111 | 112 | private function setBar() 113 | { 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /Generator/LookupMethodClassGenerator.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Generator; 20 | 21 | use CG\Generator\PhpClass; 22 | use CG\Generator\PhpMethod; 23 | use CG\Generator\PhpParameter; 24 | use CG\Generator\PhpProperty; 25 | use CG\Proxy\GeneratorInterface; 26 | use Metadata\ClassHierarchyMetadata; 27 | use Symfony\Component\DependencyInjection\Parameter; 28 | use Symfony\Component\DependencyInjection\Reference; 29 | 30 | class LookupMethodClassGenerator implements GeneratorInterface 31 | { 32 | const PREFIX = '__jmsDiExtra_'; 33 | 34 | private $metadata; 35 | private $requiredFile; 36 | 37 | public function __construct(ClassHierarchyMetadata $metadata) 38 | { 39 | $this->metadata = $metadata; 40 | } 41 | 42 | public function setRequiredFile($file) 43 | { 44 | $this->requiredFile = $file; 45 | } 46 | 47 | public function generate(\ReflectionClass $class, PhpClass $genClass) 48 | { 49 | if (!empty($this->requiredFile)) { 50 | $genClass->addRequiredFile($this->requiredFile); 51 | } 52 | 53 | $genClass->setProperty(PhpProperty::create() 54 | ->setName(self::PREFIX.'container') 55 | ->setVisibility('private') 56 | ); 57 | 58 | $genClass->setMethod(PhpMethod::create() 59 | ->setName(self::PREFIX.'setContainer') 60 | ->addParameter(PhpParameter::create() 61 | ->setName('container') 62 | ->setType('Symfony\Component\DependencyInjection\ContainerInterface') 63 | ) 64 | ->setBody('$this->'.self::PREFIX.'container = $container;') 65 | ); 66 | 67 | $genClass->addInterfaceName('JMS\DiExtraBundle\DependencyInjection\LookupMethodClassInterface'); 68 | $genClass->setMethod(PhpMethod::create() 69 | ->setName(self::PREFIX.'getOriginalClassName') 70 | ->setFinal(true) 71 | ->setBody('return '.var_export($class->name, true).';') 72 | ); 73 | 74 | foreach ($this->getLookupMethods() as $name => $value) { 75 | $genClass->setMethod(PhpMethod::fromReflection($class->getMethod($name)) 76 | ->setAbstract(false) 77 | ->setBody('return '.$this->dumpValue($value).';') 78 | ->setDocblock(null) 79 | ); 80 | } 81 | } 82 | 83 | private function getLookupMethods() 84 | { 85 | $outerClass = $this->metadata->getOutsideClassMetadata()->reflection; 86 | $lookupMethods = array(); 87 | foreach ($this->metadata->classMetadata as $classMetadata) { 88 | if (!$classMetadata->lookupMethods) { 89 | continue; 90 | } 91 | 92 | foreach ($classMetadata->lookupMethods as $name => $value) { 93 | // check if method has been overridden 94 | if ($outerClass->getMethod($name)->class !== $classMetadata->reflection->name) { 95 | continue; 96 | } 97 | 98 | $lookupMethods[$name] = $value; 99 | } 100 | } 101 | 102 | return $lookupMethods; 103 | } 104 | 105 | private function dumpValue($value) 106 | { 107 | if ($value instanceof Parameter) { 108 | return '$this->'.self::PREFIX.'container->getParameter('.var_export((string) $value, true).')'; 109 | } elseif ($value instanceof Reference) { 110 | return '$this->'.self::PREFIX.'container->get('.var_export((string) $value, true).', '.var_export($value->getInvalidBehavior(), true).')'; 111 | } elseif (is_string($value) && '%' === $value[0]) { 112 | return '$this->'.self::PREFIX.'container->getParameter('.var_export(substr($value, 1, -1), true).')'; 113 | } elseif (is_array($value) || is_scalar($value) || null === $value) { 114 | return var_export($value, true); 115 | } 116 | 117 | throw new \RuntimeException(sprintf('Invalid value for lookup method: %s', json_encode($value))); 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /Resources/doc/lazy_service_collections.rst: -------------------------------------------------------------------------------- 1 | Lazy Service Collections 2 | ======================== 3 | This bundle provides a generic lazy service map/sequence. You can use this when you have a map, or a list of services 4 | where you only need to initialize a few specific services during a single request. 5 | 6 | Lazy Service Sequence 7 | --------------------- 8 | Often you have a list of services over which you iterate until a service is able to handle your request. In Symfony2, an 9 | example could be the access decision manager which iterates over voters until it finds one that is able to make an a call 10 | on whether access should be granted or not, and then potentially stops. In such a case, any remaining voters, and their 11 | dependencies are not needed, and do not need to be initialized. 12 | 13 | The lazy service sequence ensures that initialization is delayed until a service is actually needed. Let's start by 14 | writing the service which consumes the sequence:: 15 | 16 | use JMS\DiExtraBundle\Annotation as DI; 17 | use PhpCollection\Sequence; 18 | 19 | class MyService 20 | { 21 | private $voters; 22 | 23 | public function __construct(Sequence $voters) 24 | { 25 | $this->voters = $voters; 26 | } 27 | 28 | public function isGranted(...) 29 | { 30 | foreach ($this->voters as $voter) { 31 | // Do something, potentially return early. 32 | } 33 | } 34 | } 35 | 36 | We assume that you would tag your voters in the DIC to also allow other bundles to register services. Then, you can 37 | use the provided ``LazyServiceSequencePass`` which will take care of collecting the tagged services, and generates 38 | the definition for the sequence:: 39 | 40 | use JMS\DiExtraBundle\Compiler\LazyServiceSequencePass; 41 | use Symfony\Component\DependencyInjection\ContainerBuilder; 42 | use Symfony\Component\DependencyInjection\Definition; 43 | use Symfony\Component\HttpKernel\Bundle\Bundle; 44 | 45 | class MyBundle extends Bundle 46 | { 47 | public function build(ContainerBuilder $container) 48 | { 49 | $container->addCompilerPass(new LazyServiceSequencePass('voter', 50 | function(ContainerBuilder $container, Definition $seqDef) { 51 | // Add the definition of the sequence as argument for the MyService class. 52 | $container->getDefinition('my_service')->addArgument($seqDef); 53 | } 54 | )); 55 | } 56 | } 57 | 58 | 59 | 60 | Lazy Service Map 61 | ---------------- 62 | For example, if you have a map of formats to corresponding encoders. Most likely, you only need to load the encoder for 63 | a specific format during a request. Using the map, loading of that encoder would be delayed until you know which format 64 | you need, and not load encoders (and their dependencies) for other formats. 65 | 66 | Let's start by writing the service which consumes the map:: 67 | 68 | use JMS\DiExtraBundle\Annotation as DI; 69 | use PhpCollection\Map; 70 | 71 | /** @DI\Service("my_service") */ 72 | class MyService 73 | { 74 | private $encoders; 75 | 76 | public function __construct(Map $encoders) 77 | { 78 | $this->encoders = $encoders; 79 | } 80 | 81 | public function useEncoder($format) 82 | { 83 | // The encoder is loaded here. 84 | $encoder = $this->encoders->get('json')->get(); 85 | } 86 | } 87 | 88 | Then, we would add some encoders which we would tag to allow them to be added by other bundles as well:: 89 | 90 | /** @DI\Service @DI\Tag("encoder", attributes = {"format": "json"}) */ 91 | class JsonEncoder { } 92 | 93 | /** @DI\Service @DI\Tag("encoder", attributes = {"format": "xml"}) */ 94 | class XmlEncoder { } 95 | 96 | 97 | Lastly, we just need to add the DI definition of the map which is built by the provided ``LazyServiceMapPass`` as 98 | argument to our service ``my_service``:: 99 | 100 | use JMS\DiExtraBundle\Compiler\LazyServiceMapPass; 101 | use Symfony\Component\DependencyInjection\ContainerBuilder; 102 | use Symfony\Component\DependencyInjection\Definition; 103 | use Symfony\Component\HttpKernel\Bundle\Bundle; 104 | 105 | class MyBundle extends Bundle 106 | { 107 | public function build(ContainerBuilder $container) 108 | { 109 | $container->addCompilerPass(new LazyServiceMapPass('encoder', 'format', 110 | function(ContainerBuilder $container, Definition $mapDef) { 111 | // Add the definition of the map as argument for the MyService class. 112 | $container->getDefinition('my_service')->addArgument($mapDef); 113 | } 114 | )); 115 | } 116 | } 117 | 118 | 119 | -------------------------------------------------------------------------------- /Resources/config/services.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | JMS\DiExtraBundle\Metadata\Driver\AnnotationDriver 9 | JMS\DiExtraBundle\Metadata\Driver\ConfiguredControllerInjectionsDriver 10 | Metadata\Driver\LazyLoadingDriver 11 | 12 | JMS\DiExtraBundle\Metadata\DefaultNamingStrategy 13 | 14 | Metadata\MetadataFactory 15 | Metadata\Cache\FileCache 16 | 17 | JMS\DiExtraBundle\Metadata\MetadataConverter 18 | JMS\DiExtraBundle\HttpKernel\ControllerResolver 19 | 20 | JMS\DiExtraBundle\HttpKernel\ControllerInjectorsWarmer 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | jms_di_extra.metadata_driver 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | %jms_di_extra.cache_warmer.controller_file_blacklist% 68 | %jms_di_extra.all_bundles% 69 | %jms_di_extra.bundles% 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /Generator/RepositoryInjectionGenerator.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Generator; 20 | 21 | use CG\Generator\PhpClass; 22 | use CG\Generator\PhpMethod; 23 | use CG\Generator\PhpParameter; 24 | use CG\Generator\PhpProperty; 25 | use CG\Generator\Writer; 26 | use CG\Proxy\GeneratorInterface; 27 | 28 | class RepositoryInjectionGenerator implements GeneratorInterface 29 | { 30 | public function generate(\ReflectionClass $original, PhpClass $proxy) 31 | { 32 | $writer = new Writer(); 33 | 34 | // copy over all public methods 35 | foreach ($original->getMethods(\ReflectionMethod::IS_PUBLIC) as $method) { 36 | if ($method->isStatic()) { 37 | continue; 38 | } 39 | 40 | $writer->reset()->write('return $this->delegate->')->write($method->name)->write('('); 41 | $first = true; 42 | foreach ($method->getParameters() as $param) { 43 | if (!$first) { 44 | $writer->write(', '); 45 | } 46 | $first = false; 47 | 48 | $writer->write('$')->write($param->name); 49 | } 50 | $writer->write(');'); 51 | 52 | $proxyMethod = PhpMethod::fromReflection($method) 53 | ->setBody($writer->getContent()); 54 | $proxy->setMethod($proxyMethod); 55 | } 56 | 57 | $proxy->setProperty(PhpProperty::create('delegate')->setVisibility('private')); 58 | $proxy->setProperty(PhpProperty::create('container')->setVisibility('private')); 59 | 60 | $proxy->setMethod(PhpMethod::create('__construct') 61 | ->setVisibility('public') 62 | ->addParameter(PhpParameter::create('objectManager')) 63 | ->addParameter(PhpParameter::create('container')->setType('Symfony\\Component\\DependencyInjection\\ContainerInterface')) 64 | ->setBody($writer->reset()->writeln('$this->delegate = $objectManager;')->writeln('$this->container = $container;')->getContent()) 65 | ); 66 | 67 | $proxy->setMethod(PhpMethod::fromReflection($original->getMethod('getRepository')) 68 | ->setParameters(array(PhpParameter::create('className'))) 69 | ->setBody($writer->reset()->writeln('$repository = $this->delegate->getRepository($className);'."\n") 70 | ->writeln('if ($repository instanceof \Symfony\Component\DependencyInjection\ContainerAwareInterface) {') 71 | ->indent() 72 | ->writeln('$repository->setContainer($this->container);'."\n") 73 | ->writeln('return $repository;') 74 | ->outdent() 75 | ->writeln("}\n") 76 | ->writeln('if (null !== $metadata = $this->container->get("jms_di_extra.metadata.metadata_factory")->getMetadataForClass(get_class($repository))) {') 77 | ->indent() 78 | ->writeln('foreach ($metadata->classMetadata as $classMetadata) {') 79 | ->indent() 80 | ->writeln('foreach ($classMetadata->methodCalls as $call) {') 81 | ->indent() 82 | ->writeln('list($method, $arguments) = $call;') 83 | ->writeln('call_user_func_array(array($repository, $method), $this->prepareArguments($arguments));') 84 | ->outdent() 85 | ->writeln('}') 86 | ->outdent() 87 | ->writeln('}') 88 | ->outdent() 89 | ->writeln('}'."\n") 90 | ->writeln('return $repository;') 91 | ->getContent() 92 | ) 93 | ); 94 | 95 | $proxy->setMethod(PhpMethod::create('prepareArguments') 96 | ->setVisibility('private') 97 | ->addParameter(PhpParameter::create('arguments')->setType('array')) 98 | ->setBody($writer->reset()->writeln('$processed = array();') 99 | ->writeln('foreach ($arguments as $arg) {') 100 | ->indent() 101 | ->writeln('if ($arg instanceof \Symfony\Component\DependencyInjection\Reference) {') 102 | ->indent() 103 | ->writeln('$processed[] = $this->container->get((string) $arg, $arg->getInvalidBehavior());') 104 | ->outdent() 105 | ->writeln('} else if ($arg instanceof \Symfony\Component\DependencyInjection\Parameter) {') 106 | ->indent() 107 | ->writeln('$processed[] = $this->container->getParameter((string) $arg);') 108 | ->outdent() 109 | ->writeln('} else {') 110 | ->indent() 111 | ->writeln('$processed[] = $arg;') 112 | ->outdent() 113 | ->writeln('}') 114 | ->outdent() 115 | ->writeln('}'."\n") 116 | ->writeln('return $processed;') 117 | ->getContent() 118 | ) 119 | ); 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /Tests/DependencyInjection/Compiler/AnnotationConfigurationPassTest.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | namespace JMS\DiExtraBundle\Tests\DependencyInjection\Compiler; 20 | 21 | use Doctrine\Common\Annotations\AnnotationReader; 22 | use JMS\DiExtraBundle\DependencyInjection\Compiler\AnnotationConfigurationPass; 23 | use JMS\DiExtraBundle\DependencyInjection\JMSDiExtraExtension; 24 | use PHPUnit\Framework\TestCase; 25 | use Symfony\Component\DependencyInjection\ContainerBuilder; 26 | use Symfony\Component\DependencyInjection\DefinitionDecorator; 27 | use Symfony\Component\DependencyInjection\Reference; 28 | use Symfony\Component\Filesystem\Filesystem; 29 | 30 | class AnnotationConfigurationPassTest extends TestCase 31 | { 32 | public function testProcess() 33 | { 34 | $container = $this->getContainer(array(), array( 35 | __DIR__.'/../../Fixture/', 36 | )); 37 | $container->set('doctrine.entity_manager', $em = new \stdClass()); 38 | $container->set('session', $session = new \stdClass()); 39 | $container->set('database_connection', $dbCon = new \stdClass()); 40 | $container->set('router', $router = new \stdClass()); 41 | $container->setParameter('table_name', 'foo'); 42 | $this->process($container); 43 | 44 | $this->assertTrue($container->hasDefinition('j_m_s.di_extra_bundle.tests.fixture.request_listener')); 45 | $service = $container->get('j_m_s.di_extra_bundle.tests.fixture.request_listener'); 46 | $this->assertAttributeEquals($em, 'em', $service); 47 | $this->assertAttributeEquals($session, 'session', $service); 48 | $this->assertAttributeEquals($dbCon, 'con', $service); 49 | $this->assertAttributeEquals($router, 'router', $service); 50 | $this->assertAttributeEquals('foo', 'table', $service); 51 | } 52 | 53 | public function testProcessValidator() 54 | { 55 | $container = $this->getContainer(array(), array( 56 | __DIR__.'/../../Fixture/Validator', 57 | )); 58 | $container->set('foo', $foo = new \stdClass()); 59 | $this->process($container); 60 | 61 | $this->assertTrue($container->hasDefinition('j_m_s.di_extra_bundle.tests.fixture.validator.validator')); 62 | 63 | $def = $container->getDefinition('j_m_s.di_extra_bundle.tests.fixture.validator.validator'); 64 | $this->assertEquals(array( 65 | 'validator.constraint_validator' => array( 66 | array('alias' => 'foobar'), 67 | ), 68 | ), $def->getTags()); 69 | 70 | $v = $container->get('j_m_s.di_extra_bundle.tests.fixture.validator.validator'); 71 | $this->assertAttributeEquals($foo, 'foo', $v); 72 | } 73 | 74 | public function testConstructorWithInheritance() 75 | { 76 | $container = $this->getContainer(array(), array( 77 | __DIR__.'/../../Functional/Bundle/TestBundle/Inheritance', 78 | )); 79 | $container->set('foo', $foo = new \stdClass()); 80 | $container->set('bar', $bar = new \stdClass()); 81 | $this->process($container); 82 | 83 | $this->assertTrue($container->hasDefinition('concrete_class')); 84 | $this->assertTrue($container->hasDefinition('abstract_class')); 85 | 86 | $def = new DefinitionDecorator('abstract_class'); 87 | $def->setClass('JMS\DiExtraBundle\Tests\Functional\Bundle\TestBundle\Inheritance\ConcreteClass'); 88 | $def->addArgument(new Reference('foo')); 89 | $def->addArgument(new Reference('bar')); 90 | 91 | $this->assertEquals($def, $container->getDefinition('concrete_class')); 92 | } 93 | 94 | protected function setUp() 95 | { 96 | $fs = new Filesystem(); 97 | $fs->remove(sys_get_temp_dir().'/JMSDiExtraBundle-Test-AnnotationCFG'); 98 | } 99 | 100 | protected function tearDown() 101 | { 102 | $fs = new Filesystem(); 103 | $fs->remove(sys_get_temp_dir().'/JMSDiExtraBundle-Test-AnnotationCFG'); 104 | } 105 | 106 | private function getContainer(array $bundles = array(), array $directories = array()) 107 | { 108 | $container = new ContainerBuilder(); 109 | $container->set('annotation_reader', new AnnotationReader()); 110 | $container->setParameter('kernel.debug', false); 111 | $container->setParameter('kernel.environment', 'test'); 112 | $container->setParameter('kernel.bundles', $bundles); 113 | $container->setParameter('kernel.cache_dir', sys_get_temp_dir().'/JMSDiExtraBundle-Test-AnnotationCFG'); 114 | $container->setParameter('kernel.environment', 'test'); 115 | 116 | $extension = new JMSDiExtraExtension(); 117 | $extension->load(array(array( 118 | 'locations' => array( 119 | 'bundles' => $bundles, 120 | 'directories' => $directories, 121 | ), 122 | 'metadata' => array( 123 | 'cache' => 'none', 124 | ), 125 | )), $container); 126 | 127 | return $container; 128 | } 129 | 130 | private function process(ContainerBuilder $container, array $bundles = array()) 131 | { 132 | $container->setParameter('kernel.bundles', $bundles); 133 | 134 | $pass = new AnnotationConfigurationPass(); 135 | $pass->process($container); 136 | } 137 | } 138 | --------------------------------------------------------------------------------