diff --git a/src/Service/ComponentFileManager.php b/src/Service/ComponentFileManager.php index b932f1a672cfd4c7c9ddfbd4211be20732c5cdbf..e416392d97ebd0be4b2d090f302efdbe76ec084c 100644 --- a/src/Service/ComponentFileManager.php +++ b/src/Service/ComponentFileManager.php @@ -568,52 +568,168 @@ class ComponentFileManager { } /** - * Get the provider's libraries files. + * Get the provider path. + * + * Depending on the provider, get the path of the theme or module. * * @param string $provider * The component provider. * - * @return array - * The component libraries files. + * @return string + * The theme or module path. */ - public function getLibrariesFilesFromExtension(string $provider): array { + private function getProviderPath(string $provider): string { $themeOrModulePath = $provider; - // Get the theme of module path. + if ($this->moduleExtensionList->exists($provider)) { + $themeOrModulePath = $this->moduleExtensionList->getPath($provider); + } + if ($this->themeExtensionList->exists($provider)) { $themeOrModulePath = $this->themeExtensionList->getPath($provider); } - if ($this->moduleExtensionList->exists($provider)) { - $themeOrModulePath = $this->moduleExtensionList->getPath($provider); + return $themeOrModulePath; + } + + /** + * Flatten the library files. + * + * @param array $libraryYaml + * The component library yaml. + * @param string $basePath + * The base path. + * @param array $flattenedLibraries + * The component libraries files. + * + * @return array + * The flattened libraries files. + */ + private function flattenLibraryFiles( + array $libraryYaml, + string $basePath, + array &$flattenedLibraries, + ): array { + foreach ($libraryYaml as $libraryKey => $libraryValues) { + if (!is_array($libraryValues)) { + continue; + } + + if (count($libraryValues) > 0) { + $this->flattenLibraryFiles($libraryValues, $basePath, $flattenedLibraries); + } + + $extension = pathinfo($libraryKey, PATHINFO_EXTENSION); + + if ($extension !== 'css' && $extension !== 'js') { + continue; + } + + $flattenedLibraries[$extension][] = "$basePath/$libraryKey"; } - $libraryFile = "$themeOrModulePath/$provider.libraries.yml"; + return $flattenedLibraries; + } + + /** + * Get the provider's component files. + * + * @param string $providerPath + * The component provider path. + * @param array $flattenedLibraries + * The component libraries files if given. + * + * @return array + * The flattened libraries files. + */ + private function getProviderComponentsFiles(string $providerPath, array $flattenedLibraries): array { + $componentsPath = "$providerPath/components"; - if (!file_exists($libraryFile)) { - return []; + if (!file_exists($componentsPath)) { + return $flattenedLibraries; } - $library = Yaml::decode(file_get_contents($libraryFile)); - $flattenedLibraries = ['js' => [], 'css' => []]; - - $flattenLibraryFiles = function ($library) use (&$flattenLibraryFiles, &$flattenedLibraries, $themeOrModulePath) { - foreach ($library as $libraryKey => $libraryValues) { - if (!is_array($libraryValues)) { - continue; - } - - if (count($libraryValues) > 0) { - $flattenLibraryFiles($libraryValues); - } - else { - $extension = pathinfo($libraryKey, PATHINFO_EXTENSION); - $flattenedLibraries[$extension][] = "$themeOrModulePath/$libraryKey"; - } + $dir = new \RecursiveDirectoryIterator($componentsPath, \FilesystemIterator::SKIP_DOTS); + $iterator = new \RecursiveIteratorIterator($dir, \RecursiveIteratorIterator::LEAVES_ONLY); + + foreach ($iterator as $file) { + $filepath = $file->getPathname(); + $extension = pathinfo($filepath, PATHINFO_EXTENSION); + + if ($extension !== 'css' && $extension !== 'js') { + continue; } - }; - $flattenLibraryFiles($library); + $flattenedLibraries[$extension][] = $filepath; + } + + return $flattenedLibraries; + } + + /** + * Get the parent theme libraries. + * + * @param string $provider + * The component provider. + * @param string $providerPath + * The component provider path. + * @param array $flattenedLibraries + * The component libraries files. + * + * @return array + * The component libraries files. + */ + private function getParentThemeLibraries(string $provider, string $providerPath, array $flattenedLibraries): array { + if (!$this->themeExtensionList->exists($provider)) { + return $flattenedLibraries; + } + + $infoYmlFile = "$providerPath/$provider.info.yml"; + $infoYml = file_exists($infoYmlFile) ? Yaml::decode(file_get_contents($infoYmlFile)) : []; + + // No base theme then no need to get the parent theme libraries. + if (!array_key_exists('base theme', $infoYml)) { + return $flattenedLibraries; + } + + // Get the base theme libraries. + $baseTheme = $infoYml['base theme']; + $baseThemeLibraryFiles = $this->getLibrariesFilesFromExtension($baseTheme, $flattenedLibraries); + $flattenedLibraries = array_merge_recursive($flattenedLibraries, $baseThemeLibraryFiles); + + return $flattenedLibraries; + } + + /** + * Get the provider's libraries files. + * + * @param string $provider + * The component provider. + * @param array $flattenedLibraries + * The component libraries files if given. + * + * @return array + * The component libraries files. + */ + public function getLibrariesFilesFromExtension( + string $provider, + array $flattenedLibraries = ['js' => [] , 'css' => []], + ): array { + $providerPath = $this->getProviderPath($provider); + // Get the parents files (css, js). + $flattenedLibraries = $this->getParentThemeLibraries($provider, $providerPath, $flattenedLibraries); + + // Get all the provider files set in the libraries.yml file. + $libraryFile = "$providerPath/$provider.libraries.yml"; + + if (file_exists($libraryFile)) { + $library = Yaml::decode(file_get_contents($libraryFile)); + $flattenedLibraries = $this->flattenLibraryFiles($library, $providerPath, $flattenedLibraries); + } + + // Get all the components files (css, js) from the provider. + $flattenedLibraries = $this->getProviderComponentsFiles($providerPath, $flattenedLibraries); + return $flattenedLibraries; }