From 888af69692716d4a14924b3864034b752117a35d Mon Sep 17 00:00:00 2001 From: Michael Roterman Date: Thu, 17 Dec 2020 23:55:54 +0100 Subject: [PATCH 1/3] Disable symfony deprecations listener for time being, we need to update the php-tmdb/api lib --- .gitattributes | 7 + .github/workflows/coding-standards.yml | 41 +++ .github/workflows/continuous-integration.yml | 87 ++++++ .gitignore | 1 + .phpunit.result.cache | 1 + ClientConfiguration.php | 4 +- DependencyInjection/Configuration.php | 1 + DependencyInjection/TmdbSymfonyExtension.php | 154 ++++++++++- README.md | 15 +- Resources/config/repositories.xml | 113 ++++---- Resources/config/services.xml | 21 +- Resources/config/twig.xml | 8 +- .../TmdbSymfonyExtensionTest.php | 253 +++++++++++++++++- Tests/TestKernel.php | 39 --- Tests/config.yml | 4 - composer.json | 18 +- phpcs.xml.dist | 7 + phpstan.neon.dist | 9 + phpunit.xml.dist | 39 +-- 19 files changed, 652 insertions(+), 170 deletions(-) create mode 100644 .gitattributes create mode 100644 .github/workflows/coding-standards.yml create mode 100644 .github/workflows/continuous-integration.yml create mode 100644 .phpunit.result.cache delete mode 100644 Tests/TestKernel.php delete mode 100644 Tests/config.yml create mode 100644 phpcs.xml.dist create mode 100644 phpstan.neon.dist diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..22c1526 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,7 @@ +.editorconfig export-ignore +.gitattributes export-ignore +.github export-ignore +.gitignore export-ignore +.php_cs export-ignore +phpstan.neon.dist export-ignore +Tests export-ignore diff --git a/.github/workflows/coding-standards.yml b/.github/workflows/coding-standards.yml new file mode 100644 index 0000000..88f1644 --- /dev/null +++ b/.github/workflows/coding-standards.yml @@ -0,0 +1,41 @@ +#name: "Coding Standards" +# +#on: ["pull_request", "push"] +# +#jobs: +# coding-standards: +# name: "Coding Standards" +# runs-on: "ubuntu-20.04" +# +# strategy: +# matrix: +# php-version: +# - "7.3" +# - "7.4" +# +# steps: +# - name: "Checkout" +# uses: "actions/checkout@v2" +# +# - name: "Install PHP" +# uses: "shivammathur/setup-php@v2" +# with: +# coverage: "none" +# php-version: "${{ matrix.php-version }}" +# tools: "cs2pr" +# +# - name: "Cache dependencies installed with Composer" +# uses: "actions/cache@v2" +# with: +# path: "~/.composer/cache" +# key: "php-${{ matrix.php-version }}-composer-locked-${{ hashFiles('composer.lock') }}" +# restore-keys: "php-${{ matrix.php-version }}-composer-locked-" +# +# - name: "Install dependencies with Composer" +# run: "composer update --no-interaction --no-progress --prefer-dist --prefer-stable" +# +# - name: "Run PHP_CodeSniffer" +# run: "vendor/bin/phpcs -q --no-colors --report=checkstyle | cs2pr" +# +# - name: "Run PHPStan" +# run: "vendor/bin/phpstan analyze" diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml new file mode 100644 index 0000000..d57425e --- /dev/null +++ b/.github/workflows/continuous-integration.yml @@ -0,0 +1,87 @@ +name: "Continuous Integration" + +on: ["pull_request", "push"] + +env: + fail-fast: true + +jobs: + phpunit: + name: "PHPUnit" + runs-on: "ubuntu-20.04" + env: + SYMFONY_REQUIRE: ${{matrix.symfony-require}} + SYMFONY_DEPRECATIONS_HELPER: ${{matrix.symfony-deprecations-helper}} + + strategy: + matrix: + php-version: + - "7.3" + - "7.4" + deps: + - "normal" + symfony-require: + - "" + symfony-deprecations-helper: + - "" + include: + # Test against latest Symfony 4.3 stable + - symfony-require: "4.3.*" + php-version: "7.3" + deps: "normal" + + # Test against latest Symfony 4.4 dev + - symfony-require: "4.4.*" + php-version: "7.3" + deps: "dev" + + # Test against latest Symfony 5.2 dev + - symfony-require: "5.2.*" + php-version: "7.3" + deps: "dev" + + - php-version: "8.0" + deps: "dev" + symfony-deprecations-helper: "weak" + + steps: + - name: "Checkout" + uses: "actions/checkout@v2" + with: + fetch-depth: 2 + + - name: "Install PHP with PCOV" + uses: "shivammathur/setup-php@v2" + with: + php-version: "${{ matrix.php-version }}" + coverage: "pcov" + ini-values: "zend.assertions=1" + extensions: "pdo_sqlite" + + - name: "Cache dependencies installed with composer" + uses: "actions/cache@v2" + with: + path: "~/.composer/cache" + key: "php-${{ matrix.php-version }}-composer-locked-${{ hashFiles('composer.lock') }}" + restore-keys: "php-${{ matrix.php-version }}-composer-locked-" + + - name: "Install stable dependencies with composer" + run: "composer update --no-interaction --prefer-dist --prefer-stable" + if: "${{ matrix.deps == 'normal' }}" + + - name: "Install dev dependencies with composer" + run: "composer update --no-interaction --prefer-dist" + if: "${{ matrix.deps == 'dev' }}" + + - name: "Install lowest possible dependencies with composer" + run: "composer update --no-interaction --prefer-dist --prefer-stable --prefer-lowest" + if: "${{ matrix.deps == 'low' }}" + + - name: "Run PHPUnit" + run: "vendor/bin/phpunit --coverage-clover=coverage.xml" + + - name: "Upload coverage file" + uses: "actions/upload-artifact@v2" + with: + name: "phpunit-${{ matrix.php-version }}-${{ matrix.deps }}-${{ hashFiles('composer.lock') }}.coverage" + path: "coverage.xml" diff --git a/.gitignore b/.gitignore index 63c79b6..ec35c6c 100755 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ composer.lock .idea/ vendor/ +coverage/ diff --git a/.phpunit.result.cache b/.phpunit.result.cache new file mode 100644 index 0000000..63cdc00 --- /dev/null +++ b/.phpunit.result.cache @@ -0,0 +1 @@ +C:37:"PHPUnit\Runner\DefaultTestResultCache":1037:{a:2:{s:7:"defects";a:1:{s:123:"Tmdb\SymfonyBundle\Tests\DependencyInjection\TmdbSymfonyExtensionTest::testDefaultConfigurationWithoutApiKeyThrowsException";i:4;}s:5:"times";a:7:{s:123:"Tmdb\SymfonyBundle\Tests\DependencyInjection\TmdbSymfonyExtensionTest::testDefaultConfigurationWithoutApiKeyThrowsException";d:0.02;s:105:"Tmdb\SymfonyBundle\Tests\DependencyInjection\TmdbSymfonyExtensionTest::testDefaultConfigurationWithApiKey";d:0.014;s:111:"Tmdb\SymfonyBundle\Tests\DependencyInjection\TmdbSymfonyExtensionTest::testDefaultConfigurationHasLegacyAliases";d:0.006;s:96:"Tmdb\SymfonyBundle\Tests\DependencyInjection\TmdbSymfonyExtensionTest::testDisablingRepositories";d:0.003;s:88:"Tmdb\SymfonyBundle\Tests\DependencyInjection\TmdbSymfonyExtensionTest::testDisablingTwig";d:0.005;s:117:"Tmdb\SymfonyBundle\Tests\DependencyInjection\TmdbSymfonyExtensionTest::testDisablingLegacyAliasesRemovesLegacyAliases";d:0.006;s:101:"Tmdb\SymfonyBundle\Tests\DependencyInjection\TmdbSymfonyExtensionTest::testLegacyMappingMapsCorrectly";d:0.006;}}} \ No newline at end of file diff --git a/ClientConfiguration.php b/ClientConfiguration.php index f509d19..6c7aeb4 100644 --- a/ClientConfiguration.php +++ b/ClientConfiguration.php @@ -15,9 +15,9 @@ public function __construct( EventDispatcherInterface $eventDispatcher, array $options = [] ){ - $this->parameters = $options; + $options['event_dispatcher'] = $eventDispatcher; - $this->parameters['event_dispatcher'] = $eventDispatcher; + parent::__construct($options); } public function setCacheHandler(Cache $handler = null) diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index 038831d..804ff03 100755 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -26,6 +26,7 @@ public function getConfigTreeBuilder() ->scalarNode('api_key')->isRequired()->cannotBeEmpty()->end() ->arrayNode('repositories')->canBeDisabled()->end() ->arrayNode('twig_extension')->canBeDisabled()->end() + ->booleanNode('disable_legacy_aliases')->defaultFalse()->end() ->arrayNode('options') ->addDefaultsIfNotSet() ->children() diff --git a/DependencyInjection/TmdbSymfonyExtension.php b/DependencyInjection/TmdbSymfonyExtension.php index 6194347..3a9d17a 100644 --- a/DependencyInjection/TmdbSymfonyExtension.php +++ b/DependencyInjection/TmdbSymfonyExtension.php @@ -2,16 +2,41 @@ namespace Tmdb\SymfonyBundle\DependencyInjection; +use Symfony\Component\Config\FileLocator; use Symfony\Component\DependencyInjection\Alias; use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\Config\FileLocator; -use Symfony\Component\HttpKernel\DependencyInjection\Extension; use Symfony\Component\DependencyInjection\Loader; +use Symfony\Component\HttpKernel\DependencyInjection\Extension; +use Tmdb\ApiToken; +use Tmdb\Client; +use Tmdb\Repository\AccountRepository; +use Tmdb\Repository\AuthenticationRepository; +use Tmdb\Repository\CertificationRepository; +use Tmdb\Repository\ChangesRepository; +use Tmdb\Repository\CollectionRepository; +use Tmdb\Repository\CompanyRepository; +use Tmdb\Repository\ConfigurationRepository; +use Tmdb\Repository\CreditsRepository; +use Tmdb\Repository\DiscoverRepository; +use Tmdb\Repository\FindRepository; +use Tmdb\Repository\GenreRepository; +use Tmdb\Repository\JobsRepository; +use Tmdb\Repository\KeywordRepository; +use Tmdb\Repository\ListRepository; +use Tmdb\Repository\MovieRepository; +use Tmdb\Repository\NetworkRepository; +use Tmdb\Repository\PeopleRepository; +use Tmdb\Repository\ReviewRepository; +use Tmdb\Repository\SearchRepository; +use Tmdb\Repository\TvEpisodeRepository; +use Tmdb\Repository\TvRepository; +use Tmdb\Repository\TvSeasonRepository; +use Tmdb\SymfonyBundle\ClientConfiguration; +use Tmdb\SymfonyBundle\Twig\TmdbExtension; /** - * This is the class that loads and manages your bundle configuration - * - * To learn more see {@link http://symfony.com/doc/current/cookbook/bundles/extension.html} + * Class TmdbSymfonyExtension + * @package Tmdb\SymfonyBundle\DependencyInjection */ class TmdbSymfonyExtension extends Extension { @@ -23,17 +48,29 @@ public function load(array $configs, ContainerBuilder $container) $configuration = new Configuration(); $config = $this->processConfiguration($configuration, $configs); - $loader = new Loader\XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); + $loader = new Loader\XmlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config')); $loader->load('services.xml'); $container->setParameter('tmdb.api_key', $config['api_key']); + if (!$config['disable_legacy_aliases']) { + $this->handleLegacyGeneralAliases($container); + } + if ($config['repositories']['enabled']) { $loader->load('repositories.xml'); + + if (!$config['disable_legacy_aliases']) { + $this->handleLegacyRepositoryAliases($container); + } } if ($config['twig_extension']['enabled']) { $loader->load('twig.xml'); + + if (!$config['disable_legacy_aliases']) { + $this->handleLegacyTwigExtensionAlias($container); + } } $options = $config['options']; @@ -49,6 +86,103 @@ public function load(array $configs, ContainerBuilder $container) $container->setParameter('tmdb.options', $options); } + /** + * Alias mapping for legacy constructs; public to abuse within test suite. + * + * @return \string[][] + */ + public function getLegacyAliasMapping() + { + return [ + 'repositories' => [ + 'tmdb.authentication_repository' => AuthenticationRepository::class, + 'tmdb.account_repository' => AccountRepository::class, + 'tmdb.certification_repository' => CertificationRepository::class, + 'tmdb.changes_repository' => ChangesRepository::class, + 'tmdb.collection_repository' => CollectionRepository::class, + 'tmdb.company_repository' => CompanyRepository::class, + 'tmdb.configuration_repository' => ConfigurationRepository::class, + 'tmdb.credits_repository' => CreditsRepository::class, + 'tmdb.discover_repository' => DiscoverRepository::class, + 'tmdb.find_repository' => FindRepository::class, + 'tmdb.genre_repository' => GenreRepository::class, + 'tmdb.jobs_repository' => JobsRepository::class, + 'tmdb.keyword_repository' => KeywordRepository::class, + 'tmdb.list_repository' => ListRepository::class, + 'tmdb.movie_repository' => MovieRepository::class, + 'tmdb.network_repository' => NetworkRepository::class, + 'tmdb.people_repository' => PeopleRepository::class, + 'tmdb.review_repository' => ReviewRepository::class, + 'tmdb.search_repository' => SearchRepository::class, + 'tmdb.tv_repository' => TvRepository::class, + 'tmdb.tv_episode_repository' => TvEpisodeRepository::class, + 'tmdb.tv_season_repository' => TvSeasonRepository::class, + ], + 'general' => [ + 'tmdb.client' => Client::class, + 'tmdb.api_token' => ApiToken::class, + 'tmdb.configuration' => ClientConfiguration::class + ], + 'twig' => [ + 'tmdb.twig.image_extension' => TmdbExtension::class + ] + ]; + } + + /** + * Performs mapping of legacy aliases to their new service identifiers. + * + * @param $container + * @param array $mapping + */ + protected function performAliasMapping($container, array $mapping = []) + { + foreach ($mapping as $legacyAlias => $newAlias) { + // @todo fix alias with public/private properties + $container->setAlias($legacyAlias, new Alias($newAlias)); + } + } + + /** + * Handle general lgeacy aliases. + * + * @param ContainerBuilder $container + */ + protected function handleLegacyGeneralAliases(ContainerBuilder $container) + { + $mapping = $this->getLegacyAliasMapping(); + $this->performAliasMapping($container, $mapping['general']); + } + + /** + * Map repository legacy aliases + * + * @param ContainerBuilder $container + */ + protected function handleLegacyRepositoryAliases(ContainerBuilder $container) + { + $mapping = $this->getLegacyAliasMapping(); + $this->performAliasMapping($container, $mapping['repositories']); + } + + /** + * Map twig legacy aliases + * + * @param ContainerBuilder $container + */ + protected function handleLegacyTwigExtensionAlias(ContainerBuilder $container) + { + $mapping = $this->getLegacyAliasMapping(); + $this->performAliasMapping($container, $mapping['twig']); + } + + /** + * Handle cache + * + * @param ContainerBuilder $container + * @param $options + * @return mixed + */ protected function handleCache(ContainerBuilder $container, $options) { if (null !== $handler = $options['cache']['handler']) { @@ -60,10 +194,16 @@ protected function handleCache(ContainerBuilder $container, $options) return $options; } + /** + * Handle log + * + * @param $options + * @return mixed + */ protected function handleLog($options) { if (null !== $handler = $options['log']['handler']) { - $options['log']['handler'] = !is_string($handler) ? $handler: new $handler(); + $options['log']['handler'] = !is_string($handler) ? $handler : new $handler(); } return $options; diff --git a/README.md b/README.md index b2847b7..911cc59 100755 --- a/README.md +++ b/README.md @@ -111,6 +111,16 @@ tmdb_symfony: enabled: false ``` +__Disable legacy aliases :__ + +_Set to true to remove all legacy alises ( e.g. `tmdb.client` or `tmdb.movie_repository` )._ + +```yaml +tmdb_symfony: + api_key: YOUR_API_KEY_HERE + disable_legacy_aliases: true +``` + __Full configuration with defaults :__ ```yaml tmdb_symfony: @@ -119,6 +129,7 @@ tmdb_symfony: enabled: true # Set to false to disable repositories twig_extension: enabled: true # Set to false to disable twig extensions + disable_legacy_aliases: false # Set to true to remove all legacy alises ( e.g. `tmdb.client` or `tmdb.movie_repository` ) options: adapter: null secure: true # Set to false to disable https @@ -143,13 +154,13 @@ Usage Obtaining the client ```php -$client = $this->get('tmdb.client'); +$client = $this->get(Tmdb\Client::class); ``` Obtaining repositories ```php -$movie = $this->get('tmdb.movie_repository')->load(13); +$movie = $this->get(\Tmdb\Repository\MovieRepository::class)->load(13); ``` An overview of all the repositories can be found in the services configuration [repositories.xml](https://github.com/php-tmdb/symfony/blob/master/Resources/config/repositories.xml). diff --git a/Resources/config/repositories.xml b/Resources/config/repositories.xml index c1390e5..d1848eb 100755 --- a/Resources/config/repositories.xml +++ b/Resources/config/repositories.xml @@ -4,110 +4,93 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> - - Tmdb\Repository\AuthenticationRepository - Tmdb\Repository\AccountRepository - Tmdb\Repository\CertificationRepository - Tmdb\Repository\ChangesRepository - Tmdb\Repository\CollectionRepository - Tmdb\Repository\CompanyRepository - Tmdb\Repository\ConfigurationRepository - Tmdb\Repository\CreditsRepository - Tmdb\Repository\DiscoverRepository - Tmdb\Repository\FindRepository - Tmdb\Repository\GenreRepository - Tmdb\Repository\JobsRepository - Tmdb\Repository\KeywordRepository - Tmdb\Repository\ListRepository - Tmdb\Repository\MovieRepository - Tmdb\Repository\NetworkRepository - Tmdb\Repository\PeopleRepository - Tmdb\Repository\ReviewRepository - Tmdb\Repository\SearchRepository - Tmdb\Repository\TvRepository - Tmdb\Repository\TvEpisodeRepository - Tmdb\Repository\TvSeasonRepository - - - - + + + + + + + + + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/Resources/config/services.xml b/Resources/config/services.xml index a32e439..2e6bb2b 100755 --- a/Resources/config/services.xml +++ b/Resources/config/services.xml @@ -4,28 +4,17 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> - - - - - Tmdb\Client - Tmdb\SymfonyBundle\ClientConfiguration - Tmdb\ApiToken - Tmdb\RequestToken - Tmdb\SessionToken - - - - - + + + - + %tmdb.api_key% - + %tmdb.options% diff --git a/Resources/config/twig.xml b/Resources/config/twig.xml index 13a908c..9c9a039 100755 --- a/Resources/config/twig.xml +++ b/Resources/config/twig.xml @@ -4,13 +4,9 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> - - Tmdb\SymfonyBundle\Twig\TmdbExtension - - - - + + diff --git a/Tests/DependencyInjection/TmdbSymfonyExtensionTest.php b/Tests/DependencyInjection/TmdbSymfonyExtensionTest.php index 9182d92..170f38b 100644 --- a/Tests/DependencyInjection/TmdbSymfonyExtensionTest.php +++ b/Tests/DependencyInjection/TmdbSymfonyExtensionTest.php @@ -3,23 +3,258 @@ namespace Tmdb\SymfonyBundle\Tests\DependencyInjection; use PHPUnit\Framework\TestCase; -use Symfony\Component\DependencyInjection\Container; -use Tmdb\SymfonyBundle\Tests\TestKernel; +use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\Yaml\Parser; +use Tmdb\SymfonyBundle\DependencyInjection\TmdbSymfonyExtension; final class TmdbSymfonyExtensionTest extends TestCase { + /** @var ContainerBuilder */ + protected $configuration; + + public function testDefaultConfigurationWithoutApiKeyThrowsException(): void + { + $this->expectException(InvalidConfigurationException::class); + $loader = new TmdbSymfonyExtension(); + $config = $this->getEmptyConfig(); + $loader->load([$config], new ContainerBuilder()); + } + + /** + * getEmptyConfig. + * + * @return array + */ + protected function getEmptyConfig(): array + { + return []; + } + + /** + * @test + * @group DependencyInjection + */ + public function testDefaultConfigurationWithApiKey(): void + { + $this->configuration = new ContainerBuilder(); + $loader = new TmdbSymfonyExtension(); + $config = $this->getMinimalConfig(); + $loader->load([$config], $this->configuration); + + $this->assertHasDefinition('Tmdb\Client'); + $this->assertHasDefinition('Tmdb\Repository\MovieRepository'); + $this->assertHasDefinition('Tmdb\SymfonyBundle\Twig\TmdbExtension'); + } + + /** + * getEmptyConfig. + * + * @return array + */ + protected function getMinimalConfig(): array + { + $yaml = <<parse($yaml); + } + + /** + * @param string $id + */ + private function assertHasDefinition($id): void + { + $this->assertTrue(($this->configuration->hasDefinition($id) ?: $this->configuration->hasAlias($id))); + } + + /** + * @test + * @group DependencyInjection + */ + public function testDefaultConfigurationHasLegacyAliases(): void + { + $this->configuration = new ContainerBuilder(); + $loader = new TmdbSymfonyExtension(); + $config = $this->getMinimalConfig(); + $loader->load([$config], $this->configuration); + + $this->assertAlias('Tmdb\Client', 'tmdb.client'); + $this->assertAlias('Tmdb\Repository\MovieRepository', 'tmdb.movie_repository'); + $this->assertAlias('Tmdb\SymfonyBundle\Twig\TmdbExtension', 'tmdb.twig.image_extension'); + } + + /** + * @param string $value + * @param string $key + */ + private function assertAlias($value, $key): void + { + $this->assertSame($value, (string)$this->configuration->getAlias($key), sprintf('%s alias is correct', $key)); + } + + /** + * @test + * @group DependencyInjection + */ + public function testDisablingRepositories(): void + { + $this->configuration = new ContainerBuilder(); + $loader = new TmdbSymfonyExtension(); + $config = $this->getMinimalConfig(); + $config['repositories']['enabled'] = false; + $loader->load([$config], $this->configuration); + + $this->assertAlias('Tmdb\Client', 'tmdb.client'); + $this->assertNotAlias('tmdb.movie_repository'); + $this->assertNotHasDefinition('Tmdb\Repository\MovieRepository'); + } + + /** + * @param string $key + */ + private function assertNotAlias($key): void + { + $this->assertFalse($this->configuration->hasAlias($key), sprintf('%s alias is expected not to be registered', $key)); + } + + /** + * @param string $id + */ + private function assertNotHasDefinition($id): void + { + $this->assertFalse(($this->configuration->hasDefinition($id) ?: $this->configuration->hasAlias($id))); + } + + /** + * @test + * @group DependencyInjection + */ + public function testDisablingTwig(): void + { + $this->configuration = new ContainerBuilder(); + $loader = new TmdbSymfonyExtension(); + $config = $this->getMinimalConfig(); + $config['twig_extension']['enabled'] = false; + $loader->load([$config], $this->configuration); + + $this->assertAlias('Tmdb\Client', 'tmdb.client'); + $this->assertHasDefinition('Tmdb\Repository\MovieRepository'); + $this->assertNotHasDefinition('Tmdb\SymfonyBundle\Twig\TmdbExtension'); + } + + /** + * @test + * @group DependencyInjection + */ + public function testDisablingLegacyAliasesRemovesLegacyAliases(): void + { + $this->configuration = new ContainerBuilder(); + $loader = new TmdbSymfonyExtension(); + $config = $this->getMinimalConfig(); + $config['disable_legacy_aliases'] = true; + $loader->load([$config], $this->configuration); + + $this->assertNotAlias('tmdb.client'); + $this->assertNotAlias('tmdb.movie_repository'); + $this->assertNotAlias('tmdb.twig.image_extension'); + } + /** * @test * @group DependencyInjection */ - public function all_tmdb_services_can_be_loaded() + public function testLegacyMappingMapsCorrectly(): void { - $kernel = new TestKernel('test', true); - $kernel->boot(); + $this->configuration = new ContainerBuilder(); + $loader = new TmdbSymfonyExtension(); + $config = $this->getMinimalConfig(); + $loader->load([$config], $this->configuration); + + foreach ($loader->getLegacyAliasMapping() as $group => $mapping) { + foreach ($mapping as $alias => $serviceIdentifier) { + $this->assertHasDefinition($serviceIdentifier); + $this->assertAlias($serviceIdentifier, $alias); + } + } + } - /** @var Container $container */ - $container = $kernel->getContainer(); - $this->assertInstanceOf('Tmdb\Client', $container->get('tmdb.client')); - $this->assertInstanceOf('Tmdb\Repository\MovieRepository', $container->get('tmdb.movie_repository')); + protected function tearDown(): void + { + $this->configuration = null; + } + + protected function createEmptyConfiguration(): void + { + $this->configuration = new ContainerBuilder(); + $loader = new TmdbSymfonyExtension(); + $config = $this->getEmptyConfig(); + $loader->load([$config], $this->configuration); + $this->assertTrue($this->configuration instanceof ContainerBuilder); + } + + protected function createMinimalConfiguration(): void + { + $this->configuration = new ContainerBuilder(); + $loader = new TmdbSymfonyExtension(); + $config = $this->getMinimalConfig(); + $loader->load([$config], $this->configuration); + $this->assertTrue($this->configuration instanceof ContainerBuilder); + } + + protected function createFullConfiguration(): void + { + $this->configuration = new ContainerBuilder(); + $loader = new TmdbSymfonyExtension(); + $config = $this->getFullConfig(); + $loader->load([$config], $this->configuration); + $this->assertTrue($this->configuration instanceof ContainerBuilder); + } + + /** + * @return mixed + */ + protected function getFullConfig(): array + { + $yaml = <<parse($yaml); + } + + /** + * @param mixed $value + * @param string $key + */ + private function assertParameter($value, $key): void + { + $this->assertSame($value, $this->configuration->getParameter($key), sprintf('%s parameter is correct', $key)); } } diff --git a/Tests/TestKernel.php b/Tests/TestKernel.php deleted file mode 100644 index 0249a58..0000000 --- a/Tests/TestKernel.php +++ /dev/null @@ -1,39 +0,0 @@ -load(__DIR__ . '/config.yml'); - } - - public function getRootDir() - { - return sys_get_temp_dir() . '/php-tmdb-symfony-test'; - } - - public function getCacheDir() - { - return $this->getRootDir() . '/cache'; - } - - public function getLogDir() - { - return $this->getRootDir() . '/logs'; - } -} diff --git a/Tests/config.yml b/Tests/config.yml deleted file mode 100644 index 8d8d68c..0000000 --- a/Tests/config.yml +++ /dev/null @@ -1,4 +0,0 @@ -framework: - secret: NopeChuckTesta -tmdb_symfony: - api_key: invalidapikey diff --git a/composer.json b/composer.json index bd56246..ba835aa 100755 --- a/composer.json +++ b/composer.json @@ -3,7 +3,7 @@ "license": "MIT", "type": "symfony-bundle", "description": "Symfony Bundle for TMDB (The Movie Database) API. Provides easy access to the php-tmdb/api library.", - "homepage": "https://github.com/wtfzdotnet/php-tmdb-api", + "homepage": "https://github.com/php-tmdb/symfony", "keywords": ["tmdb", "api", "php","wrapper", "movie", "cinema", "tv", "tv show", "tvdb", "symfony", "symfony2", "symfony3"], "authors": [ { @@ -13,17 +13,25 @@ } ], "require": { - "php": ">=5.5.0", + "php": ">7.3", + "doctrine/doctrine-cache-bundle": "^1.0", + "php-tmdb/api": "^3.0", "symfony/config": "^4.3.7 || ^5.0", "symfony/dependency-injection": "^4.3.7 || ^5.0", "symfony/event-dispatcher": "^4.3.7 || ^5.0", - "symfony/http-kernel": "^4.3.7 || ^5.0", + "symfony/http-kernel": "^4.3.7 || ^5.1.5", + "symfony/phpunit-bridge": "^4.2", "symfony/yaml": "^4.3.7 || ^5.0", - "php-tmdb/api": "^3.0", "twig/twig": "^2.0|^3.0" }, + "scripts": { + "test": "vendor/bin/phpunit", + "test-ci": "vendor/bin/phpunit --coverage-text --coverage-clover=build/coverage.xml coverage" + }, "require-dev": { - "phpunit/phpunit": ">=5.7", + "slevomat/coding-standard": "^6.4.1", + "squizlabs/php_codesniffer": "^3.5.8", + "phpunit/phpunit": "^7.5 || ^8.0 || ^9.3", "symfony/framework-bundle": "^4.3.7 || ^5.0" }, "autoload": { diff --git a/phpcs.xml.dist b/phpcs.xml.dist new file mode 100644 index 0000000..7abb396 --- /dev/null +++ b/phpcs.xml.dist @@ -0,0 +1,7 @@ + + + . + vendor/* + + + diff --git a/phpstan.neon.dist b/phpstan.neon.dist new file mode 100644 index 0000000..8bdfa6e --- /dev/null +++ b/phpstan.neon.dist @@ -0,0 +1,9 @@ +includes: + - phpstan-baseline.neon + +parameters: + level: 2 + inferPrivatePropertyTypeFromConstructor: true + paths: + - DependencyInjection + - Twig diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 133e76d..9245f03 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,16 +1,25 @@ - - - - ./Tests/ - - + + + + + ./ + + + ./Resources + ./Tests + ./vendor + + + + + + + + + + + + ./Tests/ + + From c2dc3f76af2f179b0be2738ab931769fafcd64bd Mon Sep 17 00:00:00 2001 From: Michael Roterman Date: Sat, 19 Dec 2020 01:15:53 +0100 Subject: [PATCH 2/3] Remove travis integration and add latest composer changes. --- .travis.yml | 37 ------------------------------------- composer.json | 6 +++--- 2 files changed, 3 insertions(+), 40 deletions(-) delete mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 519f6a7..0000000 --- a/.travis.yml +++ /dev/null @@ -1,37 +0,0 @@ -sudo: false -language: php - -php: - - 7.3 - - 7.4 - - nightly - - hhvm - -cache: - directories: - - ~/.composer/cache - -before_script: - - composer self-update - - if [ "$SYMFONY_VERSION" != "" ]; then composer require --no-update symfony/config:${SYMFONY_VERSION} symfony/dependency-injection:${SYMFONY_VERSION} symfony/event-dispatcher:${SYMFONY_VERSION} symfony/http-kernel:${SYMFONY_VERSION} symfony/framework-bundle:${SYMFONY_VERSION}; fi; - - if [ "$SYMFONY_EVENT_DISPATCHER_VERSION" != "" ]; then composer require --no-update symfony/event-dispatcher:${SYMFONY_EVENT_DISPATCHER_VERSION}; fi; - - composer install --no-interaction --prefer-source --dev - -script: vendor/bin/phpunit --verbose - -matrix: - include: - - php: 7.3 - env: [SYMFONY_VERSION="^4.4", SYMFONY_EVENT_DISPATCHER_VERSION="^4.4"] - - php: 7.3 - env: [SYMFONY_VERSION="^5.0", SYMFONY_EVENT_DISPATCHER_VERSION="^5.0"] - - - php: 7.4 - env: [SYMFONY_VERSION="^4.4", SYMFONY_EVENT_DISPATCHER_VERSION="^4.4"] - - php: 7.4 - env: [SYMFONY_VERSION="^5.0", SYMFONY_EVENT_DISPATCHER_VERSION="^5.0"] - - allow_failures: - - php: nightly - - php: hhvm - fast_finish: true diff --git a/composer.json b/composer.json index ba835aa..ea15b5e 100755 --- a/composer.json +++ b/composer.json @@ -17,9 +17,9 @@ "doctrine/doctrine-cache-bundle": "^1.0", "php-tmdb/api": "^3.0", "symfony/config": "^4.3.7 || ^5.0", - "symfony/dependency-injection": "^4.3.7 || ^5.0", - "symfony/event-dispatcher": "^4.3.7 || ^5.0", - "symfony/http-kernel": "^4.3.7 || ^5.1.5", + "symfony/dependency-injection": "^4.3.7,<6", + "symfony/event-dispatcher": "^4.3.7,<6", + "symfony/http-kernel": "^4.3.7,<6", "symfony/phpunit-bridge": "^4.2", "symfony/yaml": "^4.3.7 || ^5.0", "twig/twig": "^2.0|^3.0" From 5f1bca24ec8a11e53073b4d98e876d01e30b1f73 Mon Sep 17 00:00:00 2001 From: Michael Roterman Date: Sat, 19 Dec 2020 01:16:49 +0100 Subject: [PATCH 3/3] Adding support for github actions which includes psalm, phpcs and phpstan. Based on new tools also provides some minor fixes. --- .github/workflows/coding-standards.yml | 86 ++++++++++---------- .github/workflows/static-analysis.yml | 56 +++++++++++++ ClientConfiguration.php | 15 ++-- DependencyInjection/Configuration.php | 1 + DependencyInjection/TmdbSymfonyExtension.php | 38 +++++---- Twig/TmdbExtension.php | 37 +++++++-- composer.json | 6 +- phpcs.xml.dist | 10 ++- phpstan.neon | 10 +++ phpstan.neon.dist | 9 -- phpunit.xml.dist | 2 +- psalm.xml | 16 ++++ 12 files changed, 205 insertions(+), 81 deletions(-) create mode 100644 .github/workflows/static-analysis.yml create mode 100644 phpstan.neon delete mode 100644 phpstan.neon.dist create mode 100644 psalm.xml diff --git a/.github/workflows/coding-standards.yml b/.github/workflows/coding-standards.yml index 88f1644..8c69385 100644 --- a/.github/workflows/coding-standards.yml +++ b/.github/workflows/coding-standards.yml @@ -1,41 +1,45 @@ -#name: "Coding Standards" -# -#on: ["pull_request", "push"] -# -#jobs: -# coding-standards: -# name: "Coding Standards" -# runs-on: "ubuntu-20.04" -# -# strategy: -# matrix: -# php-version: -# - "7.3" -# - "7.4" -# -# steps: -# - name: "Checkout" -# uses: "actions/checkout@v2" -# -# - name: "Install PHP" -# uses: "shivammathur/setup-php@v2" -# with: -# coverage: "none" -# php-version: "${{ matrix.php-version }}" -# tools: "cs2pr" -# -# - name: "Cache dependencies installed with Composer" -# uses: "actions/cache@v2" -# with: -# path: "~/.composer/cache" -# key: "php-${{ matrix.php-version }}-composer-locked-${{ hashFiles('composer.lock') }}" -# restore-keys: "php-${{ matrix.php-version }}-composer-locked-" -# -# - name: "Install dependencies with Composer" -# run: "composer update --no-interaction --no-progress --prefer-dist --prefer-stable" -# -# - name: "Run PHP_CodeSniffer" -# run: "vendor/bin/phpcs -q --no-colors --report=checkstyle | cs2pr" -# -# - name: "Run PHPStan" -# run: "vendor/bin/phpstan analyze" +name: "Coding Standards" + +on: ["pull_request"] + +jobs: + coding-standards: + name: "Coding Standards" + runs-on: "ubuntu-20.04" + + strategy: + matrix: + php-version: + - "7.4" + + steps: + - name: "Checkout" + uses: "actions/checkout@v2" + with: + fetch-depth: 10 + + - name: "Install PHP" + uses: "shivammathur/setup-php@v2" + with: + coverage: "none" + php-version: "${{ matrix.php-version }}" + tools: "cs2pr" + + - name: "Cache dependencies installed with Composer" + uses: "actions/cache@v2" + with: + path: "~/.composer/cache" + key: "php-${{ matrix.php-version }}-composer-locked-${{ hashFiles('composer.lock') }}" + restore-keys: "php-${{ matrix.php-version }}-composer-locked-" + + - name: "Install dependencies with Composer" + run: "composer update --no-interaction --no-progress --prefer-dist --prefer-stable" + + - name: "Install git-phpcs" + run: "wget https://github.com/diff-sniffer/git/releases/download/0.3.2/git-phpcs.phar" + + - name: "Fetch head branch" + run: "git remote set-branches --add origin $GITHUB_BASE_REF && git fetch origin $GITHUB_BASE_REF" + + - name: "Run git-phpcs" + run: "php git-phpcs.phar origin/$GITHUB_BASE_REF...$GITHUB_SHA --report=checkstyle | cs2pr" diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml new file mode 100644 index 0000000..1fd3f32 --- /dev/null +++ b/.github/workflows/static-analysis.yml @@ -0,0 +1,56 @@ +name: Static Analysis + +on: + pull_request: + +jobs: + static-analysis-phpstan: + name: "PHPStan" + runs-on: "ubuntu-latest" + + strategy: + matrix: + php-version: + - "7.4" + + steps: + - name: "Checkout code" + uses: "actions/checkout@v2" + + - name: "Install PHP" + uses: "shivammathur/setup-php@v2" + with: + coverage: "none" + php-version: "${{ matrix.php-version }}" + tools: cs2pr + + - name: "Install dependencies with Composer" + uses: "ramsey/composer-install@v1" + + - name: "Run PHPStan" + run: "vendor/bin/phpstan analyse --error-format=checkstyle --no-progress -c phpstan.neon | cs2pr" + + static-analysis-psalm: + name: "Psalm" + runs-on: "ubuntu-latest" + + strategy: + matrix: + php-version: + - "7.4" + + steps: + - name: "Checkout code" + uses: "actions/checkout@v2" + + - name: "Install PHP" + uses: "shivammathur/setup-php@v2" + with: + coverage: "none" + php-version: "${{ matrix.php-version }}" + + - name: "Install dependencies with Composer" + uses: "ramsey/composer-install@v1" + + - name: "Run a static analysis with vimeo/psalm" + run: "vendor/bin/psalm --show-info=false --stats --output-format=github --threads=$(nproc)" diff --git a/ClientConfiguration.php b/ClientConfiguration.php index 6c7aeb4..ebe2357 100644 --- a/ClientConfiguration.php +++ b/ClientConfiguration.php @@ -1,4 +1,5 @@ $options */ public function __construct( EventDispatcherInterface $eventDispatcher, array $options = [] - ){ + ) { $options['event_dispatcher'] = $eventDispatcher; parent::__construct($options); } - public function setCacheHandler(Cache $handler = null) + /** + * @param Cache|null $handler + */ + public function setCacheHandler(Cache $handler = null): void { $this->parameters['cache']['handler'] = $handler; } /** - * @return array + * @return array */ public function all() { diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index 804ff03..115b717 100755 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -1,4 +1,5 @@ $configs + * @param ContainerBuilder $container + * @return void */ public function load(array $configs, ContainerBuilder $container) { @@ -89,7 +91,7 @@ public function load(array $configs, ContainerBuilder $container) /** * Alias mapping for legacy constructs; public to abuse within test suite. * - * @return \string[][] + * @return array */ public function getLegacyAliasMapping() { @@ -132,10 +134,12 @@ public function getLegacyAliasMapping() /** * Performs mapping of legacy aliases to their new service identifiers. * - * @param $container - * @param array $mapping + * @param ContainerBuilder $container + * @param array $mapping + * + * @return void */ - protected function performAliasMapping($container, array $mapping = []) + protected function performAliasMapping(ContainerBuilder $container, array $mapping = []): void { foreach ($mapping as $legacyAlias => $newAlias) { // @todo fix alias with public/private properties @@ -147,8 +151,10 @@ protected function performAliasMapping($container, array $mapping = []) * Handle general lgeacy aliases. * * @param ContainerBuilder $container + * + * @return void */ - protected function handleLegacyGeneralAliases(ContainerBuilder $container) + protected function handleLegacyGeneralAliases(ContainerBuilder $container): void { $mapping = $this->getLegacyAliasMapping(); $this->performAliasMapping($container, $mapping['general']); @@ -158,8 +164,10 @@ protected function handleLegacyGeneralAliases(ContainerBuilder $container) * Map repository legacy aliases * * @param ContainerBuilder $container + * + * @return void */ - protected function handleLegacyRepositoryAliases(ContainerBuilder $container) + protected function handleLegacyRepositoryAliases(ContainerBuilder $container): void { $mapping = $this->getLegacyAliasMapping(); $this->performAliasMapping($container, $mapping['repositories']); @@ -169,8 +177,10 @@ protected function handleLegacyRepositoryAliases(ContainerBuilder $container) * Map twig legacy aliases * * @param ContainerBuilder $container + * + * @return void */ - protected function handleLegacyTwigExtensionAlias(ContainerBuilder $container) + protected function handleLegacyTwigExtensionAlias(ContainerBuilder $container): void { $mapping = $this->getLegacyAliasMapping(); $this->performAliasMapping($container, $mapping['twig']); @@ -180,10 +190,10 @@ protected function handleLegacyTwigExtensionAlias(ContainerBuilder $container) * Handle cache * * @param ContainerBuilder $container - * @param $options - * @return mixed + * @param array $options + * @return array */ - protected function handleCache(ContainerBuilder $container, $options) + protected function handleCache(ContainerBuilder $container, array $options) { if (null !== $handler = $options['cache']['handler']) { $serviceId = sprintf('doctrine_cache.providers.%s', $options['cache']['handler']); @@ -197,10 +207,10 @@ protected function handleCache(ContainerBuilder $container, $options) /** * Handle log * - * @param $options - * @return mixed + * @param array $options + * @return array */ - protected function handleLog($options) + protected function handleLog(array $options): array { if (null !== $handler = $options['log']['handler']) { $options['log']['handler'] = !is_string($handler) ? $handler : new $handler(); diff --git a/Twig/TmdbExtension.php b/Twig/TmdbExtension.php index 6de674e..534225a 100644 --- a/Twig/TmdbExtension.php +++ b/Twig/TmdbExtension.php @@ -1,4 +1,5 @@ client = $client; } + /** + * @return array|TwigFilter[] + */ public function getFilters() { return array( @@ -32,26 +40,41 @@ public function getFilters() ); } - public function getHtml($image, $size = 'original', $width = null, $height = null) + /** + * @param string $image + * @param string $size + * @param int|null $width + * @param int|null $height + * @return string + */ + public function getHtml(string $image, string $size = 'original', int $width = null, int $height = null): string { return $this->getHelper()->getHtml($image, $size, $width, $height); } - public function getUrl($image, $size = 'original') + /** + * @param string $image + * @param string $size + * @return string + */ + public function getUrl(string $image, string $size = 'original'): string { return $this->getHelper()->getUrl($image, $size); } - public function getName() + /** + * @return string + */ + public function getName(): string { return 'tmdb_extension'; } /** - * @param null $client + * @param Client $client * @return $this */ - public function setClient($client) + public function setClient(Client $client) { $this->client = $client; @@ -59,9 +82,9 @@ public function setClient($client) } /** - * @return null + * @return Client|null */ - public function getClient() + public function getClient(): ?Client { return $this->client; } diff --git a/composer.json b/composer.json index ea15b5e..4280689 100755 --- a/composer.json +++ b/composer.json @@ -13,7 +13,7 @@ } ], "require": { - "php": ">7.3", + "php": "^7.3|^8.0", "doctrine/doctrine-cache-bundle": "^1.0", "php-tmdb/api": "^3.0", "symfony/config": "^4.3.7 || ^5.0", @@ -31,8 +31,10 @@ "require-dev": { "slevomat/coding-standard": "^6.4.1", "squizlabs/php_codesniffer": "^3.5.8", + "phpstan/phpstan": "^0.12.18", "phpunit/phpunit": "^7.5 || ^8.0 || ^9.3", - "symfony/framework-bundle": "^4.3.7 || ^5.0" + "symfony/framework-bundle": "^4.3.7 || ^5.0", + "vimeo/psalm": "^4" }, "autoload": { "psr-4": { "Tmdb\\SymfonyBundle\\": "" } diff --git a/phpcs.xml.dist b/phpcs.xml.dist index 7abb396..c851d73 100644 --- a/phpcs.xml.dist +++ b/phpcs.xml.dist @@ -1,7 +1,13 @@ - + + + + + + + + . vendor/* - diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 0000000..7450740 --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,10 @@ +parameters: + level: 2 + inferPrivatePropertyTypeFromConstructor: true + ignoreErrors: + - '#Call to an undefined method Symfony\\Component\\Config\\Definition\\Builder\\NodeDefinition::children\(\)\.#' + paths: + - . + excludes_analyse: + - Tests + - vendor diff --git a/phpstan.neon.dist b/phpstan.neon.dist deleted file mode 100644 index 8bdfa6e..0000000 --- a/phpstan.neon.dist +++ /dev/null @@ -1,9 +0,0 @@ -includes: - - phpstan-baseline.neon - -parameters: - level: 2 - inferPrivatePropertyTypeFromConstructor: true - paths: - - DependencyInjection - - Twig diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 9245f03..9cc592d 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,4 +1,4 @@ - + diff --git a/psalm.xml b/psalm.xml new file mode 100644 index 0000000..d1fc7bf --- /dev/null +++ b/psalm.xml @@ -0,0 +1,16 @@ + + + + + + + + + +