Merge branch '4.3' into 4.4
* 4.3: fix PHP 5.6 compatibility [Cache] fixed TagAwareAdapter returning invalid cache Add plus character `+` to legal mime subtype Make Symfony\Contracts\Service\Test\ServiceLocatorTest abstract bug #33942 [DI] Add extra type check to php dumper [Dotenv] search variable values in ENV first then env file [PropertyInfo] Respect property name case when guessing from public method name [VarDumper] fix resetting the "bold" state in CliDumper Missing argument in method_exists SCA: added missing break in a loop
This commit is contained in:
commit
ae808b0a74
@ -162,7 +162,14 @@ class TagAwareAdapter implements TagAwareAdapterInterface, TagAwareCacheInterfac
|
||||
if (!$this->pool->hasItem($key)) {
|
||||
return false;
|
||||
}
|
||||
if (!$itemTags = $this->pool->getItem(static::TAGS_PREFIX.$key)->get()) {
|
||||
|
||||
$itemTags = $this->pool->getItem(static::TAGS_PREFIX.$key);
|
||||
|
||||
if (!$itemTags->isHit()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$itemTags = $itemTags->get()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -330,7 +337,10 @@ class TagAwareAdapter implements TagAwareAdapterInterface, TagAwareCacheInterfac
|
||||
}
|
||||
|
||||
unset($tagKeys[$key]);
|
||||
$itemTags[$key] = $item->get() ?: [];
|
||||
|
||||
if ($item->isHit()) {
|
||||
$itemTags[$key] = $item->get() ?: [];
|
||||
}
|
||||
|
||||
if (!$tagKeys) {
|
||||
$tagVersions = $this->getTagVersions($itemTags);
|
||||
|
@ -101,6 +101,84 @@ class TagAwareAdapterTest extends AdapterTestCase
|
||||
$this->assertTrue($pool->getItem('foo')->isHit());
|
||||
}
|
||||
|
||||
public function testTagEntryIsCreatedForItemWithoutTags()
|
||||
{
|
||||
$pool = $this->createCachePool();
|
||||
|
||||
$itemKey = 'foo';
|
||||
$item = $pool->getItem($itemKey);
|
||||
$pool->save($item);
|
||||
|
||||
$adapter = new FilesystemAdapter();
|
||||
$this->assertTrue($adapter->hasItem(TagAwareAdapter::TAGS_PREFIX.$itemKey));
|
||||
}
|
||||
|
||||
public function testHasItemReturnsFalseWhenPoolDoesNotHaveItemTags()
|
||||
{
|
||||
$pool = $this->createCachePool();
|
||||
|
||||
$itemKey = 'foo';
|
||||
$item = $pool->getItem($itemKey);
|
||||
$pool->save($item);
|
||||
|
||||
$anotherPool = $this->createCachePool();
|
||||
|
||||
$adapter = new FilesystemAdapter();
|
||||
$adapter->deleteItem(TagAwareAdapter::TAGS_PREFIX.$itemKey); //simulate item losing tags pair
|
||||
|
||||
$this->assertFalse($anotherPool->hasItem($itemKey));
|
||||
}
|
||||
|
||||
public function testGetItemReturnsCacheMissWhenPoolDoesNotHaveItemTags()
|
||||
{
|
||||
$pool = $this->createCachePool();
|
||||
|
||||
$itemKey = 'foo';
|
||||
$item = $pool->getItem($itemKey);
|
||||
$pool->save($item);
|
||||
|
||||
$anotherPool = $this->createCachePool();
|
||||
|
||||
$adapter = new FilesystemAdapter();
|
||||
$adapter->deleteItem(TagAwareAdapter::TAGS_PREFIX.$itemKey); //simulate item losing tags pair
|
||||
|
||||
$item = $anotherPool->getItem($itemKey);
|
||||
$this->assertFalse($item->isHit());
|
||||
}
|
||||
|
||||
public function testHasItemReturnsFalseWhenPoolDoesNotHaveItemAndOnlyHasTags()
|
||||
{
|
||||
$pool = $this->createCachePool();
|
||||
|
||||
$itemKey = 'foo';
|
||||
$item = $pool->getItem($itemKey);
|
||||
$pool->save($item);
|
||||
|
||||
$anotherPool = $this->createCachePool();
|
||||
|
||||
$adapter = new FilesystemAdapter();
|
||||
$adapter->deleteItem($itemKey); //simulate losing item but keeping tags
|
||||
|
||||
$this->assertFalse($anotherPool->hasItem($itemKey));
|
||||
}
|
||||
|
||||
public function testGetItemReturnsCacheMissWhenPoolDoesNotHaveItemAndOnlyHasTags()
|
||||
{
|
||||
$pool = $this->createCachePool();
|
||||
|
||||
$itemKey = 'foo';
|
||||
$item = $pool->getItem($itemKey);
|
||||
$pool->save($item);
|
||||
|
||||
$anotherPool = $this->createCachePool();
|
||||
|
||||
$adapter = new FilesystemAdapter();
|
||||
$adapter->deleteItem($itemKey); //simulate losing item but keeping tags
|
||||
|
||||
$item = $anotherPool->getItem($itemKey);
|
||||
$this->assertFalse($item->isHit());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return MockObject|PruneableCacheInterface
|
||||
*/
|
||||
|
@ -280,6 +280,7 @@ trait MemcachedTrait
|
||||
foreach ($this->checkResultCode($this->getClient()->deleteMulti($encodedIds)) as $result) {
|
||||
if (\Memcached::RES_SUCCESS !== $result && \Memcached::RES_NOTFOUND !== $result) {
|
||||
$ok = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1953,7 +1953,7 @@ EOF;
|
||||
if (!$value = $edge->getSourceNode()->getValue()) {
|
||||
continue;
|
||||
}
|
||||
if ($edge->isLazy() || !$value->isShared()) {
|
||||
if ($edge->isLazy() || !$value instanceof Definition || !$value->isShared()) {
|
||||
return false;
|
||||
}
|
||||
$ids[$edge->getSourceNode()->getId()] = true;
|
||||
|
@ -257,6 +257,8 @@ final class Dotenv
|
||||
throw $this->createFormatException('Whitespace are not supported before the value');
|
||||
}
|
||||
|
||||
$loadedVars = array_flip(explode(',', isset($_SERVER['SYMFONY_DOTENV_VARS']) ? $_SERVER['SYMFONY_DOTENV_VARS'] : (isset($_ENV['SYMFONY_DOTENV_VARS']) ? $_ENV['SYMFONY_DOTENV_VARS'] : '')));
|
||||
unset($loadedVars['']);
|
||||
$v = '';
|
||||
|
||||
do {
|
||||
@ -295,8 +297,8 @@ final class Dotenv
|
||||
++$this->cursor;
|
||||
$value = str_replace(['\\"', '\r', '\n'], ['"', "\r", "\n"], $value);
|
||||
$resolvedValue = $value;
|
||||
$resolvedValue = $this->resolveVariables($resolvedValue);
|
||||
$resolvedValue = $this->resolveCommands($resolvedValue);
|
||||
$resolvedValue = $this->resolveVariables($resolvedValue, $loadedVars);
|
||||
$resolvedValue = $this->resolveCommands($resolvedValue, $loadedVars);
|
||||
$resolvedValue = str_replace('\\\\', '\\', $resolvedValue);
|
||||
$v .= $resolvedValue;
|
||||
} else {
|
||||
@ -318,8 +320,8 @@ final class Dotenv
|
||||
}
|
||||
$value = rtrim($value);
|
||||
$resolvedValue = $value;
|
||||
$resolvedValue = $this->resolveVariables($resolvedValue);
|
||||
$resolvedValue = $this->resolveCommands($resolvedValue);
|
||||
$resolvedValue = $this->resolveVariables($resolvedValue, $loadedVars);
|
||||
$resolvedValue = $this->resolveCommands($resolvedValue, $loadedVars);
|
||||
$resolvedValue = str_replace('\\\\', '\\', $resolvedValue);
|
||||
|
||||
if ($resolvedValue === $value && preg_match('/\s+/', $value)) {
|
||||
@ -372,7 +374,7 @@ final class Dotenv
|
||||
}
|
||||
}
|
||||
|
||||
private function resolveCommands(string $value): string
|
||||
private function resolveCommands(string $value, array $loadedVars): string
|
||||
{
|
||||
if (false === strpos($value, '$')) {
|
||||
return $value;
|
||||
@ -388,7 +390,7 @@ final class Dotenv
|
||||
)
|
||||
/x';
|
||||
|
||||
return preg_replace_callback($regex, function ($matches) {
|
||||
return preg_replace_callback($regex, function ($matches) use ($loadedVars) {
|
||||
if ('\\' === $matches[1]) {
|
||||
return substr($matches[0], 1);
|
||||
}
|
||||
@ -408,7 +410,14 @@ final class Dotenv
|
||||
$process->inheritEnvironmentVariables();
|
||||
}
|
||||
|
||||
$process->setEnv($this->values);
|
||||
$env = [];
|
||||
foreach ($this->values as $name => $value) {
|
||||
if (isset($loadedVars[$name]) || (!isset($_ENV[$name]) && !(isset($_SERVER[$name]) && 0 !== strpos($name, 'HTTP_')))) {
|
||||
$env[$name] = $value;
|
||||
}
|
||||
}
|
||||
$process->setEnv($env);
|
||||
|
||||
try {
|
||||
$process->mustRun();
|
||||
} catch (ProcessException $e) {
|
||||
@ -419,7 +428,7 @@ final class Dotenv
|
||||
}, $value);
|
||||
}
|
||||
|
||||
private function resolveVariables(string $value): string
|
||||
private function resolveVariables(string $value, array $loadedVars): string
|
||||
{
|
||||
if (false === strpos($value, '$')) {
|
||||
return $value;
|
||||
@ -436,7 +445,7 @@ final class Dotenv
|
||||
(?P<closing_brace>\})? # optional closing brace
|
||||
/x';
|
||||
|
||||
$value = preg_replace_callback($regex, function ($matches) {
|
||||
$value = preg_replace_callback($regex, function ($matches) use ($loadedVars) {
|
||||
// odd number of backslashes means the $ character is escaped
|
||||
if (1 === \strlen($matches['backslashes']) % 2) {
|
||||
return substr($matches[0], 1);
|
||||
@ -452,14 +461,16 @@ final class Dotenv
|
||||
}
|
||||
|
||||
$name = $matches['name'];
|
||||
if (isset($this->values[$name])) {
|
||||
if (isset($loadedVars[$name]) && isset($this->values[$name])) {
|
||||
$value = $this->values[$name];
|
||||
} elseif (isset($_SERVER[$name]) && 0 !== strpos($name, 'HTTP_')) {
|
||||
$value = $_SERVER[$name];
|
||||
} elseif (isset($_ENV[$name])) {
|
||||
$value = $_ENV[$name];
|
||||
} elseif (isset($_SERVER[$name]) && 0 !== strpos($name, 'HTTP_')) {
|
||||
$value = $_SERVER[$name];
|
||||
} elseif (isset($this->values[$name])) {
|
||||
$value = $this->values[$name];
|
||||
} else {
|
||||
$value = (string) getenv($name);
|
||||
$value = '';
|
||||
}
|
||||
|
||||
if ('' === $value && isset($matches['default_value'])) {
|
||||
|
@ -72,6 +72,7 @@ class DotenvTest extends TestCase
|
||||
public function getEnvData()
|
||||
{
|
||||
putenv('LOCAL=local');
|
||||
$_ENV['LOCAL'] = 'local';
|
||||
$_ENV['REMOTE'] = 'remote';
|
||||
$_SERVER['SERVERVAR'] = 'servervar';
|
||||
|
||||
@ -424,6 +425,22 @@ class DotenvTest extends TestCase
|
||||
$this->assertSame('/var/www', getenv('DOCUMENT_ROOT'));
|
||||
}
|
||||
|
||||
public function testGetVariablesValueFromEnvFirst()
|
||||
{
|
||||
$_ENV['APP_ENV'] = 'prod';
|
||||
$dotenv = new Dotenv(true);
|
||||
|
||||
$test = "APP_ENV=dev\nTEST1=foo1_\${APP_ENV}";
|
||||
$values = $dotenv->parse($test);
|
||||
$this->assertSame('foo1_prod', $values['TEST1']);
|
||||
|
||||
if ('\\' !== \DIRECTORY_SEPARATOR) {
|
||||
$test = "APP_ENV=dev\nTEST2=foo2_\$(php -r 'echo \$_SERVER[\"APP_ENV\"];')";
|
||||
$values = $dotenv->parse($test);
|
||||
$this->assertSame('foo2_prod', $values['TEST2']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @group legacy
|
||||
* @expectedDeprecation The default value of "$usePutenv" argument of "%s" will be changed from "true" to "false" in Symfony 5.0. You should define its value explicitly.
|
||||
|
@ -19,7 +19,7 @@
|
||||
"php": "^7.1.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/process": "^3.4|^4.0|^5.0"
|
||||
"symfony/process": "^3.4.2|^4.0|^5.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": { "Symfony\\Component\\Dotenv\\": "" },
|
||||
|
@ -199,7 +199,7 @@ trait HttpClientTrait
|
||||
$normalizedHeaders = [];
|
||||
|
||||
foreach ($headers as $name => $values) {
|
||||
if (\is_object($values) && method_exists('__toString')) {
|
||||
if (\is_object($values) && method_exists($values, '__toString')) {
|
||||
$values = (string) $values;
|
||||
}
|
||||
|
||||
|
@ -94,7 +94,7 @@ class FileBinaryMimeTypeGuesser implements MimeTypeGuesserInterface
|
||||
|
||||
$type = trim(ob_get_clean());
|
||||
|
||||
if (!preg_match('#^([a-z0-9\-]+/[a-z0-9\-\.]+)#i', $type, $match)) {
|
||||
if (!preg_match('#^([a-z0-9\-]+/[a-z0-9\-\+\.]+)#i', $type, $match)) {
|
||||
// it's not a type, but an error message
|
||||
return null;
|
||||
}
|
||||
|
@ -83,7 +83,7 @@ class FileBinaryMimeTypeGuesser implements MimeTypeGuesserInterface
|
||||
|
||||
$type = trim(ob_get_clean());
|
||||
|
||||
if (!preg_match('#^([a-z0-9\-]+/[a-z0-9\-\.]+)#i', $type, $match)) {
|
||||
if (!preg_match('#^([a-z0-9\-]+/[a-z0-9\-\+\.]+)#i', $type, $match)) {
|
||||
// it's not a type, but an error message
|
||||
return null;
|
||||
}
|
||||
|
@ -119,8 +119,8 @@ class ReflectionExtractor implements PropertyListExtractorInterface, PropertyTyp
|
||||
if (!$propertyName || isset($properties[$propertyName])) {
|
||||
continue;
|
||||
}
|
||||
if (!$reflectionClass->hasProperty($propertyName) && !preg_match('/^[A-Z]{2,}/', $propertyName)) {
|
||||
$propertyName = lcfirst($propertyName);
|
||||
if ($reflectionClass->hasProperty($lowerCasedPropertyName = lcfirst($propertyName)) || (!$reflectionClass->hasProperty($propertyName) && !preg_match('/^[A-Z]{2,}/', $propertyName))) {
|
||||
$propertyName = $lowerCasedPropertyName;
|
||||
}
|
||||
$properties[$propertyName] = $propertyName;
|
||||
}
|
||||
|
@ -67,6 +67,8 @@ class ReflectionExtractorTest extends TestCase
|
||||
'123',
|
||||
'self',
|
||||
'realParent',
|
||||
'xTotals',
|
||||
'YT',
|
||||
'c',
|
||||
'd',
|
||||
'e',
|
||||
|
@ -93,6 +93,16 @@ class Dummy extends ParentDummy
|
||||
*/
|
||||
public $j;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $xTotals;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $YT;
|
||||
|
||||
/**
|
||||
* This should not be removed.
|
||||
*
|
||||
@ -181,4 +191,18 @@ class Dummy extends ParentDummy
|
||||
public function setRealParent(parent $realParent)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getXTotals()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getYT()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ class CliDumper extends AbstractDumper
|
||||
protected $maxStringWidth = 0;
|
||||
protected $styles = [
|
||||
// See http://en.wikipedia.org/wiki/ANSI_escape_code#graphics
|
||||
'default' => '38;5;208',
|
||||
'default' => '0;38;5;208',
|
||||
'num' => '1;38;5;38',
|
||||
'const' => '1;38;5;208',
|
||||
'str' => '1;38;5;113',
|
||||
|
@ -15,9 +15,9 @@ use PHPUnit\Framework\TestCase;
|
||||
use Psr\Container\ContainerInterface;
|
||||
use Symfony\Contracts\Service\ServiceLocatorTrait;
|
||||
|
||||
class ServiceLocatorTest extends TestCase
|
||||
abstract class ServiceLocatorTest extends TestCase
|
||||
{
|
||||
public function getServiceLocator(array $factories)
|
||||
protected function getServiceLocator(array $factories)
|
||||
{
|
||||
return new class($factories) implements ContainerInterface {
|
||||
use ServiceLocatorTrait;
|
||||
|
Reference in New Issue
Block a user