ongr-io /
TranslationsBundle
This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
| 1 | <?php |
||
| 2 | |||
| 3 | /* |
||
| 4 | * This file is part of the ONGR package. |
||
| 5 | * |
||
| 6 | * (c) NFQ Technologies UAB <[email protected]> |
||
| 7 | * |
||
| 8 | * For the full copyright and license information, please view the LICENSE |
||
| 9 | * file that was distributed with this source code. |
||
| 10 | */ |
||
| 11 | |||
| 12 | namespace ONGR\TranslationsBundle\Service\Import; |
||
| 13 | |||
| 14 | use ONGR\ElasticsearchBundle\Service\Manager; |
||
| 15 | use ONGR\ElasticsearchBundle\Service\Repository; |
||
| 16 | use ONGR\ElasticsearchDSL\Query\FullText\MatchQuery; |
||
| 17 | use ONGR\TranslationsBundle\Document\Message; |
||
| 18 | use ONGR\TranslationsBundle\Document\Translation; |
||
| 19 | use Symfony\Component\Finder\Finder; |
||
| 20 | use Symfony\Component\Finder\SplFileInfo; |
||
| 21 | use Symfony\Component\Translation\Exception\InvalidResourceException; |
||
| 22 | use Symfony\Component\Translation\Loader\YamlFileLoader; |
||
| 23 | use Symfony\Component\Yaml\Exception\ParseException; |
||
| 24 | use Symfony\Component\Yaml\Parser as YamlParser; |
||
| 25 | |||
| 26 | /** |
||
| 27 | * Collects translations. |
||
| 28 | */ |
||
| 29 | class ImportManager |
||
| 30 | { |
||
| 31 | /** |
||
| 32 | * @var array |
||
| 33 | */ |
||
| 34 | private $locales; |
||
| 35 | |||
| 36 | /** |
||
| 37 | * @var Repository |
||
| 38 | */ |
||
| 39 | private $repository; |
||
| 40 | |||
| 41 | /** |
||
| 42 | * @var Manager |
||
| 43 | */ |
||
| 44 | private $manager; |
||
| 45 | |||
| 46 | /** |
||
| 47 | * @var YamlFileLoader |
||
| 48 | */ |
||
| 49 | private $parser; |
||
| 50 | |||
| 51 | /** |
||
| 52 | * @var string |
||
| 53 | */ |
||
| 54 | private $kernelRoot; |
||
| 55 | |||
| 56 | /** |
||
| 57 | * @param Repository $repository |
||
| 58 | */ |
||
| 59 | public function __construct( |
||
| 60 | Repository $repository, |
||
| 61 | $kernelRoot |
||
| 62 | ) |
||
| 63 | { |
||
| 64 | $this->parser = new YamlParser(); |
||
|
0 ignored issues
–
show
|
|||
| 65 | $this->repository = $repository; |
||
| 66 | $this->manager = $repository->getManager(); |
||
| 67 | $this->kernelRoot = $kernelRoot; |
||
| 68 | } |
||
| 69 | |||
| 70 | /** |
||
| 71 | * @return array |
||
| 72 | */ |
||
| 73 | public function getLocales() |
||
| 74 | { |
||
| 75 | return $this->locales; |
||
| 76 | } |
||
| 77 | |||
| 78 | /** |
||
| 79 | * @param array $locales |
||
| 80 | */ |
||
| 81 | public function setLocales(array $locales) |
||
| 82 | { |
||
| 83 | $this->locales = $locales; |
||
| 84 | } |
||
| 85 | |||
| 86 | /** |
||
| 87 | * Write translations to storage. |
||
| 88 | * |
||
| 89 | * @param $translations |
||
| 90 | */ |
||
| 91 | public function writeToStorage($domain, $translations) |
||
| 92 | { |
||
| 93 | foreach ($translations as $keys) { |
||
| 94 | foreach ($keys as $key => $transMeta) { |
||
| 95 | $search = $this->repository->createSearch(); |
||
| 96 | $search->addQuery(new MatchQuery('key', $key)); |
||
| 97 | $results = $this->repository->findDocuments($search); |
||
| 98 | if (count($results)) { |
||
| 99 | continue; |
||
| 100 | } |
||
| 101 | |||
| 102 | $document = new Translation(); |
||
| 103 | $document->setDomain($domain); |
||
| 104 | $document->setKey($key); |
||
| 105 | $document->setPath($transMeta['path']); |
||
| 106 | $document->setFormat($transMeta['format']); |
||
| 107 | foreach ($transMeta['messages'] as $locale => $text) { |
||
| 108 | $message = new Message(); |
||
| 109 | $message->setLocale($locale); |
||
| 110 | $message->setMessage($text); |
||
| 111 | $document->addMessage($message); |
||
| 112 | } |
||
| 113 | $this->manager->persist($document); |
||
| 114 | } |
||
| 115 | } |
||
| 116 | |||
| 117 | $this->manager->commit(); |
||
| 118 | } |
||
| 119 | |||
| 120 | /** |
||
| 121 | * @param array $translations |
||
| 122 | */ |
||
| 123 | public function cleanTranslations(array $translations) |
||
| 124 | { |
||
| 125 | $translationKeys = array_keys($translations); |
||
| 126 | $storedTranslations = $this->repository->findBy([]); |
||
| 127 | |||
| 128 | foreach ($storedTranslations as $document) { |
||
| 129 | if (!in_array($document->getKey(), $translationKeys)) { |
||
| 130 | $this->repository->remove($document->getId()); |
||
| 131 | } |
||
| 132 | } |
||
| 133 | } |
||
| 134 | |||
| 135 | /** |
||
| 136 | * Imports translation files from a directory. |
||
| 137 | * @param string $dir |
||
| 138 | */ |
||
| 139 | public function importTranslationFiles($domain, $dir) |
||
| 140 | { |
||
| 141 | $translations = $this->getTranslationsFromFiles($domain, $dir); |
||
| 142 | $this->writeToStorage($domain, $translations); |
||
| 143 | } |
||
| 144 | |||
| 145 | /** |
||
| 146 | * Return a Finder object if $path has a Resources/translations folder. |
||
| 147 | * |
||
| 148 | * @param string $domain |
||
| 149 | * @param string $path |
||
| 150 | * @param array $directories |
||
| 151 | * |
||
| 152 | * @return array |
||
| 153 | */ |
||
| 154 | public function getTranslationsFromFiles($domain, $path, array $directories = []) |
||
| 155 | { |
||
| 156 | if (!$directories) { |
||
|
0 ignored issues
–
show
The expression
$directories of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent. Consider making the comparison explicit by using Loading history...
|
|||
| 157 | $directories = [ |
||
| 158 | $path . 'Resources' . DIRECTORY_SEPARATOR . 'translations', |
||
| 159 | $this->kernelRoot . DIRECTORY_SEPARATOR . 'Resources' . DIRECTORY_SEPARATOR . $domain . DIRECTORY_SEPARATOR . 'translations', |
||
| 160 | ]; |
||
| 161 | } |
||
| 162 | |||
| 163 | $finder = new Finder(); |
||
| 164 | $translations = []; |
||
| 165 | |||
| 166 | foreach ($directories as $directory) { |
||
| 167 | if (is_dir($directory)) { |
||
| 168 | $finder->files() |
||
| 169 | ->name($this->getFileNamePattern()) |
||
| 170 | ->in($directory); |
||
| 171 | |||
| 172 | foreach ($finder as $file) { |
||
| 173 | $translations = array_replace_recursive($this->getFileTranslationMessages($file, $domain), $translations); |
||
| 174 | } |
||
| 175 | } |
||
| 176 | } |
||
| 177 | |||
| 178 | return $translations; |
||
| 179 | } |
||
| 180 | |||
| 181 | /** |
||
| 182 | * @param SplFileInfo $file |
||
| 183 | * @param string $domain |
||
| 184 | * |
||
| 185 | * @return array |
||
| 186 | */ |
||
| 187 | public function getFileTranslationMessages(SplFileInfo $file, $domain) |
||
| 188 | { |
||
| 189 | $locale = explode('.', $file->getFilename())[1]; |
||
| 190 | |||
| 191 | if (!in_array($locale, $this->getLocales())) { |
||
| 192 | return []; |
||
| 193 | } |
||
| 194 | |||
| 195 | $translations = []; |
||
| 196 | |||
| 197 | try { |
||
| 198 | $domainMessages = $this->parser->parse(file_get_contents($file->getPath().DIRECTORY_SEPARATOR.$file->getFilename())); |
||
|
0 ignored issues
–
show
The method
parse() does not seem to exist on object<Symfony\Component...\Loader\YamlFileLoader>.
This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces. This is most likely a typographical error or the method has been renamed. Loading history...
|
|||
| 199 | } catch (ParseException $e) { |
||
| 200 | throw new InvalidResourceException(sprintf('Error parsing YAML, invalid file "%s"', $file->getPath()), 0, $e); |
||
| 201 | } |
||
| 202 | |||
| 203 | $path = substr(pathinfo($file->getPathname(), PATHINFO_DIRNAME), strlen(getcwd()) + 1); |
||
| 204 | |||
| 205 | $domainMessages = $this->flatten($domainMessages); |
||
| 206 | |||
| 207 | foreach ($domainMessages as $key => $content) { |
||
| 208 | $translations[$domain][$key]['messages'][$locale] = $content; |
||
| 209 | $translations[$domain][$key]['path'] = $path; |
||
| 210 | $translations[$domain][$key]['format'] = $file->getExtension(); |
||
| 211 | } |
||
| 212 | |||
| 213 | return $translations; |
||
| 214 | } |
||
| 215 | |||
| 216 | /** |
||
| 217 | * Flatten multidimensional array and concatenating keys |
||
| 218 | * |
||
| 219 | * @param $array |
||
| 220 | * @return array |
||
| 221 | */ |
||
| 222 | View Code Duplication | private function flatten($array, $prefix = '') { |
|
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. Loading history...
|
|||
| 223 | $result = []; |
||
| 224 | foreach($array as $key=>$value) { |
||
| 225 | if(is_array($value)) { |
||
| 226 | $result = $result + $this->flatten($value, $prefix . $key . '.'); |
||
| 227 | } |
||
| 228 | else { |
||
| 229 | $result[$prefix . $key] = $value; |
||
| 230 | } |
||
| 231 | } |
||
| 232 | return $result; |
||
| 233 | } |
||
| 234 | |||
| 235 | /** |
||
| 236 | * @return string |
||
| 237 | */ |
||
| 238 | private function getFileNamePattern() |
||
| 239 | { |
||
| 240 | $regex = sprintf( |
||
| 241 | '/(.*\.(%s)\.(%s))/', |
||
| 242 | implode('|', $this->getLocales()), |
||
| 243 | 'yml$' |
||
| 244 | ); |
||
| 245 | return $regex; |
||
| 246 | } |
||
| 247 | } |
||
| 248 |
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.
Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..