| Total Complexity | 72 |
| Total Lines | 564 |
| Duplicated Lines | 0 % |
| Changes | 0 | ||
Complex classes like ThemeCompiler often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use ThemeCompiler, and based on these observations, apply Extract Interface, too.
| 1 | <?php declare(strict_types=1); |
||
| 25 | class ThemeCompiler implements ThemeCompilerInterface |
||
|
|
|||
| 26 | { |
||
| 27 | private FilesystemInterface $filesystem; |
||
| 28 | |||
| 29 | private AbstractScssCompiler $scssCompiler; |
||
| 30 | |||
| 31 | private ThemeFileResolver $themeFileResolver; |
||
| 32 | |||
| 33 | private ThemeFileImporterInterface $themeFileImporter; |
||
| 34 | |||
| 35 | private EventDispatcherInterface $eventDispatcher; |
||
| 36 | |||
| 37 | private FilesystemInterface $tempFilesystem; |
||
| 38 | |||
| 39 | /** |
||
| 40 | * @var Package[] |
||
| 41 | */ |
||
| 42 | private iterable $packages; |
||
| 43 | |||
| 44 | private CacheInvalidator $logger; |
||
| 45 | |||
| 46 | private AbstractThemePathBuilder $themePathBuilder; |
||
| 47 | |||
| 48 | private bool $debug; |
||
| 49 | |||
| 50 | private string $projectDir; |
||
| 51 | |||
| 52 | /** |
||
| 53 | * @internal |
||
| 54 | * |
||
| 55 | * @param Package[] $packages |
||
| 56 | */ |
||
| 57 | public function __construct( |
||
| 58 | FilesystemInterface $filesystem, |
||
| 59 | FilesystemInterface $tempFilesystem, |
||
| 60 | ThemeFileResolver $themeFileResolver, |
||
| 61 | bool $debug, |
||
| 62 | EventDispatcherInterface $eventDispatcher, |
||
| 63 | ThemeFileImporterInterface $themeFileImporter, |
||
| 64 | iterable $packages, |
||
| 65 | CacheInvalidator $logger, |
||
| 66 | AbstractThemePathBuilder $themePathBuilder, |
||
| 67 | string $projectDir, |
||
| 68 | AbstractScssCompiler $scssCompiler |
||
| 69 | ) { |
||
| 70 | $this->filesystem = $filesystem; |
||
| 71 | $this->tempFilesystem = $tempFilesystem; |
||
| 72 | $this->themeFileResolver = $themeFileResolver; |
||
| 73 | $this->themeFileImporter = $themeFileImporter; |
||
| 74 | |||
| 75 | $this->scssCompiler = $scssCompiler; |
||
| 76 | |||
| 77 | $this->eventDispatcher = $eventDispatcher; |
||
| 78 | $this->packages = $packages; |
||
| 79 | $this->logger = $logger; |
||
| 80 | $this->themePathBuilder = $themePathBuilder; |
||
| 81 | $this->debug = $debug; |
||
| 82 | $this->projectDir = $projectDir; |
||
| 83 | } |
||
| 84 | |||
| 85 | /** |
||
| 86 | * @param Context $context - @deprecated tag:v6.5.0 parameter $context will be required in v6.5.0.0 |
||
| 87 | */ |
||
| 88 | public function compileTheme( |
||
| 89 | string $salesChannelId, |
||
| 90 | string $themeId, |
||
| 91 | StorefrontPluginConfiguration $themeConfig, |
||
| 92 | StorefrontPluginConfigurationCollection $configurationCollection, |
||
| 93 | bool $withAssets = true/*, |
||
| 94 | Context $context = null */ |
||
| 95 | ): void { |
||
| 96 | if (\func_num_args() === 6) { |
||
| 97 | $context = func_get_arg(5); |
||
| 98 | } else { |
||
| 99 | $context = null; |
||
| 100 | Feature::triggerDeprecationOrThrow( |
||
| 101 | 'v6.5.0.0', |
||
| 102 | sprintf('The parameter context in method compileTheme of class %s is mandatory.', static::class) |
||
| 103 | ); |
||
| 104 | } |
||
| 105 | |||
| 106 | /** |
||
| 107 | * @feature-deprecated (flag:FEATURE_NEXT_15381) keep if branch remove complete following on feature release |
||
| 108 | */ |
||
| 109 | if (Feature::isActive('FEATURE_NEXT_15381')) { |
||
| 110 | $themePrefix = $this->themePathBuilder->assemblePath($salesChannelId, $themeId); |
||
| 111 | |||
| 112 | $resolvedFiles = $this->themeFileResolver->resolveFiles($themeConfig, $configurationCollection, false); |
||
| 113 | |||
| 114 | $styleFiles = $resolvedFiles[ThemeFileResolver::STYLE_FILES]; |
||
| 115 | |||
| 116 | $concatenatedStyles = $this->concatenateStyles( |
||
| 117 | $styleFiles, |
||
| 118 | $themeConfig, |
||
| 119 | $salesChannelId |
||
| 120 | ); |
||
| 121 | |||
| 122 | $compiled = $this->compileStyles( |
||
| 123 | $concatenatedStyles, |
||
| 124 | $themeConfig, |
||
| 125 | $styleFiles->getResolveMappings(), |
||
| 126 | $salesChannelId, |
||
| 127 | $context |
||
| 128 | ); |
||
| 129 | |||
| 130 | if ($this->filesystem->has($this->getTmpOutputPath($themePrefix))) { |
||
| 131 | $this->filesystem->deleteDir($this->getTmpOutputPath($themePrefix)); |
||
| 132 | } |
||
| 133 | |||
| 134 | if ($this->scssCompiler->filesHandledInternal() === false) { |
||
| 135 | $this->filesystem->put($this->getTmpCssFilepath($themePrefix), $compiled); |
||
| 136 | } |
||
| 137 | |||
| 138 | $concatenatedScripts = $this->getConcatenatedScripts($resolvedFiles[ThemeFileResolver::SCRIPT_FILES], $themeConfig, $salesChannelId); |
||
| 139 | |||
| 140 | $this->writeScriptFiles($this->getTmpOutputPath($themePrefix), $concatenatedScripts); |
||
| 141 | |||
| 142 | // assets |
||
| 143 | if ($withAssets) { |
||
| 144 | $this->copyAssets($themeConfig, $configurationCollection, $this->getTmpOutputPath($themePrefix)); |
||
| 145 | } |
||
| 146 | |||
| 147 | $this->copyToLiveLocation($themePrefix, $themeId); |
||
| 148 | |||
| 149 | // Reset cache buster state for improving performance in getMetadata |
||
| 150 | $this->logger->invalidate(['theme-metaData'], true); |
||
| 151 | /** |
||
| 152 | * @feature-deprecated (flag:FEATURE_NEXT_15381) remove return statement on feature release |
||
| 153 | */ |
||
| 154 | return; |
||
| 155 | } |
||
| 156 | |||
| 157 | $themePrefix = $this->themePathBuilder->assemblePath($salesChannelId, $themeId); |
||
| 158 | $outputPath = 'theme' . \DIRECTORY_SEPARATOR . $themePrefix; |
||
| 159 | |||
| 160 | if ($withAssets && $this->filesystem->has($outputPath)) { |
||
| 161 | $this->filesystem->deleteDir($outputPath); |
||
| 162 | } |
||
| 163 | |||
| 164 | $resolvedFiles = $this->themeFileResolver->resolveFiles($themeConfig, $configurationCollection, false); |
||
| 165 | /** @var FileCollection $styleFiles */ |
||
| 166 | $styleFiles = $resolvedFiles[ThemeFileResolver::STYLE_FILES]; |
||
| 167 | |||
| 168 | $concatenatedStyles = ''; |
||
| 169 | foreach ($styleFiles as $file) { |
||
| 170 | $concatenatedStyles .= $this->themeFileImporter->getConcatenableStylePath($file, $themeConfig); |
||
| 171 | } |
||
| 172 | $concatenatedStylesEvent = new ThemeCompilerConcatenatedStylesEvent($concatenatedStyles, $salesChannelId); |
||
| 173 | $this->eventDispatcher->dispatch($concatenatedStylesEvent); |
||
| 174 | $compiled = $this->compileStyles( |
||
| 175 | $concatenatedStylesEvent->getConcatenatedStyles(), |
||
| 176 | $themeConfig, |
||
| 177 | $styleFiles->getResolveMappings(), |
||
| 178 | $salesChannelId, |
||
| 179 | $context |
||
| 180 | ); |
||
| 181 | $cssFilepath = $outputPath . \DIRECTORY_SEPARATOR . 'css' . \DIRECTORY_SEPARATOR . 'all.css'; |
||
| 182 | $this->filesystem->put($cssFilepath, $compiled); |
||
| 183 | |||
| 184 | /** @var FileCollection $scriptFiles */ |
||
| 185 | $scriptFiles = $resolvedFiles[ThemeFileResolver::SCRIPT_FILES]; |
||
| 186 | $concatenatedScripts = ''; |
||
| 187 | foreach ($scriptFiles as $file) { |
||
| 188 | $concatenatedScripts .= $this->themeFileImporter->getConcatenableScriptPath($file, $themeConfig); |
||
| 189 | } |
||
| 190 | $concatenatedScriptsEvent = new ThemeCompilerConcatenatedScriptsEvent($concatenatedScripts, $salesChannelId); |
||
| 191 | $this->eventDispatcher->dispatch($concatenatedScriptsEvent); |
||
| 192 | |||
| 193 | $scriptFilepath = $outputPath . \DIRECTORY_SEPARATOR . 'js' . \DIRECTORY_SEPARATOR . 'all.js'; |
||
| 194 | $this->filesystem->put($scriptFilepath, $concatenatedScriptsEvent->getConcatenatedScripts()); |
||
| 195 | |||
| 196 | // assets |
||
| 197 | if ($withAssets) { |
||
| 198 | $this->copyAssets($themeConfig, $configurationCollection, $outputPath); |
||
| 199 | } |
||
| 200 | |||
| 201 | // Reset cache buster state for improving performance in getMetadata |
||
| 202 | $this->logger->invalidate(['theme-metaData'], true); |
||
| 203 | } |
||
| 204 | |||
| 205 | /** |
||
| 206 | * @deprecated tag:v6.5.0 - Use AbstractThemePathBuilder instead |
||
| 207 | */ |
||
| 208 | public static function getThemePrefix(string $salesChannelId, string $themeId): string |
||
| 209 | { |
||
| 210 | Feature::triggerDeprecationOrThrow( |
||
| 211 | 'v6.5.0.0', |
||
| 212 | Feature::deprecatedMethodMessage(__CLASS__, __METHOD__, 'v6.5.0.0', 'AbstractThemePathBuilder') |
||
| 213 | ); |
||
| 214 | |||
| 215 | return md5($themeId . $salesChannelId); |
||
| 216 | } |
||
| 217 | |||
| 218 | /** |
||
| 219 | * @param array<string, string> $resolveMappings |
||
| 220 | */ |
||
| 221 | public function getResolveImportPathsCallback(array $resolveMappings): \Closure |
||
| 222 | { |
||
| 223 | return function ($originalPath) use ($resolveMappings) { |
||
| 224 | foreach ($resolveMappings as $resolve => $resolvePath) { |
||
| 225 | $resolve = '~' . $resolve; |
||
| 226 | if (mb_strpos($originalPath, $resolve) === 0) { |
||
| 227 | /** |
||
| 228 | * @deprecated tag:v6.5.0 - Alias `vendorBootstrap` will be removed. |
||
| 229 | * |
||
| 230 | * Alias is used to import Bootstrap v5 instead of Bootstrap v4 if feature flag v6.5.0.0 is active. |
||
| 231 | * Package `bootstrap5` will be renamed to `bootstrap` and replace Bootstrap v4. |
||
| 232 | * Remove this if completely. |
||
| 233 | */ |
||
| 234 | if (mb_strpos($originalPath, '~vendorBootstrap/') === 0) { |
||
| 235 | $originalPath = Feature::isActive('v6.5.0.0') |
||
| 236 | ? str_replace('~vendorBootstrap/', '~vendor/bootstrap5/', $originalPath) |
||
| 237 | : str_replace('~vendorBootstrap/', '~vendor/bootstrap/', $originalPath); |
||
| 238 | } |
||
| 239 | |||
| 240 | $dirname = $resolvePath . \dirname(mb_substr($originalPath, mb_strlen($resolve))); |
||
| 241 | |||
| 242 | $filename = basename($originalPath); |
||
| 243 | $extension = $this->getImportFileExtension(pathinfo($filename, \PATHINFO_EXTENSION)); |
||
| 244 | $path = $dirname . \DIRECTORY_SEPARATOR . $filename . $extension; |
||
| 245 | if (file_exists($path)) { |
||
| 246 | return $path; |
||
| 247 | } |
||
| 248 | |||
| 249 | $path = $dirname . \DIRECTORY_SEPARATOR . '_' . $filename . $extension; |
||
| 250 | if (file_exists($path)) { |
||
| 251 | return $path; |
||
| 252 | } |
||
| 253 | } |
||
| 254 | } |
||
| 255 | |||
| 256 | return null; |
||
| 257 | }; |
||
| 258 | } |
||
| 259 | |||
| 260 | private function copyAssets( |
||
| 261 | StorefrontPluginConfiguration $configuration, |
||
| 262 | StorefrontPluginConfigurationCollection $configurationCollection, |
||
| 263 | string $outputPath |
||
| 264 | ): void { |
||
| 265 | if (!$configuration->getAssetPaths()) { |
||
| 266 | return; |
||
| 267 | } |
||
| 268 | |||
| 269 | foreach ($configuration->getAssetPaths() as $asset) { |
||
| 270 | if (mb_strpos($asset, '@') === 0) { |
||
| 271 | $name = mb_substr($asset, 1); |
||
| 272 | $config = $configurationCollection->getByTechnicalName($name); |
||
| 273 | if (!$config) { |
||
| 274 | throw new InvalidThemeException($name); |
||
| 275 | } |
||
| 276 | |||
| 277 | $this->copyAssets($config, $configurationCollection, $outputPath); |
||
| 278 | |||
| 279 | continue; |
||
| 280 | } |
||
| 281 | |||
| 282 | if ($asset[0] !== '/' && file_exists($this->projectDir . '/' . $asset)) { |
||
| 283 | $asset = $this->projectDir . '/' . $asset; |
||
| 284 | } |
||
| 285 | |||
| 286 | $assets = $this->themeFileImporter->getCopyBatchInputsForAssets($asset, $outputPath, $configuration); |
||
| 287 | |||
| 288 | // method copyBatch is provided by copyBatch filesystem plugin |
||
| 289 | $this->filesystem->copyBatch(...$assets); |
||
| 290 | } |
||
| 291 | } |
||
| 292 | |||
| 293 | /** |
||
| 294 | * @deprecated tag:v6.5.0 - $context will be mandatory |
||
| 295 | * |
||
| 296 | * @param array<string, string> $resolveMappings |
||
| 297 | */ |
||
| 298 | private function compileStyles( |
||
| 299 | string $concatenatedStyles, |
||
| 300 | StorefrontPluginConfiguration $configuration, |
||
| 301 | array $resolveMappings, |
||
| 302 | string $salesChannelId, |
||
| 303 | ?Context $context = null |
||
| 304 | ): string { |
||
| 305 | if ($context === null) { |
||
| 306 | $context = Context::createDefaultContext(); |
||
| 307 | } |
||
| 308 | |||
| 309 | $variables = $this->dumpVariables($configuration->getThemeConfig() ?? [], $salesChannelId, $context); |
||
| 310 | $features = $this->getFeatureConfigScssMap(); |
||
| 311 | |||
| 312 | $resolveImportPath = $this->getResolveImportPathsCallback($resolveMappings); |
||
| 313 | |||
| 314 | $importPaths = []; |
||
| 315 | |||
| 316 | $cwd = \getcwd(); |
||
| 317 | if ($cwd !== false) { |
||
| 318 | $importPaths[] = $cwd; |
||
| 319 | } |
||
| 320 | |||
| 321 | $importPaths[] = $resolveImportPath; |
||
| 322 | |||
| 323 | $compilerConfig = new CompilerConfiguration( |
||
| 324 | [ |
||
| 325 | 'importPaths' => $importPaths, |
||
| 326 | 'outputStyle' => $this->debug ? OutputStyle::EXPANDED : OutputStyle::COMPRESSED, |
||
| 327 | ] |
||
| 328 | ); |
||
| 329 | |||
| 330 | try { |
||
| 331 | $cssOutput = $this->scssCompiler->compileString( |
||
| 332 | $compilerConfig, |
||
| 333 | $features . $variables . $concatenatedStyles |
||
| 334 | ); |
||
| 335 | } catch (\Throwable $exception) { |
||
| 336 | throw new ThemeCompileException( |
||
| 337 | $configuration->getTechnicalName(), |
||
| 338 | $exception->getMessage() |
||
| 339 | ); |
||
| 340 | } |
||
| 341 | $autoPreFixer = new Autoprefixer($cssOutput); |
||
| 342 | /** @var string|false $compiled */ |
||
| 343 | $compiled = $autoPreFixer->compile($this->debug); |
||
| 344 | if ($compiled === false) { |
||
| 345 | throw new ThemeCompileException( |
||
| 346 | $configuration->getTechnicalName(), |
||
| 347 | 'CSS parser not initialized' |
||
| 348 | ); |
||
| 349 | } |
||
| 350 | |||
| 351 | return $compiled; |
||
| 352 | } |
||
| 353 | |||
| 354 | private function getImportFileExtension(string $extension): string |
||
| 355 | { |
||
| 356 | // If the import has no extension, it must be a SCSS module. |
||
| 357 | if ($extension === '') { |
||
| 358 | return '.scss'; |
||
| 359 | } |
||
| 360 | |||
| 361 | // If the import has a .min extension, we assume it must be a compiled CSS file. |
||
| 362 | if ($extension === 'min') { |
||
| 363 | return '.css'; |
||
| 364 | } |
||
| 365 | |||
| 366 | // If it has any other extension, we don't assume a specific extension. |
||
| 367 | return ''; |
||
| 368 | } |
||
| 369 | |||
| 370 | /** |
||
| 371 | * Converts the feature config array to a SCSS map syntax. |
||
| 372 | * This allows reading of the feature flag config inside SCSS via `map.get` function. |
||
| 373 | * |
||
| 374 | * Output example: |
||
| 375 | * $sw-features: ("FEATURE_NEXT_1234": false, "FEATURE_NEXT_1235": true); |
||
| 376 | * |
||
| 377 | * @see https://sass-lang.com/documentation/values/maps |
||
| 378 | */ |
||
| 379 | private function getFeatureConfigScssMap(): string |
||
| 380 | { |
||
| 381 | $allFeatures = Feature::getAll(); |
||
| 382 | |||
| 383 | $featuresScss = implode(',', array_map(function ($value, $key) { |
||
| 384 | return sprintf('"%s": %s', $key, json_encode($value)); |
||
| 385 | }, $allFeatures, array_keys($allFeatures))); |
||
| 386 | |||
| 387 | return sprintf('$sw-features: (%s);', $featuresScss); |
||
| 388 | } |
||
| 389 | |||
| 390 | /** |
||
| 391 | * @param array<string, string> $variables |
||
| 392 | * |
||
| 393 | * @return array<string> |
||
| 394 | */ |
||
| 395 | private function formatVariables(array $variables): array |
||
| 400 | } |
||
| 401 | |||
| 402 | private function copyToLiveLocation(string $themePrefix, string $themeId): void |
||
| 403 | { |
||
| 404 | $backupPath = 'theme' . \DIRECTORY_SEPARATOR . 'backup' . \DIRECTORY_SEPARATOR . $themePrefix; |
||
| 405 | $path = 'theme' . \DIRECTORY_SEPARATOR . $themePrefix; |
||
| 406 | |||
| 407 | $themeCopyToLiveEvent = new ThemeCopyToLiveEvent($themeId, $path, $backupPath, $this->getTmpOutputPath($themePrefix)); |
||
| 408 | $this->eventDispatcher->dispatch($themeCopyToLiveEvent); |
||
| 409 | |||
| 410 | $path = $themeCopyToLiveEvent->getPath(); |
||
| 411 | $backupPath = $themeCopyToLiveEvent->getBackupPath(); |
||
| 412 | $tmpPath = $themeCopyToLiveEvent->getTmpPath(); |
||
| 413 | |||
| 414 | if ( |
||
| 415 | !$this->filesystem->has($tmpPath) |
||
| 416 | || ($this->filesystem->getMetaData($tmpPath) ?: ['type' => false])['type'] !== 'dir') { |
||
| 417 | throw new ThemeFileCopyException( |
||
| 418 | $themeId, |
||
| 419 | sprintf('Compilation error. Compiled files not found in %s.', $tmpPath) |
||
| 420 | ); |
||
| 421 | } |
||
| 422 | |||
| 423 | // backup current theme files |
||
| 424 | if ($this->filesystem->has($path)) { |
||
| 425 | try { |
||
| 426 | $this->filesystem->deleteDir($backupPath); |
||
| 427 | $this->filesystem->rename($path, $backupPath); |
||
| 428 | } catch (\Throwable $e) { |
||
| 429 | throw new ThemeFileCopyException($themeId, $e->getMessage()); |
||
| 430 | } |
||
| 431 | } |
||
| 432 | |||
| 433 | // move new theme files to live dir. Move backup back if something failed. |
||
| 434 | try { |
||
| 435 | $this->filesystem->rename($tmpPath, $path); |
||
| 436 | } catch (\Throwable $e) { |
||
| 437 | if ($this->filesystem->has($path)) { |
||
| 438 | try { |
||
| 439 | $this->filesystem->rename($path, $backupPath); |
||
| 440 | } catch (\Throwable $innerE) { |
||
| 441 | throw new ThemeFileCopyException($themeId, $innerE->getMessage()); |
||
| 442 | } |
||
| 443 | } |
||
| 444 | |||
| 445 | throw new ThemeFileCopyException($themeId, $e->getMessage()); |
||
| 446 | } |
||
| 447 | } |
||
| 448 | |||
| 449 | /** |
||
| 450 | * @param array{fields?: array{value: null|string|array<mixed>, scss?: bool, type: string}[]} $config |
||
| 451 | */ |
||
| 452 | private function dumpVariables(array $config, string $salesChannelId, Context $context): string |
||
| 453 | { |
||
| 454 | $variables = []; |
||
| 455 | foreach ($config['fields'] ?? [] as $key => $data) { |
||
| 456 | if (!\is_array($data) || !$this->isDumpable($data)) { |
||
| 457 | continue; |
||
| 458 | } |
||
| 459 | |||
| 460 | if (\in_array($data['type'], ['media', 'textarea'], true) && \is_string($data['value'])) { |
||
| 461 | $variables[$key] = '\'' . $data['value'] . '\''; |
||
| 462 | } elseif ($data['type'] === 'switch' || $data['type'] === 'checkbox') { |
||
| 463 | $variables[$key] = (int) ($data['value']); |
||
| 464 | } else { |
||
| 465 | $variables[$key] = $data['value']; |
||
| 466 | } |
||
| 467 | } |
||
| 468 | |||
| 469 | foreach ($this->packages as $key => $package) { |
||
| 470 | $variables[sprintf('sw-asset-%s-url', $key)] = sprintf('\'%s\'', $package->getUrl('')); |
||
| 471 | } |
||
| 472 | |||
| 473 | Feature::callSilentIfInactive('v6.5.0.0', function () use (&$variables, $salesChannelId): void { |
||
| 474 | /** @deprecated tag:v6.5.0 remove this event in 6.5.0 */ |
||
| 475 | $themeVariablesEvent = new ThemeCompilerEnrichScssVariablesEvent($variables, $salesChannelId); |
||
| 476 | $this->eventDispatcher->dispatch($themeVariablesEvent); |
||
| 477 | $variables = $themeVariablesEvent->getVariables(); |
||
| 478 | }); |
||
| 479 | |||
| 480 | /** @deprecated tag:v6.5.0 remove alias */ |
||
| 481 | $themeVariablesEvent = new ThemeCompilerEnrichScssVariablesEventNew( |
||
| 482 | $variables, |
||
| 483 | $salesChannelId, |
||
| 484 | $context |
||
| 485 | ); |
||
| 486 | |||
| 487 | $this->eventDispatcher->dispatch($themeVariablesEvent); |
||
| 488 | |||
| 489 | $dump = str_replace( |
||
| 490 | ['#class#', '#variables#'], |
||
| 491 | [self::class, implode(\PHP_EOL, $this->formatVariables($themeVariablesEvent->getVariables()))], |
||
| 492 | $this->getVariableDumpTemplate() |
||
| 493 | ); |
||
| 494 | |||
| 495 | $this->tempFilesystem->put('theme-variables.scss', $dump); |
||
| 496 | |||
| 497 | return $dump; |
||
| 498 | } |
||
| 499 | |||
| 500 | /** |
||
| 501 | * @param array{value: string|array<mixed>|null, scss?: bool, type: string} $data |
||
| 502 | */ |
||
| 503 | private function isDumpable(array $data): bool |
||
| 530 | } |
||
| 531 | |||
| 532 | private function getVariableDumpTemplate(): string |
||
| 533 | { |
||
| 535 | // ATTENTION! This file is auto generated by the #class# and should not be edited. |
||
| 536 | |||
| 537 | #variables# |
||
| 538 | |||
| 539 | PHP_EOL; |
||
| 540 | } |
||
| 541 | |||
| 542 | private function writeScriptFiles( |
||
| 543 | string $tmpOutputPath, |
||
| 544 | string $concatenatedScripts |
||
| 545 | ): void { |
||
| 546 | $tmpScriptFilepath = $tmpOutputPath . \DIRECTORY_SEPARATOR . 'js' . \DIRECTORY_SEPARATOR . 'all.js'; |
||
| 547 | $this->filesystem->put($tmpScriptFilepath, $concatenatedScripts); |
||
| 548 | } |
||
| 549 | |||
| 550 | private function getTmpOutputPath(string $themePrefix): string |
||
| 551 | { |
||
| 552 | return 'theme' . \DIRECTORY_SEPARATOR . 'temp' . \DIRECTORY_SEPARATOR . $themePrefix; |
||
| 553 | } |
||
| 554 | |||
| 555 | private function getTmpCssFilepath(string $themePrefix): string |
||
| 556 | { |
||
| 557 | return $this->getTmpOutputPath($themePrefix) . \DIRECTORY_SEPARATOR . 'css' . \DIRECTORY_SEPARATOR . 'all.css'; |
||
| 558 | } |
||
| 559 | |||
| 560 | private function concatenateStyles( |
||
| 573 | } |
||
| 574 | |||
| 575 | private function getConcatenatedScripts( |
||
| 576 | FileCollection $scriptFiles, |
||
| 589 | } |
||
| 590 | } |
||
| 591 |
This interface has been deprecated. The supplier of the interface has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the interface will be removed and what other interface to use instead.