Skip to content

Instantly share code, notes, and snippets.

@MouseEatsCat
Last active January 8, 2024 18:25
Show Gist options
  • Save MouseEatsCat/1383e9b3262090c55b445ca096d8cfa4 to your computer and use it in GitHub Desktop.
Save MouseEatsCat/1383e9b3262090c55b445ca096d8cfa4 to your computer and use it in GitHub Desktop.
CharcoalValetDriver

Charcoal Valet Driver

This adds Charcoal project support for Laravel Valet.

Setup

  • Run the following command to place the CharcoalValetDriver.php driver file into ~/.config/valet/Drivers/.
curl https://gist.githubusercontent.com/raw/1383e9b3262090c55b445ca096d8cfa4/CharcoalValetDriver.php -o ~/.config/valet/Drivers/CharcoalValetDriver.php
  • An optional valet-config.json file can be placed at the root of every Charcoal project.
    • It is recommended to globally ignore valet-config.json within version control

valet-config options

The following options can be used to modify the driver's behavior:

Key Values Default Description
remote_assets_domain String n/a Use this domain as a fallback if image assets aren't found locally
allow_indexphp_files Boolean false Allow direct use of "index.php"
redirect_trailing_slashes Boolean true Redirect trailing slashes if not a folder
<?php
/**
* Charcoal Valet Driver
*
* Supported Valet Version: 4
*/
namespace Valet\Drivers\Custom;
use Valet\Drivers\ValetDriver;
class CharcoalValetDriver extends ValetDriver
{
public string $PUBLIC_DIR = '/www/';
public string $VALET_CONFIG_FILE = '/valet-config.json';
private bool $configFileLoaded = false;
private string $sitePath;
private array $valetConfig = [
'remote_assets_domain' => null,
'allow_indexphp_files' => false,
'redirect_trailing_slashes' => true,
];
/**
* Determine if the driver serves the request.
*/
public function serves(string $sitePath, string $siteName, string $uri): bool
{
$serves = is_dir($sitePath . '/metadata');
return $serves;
}
/**
* Determine if the incoming request is for a static file.
*
* @return string|false
*/
public function isStaticFile(string $sitePath, string $siteName, string $uri)
{
$staticFilePath = $sitePath . $this->PUBLIC_DIR . $uri;
return file_exists($staticFilePath) ? $staticFilePath : false;
}
/**
* Get the fully resolved path to the application's front controller.
*/
public function frontControllerPath(string $sitePath, string $siteName, string $uri): string
{
$this->sitePath = $sitePath;
// Use remote assets as fallback
if (
$this->getValetConfig('remote_assets_domain')
&& preg_match('/^(.*)\.(jpe?g|gif|pdf|png|svg|mp4)$/', $uri)
&& !$this->isStaticFile($sitePath, $siteName, $uri)
) {
$remoteAssetPath = $this->getValetConfig('remote_assets_domain') . $uri;
header('Location: ' . $remoteAssetPath);
return $remoteAssetPath;
}
// Do not allow direct use of "index.php"
if (!$this->getValetConfig('allow_indexphp_files') && preg_match('/^(.*)index.php$/', $uri)) {
$uri = str_replace('index.php', '', $uri);
header('Location: ' . $uri);
return $uri;
}
# Redirect trailing slashes if not a folder
if (
$this->getValetConfig('redirect_trailing_slashes')
&& preg_match('/^(.*)\/$/', $uri)
&& !is_dir($sitePath . $this->PUBLIC_DIR . $uri)
) {
$uri = rtrim($uri, '/');
header('Location: ' . $uri);
return $uri;
}
# Handle Front Controller...
return $sitePath . $this->PUBLIC_DIR . 'index.php';
}
/**
* Determine if valet config file exists.
*/
public function hasValetConfig(): bool
{
return file_exists($this->sitePath . $this->VALET_CONFIG_FILE);
}
/**
* Get the valet config options or a single option.
*
* @param string|null $property Get single valet config option
* @return mixed|null Returns null when no matching option is found
*/
private function getValetConfig(?string $property = null)
{
if (!$this->configFileLoaded) {
if ($this->hasValetConfig()) {
$json = file_get_contents($this->sitePath . $this->VALET_CONFIG_FILE);
$this->valetConfig = array_merge(
$this->valetConfig,
(json_decode($json, JSON_OBJECT_AS_ARRAY) ?? [])
);
$this->configFileLoaded = true;
}
}
return !empty($property) ? ($this->valetConfig[$property] ?? null) : $this->valetConfig;
}
}
{
"remote_assets_domain": "https://productionsite.com/",
"allow_indexphp_files": false,
"redirect_trailing_slashes": true
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment