Browse Source

Fix namespaced plugin translation file path

mscherer 4 years ago
parent
commit
4127908120

+ 5 - 7
src/Command/I18nExtractCommand.php

@@ -618,12 +618,6 @@ class I18nExtractCommand extends Command
                 $output .= $header . $sentence;
             }
 
-            // Remove vendor prefix if present.
-            $slashPosition = strpos($domain, '/');
-            if ($slashPosition !== false) {
-                $domain = substr($domain, $slashPosition + 1);
-            }
-
             $filename = str_replace('/', '_', $domain) . '.pot';
             $outputPath = $this->_output . $filename;
 
@@ -833,11 +827,15 @@ class I18nExtractCommand extends Command
 
         foreach ($this->_paths as $path) {
             $path = realpath($path) . DIRECTORY_SEPARATOR;
+            if (!is_dir($path)) {
+                continue;
+            }
+
             $fs = new Filesystem();
             $files = $fs->findRecursive($path, '/\.php$/');
             $files = array_keys(iterator_to_array($files));
             sort($files);
-            if (!empty($pattern)) {
+            if ($pattern) {
                 $files = preg_grep($pattern, $files, PREG_GREP_INVERT);
                 $files = array_values($files);
             }

+ 29 - 19
src/I18n/MessagesFileLoader.php

@@ -55,7 +55,7 @@ class MessagesFileLoader
      * Creates a translation file loader. The file to be loaded corresponds to
      * the following rules:
      *
-     * - The locale is a folder under the `Locale` directory, a fallback will be
+     * - The locale is a folder under the `Locale/` directory, a fallback will be
      *   used if the folder is not found.
      * - The $name corresponds to the file name to load
      * - If there is a loaded plugin with the underscored version of $name, the
@@ -82,6 +82,8 @@ class MessagesFileLoader
      * ```
      * $loader = new MessagesFileLoader('my_plugin', 'fr_FR', 'mo');
      * $package = $loader();
+     *
+     * Vendor prefixed plugins are expected to use `my_prefix_my_plugin` syntax.
      * ```
      *
      * @param string $name The name (domain) of the translations package.
@@ -108,27 +110,12 @@ class MessagesFileLoader
     public function __invoke(): Package|false
     {
         $folders = $this->translationsFolders();
-        $ext = $this->_extension;
-        $file = false;
-
-        $fileName = $this->_name;
-        $pos = strpos($fileName, '/');
-        if ($pos !== false) {
-            $fileName = substr($fileName, $pos + 1);
-        }
-        foreach ($folders as $folder) {
-            $path = $folder . $fileName . ".$ext";
-            if (is_file($path)) {
-                $file = $path;
-                break;
-            }
-        }
-
+        $file = $this->translationFile($folders, $this->_name, $this->_extension);
         if (!$file) {
             return false;
         }
 
-        $name = ucfirst($ext);
+        $name = ucfirst($this->_extension);
         $class = App::className($name, 'I18n\Parser', 'FileParser');
 
         if (!$class) {
@@ -172,7 +159,7 @@ class MessagesFileLoader
         // If space is not added after slash, the character after it remains lowercased
         $pluginName = Inflector::camelize(str_replace('/', '/ ', $this->_name));
         if (Plugin::isLoaded($pluginName)) {
-            $basePath = App::path('locales', $pluginName)[0];
+            $basePath = Plugin::path($pluginName) . 'resources' . DIRECTORY_SEPARATOR . 'locales' . DIRECTORY_SEPARATOR;
             foreach ($folders as $folder) {
                 $searchPaths[] = $basePath . $folder . DIRECTORY_SEPARATOR;
             }
@@ -180,4 +167,27 @@ class MessagesFileLoader
 
         return $searchPaths;
     }
+
+    /**
+     * @param array<string> $folders Folders
+     * @param string $name File name
+     * @param string $ext File extension
+     * @return string|null File if found
+     */
+    protected function translationFile(array $folders, string $name, string $ext): ?string
+    {
+        $file = null;
+
+        $name = str_replace('/', '_', $name);
+
+        foreach ($folders as $folder) {
+            $path = $folder . $name . ".$ext";
+            if (is_file($path)) {
+                $file = $path;
+                break;
+            }
+        }
+
+        return $file;
+    }
 }

+ 3 - 3
tests/TestCase/Command/I18nExtractCommandTest.php

@@ -269,9 +269,9 @@ class I18nExtractCommandTest extends TestCase
     }
 
     /**
-     * Test that is possible to extract messages from a vendored plugin.
+     * Test that is possible to extract messages from a vendor prefixed plugin.
      */
-    public function testExtractVendoredPlugin(): void
+    public function testExtractVendorPrefixedPlugin(): void
     {
         $this->loadPlugins(['Company/TestPluginThree']);
 
@@ -283,7 +283,7 @@ class I18nExtractCommandTest extends TestCase
         );
         $this->assertExitSuccess();
 
-        $result = file_get_contents($this->path . DS . 'test_plugin_three.pot');
+        $result = file_get_contents($this->path . DS . 'company_test_plugin_three.pot');
         $this->assertDoesNotMatchRegularExpression('#Pages#', $result);
         $this->assertMatchesRegularExpression('/default\.php:\d+/', $result);
         $this->assertStringContainsString('A vendor message', $result);

+ 2 - 2
tests/TestCase/I18n/I18nTest.php

@@ -149,7 +149,7 @@ class I18nTest extends TestCase
      * Tests that messages can also be loaded from plugins by using the
      * domain = plugin_name convention
      */
-    public function testPluginMesagesLoad(): void
+    public function testPluginMessagesLoad(): void
     {
         $this->loadPlugins([
             'TestPlugin',
@@ -170,7 +170,7 @@ class I18nTest extends TestCase
     }
 
     /**
-     * Tests that messages messages from a plugin can be automatically
+     * Tests that messages from a plugin can be automatically
      * overridden by messages in app
      */
     public function testPluginOverride(): void

+ 13 - 0
tests/TestCase/I18n/MessagesFileLoaderTest.php

@@ -78,4 +78,17 @@ class MessagesFileLoaderTest extends TestCase
         $package = $loader();
         $this->assertFalse($package);
     }
+
+    /**
+     * @return void
+     */
+    public function testTranslationsFolders(): void
+    {
+        $this->loadPlugins(['Company/TestPluginThree']);
+
+        $loader = new MessagesFileLoader('company/test_plugin_three', 'es', 'mo');
+
+        $result = $loader->translationsFolders();
+        $this->assertCount(4, $result);
+    }
 }

tests/test_app/Plugin/Company/TestPluginThree/resources/locales/en/test_plugin_three.po → tests/test_app/Plugin/Company/TestPluginThree/resources/locales/en/company_test_plugin_three.po