feature #28316 Trigger deprecation notices when inherited class calls parent method but misses adding new arguments (kevinjhappy)

This PR was merged into the 4.2-dev branch.

Discussion
----------

Trigger deprecation notices when inherited class calls parent method but misses adding new arguments

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | no
| New feature?  | no
| BC breaks?    | no
| Deprecations? | yes
| Tests pass?   | yes
| Fixed tickets |
| License       | MIT
| Doc PR        |

This Pull Request concern severals components, the purpose here is to notify in dev mode that in a case of inherit class, a function will have a new or severals arguments in Symfony 5.0, therefore not implement it is deprecated since Symfony 4.2

The function is made by these conditions :
1- ```(func_num_args() < $x)``` where [x] is the number of arguments we will have in Symfony 5.0
  this check allow to verify that the arguments are missing
2- ```(__CLASS__ !== \get_class($this))```
  this check allow to verify that the name of the class is different than the base class, therefore that we are in the child class
3- ```(__CLASS__ !== (new \ReflectionMethod($this, __FUNCTION__))->getDeclaringClass()->getName())```
  this check allow to verify that the class of the current function is different than the base class, therefore the function has been rewrote into the child class

Code exemple :
```
public function method(/* void $myNewArgument = null */)
{
	if ((func_num_args() < 1) && (__CLASS__ !== \get_class($this)) && (__CLASS__ !== (new \ReflectionMethod($this, __FUNCTION__))->getDeclaringClass()->getName())){
            @trigger_error(sprintf('The "%s()" method will have one `void $myNewArgument = null` argument in version 5.0 and higher.Not defining it is deprecated since Symfony 4.2.', __METHOD__ ), E_USER_DEPRECATED);
    }
    // do something
}
```

The unit test are made by creating a child Class using for the tested function ```return parent::function()``` and by calling this child class and catching the expected depreciation message

Commits
-------

f75fffa997 Trigger deprecation notices when inherited class calls parent method but misses adding new arguments
This commit is contained in:
Nicolas Grekas 2018-09-17 20:15:16 +02:00
commit 440944f3c2
19 changed files with 298 additions and 21 deletions

View File

@ -1,6 +1,11 @@
UPGRADE FROM 4.1 to 4.2 UPGRADE FROM 4.1 to 4.2
======================= =======================
BrowserKit
----------
* The `Client::submit()` method will have a new `$serverParameters` argument in version 5.0, not defining it is deprecated.
Cache Cache
----- -----
@ -37,6 +42,16 @@ DoctrineBridge
* The `lazy` attribute on `doctrine.event_listener` tags was removed. * The `lazy` attribute on `doctrine.event_listener` tags was removed.
Listeners are now lazy by default. So any `lazy` attributes can safely be removed from those tags. Listeners are now lazy by default. So any `lazy` attributes can safely be removed from those tags.
DomCrawler
----------
* The `Crawler::children()` method will have a new `$selector` argument in version 5.0, not defining it is deprecated.
Finder
------
* The `Finder::sortByName()` method will have a new `$useNaturalSort` argument in version 5.0, not defining it is deprecated.
Form Form
---- ----
@ -145,6 +160,11 @@ Messenger
Each interface method have been merged untouched into the `Serializer` interface, so you can simply merge your two implementations together and implement the new interface. Each interface method have been merged untouched into the `Serializer` interface, so you can simply merge your two implementations together and implement the new interface.
Monolog
-------
* The methods `DebugProcessor::getLogs()`, `DebugProcessor::countErrors()`, `Logger::getLogs()` and `Logger::countErrors()` will have a new `$request` argument in version 5.0, not defining it is deprecated.
Security Security
-------- --------
@ -171,8 +191,9 @@ SecurityBundle
Serializer Serializer
---------- ----------
* Relying on the default value (false) of the "as_collection" option is deprecated since 4.2. * Relying on the default value (false) of the "as_collection" option is deprecated.
You should set it to false explicitly instead as true will be the default value in 5.0. You should set it to false explicitly instead as true will be the default value in 5.0.
* The `AbstractNormalizer::handleCircularReference()` method will have two new `$format` and `$context` arguments in version 5.0, not defining them is deprecated.
Translation Translation
----------- -----------

View File

@ -1,6 +1,11 @@
UPGRADE FROM 4.x to 5.0 UPGRADE FROM 4.x to 5.0
======================= =======================
BrowserKit
----------
* The `Client::submit()` method has a new `$serverParameters` argument.
Cache Cache
----- -----
@ -49,11 +54,21 @@ DoctrineBridge
* Deprecated injecting `ClassMetadataFactory` in `DoctrineExtractor`, an instance of `EntityManagerInterface` should be * Deprecated injecting `ClassMetadataFactory` in `DoctrineExtractor`, an instance of `EntityManagerInterface` should be
injected instead injected instead
DomCrawler
----------
* The `Crawler::children()` method has a new `$selector` argument.
EventDispatcher EventDispatcher
--------------- ---------------
* The `TraceableEventDispatcherInterface` has been removed. * The `TraceableEventDispatcherInterface` has been removed.
Finder
------
* The `Finder::sortByName()` method has a new `$useNaturalSort` argument.
FrameworkBundle FrameworkBundle
--------------- ---------------
@ -103,6 +118,11 @@ HttpFoundation
* The `getClientSize()` method of the `UploadedFile` class has been removed. * The `getClientSize()` method of the `UploadedFile` class has been removed.
* The `getSession()` method of the `Request` class throws an exception when session is null. * The `getSession()` method of the `Request` class throws an exception when session is null.
Monolog
-------
* The methods `DebugProcessor::getLogs()`, `DebugProcessor::countErrors()`, `Logger::getLogs()` and `Logger::countErrors()` have a new `$request` argument.
Process Process
------- -------
@ -144,6 +164,11 @@ SecurityBundle
* The `security.authentication.trust_resolver.anonymous_class` parameter has been removed. * The `security.authentication.trust_resolver.anonymous_class` parameter has been removed.
* The `security.authentication.trust_resolver.rememberme_class` parameter has been removed. * The `security.authentication.trust_resolver.rememberme_class` parameter has been removed.
Serializer
----------
* The `AbstractNormalizer::handleCircularReference()` method has two new `$format` and `$context` arguments.
Translation Translation
----------- -----------

View File

@ -5,6 +5,9 @@ CHANGELOG
----- -----
* added `ProcessorInterface`: an optional interface to allow autoconfiguration of Monolog processors * added `ProcessorInterface`: an optional interface to allow autoconfiguration of Monolog processors
* The methods `DebugProcessor::getLogs()`, `DebugProcessor::countErrors()`, `Logger::getLogs()`
and `Logger::countErrors()` will have a new `$request` argument in version 5.0, not defining
it is deprecated since Symfony 4.2.
4.1.0 4.1.0
----- -----

View File

@ -26,6 +26,10 @@ class Logger extends BaseLogger implements DebugLoggerInterface, ResetInterface
*/ */
public function getLogs(/* Request $request = null */) public function getLogs(/* Request $request = null */)
{ {
if (\func_num_args() < 1 && __CLASS__ !== \get_class($this) && __CLASS__ !== (new \ReflectionMethod($this, __FUNCTION__))->getDeclaringClass()->getName() && !$this instanceof \PHPUnit\Framework\MockObject\MockObject && !$this instanceof \Prophecy\Prophecy\ProphecySubjectInterface) {
@trigger_error(sprintf('The "%s()" method will have a new "Request $request = null" argument in version 5.0, not defining it is deprecated since Symfony 4.2.', __METHOD__), E_USER_DEPRECATED);
}
if ($logger = $this->getDebugLogger()) { if ($logger = $this->getDebugLogger()) {
return $logger->getLogs(...\func_get_args()); return $logger->getLogs(...\func_get_args());
} }
@ -38,6 +42,10 @@ class Logger extends BaseLogger implements DebugLoggerInterface, ResetInterface
*/ */
public function countErrors(/* Request $request = null */) public function countErrors(/* Request $request = null */)
{ {
if (\func_num_args() < 1 && __CLASS__ !== \get_class($this) && __CLASS__ !== (new \ReflectionMethod($this, __FUNCTION__))->getDeclaringClass()->getName() && !$this instanceof \PHPUnit\Framework\MockObject\MockObject && !$this instanceof \Prophecy\Prophecy\ProphecySubjectInterface) {
@trigger_error(sprintf('The "%s()" method will have a new "Request $request = null" argument in version 5.0, not defining it is deprecated since Symfony 4.2.', __METHOD__), E_USER_DEPRECATED);
}
if ($logger = $this->getDebugLogger()) { if ($logger = $this->getDebugLogger()) {
return $logger->countErrors(...\func_get_args()); return $logger->countErrors(...\func_get_args());
} }

View File

@ -61,6 +61,10 @@ class DebugProcessor implements DebugLoggerInterface, ResetInterface
*/ */
public function getLogs(/* Request $request = null */) public function getLogs(/* Request $request = null */)
{ {
if (\func_num_args() < 1 && __CLASS__ !== \get_class($this) && __CLASS__ !== (new \ReflectionMethod($this, __FUNCTION__))->getDeclaringClass()->getName() && !$this instanceof \PHPUnit\Framework\MockObject\MockObject && !$this instanceof \Prophecy\Prophecy\ProphecySubjectInterface) {
@trigger_error(sprintf('The "%s()" method will have a new "Request $request = null" argument in version 5.0, not defining it is deprecated since Symfony 4.2.', __METHOD__), E_USER_DEPRECATED);
}
if (1 <= \func_num_args() && null !== ($request = \func_get_arg(0)) && isset($this->records[$hash = spl_object_hash($request)])) { if (1 <= \func_num_args() && null !== ($request = \func_get_arg(0)) && isset($this->records[$hash = spl_object_hash($request)])) {
return $this->records[$hash]; return $this->records[$hash];
} }
@ -77,6 +81,10 @@ class DebugProcessor implements DebugLoggerInterface, ResetInterface
*/ */
public function countErrors(/* Request $request = null */) public function countErrors(/* Request $request = null */)
{ {
if (\func_num_args() < 1 && __CLASS__ !== \get_class($this) && __CLASS__ !== (new \ReflectionMethod($this, __FUNCTION__))->getDeclaringClass()->getName() && !$this instanceof \PHPUnit\Framework\MockObject\MockObject && !$this instanceof \Prophecy\Prophecy\ProphecySubjectInterface) {
@trigger_error(sprintf('The "%s()" method will have a new "Request $request = null" argument in version 5.0, not defining it is deprecated since Symfony 4.2.', __METHOD__), E_USER_DEPRECATED);
}
if (1 <= \func_num_args() && null !== ($request = \func_get_arg(0)) && isset($this->errorCount[$hash = spl_object_hash($request)])) { if (1 <= \func_num_args() && null !== ($request = \func_get_arg(0)) && isset($this->errorCount[$hash = spl_object_hash($request)])) {
return $this->errorCount[$hash]; return $this->errorCount[$hash];
} }

View File

@ -107,4 +107,37 @@ class LoggerTest extends TestCase
$this->assertEmpty($logger->getLogs()); $this->assertEmpty($logger->getLogs());
$this->assertSame(0, $logger->countErrors()); $this->assertSame(0, $logger->countErrors());
} }
/**
* @group legacy
* @expectedDeprecation The "Symfony\Bridge\Monolog\Logger::getLogs()" method will have a new "Request $request = null" argument in version 5.0, not defining it is deprecated since Symfony 4.2.
*/
public function testInheritedClassCallGetLogsWithoutArgument()
{
$loggerChild = new ClassThatInheritLogger('test');
$loggerChild->getLogs();
}
/**
* @group legacy
* @expectedDeprecation The "Symfony\Bridge\Monolog\Logger::countErrors()" method will have a new "Request $request = null" argument in version 5.0, not defining it is deprecated since Symfony 4.2.
*/
public function testInheritedClassCallCountErrorsWithoutArgument()
{
$loggerChild = new ClassThatInheritLogger('test');
$loggerChild->countErrors();
}
}
class ClassThatInheritLogger extends Logger
{
public function getLogs()
{
parent::getLogs();
}
public function countErrors()
{
parent::countErrors();
}
} }

View File

@ -60,6 +60,26 @@ class DebugProcessorTest extends TestCase
$this->assertSame(1, $processor->countErrors($request)); $this->assertSame(1, $processor->countErrors($request));
} }
/**
* @group legacy
* @expectedDeprecation The "Symfony\Bridge\Monolog\Processor\DebugProcessor::getLogs()" method will have a new "Request $request = null" argument in version 5.0, not defining it is deprecated since Symfony 4.2.
*/
public function testInheritedClassCallGetLogsWithoutArgument()
{
$debugProcessorChild = new ClassThatInheritDebugProcessor();
$debugProcessorChild->getLogs();
}
/**
* @group legacy
* @expectedDeprecation The "Symfony\Bridge\Monolog\Processor\DebugProcessor::countErrors()" method will have a new "Request $request = null" argument in version 5.0, not defining it is deprecated since Symfony 4.2.
*/
public function testInheritedClassCallCountErrorsWithoutArgument()
{
$debugProcessorChild = new ClassThatInheritDebugProcessor();
$debugProcessorChild->countErrors();
}
private function getRecord($level = Logger::WARNING, $message = 'test') private function getRecord($level = Logger::WARNING, $message = 'test')
{ {
return array( return array(
@ -73,3 +93,16 @@ class DebugProcessorTest extends TestCase
); );
} }
} }
class ClassThatInheritDebugProcessor extends DebugProcessor
{
public function getLogs()
{
parent::getLogs();
}
public function countErrors()
{
parent::countErrors();
}
}

View File

@ -1,6 +1,12 @@
CHANGELOG CHANGELOG
========= =========
4.2.0
-----
* The method `Client::submit()` will have a new `$serverParameters` argument
in version 5.0, not defining it is deprecated since version 4.2
3.4.0 3.4.0
----- -----

View File

@ -311,6 +311,10 @@ abstract class Client
*/ */
public function submit(Form $form, array $values = array()/*, array $serverParameters = array()*/) public function submit(Form $form, array $values = array()/*, array $serverParameters = array()*/)
{ {
if (\func_num_args() < 3 && __CLASS__ !== \get_class($this) && __CLASS__ !== (new \ReflectionMethod($this, __FUNCTION__))->getDeclaringClass()->getName() && !$this instanceof \PHPUnit\Framework\MockObject\MockObject && !$this instanceof \Prophecy\Prophecy\ProphecySubjectInterface) {
@trigger_error(sprintf('The "%s()" method will have a new "array $serverParameters = array()" argument in version 5.0, not defining it is deprecated since Symfony 4.2.', __METHOD__), E_USER_DEPRECATED);
}
$form->setValues($values); $form->setValues($values);
$serverParameters = 2 < \func_num_args() ? func_get_arg(2) : array(); $serverParameters = 2 < \func_num_args() ? func_get_arg(2) : array();

View File

@ -16,6 +16,7 @@ use Symfony\Component\BrowserKit\Client;
use Symfony\Component\BrowserKit\CookieJar; use Symfony\Component\BrowserKit\CookieJar;
use Symfony\Component\BrowserKit\History; use Symfony\Component\BrowserKit\History;
use Symfony\Component\BrowserKit\Response; use Symfony\Component\BrowserKit\Response;
use Symfony\Component\DomCrawler\Form as DomCrawlerForm;
class SpecialResponse extends Response class SpecialResponse extends Response
{ {
@ -877,4 +878,42 @@ class ClientTest extends TestCase
$client = new TestClient(); $client = new TestClient();
$this->assertNull($client->getInternalRequest()); $this->assertNull($client->getInternalRequest());
} }
/**
* @group legacy
* @expectedDeprecation The "Symfony\Component\BrowserKit\Client::submit()" method will have a new "array $serverParameters = array()" argument in version 5.0, not defining it is deprecated since Symfony 4.2.
*/
public function testInheritedClassCallSubmitWithTwoArguments()
{
$clientChild = new ClassThatInheritClient();
$clientChild->setNextResponse(new Response('<html><form action="/foo"><input type="submit" /></form></html>'));
$clientChild->submit($clientChild->request('GET', 'http://www.example.com/foo/foobar')->filter('input')->form());
}
}
class ClassThatInheritClient extends Client
{
protected $nextResponse = null;
public function setNextResponse(Response $response)
{
$this->nextResponse = $response;
}
protected function doRequest($request)
{
if (null === $this->nextResponse) {
return new Response();
}
$response = $this->nextResponse;
$this->nextResponse = null;
return $response;
}
public function submit(DomCrawlerForm $form, array $values = array())
{
return parent::submit($form, $values);
}
} }

View File

@ -6,6 +6,8 @@ CHANGELOG
* The `$currentUri` constructor argument of the `AbstractUriElement`, `Link` and * The `$currentUri` constructor argument of the `AbstractUriElement`, `Link` and
`Image` classes is now optional. `Image` classes is now optional.
* The `Crawler::children()` method will have a new `$selector` argument in version 5.0,
not defining it is deprecated since version 4.2.
3.1.0 3.1.0
----- -----

View File

@ -510,6 +510,9 @@ class Crawler implements \Countable, \IteratorAggregate
*/ */
public function children(/* string $selector = null */) public function children(/* string $selector = null */)
{ {
if (\func_num_args() < 1 && __CLASS__ !== \get_class($this) && __CLASS__ !== (new \ReflectionMethod($this, __FUNCTION__))->getDeclaringClass()->getName() && !$this instanceof \PHPUnit\Framework\MockObject\MockObject && !$this instanceof \Prophecy\Prophecy\ProphecySubjectInterface) {
@trigger_error(sprintf('The "%s()" method will have a new "string $selector = null" argument in version 5.0, not defining it is deprecated since Symfony 4.2.', __METHOD__), E_USER_DEPRECATED);
}
$selector = 0 < \func_num_args() ? func_get_arg(0) : null; $selector = 0 < \func_num_args() ? func_get_arg(0) : null;
if (!$this->nodes) { if (!$this->nodes) {

View File

@ -1148,6 +1148,62 @@ HTML;
(new Crawler())->evaluate('//form/input[1]'); (new Crawler())->evaluate('//form/input[1]');
} }
/**
* @group legacy
* @expectedDeprecation The "Symfony\Component\DomCrawler\Crawler::children()" method will have a new "string $selector = null" argument in version 5.0, not defining it is deprecated since Symfony 4.2.
*/
public function testInheritedClassCallChildrenWithoutArgument()
{
$dom = new \DOMDocument();
$dom->loadHTML('
<html>
<body>
<a href="foo">Foo</a>
<a href="/foo"> Fabien\'s Foo </a>
<a href="/foo">Fabien"s Foo</a>
<a href="/foo">\' Fabien"s Foo</a>
<a href="/bar"><img alt="Bar"/></a>
<a href="/bar"><img alt=" Fabien\'s Bar "/></a>
<a href="/bar"><img alt="Fabien&quot;s Bar"/></a>
<a href="/bar"><img alt="\' Fabien&quot;s Bar"/></a>
<a href="?get=param">GetLink</a>
<a href="/example">Klausi|Claudiu</a>
<form action="foo" id="FooFormId">
<input type="text" value="TextValue" name="TextName" />
<input type="submit" value="FooValue" name="FooName" id="FooId" />
<input type="button" value="BarValue" name="BarName" id="BarId" />
<button value="ButtonValue" name="ButtonName" id="ButtonId" />
</form>
<input type="submit" value="FooBarValue" name="FooBarName" form="FooFormId" />
<input type="text" value="FooTextValue" name="FooTextName" form="FooFormId" />
<ul class="first">
<li class="first">One</li>
<li>Two</li>
<li>Three</li>
</ul>
<ul>
<li>One Bis</li>
<li>Two Bis</li>
<li>Three Bis</li>
</ul>
<div id="parent">
<div id="child"></div>
<div id="child2" xmlns:foo="http://example.com"></div>
</div>
<div id="sibling"><img /></div>
</body>
</html>
');
$crawlerChild = new ClassThatInheritCrawler($dom);
$crawlerChild->children();
}
public function createTestCrawler($uri = null) public function createTestCrawler($uri = null)
{ {
$dom = new \DOMDocument(); $dom = new \DOMDocument();
@ -1234,3 +1290,11 @@ HTML;
return $domxpath->query('//div'); return $domxpath->query('//div');
} }
} }
class ClassThatInheritCrawler extends Crawler
{
public function children()
{
parent::children();
}
}

View File

@ -5,6 +5,8 @@ CHANGELOG
----- -----
* added $useNaturalSort option to Finder::sortByName() method * added $useNaturalSort option to Finder::sortByName() method
* The `Finder::sortByName()` method will have a new `$useNaturalSort`
argument in version 5.0, not defining it is deprecated since version 4.2.
4.0.0 4.0.0
----- -----

View File

@ -419,6 +419,9 @@ class Finder implements \IteratorAggregate, \Countable
*/ */
public function sortByName(/* bool $useNaturalSort = false */) public function sortByName(/* bool $useNaturalSort = false */)
{ {
if (\func_num_args() < 1 && __CLASS__ !== \get_class($this) && __CLASS__ !== (new \ReflectionMethod($this, __FUNCTION__))->getDeclaringClass()->getName() && !$this instanceof \PHPUnit\Framework\MockObject\MockObject && !$this instanceof \Prophecy\Prophecy\ProphecySubjectInterface) {
@trigger_error(sprintf('The "%s()" method will have a new "bool $useNaturalSort = false" argument in version 5.0, not defining it is deprecated since Symfony 4.2.', __METHOD__), E_USER_DEPRECATED);
}
$useNaturalSort = 0 < \func_num_args() && func_get_arg(0); $useNaturalSort = 0 < \func_num_args() && func_get_arg(0);
$this->sort = $useNaturalSort ? Iterator\SortableIterator::SORT_BY_NAME_NATURAL : Iterator\SortableIterator::SORT_BY_NAME; $this->sort = $useNaturalSort ? Iterator\SortableIterator::SORT_BY_NAME_NATURAL : Iterator\SortableIterator::SORT_BY_NAME;

View File

@ -1231,8 +1231,26 @@ class FinderTest extends Iterator\RealIteratorTestCase
} }
} }
/**
* @group legacy
* @expectedDeprecation The "Symfony\Component\Finder\Finder::sortByName()" method will have a new "bool $useNaturalSort = false" argument in version 5.0, not defining it is deprecated since Symfony 4.2.
*/
public function testInheritedClassCallSortByNameWithNoArguments()
{
$finderChild = new ClassThatInheritFinder();
$finderChild->sortByName();
}
protected function buildFinder() protected function buildFinder()
{ {
return Finder::create(); return Finder::create();
} }
} }
class ClassThatInheritFinder extends Finder
{
public function sortByName()
{
parent::sortByName();
}
}

View File

@ -54,10 +54,8 @@ class GuardAuthenticatorHandler
* *
* @param string $providerKey The name of the provider/firewall being used for authentication * @param string $providerKey The name of the provider/firewall being used for authentication
*/ */
public function authenticateWithToken(TokenInterface $token, Request $request/*, string $providerKey */) public function authenticateWithToken(TokenInterface $token, Request $request, string $providerKey = null)
{ {
$providerKey = \func_num_args() > 2 ? func_get_arg(2) : null;
$this->migrateSession($request, $token, $providerKey); $this->migrateSession($request, $token, $providerKey);
$this->tokenStorage->setToken($token); $this->tokenStorage->setToken($token);

View File

@ -4,27 +4,31 @@ CHANGELOG
4.2.0 4.2.0
----- -----
* `AbstractNormalizer::handleCircularReference` is now final, and receives two optional extra arguments: the format and the context * `AbstractNormalizer::handleCircularReference` is now final and receives
* added support for XML comment encoding (encoding `['#comment' => ' foo ']` results `<!-- foo -->`) two optional extra arguments: the format and the context
* added optional `int[] $encoderIgnoredNodeTypes` argument to `XmlEncoder::__construct` to configure node types to be * added support for XML comment encoding (encoding `['#comment' => ' foo ']` results `<!-- foo -->`)
ignored during encoding. * added optional `int[] $encoderIgnoredNodeTypes` argument to `XmlEncoder::__construct`
* added `AdvancedNameConverterInterface` to access the class, the format and the context in a name converter to configure node types to be ignored during encoding
* added `AdvancedNameConverterInterface` to access the class,
the format and the context in a name converter
* the `AbstractNormalizer::handleCircularReference()` method will have two new `$format`
and `$context` arguments in version 5.0, not defining them is deprecated
4.1.0 4.1.0
----- -----
* added `CacheableSupportsMethodInterface` for normalizers and denormalizers that use * added `CacheableSupportsMethodInterface` for normalizers and denormalizers that use
only the type and the format in their `supports*()` methods only the type and the format in their `supports*()` methods
* added `MissingConstructorArgumentsException` new exception for deserialization failure * added `MissingConstructorArgumentsException` new exception for deserialization failure
of objects that needs data insertion in constructor of objects that needs data insertion in constructor
* added an optional `default_constructor_arguments` option of context to specify a default data in * added an optional `default_constructor_arguments` option of context to specify a default data in
case the object is not initializable by its constructor because of data missing case the object is not initializable by its constructor because of data missing
* added optional `bool $escapeFormulas = false` argument to `CsvEncoder::__construct` * added optional `bool $escapeFormulas = false` argument to `CsvEncoder::__construct`
* added `AbstractObjectNormalizer::setMaxDepthHandler` to set a handler to call when the configured * added `AbstractObjectNormalizer::setMaxDepthHandler` to set a handler to call when the configured
maximum depth is reached maximum depth is reached
* added optional `int[] $ignoredNodeTypes` argument to `XmlEncoder::__construct`. XML decoding now * added optional `int[] $ignoredNodeTypes` argument to `XmlEncoder::__construct`. XML decoding now
ignores comment node types by default. ignores comment node types by default.
* added `ConstraintViolationListNormalizer` * added `ConstraintViolationListNormalizer`
4.0.0 4.0.0
----- -----

View File

@ -199,6 +199,9 @@ abstract class AbstractNormalizer implements NormalizerInterface, DenormalizerIn
*/ */
protected function handleCircularReference($object/*, string $format = null, array $context = array()*/) protected function handleCircularReference($object/*, string $format = null, array $context = array()*/)
{ {
if (\func_num_args() < 2 && __CLASS__ !== \get_class($this) && __CLASS__ !== (new \ReflectionMethod($this, __FUNCTION__))->getDeclaringClass()->getName() && !$this instanceof \PHPUnit\Framework\MockObject\MockObject && !$this instanceof \Prophecy\Prophecy\ProphecySubjectInterface) {
@trigger_error(sprintf('The "%s()" method will have two new "string $format = null" and "array $context = array()" arguments in version 5.0, not defining it is deprecated since Symfony 4.2.', __METHOD__), E_USER_DEPRECATED);
}
$format = \func_num_args() > 1 ? func_get_arg(1) : null; $format = \func_num_args() > 1 ? func_get_arg(1) : null;
$context = \func_num_args() > 2 ? func_get_arg(2) : array(); $context = \func_num_args() > 2 ? func_get_arg(2) : array();