Skip to content

Commit 6e2f5c2

Browse files
committed
Refactor FactoryAutoloader to use PHPStan Cache
1 parent 5422c9b commit 6e2f5c2

File tree

3 files changed

+141
-9
lines changed

3 files changed

+141
-9
lines changed

src/bitExpert/PHPStan/Magento/Autoload/FactoryAutoloader.php

Lines changed: 45 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,48 @@
1212

1313
namespace bitExpert\PHPStan\Magento\Autoload;
1414

15+
use PHPStan\Cache\Cache;
16+
1517
class FactoryAutoloader
1618
{
19+
/**
20+
* @var Cache
21+
*/
22+
private $cache;
23+
24+
/**
25+
* FactoryAutoloader constructor.
26+
*
27+
* @param Cache $cache
28+
*/
29+
public function __construct(Cache $cache)
30+
{
31+
$this->cache = $cache;
32+
}
33+
1734
public function autoload(string $class): void
1835
{
1936
if (!preg_match('#Factory$#', $class)) {
2037
return;
2138
}
2239

40+
$cacheFilename = $this->cache->load($class, '');
41+
if ($cacheFilename === null) {
42+
$this->cache->save($class, '', $this->getFileContents($class));
43+
$cacheFilename = $this->cache->load($class, '');
44+
}
45+
46+
require_once($cacheFilename);
47+
}
48+
49+
/**
50+
* Generate the factory file content as Magento would.
51+
*
52+
* @param $class
53+
* @return string
54+
*/
55+
protected function getFileContents($class): string
56+
{
2357
$namespace = explode('\\', ltrim($class, '\\'));
2458
$factoryClassname = array_pop($namespace);
2559
$originalClassname = str_replace('Factory', '', $factoryClassname);
@@ -41,16 +75,18 @@ public function autoload(string $class): void
4175
$template .= " public function create(array \$data = array()) {}\n";
4276
$template .= "}\n";
4377

44-
$template = str_replace(
45-
['{NAMESPACE}', '{CLASSNAME}', '{FACTORY_CLASSNAME}'],
46-
[$namespace, $originalClassname, $factoryClassname],
78+
return str_replace(
79+
[
80+
'{NAMESPACE}',
81+
'{CLASSNAME}',
82+
'{FACTORY_CLASSNAME}'
83+
],
84+
[
85+
$namespace,
86+
$originalClassname,
87+
$factoryClassname
88+
],
4789
$template
4890
);
49-
50-
// we need to store the generated file on disk as PHPStan will try to access the file in several ways. Just
51-
// eval'ing the php code to make the class available won't work!
52-
$tmpFilename = tempnam(sys_get_temp_dir(), 'PSMF');
53-
file_put_contents($tmpFilename, $template, LOCK_EX);
54-
include($tmpFilename);
5591
}
5692
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the phpstan-magento package.
5+
*
6+
* (c) bitExpert AG
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
declare(strict_types=1);
12+
13+
namespace bitExpert\PHPStan\Magento\Autoload;
14+
15+
use PHPStan\Cache\Cache;
16+
use PHPStan\Cache\CacheStorage;
17+
use PHPUnit\Framework\TestCase;
18+
19+
class FactoryAutoloaderUnitTest extends TestCase
20+
{
21+
/**
22+
* @var CacheStorage|\PHPUnit\Framework\MockObject\MockObject
23+
*/
24+
private $storage;
25+
/**
26+
* @var FactoryAutoloader
27+
*/
28+
private $autoloader;
29+
30+
public function setUp(): void
31+
{
32+
$this->storage = $this->createMock(CacheStorage::class);
33+
$this->autoloader = new FactoryAutoloader(new Cache($this->storage));
34+
}
35+
36+
/**
37+
* @test
38+
*/
39+
public function autoloaderIgnoresClassesWithoutFactoryPostfix()
40+
{
41+
$this->storage->expects($this->never())
42+
->method('load');
43+
44+
$this->autoloader->autoload('SomeClass');
45+
}
46+
47+
/**
48+
* @test
49+
*/
50+
public function autoloaderUsesCachedFileWhenFound()
51+
{
52+
$this->storage->expects($this->once())
53+
->method('load')
54+
->willReturn(__DIR__ . '/HelperFactory.php');
55+
56+
$this->autoloader->autoload(HelperFactory::class);
57+
58+
self::assertTrue(class_exists(HelperFactory::class, false));
59+
}
60+
61+
/**
62+
* @test
63+
*/
64+
public function autoloaderGeneratesCacheFileWhenNotFoundInCache()
65+
{
66+
$this->storage->expects($this->atMost(2))
67+
->method('load')
68+
->willReturnOnConsecutiveCalls(null, __DIR__ . '/HelperFactory.php');
69+
$this->storage->expects($this->once())
70+
->method('save');
71+
72+
$this->autoloader->autoload(HelperFactory::class);
73+
74+
self::assertTrue(class_exists(HelperFactory::class, false));
75+
}
76+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the phpstan-magento package.
5+
*
6+
* (c) bitExpert AG
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
declare(strict_types=1);
12+
13+
namespace bitExpert\PHPStan\Magento\Autoload;
14+
15+
/**
16+
* Dummy class that can be loaded via the Autoloader in the test cases.
17+
*/
18+
class HelperFactory
19+
{
20+
}

0 commit comments

Comments
 (0)