1<?php 2 3/** 4 * Copyright since 2007 PrestaShop SA and Contributors 5 * PrestaShop is an International Registered Trademark & Property of PrestaShop SA 6 * 7 * NOTICE OF LICENSE 8 * 9 * This source file is subject to the Open Software License (OSL 3.0) 10 * that is bundled with this package in the file LICENSE.md. 11 * It is also available through the world-wide-web at this URL: 12 * https://opensource.org/licenses/OSL-3.0 13 * If you did not receive a copy of the license and are unable to 14 * obtain it through the world-wide-web, please send an email 15 * to license@prestashop.com so we can send you a copy immediately. 16 * 17 * DISCLAIMER 18 * 19 * Do not edit or add to this file if you wish to upgrade PrestaShop to newer 20 * versions in the future. If you wish to customize PrestaShop for your 21 * needs please refer to https://devdocs.prestashop.com/ for more information. 22 * 23 * @author PrestaShop SA and Contributors <contact@prestashop.com> 24 * @copyright Since 2007 PrestaShop SA and Contributors 25 * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) 26 */ 27 28namespace PrestaShopBundle\Translation\Loader; 29 30use Doctrine\ORM\EntityManagerInterface; 31use Doctrine\ORM\EntityRepository; 32use Doctrine\ORM\QueryBuilder; 33use PrestaShopBundle\Entity\Lang; 34use PrestaShopBundle\Entity\Translation; 35use Symfony\Component\Translation\Loader\LoaderInterface; 36use Symfony\Component\Translation\MessageCatalogue; 37 38/** 39 * The user translated catalogue is stored in database. 40 * This class is a helper to build the query for retrieving the translations. 41 * They depend on parameters like locale, theme or domain. 42 */ 43class DatabaseTranslationLoader implements LoaderInterface 44{ 45 /** @var EntityManagerInterface */ 46 protected $entityManager; 47 48 /** 49 * @param EntityManagerInterface $entityManager 50 */ 51 public function __construct(EntityManagerInterface $entityManager) 52 { 53 $this->entityManager = $entityManager; 54 } 55 56 /** 57 * {@inheritdoc} 58 * 59 * @todo: this method doesn't match the interface 60 */ 61 public function load($resource, $locale, $domain = 'messages', $theme = null) 62 { 63 static $langs = []; 64 $catalogue = new MessageCatalogue($locale); 65 66 // do not try and load translations for a locale that cannot be saved to DB anyway 67 if ($locale === 'default') { 68 return $catalogue; 69 } 70 71 if (!array_key_exists($locale, $langs)) { 72 $langs[$locale] = $this->entityManager->getRepository('PrestaShopBundle:Lang')->findOneBy(['locale' => $locale]); 73 } 74 75 /** @var EntityRepository $translationRepository */ 76 $translationRepository = $this->entityManager->getRepository('PrestaShopBundle:Translation'); 77 78 $queryBuilder = $translationRepository->createQueryBuilder('t'); 79 80 $this->addLangConstraint($queryBuilder, $langs[$locale]); 81 82 $this->addThemeConstraint($queryBuilder, $theme); 83 84 $this->addDomainConstraint($queryBuilder, $domain); 85 86 $translations = $queryBuilder 87 ->getQuery() 88 ->getResult(); 89 90 /** @var Translation $translation */ 91 foreach ($translations as $translation) { 92 $catalogue->set($translation->getKey(), $translation->getTranslation(), $translation->getDomain()); 93 } 94 95 return $catalogue; 96 } 97 98 /** 99 * @param QueryBuilder $queryBuilder 100 * @param Lang $currentLang 101 */ 102 private function addLangConstraint(QueryBuilder $queryBuilder, Lang $currentLang) 103 { 104 $queryBuilder->andWhere('t.lang =:lang') 105 ->setParameter('lang', $currentLang); 106 } 107 108 /** 109 * @param QueryBuilder $queryBuilder 110 * @param string|null $theme 111 */ 112 private function addThemeConstraint(QueryBuilder $queryBuilder, $theme) 113 { 114 if (null === $theme) { 115 $queryBuilder->andWhere('t.theme IS NULL'); 116 } else { 117 $queryBuilder 118 ->andWhere('t.theme = :theme') 119 ->setParameter('theme', $theme); 120 } 121 } 122 123 /** 124 * @param QueryBuilder $queryBuilder 125 * @param string $domain 126 */ 127 private function addDomainConstraint(QueryBuilder $queryBuilder, $domain) 128 { 129 if ($domain !== '*') { 130 $queryBuilder->andWhere('REGEXP(t.domain, :domain) = true') 131 ->setParameter('domain', $domain); 132 } 133 } 134} 135