Skip to content

Commit

Permalink
feat: Automated .htaccess generation in migration
Browse files Browse the repository at this point in the history
  • Loading branch information
rafaucau committed May 15, 2023
1 parent cba595a commit 20d034d
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 0 deletions.
18 changes: 18 additions & 0 deletions migrations/2023_05_16_000001_update_htaccess.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

use ACPL\FlarumCache\Utility\HtaccessManager;
use Flarum\Foundation\Paths;
use Illuminate\Database\Schema\Builder;

return [
'up' => function (Builder $schema) {
$paths = resolve(Paths::class);
$htaccessManager = new HtaccessManager($paths);
$htaccessManager->updateHtaccess();
},
'down' => function (Builder $schema) {
$paths = resolve(Paths::class);
$htaccessManager = new HtaccessManager($paths);
$htaccessManager->removeLsCacheBlock();
}
];
98 changes: 98 additions & 0 deletions src/Utility/HtaccessManager.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
<?php

namespace ACPL\FlarumCache\Utility;

use Flarum\Foundation\Paths;
use Illuminate\Contracts\Filesystem\FileNotFoundException;
use Illuminate\Filesystem\Filesystem;

class HtaccessManager
{
private const BEGIN_LSCACHE = '# BEGIN LSCACHE';
private const END_LSCACHE = '# END LSCACHE';

private string $htaccessPath;
private Filesystem $filesystem;

public function __construct(Paths $paths)
{
$this->filesystem = new Filesystem();
$this->htaccessPath = $paths->public.'/.htaccess';
}

/**
* Updates the .htaccess file with the new LSCache block content. If the LSCache block is already there, it replaces it. Otherwise, it appends it
* @throws FileNotFoundException
*/
public function updateHtaccess(): void
{
$htaccessContent = $this->filesystem->get($this->htaccessPath);
$newContent = $this->generateLsCacheBlock();

if ($this->hasLsCacheBlock($htaccessContent)) {
$htaccessContent = $this->replaceLsCacheBlock($htaccessContent, $newContent);
} else {
$htaccessContent = $this->prependLsCacheBlock($htaccessContent, $newContent);
}

$this->filesystem->put($this->htaccessPath, $htaccessContent);
}

/** Generates the content of the LSCache block to be inserted into the .htaccess file. */
private function generateLsCacheBlock(): string
{
$block = self::BEGIN_LSCACHE." - Do not edit the contents of this block!\n";
$block .= '<IfModule LiteSpeed>'.
$this->addLine('CacheLookup on').
$this->addLine('RewriteEngine On').
$this->addLine('RewriteCond %{REQUEST_METHOD} ^HEAD|GET$').
$this->addLine('RewriteRule .* - [E="Cache-Vary:flarum_remember,flarum_lscache_vary,locale"]');
$block .= "\n</IfModule>";
$block .= "\n".self::END_LSCACHE;

return $block;
}

/** Helper method for generating a line of the LSCache block content */
private function addLine(string $line): string
{
return "\n\t$line";
}

/** Checks if the LSCache block is present in the provided .htaccess content */
private function hasLsCacheBlock(string $htaccessContent): bool
{
return str_contains($htaccessContent, self::BEGIN_LSCACHE);
}

/** Replaces the existing LSCache block in the .htaccess content with the new content */
private function replaceLsCacheBlock(string $htaccessContent, string $newContent): string
{
$pattern = '/'.preg_quote(self::BEGIN_LSCACHE, '/').'.*'.preg_quote(self::END_LSCACHE, '/').'/s';
return preg_replace($pattern, $newContent, $htaccessContent);
}

/** Prepends the new LSCache block to the .htaccess content */
private function prependLsCacheBlock(string $htaccessContent, string $newContent): string
{
return "$newContent\n".$htaccessContent;
}

/**
* Removes the LSCache block from the .htaccess file. If the block is not present, it does nothing
* @throws FileNotFoundException
*/
public function removeLsCacheBlock(): void
{
$htaccessContent = $this->filesystem->get($this->htaccessPath);

if (! $this->hasLsCacheBlock($htaccessContent)) {
return;
}

$pattern = '/'.preg_quote(self::BEGIN_LSCACHE, '/').'.*'.preg_quote(self::END_LSCACHE, '/').'/s';
$htaccessContent = preg_replace($pattern, '', $htaccessContent);

$this->filesystem->put($this->htaccessPath, $htaccessContent);
}
}

0 comments on commit 20d034d

Please sign in to comment.