Merge branch '4.1'

* 4.1:
  [Console] fix CS
  [OptionResolver] resolve arrays
  [TwigBridge] Fix missing path and separators in loader paths list on debug:twig output
  [PropertyInfo] Fix dock block lookup fallback loop
  [FrameworkBundle] Fixed phpdoc in MicroKernelTrait::configureRoutes()
  [HttpFoundation] don't encode cookie name for BC
  improve deprecation messages
  minor #27858 [Console] changed warning verbosity; fixes typo (adrian-enspired)
  AppBundle->App.
  [Workflow] Fixed BC break
  [DI] Fix dumping ignore-on-uninitialized references to synthetic services
This commit is contained in:
Nicolas Grekas 2018-07-07 18:01:39 +02:00
commit ffab7d6d68
17 changed files with 481 additions and 82 deletions

View File

@ -118,19 +118,27 @@ EOF
}
$rows = array();
$firstNamespace = true;
$prevHasSeparator = false;
foreach ($this->getLoaderPaths() as $namespace => $paths) {
if (count($paths) > 1) {
if (!$firstNamespace && !$prevHasSeparator && count($paths) > 1) {
$rows[] = array('', '');
}
$firstNamespace = false;
foreach ($paths as $path) {
$rows[] = array($namespace, '- '.$path);
$rows[] = array($namespace, $path.DIRECTORY_SEPARATOR);
$namespace = '';
}
if (count($paths) > 1) {
$rows[] = array('', '');
$prevHasSeparator = true;
} else {
$prevHasSeparator = false;
}
}
array_pop($rows);
if ($prevHasSeparator) {
array_pop($rows);
}
$io->section('Loader Paths');
$io->table(array('Namespace', 'Paths'), $rows);
$messages = $this->buildWarningMessages($this->findWrongBundleOverrides());

View File

@ -0,0 +1,81 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bridge\Twig\Tests\Command;
use PHPUnit\Framework\TestCase;
use Symfony\Bridge\Twig\Command\DebugCommand;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Tester\CommandTester;
use Twig\Loader\FilesystemLoader;
use Twig\Environment;
class DebugCommandTest extends TestCase
{
public function testDebugCommand()
{
$tester = $this->createCommandTester();
$ret = $tester->execute(array(), array('decorated' => false));
$this->assertEquals(0, $ret, 'Returns 0 in case of success');
$this->assertContains('Functions', trim($tester->getDisplay()));
}
public function testLineSeparatorInLoaderPaths()
{
// these paths aren't realistic,
// they're configured to force the line separator
$tester = $this->createCommandTester(array(
'Acme' => array('extractor', 'extractor'),
'!Acme' => array('extractor', 'extractor'),
FilesystemLoader::MAIN_NAMESPACE => array('extractor', 'extractor'),
));
$ret = $tester->execute(array(), array('decorated' => false));
$ds = DIRECTORY_SEPARATOR;
$loaderPaths = <<<TXT
Loader Paths
------------
----------- ------------
Namespace Paths
----------- ------------
@Acme extractor$ds
extractor$ds
@!Acme extractor$ds
extractor$ds
(None) extractor$ds
extractor$ds
----------- ------------
TXT;
$this->assertEquals(0, $ret, 'Returns 0 in case of success');
$this->assertContains($loaderPaths, trim($tester->getDisplay(true)));
}
private function createCommandTester(array $paths = array())
{
$filesystemLoader = new FilesystemLoader(array(), dirname(__DIR__).'/Fixtures');
foreach ($paths as $namespace => $relDirs) {
foreach ($relDirs as $relDir) {
$filesystemLoader->addPath($relDir, $namespace);
}
}
$command = new DebugCommand(new Environment($filesystemLoader));
$application = new Application();
$application->add($command);
$command = $application->find('debug:twig');
return new CommandTester($command);
}
}

View File

@ -28,7 +28,7 @@ trait MicroKernelTrait
* Add or import routes into your application.
*
* $routes->import('config/routing.yml');
* $routes->add('/admin', 'AppBundle:Admin:dashboard', 'admin_dashboard');
* $routes->add('/admin', 'App\Controller\AdminController::dashboard', 'admin_dashboard');
*
* @param RouteCollectionBuilder $routes
*/

View File

@ -70,7 +70,7 @@ Suppose that you have the following security configuration in your application:
security:
encoders:
Symfony\Component\Security\Core\User\User: plaintext
AppBundle\Entity\User: bcrypt
App\Entity\User: bcrypt
</comment>
If you execute the command non-interactively, the first available configured
@ -82,16 +82,16 @@ generated to encode the password:
Pass the full user class path as the second argument to encode passwords for
your own entities:
<info>php %command.full_name% --no-interaction [password] AppBundle\Entity\User</info>
<info>php %command.full_name% --no-interaction [password] App\Entity\User</info>
Executing the command interactively allows you to generate a random salt for
encoding the password:
<info>php %command.full_name% [password] AppBundle\Entity\User</info>
<info>php %command.full_name% [password] App\Entity\User</info>
In case your encoder doesn't require a salt, add the <comment>empty-salt</comment> option:
<info>php %command.full_name% --empty-salt [password] AppBundle\Entity\User</info>
<info>php %command.full_name% --empty-salt [password] App\Entity\User</info>
EOF
)

View File

@ -363,8 +363,8 @@ class MainConfiguration implements ConfigurationInterface
->children()
->arrayNode('encoders')
->example(array(
'AppBundle\Entity\User1' => 'bcrypt',
'AppBundle\Entity\User2' => array(
'App\Entity\User1' => 'bcrypt',
'App\Entity\User2' => array(
'algorithm' => 'bcrypt',
'cost' => 13,
),

View File

@ -220,10 +220,7 @@ class Command
if (function_exists('cli_set_process_title')) {
if (!@cli_set_process_title($this->processTitle)) {
if ('Darwin' === PHP_OS) {
$output->writeln(
'<comment>Running "cli_set_process_title" as an unprivileged user is not supported on MacOS.</comment>',
OutputInterface::VERBOSITY_VERY_VERBOSE
);
$output->writeln('<comment>Running "cli_set_process_title" as an unprivileged user is not supported on MacOS.</comment>', OutputInterface::VERBOSITY_VERY_VERBOSE);
} else {
cli_set_process_title($this->processTitle);
}

View File

@ -1680,8 +1680,10 @@ EOF;
return '$this';
}
if ($this->container->hasDefinition($id) && ($definition = $this->container->getDefinition($id)) && !$definition->isSynthetic()) {
if (null !== $reference && ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE === $reference->getInvalidBehavior()) {
if ($this->container->hasDefinition($id) && $definition = $this->container->getDefinition($id)) {
if ($definition->isSynthetic()) {
$code = sprintf('$this->get(\'%s\'%s)', $id, null !== $reference ? ', '.$reference->getInvalidBehavior() : '');
} elseif (null !== $reference && ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE === $reference->getInvalidBehavior()) {
$code = 'null';
if (!$definition->isShared()) {
return $code;

View File

@ -1399,6 +1399,21 @@ class ContainerBuilderTest extends TestCase
$this->assertSame('via-bindings', $container->get('foo')->class2->identifier);
}
public function testUninitializedSyntheticReference()
{
$container = new ContainerBuilder();
$container->register('foo', 'stdClass')->setPublic(true)->setSynthetic(true);
$container->register('bar', 'stdClass')->setPublic(true)->setShared(false)
->setProperty('foo', new Reference('foo', ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE));
$container->compile();
$this->assertEquals((object) array('foo' => null), $container->get('bar'));
$container->set('foo', (object) array(123));
$this->assertEquals((object) array('foo' => (object) array(123)), $container->get('bar'));
}
public function testIdCanBeAnObjectAsLongAsItCanBeCastToString()
{
$id = new Reference('another_service');

View File

@ -960,6 +960,29 @@ class PhpDumperTest extends TestCase
$this->assertInstanceOf('stdClass', $container->get('bar'));
}
public function testUninitializedSyntheticReference()
{
$container = new ContainerBuilder();
$container->register('foo', 'stdClass')->setPublic(true)->setSynthetic(true);
$container->register('bar', 'stdClass')->setPublic(true)->setShared(false)
->setProperty('foo', new Reference('foo', ContainerBuilder::IGNORE_ON_UNINITIALIZED_REFERENCE));
$container->compile();
$dumper = new PhpDumper($container);
eval('?>'.$dumper->dump(array(
'class' => 'Symfony_DI_PhpDumper_Test_UninitializedSyntheticReference',
'inline_class_loader_parameter' => 'inline_requires',
)));
$container = new \Symfony_DI_PhpDumper_Test_UninitializedSyntheticReference();
$this->assertEquals((object) array('foo' => null), $container->get('bar'));
$container->set('foo', (object) array(123));
$this->assertEquals((object) array('foo' => (object) array(123)), $container->get('bar'));
}
/**
* This test checks the trigger of a deprecation note and should not be removed in major releases.
*

View File

@ -329,12 +329,17 @@ class Response
}
// headers
foreach ($this->headers->allPreserveCase() as $name => $values) {
foreach ($this->headers->allPreserveCaseWithoutCookies() as $name => $values) {
foreach ($values as $value) {
header($name.': '.$value, false, $this->statusCode);
}
}
// cookies
foreach ($this->headers->getCookies() as $cookie) {
header('Set-Cookie: '.$cookie->getName().strstr($cookie, '='), false, $this->statusCode);
}
// status
header(sprintf('HTTP/%s %s %s', $this->version, $this->statusCode, $this->statusText), true, $this->statusCode);

View File

@ -4,7 +4,7 @@ Array
[0] => Content-Type: text/plain; charset=utf-8
[1] => Cache-Control: no-cache, private
[2] => Date: Sat, 12 Nov 1955 20:04:00 GMT
[3] => Set-Cookie: %3F%2A%28%29%3A%40%26%2B%24%2F%25%23%5B%5D=%3F%2A%28%29%3A%40%26%2B%24%2F%25%23%5B%5D; path=/
[3] => Set-Cookie: ?*():@&+$/%#[]=%3F%2A%28%29%3A%40%26%2B%24%2F%25%23%5B%5D; path=/
[4] => Set-Cookie: ?*():@&+$/%#[]=%3F%2A%28%29%3A%40%26%2B%24%2F%25%23%5B%5D; path=/
)
shutdown

View File

@ -490,7 +490,7 @@ class OptionsResolver implements Options
));
}
$this->allowedValues[$option] = is_array($allowedValues) ? $allowedValues : array($allowedValues);
$this->allowedValues[$option] = \is_array($allowedValues) ? $allowedValues : array($allowedValues);
// Make sure the option is processed
unset($this->resolved[$option]);
@ -843,14 +843,13 @@ class OptionsResolver implements Options
}
if (!$valid) {
throw new InvalidOptionsException(sprintf(
'The option "%s" with value %s is expected to be of type '.
'"%s", but is of type "%s".',
$option,
$this->formatValue($value),
implode('" or "', $this->allowedTypes[$option]),
implode('|', array_keys($invalidTypes))
));
$keys = array_keys($invalidTypes);
if (1 === \count($keys) && '[]' === substr($keys[0], -2)) {
throw new InvalidOptionsException(sprintf('The option "%s" with value %s is expected to be of type "%s", but one of the elements is of type "%s".', $option, $this->formatValue($value), implode('" or "', $this->allowedTypes[$option]), $keys[0]));
}
throw new InvalidOptionsException(sprintf('The option "%s" with value %s is expected to be of type "%s", but is of type "%s".', $option, $this->formatValue($value), implode('" or "', $this->allowedTypes[$option]), implode('|', array_keys($invalidTypes))));
}
}
@ -939,32 +938,10 @@ class OptionsResolver implements Options
return $value;
}
/**
* @param string $type
* @param mixed $value
* @param array &$invalidTypes
*
* @return bool
*/
private function verifyTypes($type, $value, array &$invalidTypes)
private function verifyTypes(string $type, $value, array &$invalidTypes): bool
{
if ('[]' === substr($type, -2) && is_array($value)) {
$originalType = $type;
$type = substr($type, 0, -2);
$invalidValues = array_filter( // Filter out valid values, keeping invalid values in the resulting array
$value,
function ($value) use ($type) {
return !self::isValueValidType($type, $value);
}
);
if (!$invalidValues) {
return true;
}
$invalidTypes[$this->formatTypeOf($value, $originalType)] = true;
return false;
if (\is_array($value) && '[]' === substr($type, -2)) {
return $this->verifyArrayType($type, $value, $invalidTypes);
}
if (self::isValueValidType($type, $value)) {
@ -978,6 +955,43 @@ class OptionsResolver implements Options
return false;
}
private function verifyArrayType(string $type, array $value, array &$invalidTypes, int $level = 0): bool
{
$type = substr($type, 0, -2);
$suffix = '[]';
while (\strlen($suffix) <= $level * 2) {
$suffix .= '[]';
}
if ('[]' === substr($type, -2)) {
$success = true;
foreach ($value as $item) {
if (!\is_array($item)) {
$invalidTypes[$this->formatTypeOf($item, null).$suffix] = true;
return false;
}
if (!$this->verifyArrayType($type, $item, $invalidTypes, $level + 1)) {
$success = false;
}
}
return $success;
}
foreach ($value as $item) {
if (!self::isValueValidType($type, $item)) {
$invalidTypes[$this->formatTypeOf($item, $type).$suffix] = $value;
return false;
}
}
return true;
}
/**
* Returns whether a resolved option with the given name exists.
*
@ -1058,13 +1072,13 @@ class OptionsResolver implements Options
while ('[]' === substr($type, -2)) {
$type = substr($type, 0, -2);
$value = array_shift($value);
if (!is_array($value)) {
if (!\is_array($value)) {
break;
}
$suffix .= '[]';
}
if (is_array($value)) {
if (\is_array($value)) {
$subTypes = array();
foreach ($value as $val) {
$subTypes[$this->formatTypeOf($val, null)] = true;
@ -1074,7 +1088,7 @@ class OptionsResolver implements Options
}
}
return (is_object($value) ? get_class($value) : gettype($value)).$suffix;
return (\is_object($value) ? get_class($value) : gettype($value)).$suffix;
}
/**
@ -1088,19 +1102,19 @@ class OptionsResolver implements Options
*/
private function formatValue($value): string
{
if (is_object($value)) {
if (\is_object($value)) {
return get_class($value);
}
if (is_array($value)) {
if (\is_array($value)) {
return 'array';
}
if (is_string($value)) {
if (\is_string($value)) {
return '"'.$value.'"';
}
if (is_resource($value)) {
if (\is_resource($value)) {
return 'resource';
}
@ -1136,8 +1150,21 @@ class OptionsResolver implements Options
return implode(', ', $values);
}
private static function isValueValidType($type, $value)
private static function isValueValidType(string $type, $value): bool
{
return (function_exists($isFunction = 'is_'.$type) && $isFunction($value)) || $value instanceof $type;
}
private function getInvalidValues(array $arrayValues, string $type): array
{
$invalidValues = array();
foreach ($arrayValues as $key => $value) {
if (!self::isValueValidType($type, $value)) {
$invalidValues[$key] = $value;
}
}
return $invalidValues;
}
}

View File

@ -664,7 +664,7 @@ class OptionsResolverTest extends TestCase
/**
* @expectedException \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException
* @expectedExceptionMessage The option "foo" with value array is expected to be of type "int[]", but is of type "DateTime[]".
* @expectedExceptionMessage The option "foo" with value array is expected to be of type "int[]", but one of the elements is of type "DateTime[]".
*/
public function testResolveFailsIfInvalidTypedArray()
{
@ -688,7 +688,7 @@ class OptionsResolverTest extends TestCase
/**
* @expectedException \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException
* @expectedExceptionMessage The option "foo" with value array is expected to be of type "int[]", but is of type "integer|stdClass|array|DateTime[]".
* @expectedExceptionMessage The option "foo" with value array is expected to be of type "int[]", but one of the elements is of type "stdClass[]".
*/
public function testResolveFailsIfTypedArrayContainsInvalidTypes()
{
@ -705,7 +705,7 @@ class OptionsResolverTest extends TestCase
/**
* @expectedException \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException
* @expectedExceptionMessage The option "foo" with value array is expected to be of type "int[][]", but is of type "double[][]".
* @expectedExceptionMessage The option "foo" with value array is expected to be of type "int[][]", but one of the elements is of type "double[][]".
*/
public function testResolveFailsWithCorrectLevelsButWrongScalar()
{
@ -1767,4 +1767,151 @@ class OptionsResolverTest extends TestCase
count($this->resolver);
}
public function testNestedArrays()
{
$this->resolver->setDefined('foo');
$this->resolver->setAllowedTypes('foo', 'int[][]');
$this->assertEquals(array(
'foo' => array(
array(
1, 2,
),
),
), $this->resolver->resolve(
array(
'foo' => array(
array(1, 2),
),
)
));
}
public function testNested2Arrays()
{
$this->resolver->setDefined('foo');
$this->resolver->setAllowedTypes('foo', 'int[][][][]');
$this->assertEquals(array(
'foo' => array(
array(
array(
array(
1, 2,
),
),
),
),
), $this->resolver->resolve(
array(
'foo' => array(
array(
array(
array(1, 2),
),
),
),
)
));
}
/**
* @expectedException \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException
* @expectedExceptionMessage The option "foo" with value array is expected to be of type "float[][][][]", but one of the elements is of type "integer[][][][]".
*/
public function testNestedArraysException()
{
$this->resolver->setDefined('foo');
$this->resolver->setAllowedTypes('foo', 'float[][][][]');
$this->resolver->resolve(
array(
'foo' => array(
array(
array(
array(1, 2),
),
),
),
)
);
}
/**
* @expectedException \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException
* @expectedExceptionMessage The option "foo" with value array is expected to be of type "int[][]", but one of the elements is of type "boolean[][]".
*/
public function testNestedArrayException1()
{
$this->resolver->setDefined('foo');
$this->resolver->setAllowedTypes('foo', 'int[][]');
$this->resolver->resolve(array(
'foo' => array(
array(1, true, 'str', array(2, 3)),
),
));
}
/**
* @expectedException \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException
* @expectedExceptionMessage The option "foo" with value array is expected to be of type "int[][]", but one of the elements is of type "boolean[][]".
*/
public function testNestedArrayException2()
{
$this->resolver->setDefined('foo');
$this->resolver->setAllowedTypes('foo', 'int[][]');
$this->resolver->resolve(array(
'foo' => array(
array(true, 'str', array(2, 3)),
),
));
}
/**
* @expectedException \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException
* @expectedExceptionMessage The option "foo" with value array is expected to be of type "string[][][]", but one of the elements is of type "string[][]".
*/
public function testNestedArrayException3()
{
$this->resolver->setDefined('foo');
$this->resolver->setAllowedTypes('foo', 'string[][][]');
$this->resolver->resolve(array(
'foo' => array(
array('str', array(1, 2)),
),
));
}
/**
* @expectedException \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException
* @expectedExceptionMessage The option "foo" with value array is expected to be of type "string[][][]", but one of the elements is of type "integer[][][]".
*/
public function testNestedArrayException4()
{
$this->resolver->setDefined('foo');
$this->resolver->setAllowedTypes('foo', 'string[][][]');
$this->resolver->resolve(array(
'foo' => array(
array(
array('str'), array(1, 2), ),
),
));
}
/**
* @expectedException \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException
* @expectedExceptionMessage The option "foo" with value array is expected to be of type "string[]", but one of the elements is of type "array[]".
*/
public function testNestedArrayException5()
{
$this->resolver->setDefined('foo');
$this->resolver->setAllowedTypes('foo', 'string[]');
$this->resolver->resolve(array(
'foo' => array(
array(
array('str'), array(1, 2), ),
),
));
}
}

View File

@ -161,25 +161,21 @@ class PhpDocExtractor implements PropertyDescriptionExtractorInterface, Property
$ucFirstProperty = ucfirst($property);
try {
switch (true) {
case $docBlock = $this->getDocBlockFromProperty($class, $property):
$data = array($docBlock, self::PROPERTY, null);
break;
switch (true) {
case $docBlock = $this->getDocBlockFromProperty($class, $property):
$data = array($docBlock, self::PROPERTY, null);
break;
case list($docBlock) = $this->getDocBlockFromMethod($class, $ucFirstProperty, self::ACCESSOR):
$data = array($docBlock, self::ACCESSOR, null);
break;
case list($docBlock) = $this->getDocBlockFromMethod($class, $ucFirstProperty, self::ACCESSOR):
$data = array($docBlock, self::ACCESSOR, null);
break;
case list($docBlock, $prefix) = $this->getDocBlockFromMethod($class, $ucFirstProperty, self::MUTATOR):
$data = array($docBlock, self::MUTATOR, $prefix);
break;
case list($docBlock, $prefix) = $this->getDocBlockFromMethod($class, $ucFirstProperty, self::MUTATOR):
$data = array($docBlock, self::MUTATOR, $prefix);
break;
default:
$data = array(null, null, null);
}
} catch (\InvalidArgumentException $e) {
$data = array(null, null, null);
default:
$data = array(null, null, null);
}
return $this->docBlocks[$propertyHash] = $data;
@ -194,7 +190,11 @@ class PhpDocExtractor implements PropertyDescriptionExtractorInterface, Property
return null;
}
return $this->docBlockFactory->create($reflectionProperty, $this->contextFactory->createFromReflector($reflectionProperty->getDeclaringClass()));
try {
return $this->docBlockFactory->create($reflectionProperty, $this->contextFactory->createFromReflector($reflectionProperty->getDeclaringClass()));
} catch (\InvalidArgumentException $e) {
return null;
}
}
private function getDocBlockFromMethod(string $class, string $ucFirstProperty, int $type): ?array
@ -226,6 +226,10 @@ class PhpDocExtractor implements PropertyDescriptionExtractorInterface, Property
return null;
}
return array($this->docBlockFactory->create($reflectionMethod, $this->contextFactory->createFromReflector($reflectionMethod)), $prefix);
try {
return array($this->docBlockFactory->create($reflectionMethod, $this->contextFactory->createFromReflector($reflectionMethod)), $prefix);
} catch (\InvalidArgumentException $e) {
return null;
}
}
}

View File

@ -218,6 +218,29 @@ class PhpDocExtractorTest extends TestCase
{
$this->assertNull($this->extractor->getShortDescription(EmptyDocBlock::class, 'foo'));
}
public function dockBlockFallbackTypesProvider()
{
return array(
'pub' => array(
'pub', array(new Type(Type::BUILTIN_TYPE_STRING)),
),
'protAcc' => array(
'protAcc', array(new Type(Type::BUILTIN_TYPE_INT)),
),
'protMut' => array(
'protMut', array(new Type(Type::BUILTIN_TYPE_BOOL)),
),
);
}
/**
* @dataProvider dockBlockFallbackTypesProvider
*/
public function testDocBlockFallback($property, $types)
{
$this->assertEquals($types, $this->extractor->getTypes('Symfony\Component\PropertyInfo\Tests\Fixtures\DockBlockFallback', $property));
}
}
class EmptyDocBlock

View File

@ -0,0 +1,64 @@
<?php
namespace Symfony\Component\PropertyInfo\Tests\Fixtures;
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\PropertyInfo\Tests\Fixtures;
/**
* PhpDocExtractor should fallback from property -> accessor -> mutator when looking up dockblocks.
*
* @author Martin Rademacher <mano@radebatz.net>
*/
class DockBlockFallback
{
/** @var string $pub */
public $pub = 'pub';
protected $protAcc;
protected $protMut;
public function getPub()
{
return $this->pub;
}
public function setPub($pub)
{
$this->pub = $pub;
}
/**
* @return int
*/
public function getProtAcc()
{
return $this->protAcc;
}
public function setProt($protAcc)
{
$this->protAcc = $protAcc;
}
public function getProtMut()
{
return $this->protMut;
}
/**
* @param bool $protMut
*/
public function setProtMut($protMut)
{
$this->protMut = $protMut;
}
}

View File

@ -40,7 +40,10 @@ class Event extends BaseEvent
$this->subject = $subject;
$this->marking = $marking;
$this->transition = $transition;
if (is_string($workflow)) {
if (null === $workflow) {
@trigger_error(sprintf('Passing only three parameters to "%s" is deprecated since Symfony 4.1. Pass a %s instance as fourth parameter instead.', __METHOD__, WorkflowInterface::class), E_USER_DEPRECATED);
$this->workflowName = 'unnamed';
} elseif (is_string($workflow)) {
@trigger_error(sprintf('Passing a string as 4th parameter of "%s" is deprecated since Symfony 4.1. Pass a %s instance instead.', __METHOD__, WorkflowInterface::class), E_USER_DEPRECATED);
$this->workflowName = $workflow;
} elseif ($workflow instanceof WorkflowInterface) {