Skip to content

Instantly share code, notes, and snippets.

@mishterk
Last active August 15, 2024 19:05
Show Gist options
  • Save mishterk/a8f19eeb514cf77ad333fb67b3c7aeb9 to your computer and use it in GitHub Desktop.
Save mishterk/a8f19eeb514cf77ad333fb67b3c7aeb9 to your computer and use it in GitHub Desktop.
A local Valet driver for proxying images to a remote host
<?php
/**
* Class LocalValetDriver
*
* This class demonstrates how we might go about proxying any missing local images to a remote host. i.e; the production
* site. This has been created with WordPress in mind but could be adjusted to work with any other system.
*/
class LocalValetDriver extends WordPressValetDriver {
/** @var string The remote host to proxy requests to */
const REMOTE_HOST = 'https://remotehost.com/';
/** @var string If the request URI starts with this, we want to proxy the request to the remote host */
const URI_PREFIX = '/wp-content/uploads/';
/** @var bool Whether or not to load the current request remotely */
private static $tryRemoteFallback = false;
/**
* This method checks if we have the file on disk. If not, changes the domain of any requests for files within the
* uploads directory to the remote domain. It also sets a flag that this request is now a remote request.
*
* @param string $sitePath
* @param string $siteName
* @param string $uri
*
* @return bool|false|string
*/
public function isStaticFile( $sitePath, $siteName, $uri ) {
$localFileFound = parent::isStaticFile( $sitePath, $siteName, $uri );
if ( $localFileFound ) {
return $localFileFound;
}
if ( self::stringStartsWith( $uri, self::URI_PREFIX ) ) {
self::$tryRemoteFallback = true;
return rtrim( self::REMOTE_HOST, '/' ) . $uri;
}
return false;
}
/**
* This method checks if the remote flag is set and, if so, redirects the request by setting the Location header.
*
* @param string $staticFilePath
* @param string $sitePath
* @param string $siteName
* @param string $uri
*/
public function serveStaticFile( $staticFilePath, $sitePath, $siteName, $uri ) {
if ( self::$tryRemoteFallback ) {
header( "Location: $staticFilePath" );
} else {
parent::serveStaticFile( $staticFilePath, $sitePath, $siteName, $uri );
}
}
/**
* @param string $string
* @param string $startsWith
*
* @return bool
*/
private static function stringStartsWith( $string, $startsWith ) {
return strpos( $string, $startsWith ) === 0;
}
}
@benpohdigital
Copy link

I keep getting declaration errors on serverStaticFile Ln55

@reformatco
Copy link

For anyone who needs it, here's a working version for Valet 11

use Valet\Drivers\Specific\WordPressValetDriver;

class LocalValetDriver extends WordPressValetDriver
{
    private const REMOTE_HOST = 'https://domain.com/';
    private const URI_PREFIX = '/wp-content/uploads/';

    private bool $tryRemoteFallback = false;

    public function isStaticFile(string $sitePath, string $siteName, string $uri): bool|string
    {
        $localFileFound = parent::isStaticFile($sitePath, $siteName, $uri);

        if ($localFileFound) {
            return $localFileFound;
        }

        if (str_starts_with($uri, self::URI_PREFIX)) {
            $this->tryRemoteFallback = true;
            return rtrim(self::REMOTE_HOST, '/') . $uri;
        }

        return false;
    }

    public function serveStaticFile(string $staticFilePath, string $sitePath, string $siteName, string $uri): void
    {
        if ($this->tryRemoteFallback) {
            header("Location: $staticFilePath");
            return;
        }

        parent::serveStaticFile($staticFilePath, $sitePath, $siteName, $uri);
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment