Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Specific Valet Drivers not found when adding LocalValetDriver #1405

Closed
amuscalu opened this issue Apr 26, 2023 · 11 comments · Fixed by #1414
Closed

Specific Valet Drivers not found when adding LocalValetDriver #1405

amuscalu opened this issue Apr 26, 2023 · 11 comments · Fixed by #1414

Comments

@amuscalu
Copy link

Description

Getting Fatal error when adding LocalValetDriver.php file to the root of my wordpress site.

Fatal error: Uncaught Error: Class "Valet\Drivers\Specific\WordPressValetDriver" not found in /Users/amuscalu/Sites/icd/LocalValetDriver.php:11 Stack trace: #0 /Users/amuscalu/.composer/vendor/laravel/valet/cli/Valet/Drivers/ValetDriver.php(75): require_once() #1 /Users/amuscalu/.composer/vendor/laravel/valet/cli/Valet/Drivers/ValetDriver.php(37): Valet\Drivers\ValetDriver::customSiteDriver('/Users/amuscalu...') #2 /Users/amuscalu/.composer/vendor/laravel/valet/server.php(54): Valet\Drivers\ValetDriver::assign('/Users/amuscalu...', 'icd', '/') #3 {main} thrown in /Users/amuscalu/Sites/icd/LocalValetDriver.php on line 11

Related to valet version 4.0.1 & PR #1388

Steps To Reproduce

Diagnosis

sw_vers
ProductName:	macOS
ProductVersion:	12.6.5
BuildVersion:	21G531
valet --version
Laravel Valet 4.0.1
cat ~/.config/valet/config.json
{
    "tld": "test",
    "loopback": "127.0.0.1",
    "paths": [
        "/Users/amuscalu/Sites"
    ]
}
cat ~/.composer/composer.json
{
    "require": {
        "laravel/valet": "^4.0"
    }
}
composer global diagnose
Changed current directory to /Users/amuscalu/.composer
Checking composer.json: WARNING
No license specified, it is recommended to do so. For closed-source software you may use "proprietary" as license.
Checking platform settings: OK
Checking git settings: OK git version 2.37.1
Checking http connectivity to packagist: OK
Checking https connectivity to packagist: OK
Checking github.com rate limit: OK
Checking disk free space: OK
Checking pubkeys: FAIL
Missing pubkey for tags verification
Missing pubkey for dev verification
Run composer self-update --update-keys to set them up
Checking composer version: OK
Composer version: 2.5.5
PHP version: 8.2.5
PHP binary path: /opt/homebrew/Cellar/php/8.2.5/bin/php
OpenSSL version: OpenSSL 1.1.1t  7 Feb 2023
cURL version: 8.0.1 libz 1.2.11 ssl (SecureTransport) OpenSSL/1.1.1t
zip: extension present, unzip present, 7-Zip not available
composer global outdated
Changed current directory to /Users/amuscalu/.composer
Legend:
! patch or minor release available - update recommended
~ major release available - update possible

Direct dependencies required in composer.json:
Everything up to date

Transitive dependencies not required in composer.json:
illuminate/collections v10.8.0 ! v10.9.0 The Illuminate Collections package.
illuminate/conditionable v10.8.0 ! v10.9.0 The Illuminate Conditionable pack...
illuminate/container v10.8.0 ! v10.9.0 The Illuminate Container package.
illuminate/contracts v10.8.0 ! v10.9.0 The Illuminate Contracts package.
illuminate/macroable v10.8.0 ! v10.9.0 The Illuminate Macroable package.

ls -al /etc/sudoers.d/
total 0
drwxr-xr-x   2 root  wheel    64 Apr  4 10:24 .
drwxr-xr-x  81 root  wheel  2592 Apr 26 10:14 ..
brew config
HOMEBREW_VERSION: 4.0.15
ORIGIN: https://github.com/Homebrew/brew
HEAD: 763c41f006ab9b44261e313b0aaa24a047431b06
Last commit: 2 days ago
Core tap JSON: 26 Apr 12:06 UTC
HOMEBREW_PREFIX: /opt/homebrew
HOMEBREW_CASK_OPTS: []
HOMEBREW_MAKE_JOBS: 10
Homebrew Ruby: 2.6.10 => /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/bin/ruby
CPU: 10-core 64-bit arm_firestorm_icestorm
Clang: 14.0.0 build 1400
Git: 2.37.1 => /Library/Developer/CommandLineTools/usr/bin/git
Curl: 7.87.0 => /usr/bin/curl
macOS: 12.6.5-arm64
CLT: 14.2.0.0.1.1668646533
Xcode: N/A
Rosetta 2: false
brew services list
Name    Status User File
dnsmasq none            root 
nginx   none            root 
php     none            root
brew list --formula --versions | grep -E "(php|nginx|dnsmasq|mariadb|mysql|mailhog|openssl)(@\d\..*)?\s"
dnsmasq 2.89
nginx 1.23.4
[email protected] 1.1.1t
php 8.2.5
brew outdated
gd
libtiff
little-cms2
webp
brew tap
homebrew/services
php -v
PHP 8.2.5 (cli) (built: Apr 13 2023 18:11:42) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.2.5, Copyright (c) Zend Technologies
    with Zend OPcache v8.2.5, Copyright (c), by Zend Technologies
which -a php
/opt/homebrew/bin/php
php --ini
Configuration File (php.ini) Path: /opt/homebrew/etc/php/8.2
Loaded Configuration File:         /opt/homebrew/etc/php/8.2/php.ini
Scan for additional .ini files in: /opt/homebrew/etc/php/8.2/conf.d
Additional .ini files parsed:      /opt/homebrew/etc/php/8.2/conf.d/error_log.ini,
/opt/homebrew/etc/php/8.2/conf.d/ext-opcache.ini,
/opt/homebrew/etc/php/8.2/conf.d/php-memory-limits.ini
nginx -v
nginx version: nginx/1.23.4
curl --version
curl 7.87.0 (x86_64-apple-darwin21.0) libcurl/7.87.0 (SecureTransport) LibreSSL/3.3.6 zlib/1.2.11 nghttp2/1.45.1
Release-Date: 2022-12-21
Protocols: dict file ftp ftps gopher gophers http https imap imaps ldap ldaps mqtt pop3 pop3s rtsp smb smbs smtp smtps telnet tftp
Features: alt-svc AsynchDNS GSS-API HSTS HTTP2 HTTPS-proxy IPv6 Kerberos Largefile libz MultiSSL NTLM NTLM_WB SPNEGO SSL threadsafe UnixSockets
php --ri curl
curl

cURL support => enabled
cURL Information => 8.0.1
Age => 10
Features
AsynchDNS => Yes
CharConv => No
Debug => No
GSS-Negotiate => No
IDN => Yes
IPv6 => Yes
krb4 => No
Largefile => Yes
libz => Yes
NTLM => Yes
NTLMWB => Yes
SPNEGO => Yes
SSL => Yes
SSPI => No
TLS-SRP => Yes
HTTP2 => Yes
GSSAPI => Yes
KERBEROS5 => Yes
UNIX_SOCKETS => Yes
PSL => No
HTTPS_PROXY => Yes
MULTI_SSL => Yes
BROTLI => Yes
ALTSVC => Yes
HTTP3 => No
UNICODE => No
ZSTD => Yes
HSTS => Yes
GSASL => No
Protocols => dict, file, ftp, ftps, gopher, gophers, http, https, imap, imaps, ldap, ldaps, mqtt, pop3, pop3s, rtmp, rtmpe, rtmps, rtmpt, rtmpte, rtmpts, rtsp, scp, sftp, smb, smbs, smtp, smtps, telnet, tftp
Host => aarch64-apple-darwin21.6.0
SSL Version => (SecureTransport) OpenSSL/1.1.1t
ZLib Version => 1.2.11
libSSH Version => libssh2/1.10.0

Directive => Local Value => Master Value
curl.cainfo => no value => no value

/opt/homebrew/bin/ngrok version
sudo: /opt/homebrew/bin/ngrok: command not found
ls -al ~/.ngrok2
ls: /Users/amuscalu/.ngrok2: No such file or directory
brew info nginx
==> nginx: stable 1.23.4 (bottled), HEAD
HTTP(S) server and reverse proxy, and IMAP/POP3 proxy server
https://nginx.org/
/opt/homebrew/Cellar/nginx/1.23.4 (26 files, 2.2MB) *
  Poured from bottle using the formulae.brew.sh API on 2023-04-22 at 09:38:02
From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/nginx.rb
License: BSD-2-Clause
==> Dependencies
Required: [email protected], pcre2
==> Options
--HEAD
	Install HEAD version
==> Caveats
Docroot is: /opt/homebrew/var/www

The default port has been set in /opt/homebrew/etc/nginx/nginx.conf to 8080 so that
nginx can run without sudo.

nginx will load all files in /opt/homebrew/etc/nginx/servers/.

To restart nginx after an upgrade:
brew services restart nginx
Or, if you don't want/need a background service you can just run:
/opt/homebrew/opt/nginx/bin/nginx -g daemon off;
==> Analytics
install: 1,426 (30 days), 37,992 (90 days), 384,968 (365 days)
install-on-request: 1,424 (30 days), 37,943 (90 days), 384,334 (365 days)
build-error: 2 (30 days)

brew info php
==> php: stable 8.2.5 (bottled), HEAD
General-purpose scripting language
https://www.php.net/
/opt/homebrew/Cellar/php/8.2.5 (520 files, 83.4MB) *
  Poured from bottle using the formulae.brew.sh API on 2023-04-22 at 09:32:19
From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/php.rb
License: PHP-3.01
==> Dependencies
Build: httpd, pkg-config
Required: apr, apr-util, argon2, aspell, autoconf, curl, freetds, gd, gettext, gmp, icu4c, krb5, libpq, libsodium, libzip, oniguruma, openldap, [email protected], pcre2, sqlite, tidy-html5, unixodbc
==> Options
--HEAD
	Install HEAD version
==> Caveats
To enable PHP in Apache add the following to httpd.conf and restart Apache:
    LoadModule php_module /opt/homebrew/opt/php/lib/httpd/modules/libphp.so
<FilesMatch \.php$>
    SetHandler application/x-httpd-php
</FilesMatch>

Finally, check DirectoryIndex includes index.php
DirectoryIndex index.php index.html

The php.ini and php-fpm.ini file can be found in:
/opt/homebrew/etc/php/8.2/

To restart php after an upgrade:
brew services restart php
Or, if you don't want/need a background service you can just run:
/opt/homebrew/opt/php/sbin/php-fpm --nodaemonize
==> Analytics
install: 1,898 (30 days), 143,109 (90 days), 1,257,751 (365 days)
install-on-request: 1,723 (30 days), 126,746 (90 days), 1,098,027 (365 days)
build-error: 0 (30 days)

brew info openssl
==> openssl@3: stable 3.1.0 (bottled) [keg-only]
Cryptography and SSL/TLS Toolkit
https://openssl.org/
Not installed
From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/[email protected]
License: Apache-2.0
==> Dependencies
Required: ca-certificates
==> Caveats
A CA file has been bootstrapped using certificates from the system
keychain. To add additional certificates, place .pem files in
  /opt/homebrew/etc/openssl@3/certs

and run
/opt/homebrew/opt/openssl@3/bin/c_rehash

openssl@3 is keg-only, which means it was not symlinked into /opt/homebrew,
because macOS provides LibreSSL.
==> Analytics
install: 5,622 (30 days), 511,718 (90 days), 2,166,358 (365 days)
install-on-request: 2,526 (30 days), 113,970 (90 days), 1,123,135 (365 days)
build-error: 597 (30 days)

openssl version -a
LibreSSL 2.8.3
built on: date not available
platform: information not available
options:  bn(64,64) rc4(ptr,int) des(idx,cisc,16,int) blowfish(idx) 
compiler: information not available
OPENSSLDIR: "/private/etc/ssl"
openssl ciphers
ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:GOST2012256-GOST89-GOST89:DHE-RSA-CAMELLIA256-SHA256:DHE-RSA-CAMELLIA256-SHA:GOST2001-GOST89-GOST89:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA:CAMELLIA256-SHA256:CAMELLIA256-SHA:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-CAMELLIA128-SHA256:DHE-RSA-CAMELLIA128-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:CAMELLIA128-SHA256:CAMELLIA128-SHA:ECDHE-RSA-RC4-SHA:ECDHE-ECDSA-RC4-SHA:RC4-SHA:RC4-MD5:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:DES-CBC3-SHA
sudo nginx -t
nginx: the configuration file /opt/homebrew/etc/nginx/nginx.conf syntax is ok
nginx: configuration file /opt/homebrew/etc/nginx/nginx.conf test is successful
which -a php-fpm
/opt/homebrew/sbin/php-fpm
/opt/homebrew/opt/php/sbin/php-fpm -v
PHP 8.2.5 (fpm-fcgi) (built: Apr 13 2023 18:11:44)
Copyright (c) The PHP Group
Zend Engine v4.2.5, Copyright (c) Zend Technologies
    with Zend OPcache v8.2.5, Copyright (c), by Zend Technologies
sudo /opt/homebrew/opt/php/sbin/php-fpm -y /opt/homebrew/etc/php/8.2/php-fpm.conf --test
[26-Apr-2023 15:06:26] NOTICE: configuration file /opt/homebrew/etc/php/8.2/php-fpm.conf test is successful
ls -al ~/Library/LaunchAgents | grep homebrew

ls -al /Library/LaunchAgents | grep homebrew

ls -al /Library/LaunchDaemons | grep homebrew
-rw-r--r--   1 root  admin   797 Apr 26 14:11 homebrew.mxcl.dnsmasq.plist
-rw-r--r--   1 root  admin   685 Apr 26 14:11 homebrew.mxcl.nginx.plist
-rw-r--r--   1 root  admin   781 Apr 26 14:11 homebrew.mxcl.php.plist
ls -al /Library/LaunchDaemons | grep "com.laravel.valet."

ls -aln /etc/resolv.conf
lrwxr-xr-x  1 0  0  22 Apr  4 10:24 /etc/resolv.conf -> ../var/run/resolv.conf
cat /etc/resolv.conf
#
# macOS Notice
#
# This file is not consulted for DNS hostname resolution, address
# resolution, or the DNS query routing mechanism used by most
# processes on this system.
#
# To view the DNS configuration used by this system, use:
#   scutil --dns
#
# SEE ALSO
#   dns-sd(1), scutil(8)
#
# This file is automatically generated.
#
nameserver 2a02:2f0c:8000:3::1
nameserver 2a02:2f0c:8000:8::1
nameserver 193.231.252.1
nameserver 213.154.124.1
ifconfig lo0
lo0: flags=8049 mtu 16384
	options=1203
	inet 127.0.0.1 netmask 0xff000000 
	inet6 ::1 prefixlen 128 
	inet6 fe80::1%lo0 prefixlen 64 scopeid 0x1 
	nd6 options=201
sh -c 'echo "------\n/opt/homebrew/etc/nginx/valet/valet.conf\n---\n"; cat /opt/homebrew/etc/nginx/valet/valet.conf | grep -n "# valet loopback"; echo "\n------\n"'
------
/opt/homebrew/etc/nginx/valet/valet.conf
---

3: #listen VALET_LOOPBACK:80; # valet loopback

------

sh -c 'for file in ~/.config/valet/dnsmasq.d/*; do echo "------\n~/.config/valet/dnsmasq.d/$(basename $file)\n---\n"; cat $file; echo "\n------\n"; done'
------
~/.config/valet/dnsmasq.d/tld-test.conf
---

address=/.test/127.0.0.1
listen-address=127.0.0.1

------

sh -c 'for file in ~/.config/valet/nginx/*; do echo "------\n~/.config/valet/nginx/$(basename $file)\n---\n"; cat $file | grep -n "# valet loopback"; echo "\n------\n"; done'
------
~/.config/valet/nginx/icd.test
---

3: #listen 127.0.0.1:80; # valet loopback
10: #listen 127.0.0.1:443 ssl http2; # valet loopback
54: #listen 127.0.0.1:60; # valet loopback

------

@mattstauffer
Copy link
Collaborator

Huh. I tested this functionality when I was writing it... but now I'm seeing the same error. Thanks for the issue! Let me see what I can do.

@mattstauffer
Copy link
Collaborator

Nevermind lol.. I was on an old version of Valet I was testing. I can no longer reproduce this.

Can you paste the contents of your LocalValetDriver.php file in here?

@amuscalu
Copy link
Author

Sure thing, here is my LocalValetDriver.php that I've been using to display images from a different URL if they don't exists on my local.

<?php
use Valet\Drivers\Specific\WordPressValetDriver;

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 ): void {
		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;
	}

}

@amuscalu
Copy link
Author

amuscalu commented May 3, 2023

@mattstauffer has the LocalValetDriver.php been any help at replicating the issue?

@drbyte
Copy link
Contributor

drbyte commented May 3, 2023

@amuscalu this may have some side-effects with other sites you serve, but even reporting on those will be helpful in coming up with a complete fix...

/Users/YOURNAME/.composer/vendor/laravel/valet/cli/Valet/Drivers/ValetDriver.php

    public static function assign(string $sitePath, string $siteName, string $uri): ?ValetDriver
    {
        $drivers = [];

+        // Must scan these so they're extendable by customSiteDrivers loaded next
+        $specificDrivers = static::specificDrivers();
+
        // Queue custom driver based on path
        if ($customSiteDriver = static::customSiteDriver($sitePath)) {
            $drivers[] = $customSiteDriver;
        }

        // Queue custom drivers for this environment
        $drivers = array_merge($drivers, static::customDrivers());

        // Queue Valet-shipped drivers
        $drivers[] = 'LaravelValetDriver';
-        $drivers = array_merge($drivers, static::SpecificDrivers());
+        $drivers = array_merge($drivers, $specificDrivers);
        $drivers[] = 'BasicWithPublicValetDriver';
        $drivers[] = 'BasicValetDriver';

@amuscalu
Copy link
Author

amuscalu commented May 5, 2023

above solution is working

@mattstauffer
Copy link
Collaborator

I'd accept a PR for the above from anyone who has time, or I'll get to it as soon as I can get a free moment; likely next week

@drbyte
Copy link
Contributor

drbyte commented May 5, 2023

@mattstauffer
I had considered doing a PR, but haven't had a chance to study the test suite regarding these kinds of drivers, to figure out how best to test something like this.

I'm not certain whether there are any side-effects due to order-of-loading.

At this stage I think you grok the inner workings of this part way better than I do yet ;)

@jbeales
Copy link

jbeales commented Jun 20, 2023

Could the documentation be updated to mention the Valet\Drivers\Specific namespace? I just updated Valet for the first time in a while and my WordPress custom drivers died because of the namespace change.

@drbyte
Copy link
Contributor

drbyte commented Jun 20, 2023

Could the documentation be updated to mention the Valet\Drivers\Specific namespace? I just updated Valet for the first time in a while and my WordPress custom drivers died because of the namespace change.

Something like this? : https://github.com/laravel/valet/blob/master/UPGRADE.md

@jbeales
Copy link

jbeales commented Jun 22, 2023

Something like that! I swear I was using 4 before, because I had to change from just extending LaravelValetDriver or WordPressValetDriver to extending \Valet\Drivers\LaravelValetDriver and \Valet\Drivers\WordPressValetDriver, but the addition of the Specific namespace slipped by me. The fact that the docs use the LaravelValetDriver as the example, which is not in the Specific namespace, makes the existence of Specific hard to find.

Thinking more, my suggestion is that \Valet\Drivers\LaravelValetDriver should be moved to \Valet\Drivers\Specific\LaravelValetDriver. I know Valet is a Laravel-first project, but it works just as well for other frameworks and CMSes, so logically the Laravel, Cake, WordPress, Joomla, Drupal, etc drivers should be in the same place.

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

Successfully merging a pull request may close this issue.

5 participants