Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Profiler][Validator] Add a validator panel in profiler #22554

Merged
merged 1 commit into from Jun 19, 2017
Merged

[Profiler][Validator] Add a validator panel in profiler #22554

merged 1 commit into from Jun 19, 2017

Conversation

ogizanagi
Copy link
Member

@ogizanagi ogizanagi commented Apr 27, 2017

Q A
Branch? 3.4
Bug fix? no
New feature? yes
BC breaks? no
Deprecations? no
Tests pass? yes
Fixed tickets N/A
License MIT
Doc PR N/A

I'm exploring the possibility of having a validator panel in the profiler.
The integration in the form panel is great, but there are a lot of other use-cases where you're likely to call the validator. The idea of this panel is to reference every calls made to the validator (ValidatorInterface::validate() at least) along with detailed informations.
Dealing with apis and a mobile app, it's not always easy to get the response body within the app to get what's wrong with the call. So now with this panel, I'm able to get the details without the api response.

In action with Symfony demo (on the admin new post form):

symfony-demo

capture d ecran 2017-04-27 a 17 14 24

On another app, by calling the validator elsewhere:

No violations With violations
capture d ecran 2017-04-27 a 17 16 41 capture d ecran 2017-04-27 a 17 17 32

What do you think ?


Note: the SVG icon used should be changed. If anyone is willing to contribute and provide one, I'll be glad to add it!

Copy link
Member

@stof stof left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tests are also missing

xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">

<services>
<service id="debug.validator" decorates="validator" class="Symfony\Component\Validator\Validator\TraceableValidator">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this service should be private, as you should never get it at runtime explicitly as debug.validator

{% endblock %}

{% block head %}
{{ parent() }}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

useless as you don't add anything. Skip overwriting the block

<th>Violation</th>
</tr>
</thead>
{% for violationDate in call.violations %}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why date ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be data. Good catch.

*/
public function startContext()
{
$this->validator->startContext();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing return

@javiereguiluz
Copy link
Member

(about the icon, we'll ask to tweak it to the designer who created the rest of the profiler icons)

@ogizanagi
Copy link
Member Author

@stof: I forgot to mention this is a POC/WIP (even if I think I'm almost done for the panel itself).
So I'll add tests if this PR makes enough sense to be merged. :)

@nicolas-grekas nicolas-grekas added this to the 3.4 milestone Apr 28, 2017
@fabpot
Copy link
Member

fabpot commented Apr 29, 2017

Looks great to me :)

@ogizanagi
Copy link
Member Author

ogizanagi commented Apr 30, 2017

PR updated:

  • implemented LateDataCollectorInterface as a straightforward solution to collect only once, on kernel terminate (and thus avoid the need to identify duplicates when running sub-requests).
  • drastically simplified the data collector itself, thanks to [VarDumper] Allow seamless use of Data clones #21638, which I almost forgot!
  • added some tests.

public function lateCollect()
{
foreach ($this->validator->getCollectedData() as $collected) {
$this->data['calls'][] = $this->cloneVar($collected);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doing a single clone for all calls would improve perf and size of the resulting serialized payload.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed.

/**
* {@inheritdoc}
*/
protected function cloneVar($var, $isClass = false)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Anyway​to reuse the parent?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think so? I need to add a specific caster for FormInterface, and the static $cloner property in the parent is private. Unless we want to open it? (I based this method on FormDataCollector::cloneVar)

Copy link
Member Author

@ogizanagi ogizanagi Apr 30, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be worth adding an empty DataCollector::getCasters() method to implement in children when needed, or a DataCollector::configureCloner(VarCloner $cloner) one? (making the property non-static anymore btw)

@@ -22,6 +22,8 @@
},
"require-dev": {
"symfony/http-foundation": "~2.8|~3.0",
"symfony/http-kernel": "~2.8|~3.0",
"symfony/var-dumper": "~2.8|~3.0",
Copy link
Member Author

@ogizanagi ogizanagi Apr 30, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nicolas-grekas : Do you know what would be the proper version constraint to avoid this issue with the var-dumper component?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NVM. Anyway 3.3 is required for #21638.

@robfrawley
Copy link
Contributor

@ogizanagi This looks wonderful!

@stof stof added this to WIP in Profiler panels Apr 30, 2017
</service>

<!-- DataCollector -->
<service id="data_collector.validator" class="Symfony\Component\Validator\DataCollector\ValidatorDataCollector">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can be private too, right?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated to use <defaults public="false" />

@@ -434,6 +435,10 @@ private function registerProfilerConfiguration(array $config, ContainerBuilder $
$loader->load('form_debug.xml');
}

if ($this->validatorConfigEnabled) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We also need to ensure that the Symfony\Component\Validator\Validator\TraceableValidator does exist to prevent issue when FrameworkBundle 3.4 is used with older versions of the Validator component.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

simpler solution is to add a conflict rule in FrameworkBundle to forbid using an older version of symfony/validator when using FrameworkBundle 3.4

Copy link
Member Author

@ogizanagi ogizanagi May 12, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've updated the conflict rule.

</div>
<div class="sf-toolbar-info-piece">
<b>Number of violations</b>
<span class="sf-toolbar-status sf-toolbar-status-{{ collector.data.nb_violations > 0 ? 'red' }}">{{ collector.data.nb_violations }}</span>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

{{ collector.data.nb_violations > 0 ? 'sf-toolbar-status-red' }} (otherwise there will be a sf-toolbar-status- class)

{% set icon %}
{{ include('@WebProfiler/Icon/validator.svg') }}
<span class="sf-toolbar-value">
{{ collector.data.nb_violations ?: collector.data.calls|length }}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if it is a good idea that the displayed property may vary.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with @xabbuh here. It looks weird to switch between violation and calls.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree. I started the template from the Forms collector one. It's a mistake due to fact I overlooked at it in the first place. 😄 (but I wonder if it really make more sense for forms to switch between errors and forms count)
We should always show the number of violations instead.

}, 0);
}

public function getData()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Other collectors do not expose the $data property, but provide concrete getter methods. I think we should do the same here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not true for the form collector for instance. But I guess getCalls() and getViolationsCount() makes sense :)

use Symfony\Component\VarDumper\Caster\Caster;
use Symfony\Component\VarDumper\Caster\ClassStub;
use Symfony\Component\VarDumper\Cloner\Data;
use Symfony\Component\VarDumper\Cloner\VarCloner;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should probably exit early if the VarDumper component is not installed.

Copy link
Member Author

@ogizanagi ogizanagi May 12, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure it's needed. It seems to me the symfony/var-dumper is a hard requirement to use the profiler since 3.3 (and required by the WebProfilerBundle): https://github.com/symfony/symfony/blob/master/src/Symfony/Component/HttpKernel/DataCollector/DataCollector.php#L69

xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">

<services>
<service id="debug.validator" decorates="validator" class="Symfony\Component\Validator\Validator\TraceableValidator" public="false">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we define a priority here to avoid issues if the validator is decorated somewhere else?

Copy link
Member Author

@ogizanagi ogizanagi May 12, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's a good idea. Which priority would you use? "Highest" one (i.e 255 even if there is no real limit)? So it'll be applied first and no one relying on decorating the validator with its own class would get surprised.

@ogizanagi ogizanagi changed the base branch from master to 3.4 May 17, 2017 18:30
@fabpot
Copy link
Member

fabpot commented Jun 9, 2017

@javiereguiluz I think it would be good to work on the icons.

@robfrawley
Copy link
Contributor

robfrawley commented Jun 9, 2017

I might be able to throw an SVG icon together, but what kind of icon would be appropriate? The check mark used in the example seems too generic.

@ogizanagi
Copy link
Member Author

@javiereguiluz : Any update about the new SVG icon? :)

@javiereguiluz
Copy link
Member

@ogizanagi thanks for reminding me about this. I've just asked for this to our designer. I'll share here his proposal. Thanks!

@javiereguiluz
Copy link
Member

This is the icon created by our designer:

<svg xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" width="24" height="24" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve"><path fill="#aaaaaa" d="M20,23H3.79A2.88,2.88,0,0,1,.92,20.13V3.87A2.88,2.88,0,0,1,3.79,1H20a1,1,0,0,1,0,2H3.79a.88.88,0,0,0-.87.87V20.13a.88.88,0,0,0,.87.87H20a.88.88,0,0,0,.87-.87V11.79a1,1,0,1,1,2,0v8.33A2.88,2.88,0,0,1,20,23Zm-6.56-3.92L23.31,6.77a2,2,0,0,0-3.12-2.5L12.06,14.45,8.25,8.76A2,2,0,0,0,4.93,11l5.32,8a2,2,0,0,0,1.58.89h.08A2,2,0,0,0,13.48,19.08Z"/></svg>

And this is how it looks:

validator-icon

@fabpot
Copy link
Member

fabpot commented Jun 19, 2017

The new icon "looks" bigger than the existing one (perhaps you can also add a screenshot when it is not selected?).

@javiereguiluz
Copy link
Member

Here is unhighlighted:

validator-icon-unselected

@fabpot
Copy link
Member

fabpot commented Jun 19, 2017

I would make it a bit smaller if possible.

@javiereguiluz
Copy link
Member

Here is the new version:

<svg xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" width="24" height="24" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve"><path fill="#aaaaaa" d="M19.54,22.5H4.29a2.88,2.88,0,0,1-2.87-2.87V4.37A2.88,2.88,0,0,1,4.29,1.5H18.54a1,1,0,0,1,0,2H4.29a.88.88,0,0,0-.87.87V19.63a.88.88,0,0,0,.87.87H19.54a.88.88,0,0,0,.87-.87V11.29a1,1,0,1,1,2,0v8.33A2.88,2.88,0,0,1,19.54,22.5ZM13,17.29,22.88,6a1.5,1.5,0,1,0-2.26-2L12,14,8,9.11A1.5,1.5,0,0,0,5.65,11l5.1,6.25a1.5,1.5,0,0,0,1.14.55h0A1.5,1.5,0,0,0,13,17.29Z"/></svg>

And this is how it looks:

icon-1

icon-2

icon-3

@fabpot
Copy link
Member

fabpot commented Jun 19, 2017

@ogizanagi I think you can update this PR with the new icon.

@ogizanagi
Copy link
Member Author

Updated with the new icon. Many thanks to you and your designer. ;)

@ogizanagi
Copy link
Member Author

(deps=high failure should be fixed once merged, in order for the FrameworkBundle to be able to see the validator component's collector)

@fabpot
Copy link
Member

fabpot commented Jun 19, 2017

Thank you @ogizanagi.

@fabpot fabpot merged commit ac5e884 into symfony:3.4 Jun 19, 2017
fabpot added a commit that referenced this pull request Jun 19, 2017
…r (ogizanagi)

This PR was merged into the 3.4 branch.

Discussion
----------

[Profiler][Validator] Add a validator panel in profiler

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

I'm exploring the possibility of having a validator panel in the profiler.
The integration in the form panel is great, but there are a lot of other use-cases where you're likely to call the validator. The idea of this panel is to reference every calls made to the validator (`ValidatorInterface::validate()` at least) along with detailed informations.
Dealing with apis and a mobile app, it's not always easy to get the response body within the app to get what's wrong with the call. So now with this panel, I'm able to get the details without the api response.

In action with Symfony demo (on the admin new post form):

![symfony-demo](https://cloud.githubusercontent.com/assets/2211145/25490828/579a2c96-2b6e-11e7-9574-fb0975a5db83.gif)

![capture d ecran 2017-04-27 a 17 14 24](https://cloud.githubusercontent.com/assets/2211145/25490866/77d76988-2b6e-11e7-83c7-a10613442a5e.png)

On another app, by calling the validator elsewhere:

|No violations|With violations|
|--|--|
|![capture d ecran 2017-04-27 a 17 16 41](https://cloud.githubusercontent.com/assets/2211145/25490861/741886f6-2b6e-11e7-9e18-5948312d0096.png)|![capture d ecran 2017-04-27 a 17 17 32](https://cloud.githubusercontent.com/assets/2211145/25490860/74128daa-2b6e-11e7-979f-0d39741cc172.png)|

What do you think ?

---

Note: the SVG icon used should be changed. If anyone is willing to contribute and provide one, I'll be glad to add it!

Commits
-------

ac5e884 [Profiler][Validator] Add a validator panel in profiler
@ogizanagi ogizanagi deleted the feature/profiler/validator_panel branch June 19, 2017 18:57
@TomasVotruba
Copy link
Contributor

@ogizanagi OT: I love the gifs. What do you use to make them?
I'm on Linux.

@ogizanagi
Copy link
Member Author

ogizanagi commented Jun 26, 2017

I'm using Giphy Capture.

Before, I used to make a screen cast video (using Quicktime) and convert it using a custom alias calling ffmpeg (alias which I don't have anymore :/).

But I'm sure there are tons of other solutions, for instance https://github.com/phw/peek, http://www.cockos.com/licecap/ (but the last one not for linux AFAIK), ...

@TomasVotruba
Copy link
Contributor

Thanks. I thought that might be some nice Mac tool.

I'm using Peek now, but it is very simple and doesn't have that "click circle" feature in it.

@ogizanagi ogizanagi moved this from WIP to DONE in Profiler panels Jul 19, 2017
fabpot added a commit that referenced this pull request Aug 10, 2017
…th the form one (ogizanagi)

This PR was merged into the 3.4 branch.

Discussion
----------

[Profiler] Make the validator toolbar item consistent with the form one

| Q             | A
| ------------- | ---
| Branch?       | 3.4 <!-- see comment below -->
| Bug fix?      | no
| New feature?  | no <!-- don't forget updating src/**/CHANGELOG.md files -->
| BC breaks?    | no
| Deprecations? | no <!-- don't forget updating UPGRADE-*.md files -->
| Tests pass?   | yes
| Fixed tickets | N/A <!-- #-prefixed issue number(s), if any -->
| License       | MIT
| Doc PR        | N/A

After more time experiencing it, I changed my mind about #22554 (review).

I do think replicating the form toolbar item behavior is the best thing to do.
Displaying a different property under some conditions may seem to be a bad idea, but the difference is clearly expressed by the background color used:

|-|-|
|--|--|
|<img alt="screenshot 2017-08-09 a 15 59 56" src="https://user-images.githubusercontent.com/2211145/29125368-de340da4-7d1b-11e7-9b04-8ff395e118f0.PNG">| Red: something wrong happened. Shows the relevant information: the number of violations.|
|<img alt="screenshot 2017-08-09 a 16 00 05" src="https://user-images.githubusercontent.com/2211145/29125374-e28dd6a0-7d1b-11e7-8ed6-b0d7634a5b21.PNG">| Grey: Everything went fine. Acknowledge the validator calls were made and passed by showing the number of calls.|

In any case, everything is clear when hovering the toolbar item (and most users are probably already used to this behavior due to the form item):

|Violations|No violations|
|--|--|
|<img width="173" alt="screenshot 2017-08-09 a 15 51 18" src="https://user-images.githubusercontent.com/2211145/29125023-e35ca602-7d1a-11e7-82d5-0ff3c0d9c46c.PNG">|<img width="172" alt="screenshot 2017-08-09 a 15 51 31" src="https://user-images.githubusercontent.com/2211145/29125037-ebbf0614-7d1a-11e7-8cd2-de6cb963a282.PNG">|

Commits
-------

b622d26 [Profiler] Make the validator toolbar item consistent with the form one
This was referenced Oct 18, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
No open projects
Development

Successfully merging this pull request may close these issues.

None yet

9 participants