New! Our new Issues homepage has the latest issue ticket changes. Follow the latest progress of eZ Publish!


Added a ConstraintViolationListNormalizer

Contributed by
Grégoire Pineau
in #22150.

When working on APIs with Symfony, it's common to use code like this:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
/**
 * @Route("/blog/new", name="api_blog_new")
 * @Method("POST")
 * @Security("is_granted('ROLE_ADMIN')")
 */
public function new(Request $request, SerializerInterface $serializer, ValidatorInterface $validator)
{
    $data = $request->getContent();
    $post = $serializer->deserialize($data, Post::class, 'json', ['groups' => ['post_write']]);
    $post->setAuthor($this->getUser());

    $violations = $validator->validate($post);
    if (count($violations) > 0) {
        $repr = $serializer->serialize($violations, 'json');

        return JsonResponse::fromJsonString($repr, 400);
    }

    // ...
}

The $violations variable contains a ConstraintViolationList object and it's common to transform it into a list of errors and serialize the list to include it in a JSON response. That's why in Symfony 4.1 we've added a ConstraintViolationListNormalizer which does that for you automatically. The normalizer follows the RFC 7807 specification to generate the list of errors.

Getting the XML and CSV results as a collection

Contributed by
Hamza Amrouche
in #25218 and #25369.

The CsvEncoder and XmlEncoder now define a new config option called as_collection. If you pass that option as part of the context argument and set it to true, the results will be a collection.

Default constructor arguments for denormalization

Contributed by
Maxime Veber
in #25493.

If the constructor of a class defines arguments, as usually happens when using Value Objects, the serializer won't be able to create the object. In Symfony 4.1 we've introduced a new default_constructor_arguments context option to solve this problem.

In the following example, both foo and bar are required constructor arguments but only foo is provided. The value of bar is taken from the default_constructor_arguments option:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
use Symfony\Component\Serializer\Serializer;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;

class MyObj
{
    private $foo;
    private $bar;

    public function __construct($foo, $bar)
    {
        $this->foo = $foo;
        $this->bar = $bar;
    }
}

$normalizer = new ObjectNormalizer($classMetadataFactory);
$serializer = new Serializer(array($normalizer));

// this is equivalent to $data = new MyObj('Hello', '');
$data = $serializer->denormalize(['foo' => 'Hello'], 'MyObj', [
    'default_constructor_arguments' => [
        'MyObj' => ['foo' => '', 'bar' => ''],
    ]
]);

Added a MaxDepth handler

Contributed by
Kévin Dunglas
in #26108.

Sometimes, instead of just stopping the serialization process when the configured max depth is reached, it's better to let the developer handle this situation to return something (e.g. the identifier of the entity).

In Symfony 4.1 you can solve this problem defining a custom handler with the new setMaxDepthHandler() method:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
use Doctrine\Common\Annotations\AnnotationReader;
use Symfony\Component\Serializer\Serializer;
use Symfony\Component\Serializer\Annotation\MaxDepth;
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory;
use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;

class Foo
{
    public $id;

    /** @MaxDepth(1) */
    public $child;
}

$level1 = new Foo();
$level1->id = 1;

$level2 = new Foo();
$level2->id = 2;
$level1->child = $level2;

$level3 = new Foo();
$level3->id = 3;
$level2->child = $level3;

$classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
$normalizer = new ObjectNormalizer($classMetadataFactory);
$normalizer->setMaxDepthHandler(function ($foo) {
    return '/foos/'.$foo->id;
});

$serializer = new Serializer(array($normalizer));
$result = $serializer->normalize($level1, null, array(ObjectNormalizer::ENABLE_MAX_DEPTH => true));
/*
$result = array[
    'id' => 1,
    'child' => [
        'id' => 2,
        'child' => '/foos/3',
    ]
];
*/

Ignore comments when decoding XML

Contributed by
James Sansbury
in #26445.

In previous Symfony versions, XML comments were processed when decoding contents. Also, if the first line of the XML content was a comment, it was used as the root node of the decoded XML.

In Symfony 4.1, XML comments are removed by default but you can control this behavior with the new optional third constructor argument:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
class XmlEncoder
{
    public function __construct(
        string $rootNodeName = 'response',
        int $loadOptions = null,
        array $ignoredNodeTypes = array(XML_PI_NODE, XML_COMMENT_NODE)
    ) {
        // ...
    }
}

Be trained by Symfony experts - 2018-04-23 Lyon - 2018-04-23 Lyon - 2018-04-25 Clichy
04/20/2018 03:54 am   Symfony Blog   Mirror   Link   @4
@ezpublishlegacy
ezpublishlegacy pushed to master in ezpublishlegacy/repository-forms Apr 19, 2018
04/19/2018 12:30 pm   eZPublishLegacy @ GitHub   Mirror   Link   @4
@ezpublishlegacy
ezpublishlegacy pushed to master in ezpublishlegacy/ezpublish-kernel Apr 19, 2018
04/19/2018 12:12 pm   eZPublishLegacy @ GitHub   Mirror   Link  
@ezecosystem
ezecosystem pushed to master in ezecosystem/Sylius Apr 19, 2018
04/19/2018 12:07 pm   eZecosystem @ GitHub   Mirror   Link   @6
@ezecosystem
ezecosystem pushed to master in ezecosystem/repository-forms Apr 19, 2018
04/19/2018 12:06 pm   eZecosystem @ GitHub   Mirror   Link  
@ezecosystem
ezecosystem pushed to master in ezecosystem/ezstudio-installer Apr 19, 2018
04/19/2018 12:00 pm   eZecosystem @ GitHub   Mirror   Link  
@ezecosystem
ezecosystem pushed to master in ezecosystem/ezpublish-kernel Apr 19, 2018
04/19/2018 11:59 am   eZecosystem @ GitHub   Mirror   Link  
@ezecosystem
ezecosystem pushed to master in ezecosystem/ezplatform-com Apr 19, 2018
  • @SylvainGuittard c8e94c3
    EZP-26809: Unify installation instructions (#131)
04/19/2018 11:59 am   eZecosystem @ GitHub   Mirror   Link  

A simpler way to test Ajax requests

Contributed by
Hamza Amrouche
in #26381.

The BrowserKit component used in Symfony functional tests provides lots of utilities to simulate the behavior of a web browser. In Symfony 4.1 we've added a new utility to make Ajax requests simpler: xmlHttpRequest().

This method works the same as the current request() method and accepts the same arguments, but it adds the required HTTP_X_REQUESTED_WITH header automatically so you don't have to do that yourself:

1
2
3
4
5
6
7
// Before
$crawler = $client->request('GET', '/some/path', [], [], [
    'HTTP_X-Requested-With' => 'XMLHttpRequest',
]);

// After
$crawler = $client->xmlHttpRequest('GET', '/some/path');

Improved the Ajax panel in the debug toolbar

The first minor but noticeable change is that the link to the Ajax request profile has been moved to the first column of the table, so it's easier to click on it.

In addition, when the Ajax request results in an exception (HTTP status of 400 or higher) the profiler link points to the exception profiler panel instead of the default request/response panel:

In any case, the biggest new feature of the Ajax panel is that requests now display their duration in real-time, so you always know which requests are still pending to finish:


Be trained by Symfony experts - 2018-04-23 Lyon - 2018-04-23 Lyon - 2018-04-25 Clichy
04/19/2018 03:15 am   Symfony Blog   Mirror   Link  
@ezecosystem
ezecosystem pushed to master in ezecosystem/ezplatform-com Apr 19, 2018
  • @SylvainGuittard e404bbb
    CSS fix for the new homepage banner
04/18/2018 11:58 pm   eZecosystem @ GitHub   Mirror   Link   @4
@ezpublishlegacy
ezpublishlegacy pushed to master in ezpublishlegacy/ezstudio Apr 18, 2018
04/18/2018 12:15 pm   eZPublishLegacy @ GitHub   Mirror   Link   @4
@ezpublishlegacy
ezpublishlegacy pushed to master in ezpublishlegacy/ezplatform Apr 18, 2018
04/18/2018 12:11 pm   eZPublishLegacy @ GitHub   Mirror   Link   @4
@ezecosystem
ezecosystem pushed to master in ezecosystem/Sylius Apr 18, 2018
04/18/2018 12:07 pm   eZecosystem @ GitHub   Mirror   Link   @4
@ezecosystem
ezecosystem pushed to master in ezecosystem/ezstudio Apr 18, 2018
04/18/2018 12:00 pm   eZecosystem @ GitHub   Mirror   Link   @4
@ezecosystem
ezecosystem pushed to master in ezecosystem/ezplatform Apr 18, 2018
04/18/2018 11:59 am   eZecosystem @ GitHub   Mirror   Link   @4
@ezpublishlegacy
ezpublishlegacy pushed to master in ezpublishlegacy/phpunit Apr 17, 2018
04/17/2018 12:34 pm   eZPublishLegacy @ GitHub   Mirror   Link   @6
@ezpublishlegacy
ezpublishlegacy pushed to master in ezpublishlegacy/mugoobjectrelations Apr 17, 2018
  • @pkamps bb09ba4
    That extension claims to have template operators but it does not have…
04/17/2018 12:25 pm   eZPublishLegacy @ GitHub   Mirror   Link  
@ezpublishlegacy
ezpublishlegacy pushed to master in ezpublishlegacy/ezstudio-demo Apr 17, 2018
04/17/2018 12:17 pm   eZPublishLegacy @ GitHub   Mirror   Link   @6
@ezecosystem
ezecosystem pushed to master in ezecosystem/Sylius Apr 17, 2018
04/17/2018 12:07 pm   eZecosystem @ GitHub   Mirror   Link   @4
@ezecosystem
ezecosystem pushed to master in ezecosystem/ezstudio-demo Apr 17, 2018
04/17/2018 12:01 pm   eZecosystem @ GitHub   Mirror   Link   @4

Contributed by
Shaun Simmons
in #23707.

Logging as much information as possible is essential to help you debug the issues found in your applications. However, logging too much information can be as bad as logging too little, because of all the "noise" added to your logs.

That's why in Symfony 4.1 we've improved the Monolog integration to allow you exclude log messages related to specific HTTP codes. For example, when using a fingers_crossed handler, use the following configuration to ignore the logs about 403 and 404 errors:

1
2
3
4
5
6
7
# config/packages/monolog.yaml
monolog:
    handlers:
        main:
            # ...
            type: 'fingers_crossed'
            excluded_http_codes: [403, 404]

For more complex needs, it's also possible to exclude logs only for certain URLs, defined as regular expression patterns:

1
2
3
4
5
6
# config/packages/monolog.yaml
monolog:
    handlers:
        main:
            # ...
            excluded_http_codes: [{ 400: ['^/foo', '^/bar'] }, 403, 404]

If you prefer XML configuration, this is how the previous example would look like:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<!-- config/packages/monolog.xml -->
<monolog:config>
    <monolog:handler type="fingers_crossed" name="main" handler="...">
        <!-- ... -->
        <monolog:excluded-http-code code="400">
            <monolog:url>^/foo</monolog:url>
            <monolog:url>^/bar</monolog:url>
        </monolog:excluded-http-code>
        <monolog:excluded-http-code code="403" />
        <monolog:excluded-http-code code="404" />
    </monolog:handler>
</monolog:config>

Be trained by Symfony experts - 2018-04-23 Lyon - 2018-04-23 Lyon - 2018-04-25 Clichy
04/17/2018 04:33 am   Symfony Blog   Mirror   Link  
@ezpublishlegacy
ezpublishlegacy pushed to master in ezpublishlegacy/PlatformUIBundle Apr 17, 2018
04/17/2018 12:24 am   eZPublishLegacy @ GitHub   Mirror   Link  
@ezpublishlegacy
ezpublishlegacy pushed to master in ezpublishlegacy/mugo_varnish Apr 17, 2018
  • @pkamps f2ce733
    View to send custom ban requsts fixed
04/17/2018 12:18 am   eZPublishLegacy @ GitHub   Mirror   Link   @4

Q: What was the driving decision behind going with the HTTP Request/Response model instead of the more common MVC architecture when Symfony was invented?

A: The request/response model is the basic foundation for all web frameworks, it allows you to work with the pattern that best fits your application. Symfony Full-Stack out of the box actually uses a form of MVC. But it is also flexible enough to work with other patterns you might want to implement. So it is actually not a question of a specific model, but of being open to all kinds of use cases on the web.

Q: What are some of the challenges SensioLabs must overcome when onboarding developers with a background in different frameworks?

A: Most of the concepts that Symfony has introduced to the PHP world in version 2—things like request/response encapsulation, dependency injection, a modern framework architecture—have become mainstream now in most frameworks and in the PHP world in general. So if the developer in question has a background in another contemporary framework, the barrier of entry is actually not high.

Q: With Symfony 4, the full-stack approach is no longer in the spotlight, marking a huge change in thinking for many developers not used to microservices architectures. What is Sensio’s strategy to help these developers change how they approach and solve architectural challenges?

A: Symfony 4 changes the way components and bundles are installed, and Flex gives you the tools to only install what you need. The recommended way to configure your app is now by way of environment variables, and you are able to pre-warm the cache for deployment. All of these features will be just as beneficial for traditional full-stack applications, and making use of them (or not) does not make or break a microservice. Symfony is the full-stack framework it always was, but it's now easier to finely tune it to your needs—which might or might not include microservices. If you have a use case that does not benefit from a microservice architecture—and a good portion of small to mid-sized projects don't—then nothing changes for you. Symfony full-stack is not going away.

Q: Changing from Assetic to Webpack is another big shift for many developers. Do you see a growing need to be a full-stack polyglot to play well with Symfony in the future?

A: Assetic had gone out of use in most projects for some time already. It was removed for a variety of reasons, including performance, but most importantly, because Symfony is a PHP framework and should not make any assumptions about the frontend in a rapidly changing frontend world, where every team has different needs. Note that while Webpack Encore is published under the "Symfony" vendor name, it is not specifically tailored to the Symfony framework, nor indeed to PHP. You can perfectly use it in a Python Flask application for example. As such, Symfony does not really play into the question of whether you should be a polyglot developer or not.

Q: SensioLabs will be holding training alongside eZ’s training workshop on June 5 in Cologne, one day before eZ Conference. What can developers look forward to learning in SensioLabs’ training?

A: Developers in the workshop will get a hands-on introduction to working with the Symfony 4 framework. Starting with the project setup, we'll cover most of the everyday uses of the framework, from how routing and controllers work, to implementing a simple form and a quick introduction to the dependency injection container. Attendees should be sure to bring their own laptop with a development environment compatible with Symfony 4.

If you have not yet registered for eZ Conference on June 6 or eZ's workshop training on June 5 in Cologne, there's still time. We hope to see you there!

04/16/2018 04:05 pm   ez.no/About-eZ/Blog   Mirror   Link  

Q: What was the driving decision behind going with the HTTP Request/Response model instead of the more common MVC architecture when Symfony was invented?

A: The request/response model is the basic foundation for all web frameworks, it allows you to work with the pattern that best fits your application. Symfony Full-Stack out of the box actually uses a form of MVC. But it is also flexible enough to work with other patterns you might want to implement. So it is actually not a question of a specific model, but of being open to all kinds of use cases on the web.

Q: What are some of the challenges SensioLabs must overcome when onboarding developers with a background in different frameworks?

A: Most of the concepts that Symfony has introduced to the PHP world in version 2—things like request/response encapsulation, dependency injection, a modern framework architecture—have become mainstream now in most frameworks and in the PHP world in general. So if the developer in question has a background in another contemporary framework, the barrier of entry is actually not high.

Q: With Symfony 4, the full-stack approach is no longer in the spotlight, marking a huge change in thinking for many developers not used to microservices architectures. What is Sensio’s strategy to help these developers change how they approach and solve architectural challenges?

A: Symfony 4 changes the way components and bundles are installed, and Flex gives you the tools to only install what you need. The recommended way to configure your app is now by way of environment variables, and you are able to pre-warm the cache for deployment. All of these features will be just as beneficial for traditional full-stack applications, and making use of them (or not) does not make or break a microservice. Symfony is the full-stack framework it always was, but it's now easier to finely tune it to your needs—which might or might not include microservices. If you have a use case that does not benefit from a microservice architecture—and a good portion of small to mid-sized projects don't—then nothing changes for you. Symfony full-stack is not going away.

Q: Changing from Assetic to Webpack is another big shift for many developers. Do you see a growing need to be a full-stack polyglot to play well with Symfony in the future?

A: Assetic had gone out of use in most projects for some time already. It was removed for a variety of reasons, including performance, but most importantly, because Symfony is a PHP framework and should not make any assumptions about the frontend in a rapidly changing frontend world, where every team has different needs. Note that while Webpack Encore is published under the "Symfony" vendor name, it is not specifically tailored to the Symfony framework, nor indeed to PHP. You can perfectly use it in a Python Flask application for example. As such, Symfony does not really play into the question of whether you should be a polyglot developer or not.

Q: SensioLabs will be holding training alongside eZ’s training workshop on June 5 in Cologne, one day before eZ Conference. What can developers look forward to learning in SensioLabs’ training?

A: Developers in the workshop will get a hands-on introduction to working with the Symfony 4 framework. Starting with the project setup, we'll cover most of the everyday uses of the framework, from how routing and controllers work, to implementing a simple form and a quick introduction to the dependency injection container. Attendees should be sure to bring their own laptop with a development environment compatible with Symfony 4.

If you have not yet registered for eZ Conference on June 6 or eZ's workshop training on June 5 in Cologne, there's still time. We hope to see you there!

04/16/2018 04:05 pm   eZ Systems News   Mirror   Link   @4
@ezpublishlegacy
ezpublishlegacy pushed to master in ezpublishlegacy/xrowmetadata Apr 16, 2018
  • 257cd43
    Fix: Too few arguments to function xrowSitemapItemModified::__constru…
04/16/2018 12:40 pm   eZPublishLegacy @ GitHub   Mirror   Link   @8
@ezpublishlegacy
ezpublishlegacy pushed to master in ezpublishlegacy/ezstudio Apr 16, 2018
04/16/2018 12:16 pm   eZPublishLegacy @ GitHub   Mirror   Link   @6