Skip to content

Commit cdb6a68

Browse files
authored
Merge pull request #33 from danieltoader/add_own_filewriter_to_avoid_ocramius_permission_bug_from_2.1_and_up
Add own filewriter to avoid ocramius permission bug from 2.1 and up
2 parents d5b98a4 + 0e052e0 commit cdb6a68

File tree

3 files changed

+89
-1
lines changed

3 files changed

+89
-1
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ tests/app/logs/*
44
reports/
55
composer.phar
66
composer.lock
7+
.idea/
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Emag\CacheBundle\ProxyManager\GeneratorStrategy;
6+
7+
use ProxyManager\GeneratorStrategy\GeneratorStrategyInterface;
8+
use Zend\Code\Generator\ClassGenerator;
9+
use ProxyManager\Exception\FileNotWritableException;
10+
use ProxyManager\FileLocator\FileLocatorInterface;
11+
12+
/**
13+
* Class FileWriter
14+
*
15+
* @package Emag\CacheBundle\ProxyManager\GeneratorStrategy
16+
*/
17+
class FileWriter implements GeneratorStrategyInterface
18+
{
19+
20+
/**
21+
* @var \ProxyManager\FileLocator\FileLocatorInterface
22+
*/
23+
protected $fileLocator;
24+
25+
/**
26+
* @var callable
27+
*/
28+
private $emptyErrorHandler;
29+
30+
/**
31+
* @param \ProxyManager\FileLocator\FileLocatorInterface $fileLocator
32+
*/
33+
public function __construct(FileLocatorInterface $fileLocator)
34+
{
35+
$this->fileLocator = $fileLocator;
36+
$this->emptyErrorHandler = function () {
37+
};
38+
}
39+
40+
/**
41+
* Write generated code to disk and return the class code
42+
*
43+
* {@inheritDoc}
44+
*
45+
* @throws FileNotWritableException
46+
*/
47+
public function generate(ClassGenerator $classGenerator): string
48+
{
49+
$className = trim($classGenerator->getNamespaceName(), '\\')
50+
.'\\'.trim($classGenerator->getName(), '\\');
51+
$generatedCode = $classGenerator->generate();
52+
$fileName = $this->fileLocator->getProxyFileName($className);
53+
54+
set_error_handler($this->emptyErrorHandler);
55+
56+
try {
57+
$this->writeFile("<?php\n\n".$generatedCode, $fileName);
58+
59+
return $generatedCode;
60+
} finally {
61+
restore_error_handler();
62+
}
63+
}
64+
65+
/**
66+
* Writes the source file in such a way that race conditions are avoided when the same file is written
67+
* multiple times in a short time period
68+
*
69+
* @param string $source
70+
* @param string $location
71+
*
72+
* @throws FileNotWritableException
73+
*/
74+
private function writeFile(string $source, string $location)
75+
{
76+
$tmpFileName = tempnam($location, 'temporaryProxyManagerFile');
77+
78+
file_put_contents($tmpFileName, $source);
79+
chmod($tmpFileName, 0666 & ~umask());
80+
81+
if (!rename($tmpFileName, $location)) {
82+
unlink($tmpFileName);
83+
84+
throw FileNotWritableException::fromInvalidMoveOperation($tmpFileName, $location);
85+
}
86+
}
87+
}

src/Resources/config/services.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ parameters:
55
emag.cache.proxy.manager.class: Emag\CacheBundle\ProxyManager\Factory\ProxyCachingObjectFactory
66
emag.cache.proxy.generator.class: Emag\CacheBundle\ProxyManager\ProxyGenerator\CachedObjectGenerator
77
emag.cache.proxy.configuration.class: ProxyManager\Configuration
8-
emag.cache.proxy.persister.class: ProxyManager\GeneratorStrategy\FileWriterGeneratorStrategy
8+
emag.cache.proxy.persister.class: Emag\CacheBundle\ProxyManager\GeneratorStrategy\FileWriter
99
emag.cache.proxy.locator.class: ProxyManager\FileLocator\FileLocator
1010
emag.cache.proxy.cache-locator.class: Symfony\Component\DependencyInjection\ServiceLocator
1111

0 commit comments

Comments
 (0)