Skip to content

Instantly share code, notes, and snippets.

@dmaksimov
Created February 9, 2022 17:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dmaksimov/7e80bf93e4f1e7d52e8741050bd5687c to your computer and use it in GitHub Desktop.
Save dmaksimov/7e80bf93e4f1e7d52e8741050bd5687c to your computer and use it in GitHub Desktop.
<?php
declare(strict_types=1);
use App\Models\Style;
use Illuminate\Support\Str;
use Symfony\Component\Finder\Finder;
use Symfony\Component\Finder\SplFileInfo;
/**
* Class AddStyleManager
*/
class AddStyleManager extends \App\Upgrade
{
/**
* In production, the database is backed up before upgrades are run. Since
* the sent emails tables are huge, we speed up the backup process by
* excluding those tables from the backup by default. If this upgrade is
* making changes to the sent emails tables, you may choose to backup
* those tables.
*
* @var boolean
*/
protected $backupSentEmails = false;
/**
* Run the upgrade
*/
public function run()
{
$this->migrateStylesIn(resource_path('assets/sass/custom'));
}
/**
* Migrate all styles in a give directory.
* @param string $directory
*/
private function migrateStylesIn(string $directory): void
{
$sassFiles = (new Finder)->in($directory)->files()->filter($this->onlySassFiles());
foreach ($sassFiles as $sassFile) {
$name = $this->resolveStyleName($sassFile, $directory);
$this->migrateStyleToDatabase($name, $sassFile->getPathname());
}
}
private function migrateStyleToDatabase(string $name, string $pathName)
{
Style::firstOrCreate(
[
'name' => $name,
],
[
'css' => $this->replaceImportPaths(file_get_contents($pathName)),
'is_variable' => $this->checkVariableStyle($name)
]
);
}
/**
* @param $sassFile
* @param string $sassDirectory
* @return string
*/
private function resolveStyleName($sassFile, string $sassDirectory): string
{
$prefix = $this->toStylePrefix(Str::after($sassFile->getPath(), $sassDirectory));
$fileName = $this->toStyleName($sassFile->getFilenameWithoutExtension());
return empty($prefix) ? $fileName : $prefix . $this->styleDelimiter() . $fileName;
}
/**
* Filter to get SASS files only.
* @return \Closure
*/
private function onlySassFiles(): \Closure
{
return function (SplFileInfo $file) {
return \preg_match('/\.(scss)$/', $file->getPathname());
};
}
private function checkVariableStyle(string $name): bool
{
return Str::endsWith($name, ['Variable', 'Variables']);
}
/**
* Remove import statement in style file.
* @param string $css
* @return string
*/
private function replaceImportPaths(string $css): string
{
foreach (getStringBetween($css, '@import', ';') as $name) {
$css = str_replace($name, $this->resolveStyleNameFromImport($name), $css);
}
return $css;
}
private function resolveStyleNameFromImport(string $value): string
{
$value = str_replace('.', '', $value);
$value = str_replace('"/', '"', $value);
$value = str_replace('/_', $this->styleDelimiter(), $value);
return $this->toStyleName($value);
}
/**
* @param string $value
* @return string
*/
private function toStyleName(string $value): string
{
return trim(Str::title(str_replace('_', ' ', $value)));
}
/**
* @param string $value
* @return string
*/
private function toStylePrefix(string $value): string
{
return str_replace('/', $this->styleDelimiter(), $this->toStyleName(ltrim($value, '/')));
}
private function styleDelimiter(): string
{
return ' - ';
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment