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

Merge release 1.4.1 into 1.5.x #91

Merged
merged 3 commits into from Dec 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
18 changes: 0 additions & 18 deletions psalm-baseline.xml
Expand Up @@ -12,9 +12,6 @@
<code>$class</code>
<code>$class</code>
</MissingClosureParamType>
<MissingFile occurrences="1">
<code>include __DIR__ . '/../../../autoload.php'</code>
</MissingFile>
<MissingReturnType occurrences="1">
<code>load</code>
</MissingReturnType>
Expand All @@ -31,25 +28,10 @@
<MixedArrayOffset occurrences="1">
<code>$loaded[$class]</code>
</MixedArrayOffset>
<MixedInferredReturnType occurrences="1">
<code>ClassLoader</code>
</MixedInferredReturnType>
<MixedOperand occurrences="2">
<code>$namespaces[$check]</code>
<code>$namespaces[$check]</code>
</MixedOperand>
<MixedReturnStatement occurrences="3">
<code>include __DIR__ . '/../../../autoload.php'</code>
<code>include __DIR__ . '/../vendor/autoload.php'</code>
<code>include getenv('COMPOSER_VENDOR_DIR') . '/autoload.php'</code>
</MixedReturnStatement>
<PossiblyFalseOperand occurrences="2">
<code>getenv('COMPOSER_VENDOR_DIR')</code>
<code>getenv('COMPOSER_VENDOR_DIR')</code>
</PossiblyFalseOperand>
<UnresolvableInclude occurrences="1">
<code>include getenv('COMPOSER_VENDOR_DIR') . '/autoload.php'</code>
</UnresolvableInclude>
</file>
<file src="src/ConfigPostProcessor.php">
<InvalidArgument occurrences="1">
Expand Down
49 changes: 32 additions & 17 deletions src/Autoloader.php
Expand Up @@ -11,6 +11,7 @@
use function class_exists;
use function explode;
use function file_exists;
use function getenv;
use function interface_exists;
use function spl_autoload_register;
use function strlen;
Expand All @@ -23,6 +24,9 @@
*/
class Autoloader
{
private const UPSTREAM_COMPOSER_VENDOR_DIRECTORY = __DIR__ . '/../../..';
private const LOCAL_COMPOSER_VENDOR_DIRECTORY = __DIR__ . '/../vendor';

/**
* Attach autoloaders for managing legacy ZF artifacts.
*
Expand All @@ -41,10 +45,15 @@ class Autoloader
public static function load()
{
$loaded = new ArrayObject([]);
$classLoader = self::getClassLoader();

if ($classLoader === null) {
return;
}

spl_autoload_register(self::createPrependAutoloader(
RewriteRules::namespaceReverse(),
self::getClassLoader(),
$classLoader,
$loaded
), true, true);

Expand All @@ -54,25 +63,15 @@ public static function load()
));
}

/**
* @return ClassLoader
* @throws RuntimeException
*/
private static function getClassLoader()
private static function getClassLoader(): ?ClassLoader
{
if (getenv('COMPOSER_VENDOR_DIR') && file_exists(getenv('COMPOSER_VENDOR_DIR') . '/autoload.php')) {
return include getenv('COMPOSER_VENDOR_DIR') . '/autoload.php';
}

if (file_exists(__DIR__ . '/../../../autoload.php')) {
return include __DIR__ . '/../../../autoload.php';
}

if (file_exists(__DIR__ . '/../vendor/autoload.php')) {
return include __DIR__ . '/../vendor/autoload.php';
$composerVendorDirectory = getenv('COMPOSER_VENDOR_DIR');
if (is_string($composerVendorDirectory)) {
return self::getClassLoaderFromVendorDirectory($composerVendorDirectory);
}

throw new RuntimeException('Cannot detect composer autoload. Please run composer install');
return self::getClassLoaderFromVendorDirectory(self::UPSTREAM_COMPOSER_VENDOR_DIRECTORY)
?? self::getClassLoaderFromVendorDirectory(self::LOCAL_COMPOSER_VENDOR_DIRECTORY);
}

/**
Expand Down Expand Up @@ -163,4 +162,20 @@ class_alias($alias, $class);
}
};
}

private static function getClassLoaderFromVendorDirectory(string $composerVendorDirectory): ?ClassLoader
{
$filename = rtrim($composerVendorDirectory, '/') . '/autoload.php';
if (!file_exists($filename)) {
return null;
}

/** @psalm-suppress MixedAssignment */
$loader = include $filename;
if (!$loader instanceof ClassLoader) {
return null;
}

return $loader;
}
}
24 changes: 24 additions & 0 deletions test/AutoloaderTest.php
Expand Up @@ -3,14 +3,20 @@
namespace LaminasTest\ZendFrameworkBridge;

use Laminas\LegacyTypeHint;
use Laminas\ZendFrameworkBridge\Autoloader;
use PHPUnit\Framework\TestCase;

use function class_exists;
use function clearstatcache;
use function file_exists;
use function get_class;
use function interface_exists;
use function rename;

class AutoloaderTest extends TestCase
{
private const PATH_TO_AUTOLOADER = __DIR__ . '/../vendor/autoload.php';

/**
* @return array[]
*/
Expand Down Expand Up @@ -139,4 +145,22 @@ public function testReverseAliasCreated($actual, $legacy)
self::assertTrue(class_exists($actual));
self::assertTrue(class_exists($legacy));
}

public function testCanHandleNonExistentAutoloadFile(): void
{
self::assertTrue(file_exists(self::PATH_TO_AUTOLOADER));
$pathToAutoloaderBackup = sprintf('%s.bak', self::PATH_TO_AUTOLOADER);
rename(self::PATH_TO_AUTOLOADER, $pathToAutoloaderBackup);
clearstatcache();
self::assertFalse(file_exists(self::PATH_TO_AUTOLOADER));

try {
Autoloader::load();
} finally {
rename($pathToAutoloaderBackup, self::PATH_TO_AUTOLOADER);
}

clearstatcache();
self::assertTrue(file_exists(self::PATH_TO_AUTOLOADER));
}
}