class LessCompiler extends RevisionCompiler
Traits
Constants
| EMPTY_REVISION |
|
Properties
| protected callable[] | $sourcesCallbacks | from HasSources |
|
|
| protected array<string,string> | $pendingSidecars | Sidecar files (e.g. JsCompiler's `.map`) queued by renderOutput() during the current commit, written only if the primary file is — so an unchanged bundle rewrites nothing at all. | from RevisionCompiler |
|
| protected string | $cacheDir |
|
||
| protected array | $importDirs |
|
||
| protected array | $customFunctions |
|
||
| protected Collection|null | $lessImportOverrides |
|
||
| protected Collection|null | $fileSourceOverrides |
|
||
| protected string|null | $fontsDir |
|
Methods
No description
Recompile this asset and record its revision. Files are only written when the compiled output actually differs from what the revision manifest says is on disk (or the file has gone missing) — so routine rebuilds of unchanged assets are complete no-ops with zero writes.
Produce the exact bytes to write to the primary asset file, or null when there is nothing to write (empty sources). This is what the revision is hashed from, so it must be identical to what gets committed — subclasses that transform or add to the output (e.g. JsCompiler's sourcemap handling) override this and queue any sidecar files (like the `.map`) on {$pendingSidecars} rather than writing them, so sidecars are only written when the bundle itself is.
The directory holding the webfonts that get published to `assets/fonts`.
Read a cached parse result for less.php. Returns the cached rules, or null to signal a miss so less.php reparses the file.
Persist a parse result for less.php, writing atomically so a concurrent reader never observes a half-written cache file: serialize to a temporary file in the same directory, then rename() it into place (atomic on the same filesystem).
Prune expired cache files at most once per request. less.php's own GC (Less_Cache::CleanCache) only runs from its high-level Less_Cache::Get() API, which Flarum doesn't use — the direct Less_Parser path GC'd inline on every serialize write instead. In callback mode neither fires, so without this the directory would grow unbounded.
Point font URLs at the published `assets/fonts` directory, and stamp each with a revision derived from the font file itself.
A short hash of a webfont's contents, or null when it can't be read — fonts are published separately, so a compile must never fail just because the directory isn't there yet.
Details
in HasSources
at
line 25
void
addSources(callable $callback)
in HasSources
at
line 33
protected array
getSources()
in HasSources
at
line 44
abstract protected array
allowedSourceTypes()
in RevisionCompiler
at
line 28
__construct(Cloud $assetsDir, string $filename, SettingsRepositoryInterface $settings, VersionerInterface $versioner)
in RevisionCompiler
at
line 36
string|null
getFilename()
in RevisionCompiler
at
line 41
void
setFilename(string $filename)
in RevisionCompiler
at
line 57
void
commit(bool $force = false)
Recompile this asset and record its revision. Files are only written when the compiled output actually differs from what the revision manifest says is on disk (or the file has gone missing) — so routine rebuilds of unchanged assets are complete no-ops with zero writes.
in RevisionCompiler
at
line 101
protected void
writePendingSidecars()
in RevisionCompiler
at
line 108
protected string
hashOutput(string $content)
in RevisionCompiler
at
line 124
protected string|null
renderOutput(array $sources)
Produce the exact bytes to write to the primary asset file, or null when there is nothing to write (empty sources). This is what the revision is hashed from, so it must be identical to what gets committed — subclasses that transform or add to the output (e.g. JsCompiler's sourcemap handling) override this and queue any sidecar files (like the `.map`) on {$pendingSidecars} rather than writing them, so sidecars are only written when the bundle itself is.
in RevisionCompiler
at
line 131
string|null
getUrl()
at
line 77
protected string
compile(array $sources)
in RevisionCompiler
at
line 170
protected string
format(string $string)
in RevisionCompiler
at
line 175
void
flush()
in RevisionCompiler
at
line 184
protected void
delete(string $file)
at
line 30
string
getCacheDir()
at
line 39
void
setFontsDir(string|null $fontsDir)
The directory holding the webfonts that get published to `assets/fonts`.
Used to revision the font URLs emitted into the compiled CSS.
at
line 44
void
setCacheDir(string $cacheDir)
at
line 49
array
getImportDirs()
at
line 54
void
setImportDirs(array $importDirs)
at
line 59
void
setLessImportOverrides(array $lessImportOverrides)
at
line 64
void
setFileSourceOverrides(array $fileSourceOverrides)
at
line 69
void
setCustomFunctions(array $customFunctions)
at
line 169
protected mixed
readCache(Less_Parser $parser, string $filePath, string $cacheFile)
Read a cached parse result for less.php. Returns the cached rules, or null to signal a miss so less.php reparses the file.
A corrupt or unreadable cache file (e.g. a partial write from a raced compile) is treated as a miss rather than allowed to fatal on unserialize()'s "Extra data" warning, which Flarum's error handler would otherwise escalate to an uncaught exception.
at
line 207
protected void
writeCache(Less_Parser $parser, string $filePath, string $cacheFile, mixed $rules)
Persist a parse result for less.php, writing atomically so a concurrent reader never observes a half-written cache file: serialize to a temporary file in the same directory, then rename() it into place (atomic on the same filesystem).
at
line 245
protected void
pruneCacheOnce()
Prune expired cache files at most once per request. less.php's own GC (Less_Cache::CleanCache) only runs from its high-level Less_Cache::Get() API, which Flarum doesn't use — the direct Less_Parser path GC'd inline on every serialize write instead. In callback mode neither fires, so without this the directory would grow unbounded.
We prune here rather than call CleanCache() because that method is deprecated-internal, and hand-rolling the sweep lets us tolerate the scandir/unlink race (a concurrent sweep removing the same aged file) by simply suppressing the "No such file" and moving on. Files are removed by mtime, matching less.php's own policy; a cache hit re-reads and is not touched, so anything past the lifetime is genuinely stale.
at
line 290
protected string
finalize(string $parsedCss)
Point font URLs at the published `assets/fonts` directory, and stamp each with a revision derived from the font file itself.
The stylesheet is already cache-busted (`forum.css?v=<rev>`), but the font URLs inside it were not. On a FontAwesome major upgrade every browser therefore picked up the new CSS immediately while continuing to serve the *previous* font file from cache — same filename, same URL, long max-age. The new CSS asks for codepoints the old font doesn't contain, so every icon rendered as a placeholder box until that cache entry happened to expire. Revisioning the URL means a changed font is always a new URL, for browser and CDN caches alike. Because the asset revision is a hash of this compiled output, a font change also moves the stylesheet's own revision — so connected clients get the usual "reload for the new version" prompt without any extra wiring.
at
line 316
protected string|null
fontRevision(string $file)
A short hash of a webfont's contents, or null when it can't be read — fonts are published separately, so a compile must never fail just because the directory isn't there yet.