diff --git a/Catalogue/CatalogueFetcher.php b/Catalogue/CatalogueFetcher.php index e06da8f8..94b90df7 100644 --- a/Catalogue/CatalogueFetcher.php +++ b/Catalogue/CatalogueFetcher.php @@ -12,7 +12,6 @@ namespace Translation\Bundle\Catalogue; use Nyholm\NSA; -use Symfony\Bundle\FrameworkBundle\Translation\TranslationLoader as SymfonyTranslationLoader; use Symfony\Component\Translation\MessageCatalogue; use Symfony\Component\Translation\Reader\TranslationReaderInterface; use Translation\Bundle\Model\Configuration; @@ -35,7 +34,7 @@ final class CatalogueFetcher private $reader; /** - * @param SymfonyTranslationLoader|TranslationLoader|TranslationReaderInterface $reader + * @param TranslationLoader|TranslationReaderInterface $reader */ public function __construct($reader) { diff --git a/Catalogue/CatalogueManager.php b/Catalogue/CatalogueManager.php index 8c9a3135..c0177dd7 100644 --- a/Catalogue/CatalogueManager.php +++ b/Catalogue/CatalogueManager.php @@ -17,7 +17,7 @@ use Translation\Bundle\Model\Metadata; /** - * A manager that handle loaded catalogues. + * A manager that handles loaded catalogues. * * @author Tobias Nyholm */ @@ -123,11 +123,7 @@ public function findMessages(array $config = []): array return $messages; } - /** - * @param string $domain - * @param string $key - */ - public function getTranslations($domain, $key): array + public function getTranslations(string $domain, string $key): array { $translations = []; foreach ($this->catalogues as $locale => $catalogue) { @@ -139,8 +135,13 @@ public function getTranslations($domain, $key): array return $translations; } - private function createMessage(MessageCatalogueInterface $catalogue, string $locale, string $domain, string $key, string $text): CatalogueMessage - { + private function createMessage( + MessageCatalogueInterface $catalogue, + string $locale, + string $domain, + string $key, + string $text + ): CatalogueMessage { $catalogueMessage = new CatalogueMessage($this, $locale, $domain, $key, $text); if ($catalogue instanceof MetadataAwareInterface) { diff --git a/Controller/EditInPlaceController.php b/Controller/EditInPlaceController.php index 52650b27..fc16d4e1 100644 --- a/Controller/EditInPlaceController.php +++ b/Controller/EditInPlaceController.php @@ -11,10 +11,13 @@ namespace Translation\Bundle\Controller; -use Symfony\Bundle\FrameworkBundle\Controller\Controller; +use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\Validator\Validator\ValidatorInterface; use Translation\Bundle\Exception\MessageValidationException; +use Translation\Bundle\Service\CacheClearer; +use Translation\Bundle\Service\StorageManager; use Translation\Bundle\Service\StorageService; use Translation\Common\Model\Message; use Translation\Common\Model\MessageInterface; @@ -22,8 +25,30 @@ /** * @author Damien Alexandre */ -class EditInPlaceController extends Controller +class EditInPlaceController extends AbstractController { + /** + * @var StorageManager + */ + private $storageManager; + + /** + * @var CacheClearer + */ + private $cacheClearer; + + /** + * @var ValidatorInterface + */ + private $validator; + + public function __construct(StorageManager $storageManager, CacheClearer $cacheClearer, ValidatorInterface $validator) + { + $this->storageManager = $storageManager; + $this->cacheClearer = $cacheClearer; + $this->validator = $validator; + } + public function editAction(Request $request, string $configName, string $locale): Response { try { @@ -33,13 +58,13 @@ public function editAction(Request $request, string $configName, string $locale) } /** @var StorageService $storage */ - $storage = $this->get('php_translation.storage_manager')->getStorage($configName); + $storage = $this->storageManager->getStorage($configName); + foreach ($messages as $message) { $storage->update($message); } - $cacheClearer = $this->get('php_translation.cache_clearer'); - $cacheClearer->clearAndWarmUp($locale); + $this->cacheClearer->clearAndWarmUp($locale); return new Response(); } @@ -56,14 +81,13 @@ private function getMessages(Request $request, string $locale, array $validation $json = $request->getContent(); $data = \json_decode($json, true); $messages = []; - $validator = $this->get('validator'); foreach ($data as $key => $value) { [$domain, $translationKey] = \explode('|', $key); $message = new Message($translationKey, $domain, $locale, $value); + $errors = $this->validator->validate($message, null, $validationGroups); - $errors = $validator->validate($message, null, $validationGroups); if (\count($errors) > 0) { throw MessageValidationException::create(); } diff --git a/Controller/SymfonyProfilerController.php b/Controller/SymfonyProfilerController.php index 6eb87f14..9e14742b 100644 --- a/Controller/SymfonyProfilerController.php +++ b/Controller/SymfonyProfilerController.php @@ -11,9 +11,10 @@ namespace Translation\Bundle\Controller; -use Symfony\Bundle\FrameworkBundle\Controller\Controller; +use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\Profiler\Profiler; use Symfony\Component\Translation\DataCollectorTranslator; use Symfony\Component\VarDumper\Cloner\Data; use Translation\Bundle\Model\SfProfilerMessage; @@ -23,8 +24,24 @@ /** * @author Tobias Nyholm */ -class SymfonyProfilerController extends Controller +class SymfonyProfilerController extends AbstractController { + /** + * @var StorageService + */ + private $storageService; + + /** + * @var Profiler + */ + private $profiler; + + public function __construct(StorageService $storageService, Profiler $profiler) + { + $this->storageService = $storageService; + $this->profiler = $profiler; + } + public function editAction(Request $request, string $token): Response { if (!$this->getParameter('php_translation.toolbar.allow_edit')) { @@ -36,11 +53,9 @@ public function editAction(Request $request, string $token): Response } $message = $this->getMessage($request, $token); - /** @var StorageService $storage */ - $storage = $this->get('php_translation.storage'); if ($request->isMethod('GET')) { - $translation = $storage->syncAndFetchMessage($message->getLocale(), $message->getDomain(), $message->getKey()); + $translation = $this->storageService->syncAndFetchMessage($message->getLocale(), $message->getDomain(), $message->getKey()); return $this->render('@Translation/SymfonyProfiler/edit.html.twig', [ 'message' => $translation, @@ -50,7 +65,7 @@ public function editAction(Request $request, string $token): Response //Assert: This is a POST request $message->setTranslation($request->request->get('translation')); - $storage->update($message->convertToMessage()); + $this->storageService->update($message->convertToMessage()); return new Response($message->getTranslation()); } @@ -61,10 +76,8 @@ public function syncAction(Request $request, string $token): Response return $this->redirectToRoute('_profiler', ['token' => $token]); } - /** @var StorageService $storage */ - $storage = $this->get('php_translation.storage'); $sfMessage = $this->getMessage($request, $token); - $message = $storage->syncAndFetchMessage($sfMessage->getLocale(), $sfMessage->getDomain(), $sfMessage->getKey()); + $message = $this->storageService->syncAndFetchMessage($sfMessage->getLocale(), $sfMessage->getDomain(), $sfMessage->getKey()); if (null !== $message) { return new Response($message->getTranslation()); @@ -73,18 +86,13 @@ public function syncAction(Request $request, string $token): Response return new Response('Asset not found', 404); } - /** - * @return \Symfony\Component\HttpFoundation\RedirectResponse|Response - */ public function syncAllAction(Request $request, string $token): Response { if (!$request->isXmlHttpRequest()) { return $this->redirectToRoute('_profiler', ['token' => $token]); } - /** @var StorageService $storage */ - $storage = $this->get('php_translation.storage'); - $storage->sync(); + $this->storageService->sync(); return new Response('Started synchronization of all translations'); } @@ -106,10 +114,9 @@ public function createAssetsAction(Request $request, string $token): Response } $uploaded = []; - /** @var StorageService $storage */ - $storage = $this->get('php_translation.storage'); + foreach ($messages as $message) { - $storage->create($message); + $this->storageService->create($message); $uploaded[] = $message; } @@ -118,12 +125,12 @@ public function createAssetsAction(Request $request, string $token): Response private function getMessage(Request $request, string $token): SfProfilerMessage { - $profiler = $this->get('profiler'); - $profiler->disable(); + $this->profiler->disable(); $messageId = $request->request->get('message_id', $request->query->get('message_id')); - $profile = $profiler->loadProfile($token); + $profile = $this->profiler->loadProfile($token); + if (null === $dataCollector = $profile->getCollector('translation')) { throw $this->createNotFoundException('No collector with name "translation" was found.'); } @@ -137,6 +144,7 @@ private function getMessage(Request $request, string $token): SfProfilerMessage if (!isset($collectorMessages[$messageId])) { throw $this->createNotFoundException(\sprintf('No message with key "%s" was found.', $messageId)); } + $message = SfProfilerMessage::create($collectorMessages[$messageId]); if (DataCollectorTranslator::MESSAGE_EQUALS_FALLBACK === $message->getState()) { @@ -152,15 +160,14 @@ private function getMessage(Request $request, string $token): SfProfilerMessage */ protected function getSelectedMessages(Request $request, string $token): array { - $profiler = $this->get('profiler'); - $profiler->disable(); + $this->profiler->disable(); $selected = $request->request->get('selected'); if (!$selected || 0 == \count($selected)) { return []; } - $profile = $profiler->loadProfile($token); + $profile = $this->profiler->loadProfile($token); $dataCollector = $profile->getCollector('translation'); $messages = $dataCollector->getMessages(); diff --git a/Controller/WebUIController.php b/Controller/WebUIController.php index 451da68c..6ba13554 100644 --- a/Controller/WebUIController.php +++ b/Controller/WebUIController.php @@ -11,15 +11,20 @@ namespace Translation\Bundle\Controller; -use Symfony\Bundle\FrameworkBundle\Controller\Controller; +use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; use Symfony\Component\Intl\Intl; use Symfony\Component\Intl\Locales; use Symfony\Component\Translation\MessageCatalogue; +use Symfony\Component\Validator\Validator\ValidatorInterface; +use Translation\Bundle\Catalogue\CatalogueFetcher; +use Translation\Bundle\Catalogue\CatalogueManager; use Translation\Bundle\Exception\MessageValidationException; use Translation\Bundle\Model\CatalogueMessage; +use Translation\Bundle\Service\ConfigurationManager; +use Translation\Bundle\Service\StorageManager; use Translation\Bundle\Service\StorageService; use Translation\Common\Exception\StorageException; use Translation\Common\Model\Message; @@ -28,8 +33,47 @@ /** * @author Tobias Nyholm */ -class WebUIController extends Controller +class WebUIController extends AbstractController { + /** + * @var StorageManager + */ + private $storageManager; + + /** + * @var ConfigurationManager + */ + private $configurationManager; + + /** + * @var CatalogueManager + */ + private $catalogueManager; + + /** + * @var CatalogueFetcher + */ + private $catalogueFetcher; + + /** + * @var ValidatorInterface + */ + private $validator; + + public function __construct( + StorageManager $storageManager, + ConfigurationManager $configurationManager, + CatalogueManager $catalogueManager, + CatalogueFetcher $catalogueFetcher, + ValidatorInterface $validator + ) { + $this->storageManager = $storageManager; + $this->configurationManager = $configurationManager; + $this->catalogueManager = $catalogueManager; + $this->catalogueFetcher = $catalogueFetcher; + $this->validator = $validator; + } + /** * Show a dashboard for the configuration. */ @@ -39,10 +83,9 @@ public function indexAction(?string $configName = null): Response return new Response('You are not allowed here. Check you config. ', 400); } - $configManager = $this->get('php_translation.configuration_manager'); - $config = $configManager->getConfiguration($configName); + $config = $this->configurationManager->getConfiguration($configName); $localeMap = $this->getLocale2LanguageMap(); - $catalogues = $this->get('php_translation.catalogue_fetcher')->getCatalogues($config); + $catalogues = $this->catalogueFetcher->getCatalogues($config); $catalogueSize = []; $maxDomainSize = []; @@ -75,7 +118,7 @@ public function indexAction(?string $configName = null): Response 'maxCatalogueSize' => $maxCatalogueSize, 'localeMap' => $localeMap, 'configName' => $config->getName(), - 'configNames' => $configManager->getNames(), + 'configNames' => $this->configurationManager->getNames(), ]); } @@ -87,27 +130,26 @@ public function showAction(string $configName, string $locale, string $domain): if (!$this->getParameter('php_translation.webui.enabled')) { return new Response('You are not allowed here. Check you config. ', 400); } - $configManager = $this->get('php_translation.configuration_manager'); - $config = $configManager->getConfiguration($configName); + + $config = $this->configurationManager->getConfiguration($configName); // Get a catalogue manager and load it with all the catalogues - $catalogueManager = $this->get('php_translation.catalogue_manager'); - $catalogueManager->load($this->get('php_translation.catalogue_fetcher')->getCatalogues($config)); + $this->catalogueManager->load($this->catalogueFetcher->getCatalogues($config)); /** @var CatalogueMessage[] $messages */ - $messages = $catalogueManager->getMessages($locale, $domain); + $messages = $this->catalogueManager->getMessages($locale, $domain); \usort($messages, function (CatalogueMessage $a, CatalogueMessage $b) { return \strcmp($a->getKey(), $b->getKey()); }); return $this->render('@Translation/WebUI/show.html.twig', [ 'messages' => $messages, - 'domains' => $catalogueManager->getDomains(), + 'domains' => $this->catalogueManager->getDomains(), 'currentDomain' => $domain, 'locales' => $this->getParameter('php_translation.locales'), 'currentLocale' => $locale, 'configName' => $config->getName(), - 'configNames' => $configManager->getNames(), + 'configNames' => $this->configurationManager->getNames(), 'allow_create' => $this->getParameter('php_translation.webui.allow_create'), 'allow_delete' => $this->getParameter('php_translation.webui.allow_delete'), 'file_base_path' => $this->getParameter('php_translation.webui.file_base_path'), @@ -121,7 +163,7 @@ public function createAction(Request $request, string $configName, string $local } /** @var StorageService $storage */ - $storage = $this->get('php_translation.storage_manager')->getStorage($configName); + $storage = $this->storageManager->getStorage($configName); try { $message = $this->getMessageFromRequest($request); @@ -159,7 +201,7 @@ public function editAction(Request $request, string $configName, string $locale, } /** @var StorageService $storage */ - $storage = $this->get('php_translation.storage_manager')->getStorage($configName); + $storage = $this->storageManager->getStorage($configName); $storage->update($message); return new Response('Translation updated'); @@ -181,13 +223,13 @@ public function deleteAction(Request $request, string $configName, string $local } /** @var StorageService $storage */ - $storage = $this->get('php_translation.storage_manager')->getStorage($configName); + $storage = $this->storageManager->getStorage($configName); $storage->delete($locale, $domain, $message->getKey()); return new Response('Message was deleted'); } - private function getMessageFromRequest(Request $request): Message + private function getMessageFromRequest(Request $request): MessageInterface { $json = $request->getContent(); $data = \json_decode($json, true); @@ -223,7 +265,7 @@ private function getLocale2LanguageMap(): array */ private function validateMessage(MessageInterface $message, array $validationGroups): void { - $errors = $this->get('validator')->validate($message, null, $validationGroups); + $errors = $this->validator->validate($message, null, $validationGroups); if (\count($errors) > 0) { throw MessageValidationException::create(); } diff --git a/DependencyInjection/CompilerPass/ExtractorPass.php b/DependencyInjection/CompilerPass/ExtractorPass.php index 030f0f3f..d131fc49 100644 --- a/DependencyInjection/CompilerPass/ExtractorPass.php +++ b/DependencyInjection/CompilerPass/ExtractorPass.php @@ -54,6 +54,9 @@ private function getExtractors(ContainerBuilder $container): array return $extractors; } + /** + * @param Definition[] $extractors + */ private function addVisitors(ContainerBuilder $container, array $extractors): void { $services = $container->findTaggedServiceIds('php_translation.visitor'); diff --git a/DependencyInjection/TranslationExtension.php b/DependencyInjection/TranslationExtension.php index c7a802cc..125dbd93 100644 --- a/DependencyInjection/TranslationExtension.php +++ b/DependencyInjection/TranslationExtension.php @@ -11,11 +11,11 @@ namespace Translation\Bundle\DependencyInjection; +use Symfony\Component\Config\Definition\ConfigurationInterface; use Symfony\Component\Config\FileLocator; use Symfony\Component\DependencyInjection\Alias; use Symfony\Component\DependencyInjection\ChildDefinition; use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\DependencyInjection\DefinitionDecorator; use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; use Symfony\Component\DependencyInjection\Loader; use Symfony\Component\DependencyInjection\Reference; @@ -32,6 +32,8 @@ class TranslationExtension extends Extension { /** * {@inheritdoc} + * + * @throws \Exception */ public function load(array $configs, ContainerBuilder $container): void { @@ -41,6 +43,7 @@ public function load(array $configs, ContainerBuilder $container): void $loader->load('services.yml'); $loader->load('extractors.yml'); + $loader->load('controllers.yml'); // Add major version to extractor $container->getDefinition('php_translation.extractor.php.visitor.FormTypeChoices') @@ -223,24 +226,15 @@ public function getAlias(): string return 'translation'; } - /** - * To avoid BC break for Symfony 3.3+. - * - * @return ChildDefinition|DefinitionDecorator - */ - private function createChildDefinition(string $parent) + private function createChildDefinition(string $parent): ChildDefinition { - if (\class_exists(ChildDefinition::class)) { - return new ChildDefinition($parent); - } - - return new DefinitionDecorator($parent); + return new ChildDefinition($parent); } /** * {@inheritdoc} */ - public function getConfiguration(array $config, ContainerBuilder $container): Configuration + public function getConfiguration(array $config, ContainerBuilder $container): ConfigurationInterface { return new Configuration($container); } diff --git a/Model/CatalogueMessage.php b/Model/CatalogueMessage.php index e0caf5c2..dd081ee1 100644 --- a/Model/CatalogueMessage.php +++ b/Model/CatalogueMessage.php @@ -59,7 +59,7 @@ public function __construct(CatalogueManager $catalogueManager, string $locale, $this->message = $message; } - public function setMetadata(Metadata $metadata): void + public function setMetadata(?Metadata $metadata): void { $this->metadata = $metadata; } diff --git a/Resources/config/controllers.yml b/Resources/config/controllers.yml new file mode 100644 index 00000000..5a4c99aa --- /dev/null +++ b/Resources/config/controllers.yml @@ -0,0 +1,18 @@ +services: + Translation\Bundle\Controller\EditInPlaceController: + public: true + tags: ['controller.service_arguments'] + arguments: + ['@php_translation.storage_manager', '@php_translation.cache_clearer', '@validator'] + + Translation\Bundle\Controller\SymfonyProfilerController: + public: true + tags: ['controller.service_arguments'] + arguments: + ['@php_translation.storage.abstract', '@profiler'] + + Translation\Bundle\Controller\WebUIController: + public: true + tags: ['controller.service_arguments'] + arguments: + ['@php_translation.storage_manager', '@php_translation.configuration_manager', '@php_translation.catalogue_manager', '@php_translation.catalogue_fetcher', '@validator'] diff --git a/Service/Importer.php b/Service/Importer.php index 7d83057e..d47e3f2a 100644 --- a/Service/Importer.php +++ b/Service/Importer.php @@ -61,10 +61,10 @@ public function __construct(Extractor $extractor, Environment $twig, string $def * @param MessageCatalogue[] $catalogues * @param array $config { * - * @var array $blacklist_domains Blacklist the domains we should exclude. Cannot be used with whitelist. - * @var array $whitelist_domains Whitelist the domains we should include. Cannot be used with blacklist. - * @var string $project_root The project root will be removed from the source location. - * } + * @var array $whitelist_domains Whitelist the domains we should include. Cannot be used with blacklist. + * @var string $project_root The project root will be removed from the source location. + * } + * @var array $blacklist_domains Blacklist the domains we should exclude. Cannot be used with whitelist. */ public function extractToCatalogues(Finder $finder, array $catalogues, array $config = []): ImportResult { diff --git a/composer.json b/composer.json index bbd4551e..a24570a3 100644 --- a/composer.json +++ b/composer.json @@ -22,7 +22,8 @@ "php-translation/symfony-storage": "^1.0", "php-translation/extractor": "^1.6", "nyholm/nsa": "^1.1", - "twig/twig": "^1.42 || ^2.11" + "twig/twig": "^1.42 || ^2.11", + "ext-json": "*" }, "require-dev": { "symfony/phpunit-bridge": "^4.4",