Skip to content

Commit fbef8e3

Browse files
committed
reducing collector data payload and using twig extension for details
1 parent 48e3097 commit fbef8e3

File tree

4 files changed

+144
-121
lines changed

4 files changed

+144
-121
lines changed

Collector/MigrationsCollector.php

Lines changed: 10 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,7 @@
55
namespace Doctrine\Bundle\MigrationsBundle\Collector;
66

77
use Doctrine\Migrations\DependencyFactory;
8-
use Doctrine\Migrations\Metadata\AvailableMigration;
98
use Doctrine\Migrations\Metadata\AvailableMigrationsList;
10-
use Doctrine\Migrations\Metadata\ExecutedMigration;
119
use Doctrine\Migrations\Metadata\ExecutedMigrationsList;
1210
use Doctrine\Migrations\Metadata\Storage\TableMetadataStorageConfiguration;
1311
use Symfony\Component\HttpFoundation\Request;
@@ -30,17 +28,10 @@ public function collect(Request $request, Response $response, \Throwable $except
3028
$planCalculator = $this->dependencyFactory->getMigrationPlanCalculator();
3129
$statusCalculator = $this->dependencyFactory->getMigrationStatusCalculator();
3230

33-
$availableMigrations = $planCalculator->getMigrations();
34-
$this->data['available_migrations'] = $this->flattenAvailableMigrations($availableMigrations);
35-
$this->data['executed_migrations'] = $this->flattenExecutedMigrations(
36-
$metadataStorage->getExecutedMigrations(),
37-
$availableMigrations
38-
);
39-
$this->data['new_migrations'] = $this->flattenAvailableMigrations($statusCalculator->getNewMigrations());
40-
$this->data['executed_unavailable_migrations'] = $this->flattenExecutedMigrations(
41-
$statusCalculator->getExecutedUnavailableMigrations(),
42-
new AvailableMigrationsList([])
43-
);
31+
$this->data['available_migrations'] = $this->flattenMigrations($planCalculator->getMigrations());
32+
$this->data['executed_migrations'] = $this->flattenMigrations($metadataStorage->getExecutedMigrations());
33+
$this->data['new_migrations'] = $this->flattenMigrations($statusCalculator->getNewMigrations());
34+
$this->data['unavailable_migrations'] = $this->flattenMigrations($statusCalculator->getExecutedUnavailableMigrations());
4435

4536
$this->data['storage'] = get_class($metadataStorage);
4637
$configuration = $this->dependencyFactory->getConfiguration();
@@ -72,29 +63,13 @@ public function reset()
7263
$this->data = [];
7364
}
7465

75-
private function flattenExecutedMigrations(
76-
ExecutedMigrationsList $executedMigrations,
77-
AvailableMigrationsList $availableMigrations
78-
): array {
79-
return array_map(static function (ExecutedMigration $migration) use ($availableMigrations) {
80-
$version = $migration->getVersion();
81-
return [
82-
'version' => (string)$version,
83-
'executed_at' => $migration->getExecutedAt(),
84-
'execution_time' => $migration->getExecutionTime(),
85-
'description' => $availableMigrations->hasMigration($version)
86-
? $availableMigrations->getMigration($version)->getMigration()->getDescription() : null,
87-
];
88-
}, $executedMigrations->getItems());
89-
}
90-
91-
private function flattenAvailableMigrations(AvailableMigrationsList $migrationsList): array
66+
/**
67+
* @param AvailableMigrationsList|ExecutedMigrationsList $migrationsList
68+
*/
69+
private function flattenMigrations($migrationsList): array
9270
{
93-
return array_map(static function (AvailableMigration $migration) {
94-
return [
95-
'version' => (string)$migration->getVersion(),
96-
'description' => $migration->getMigration()->getDescription(),
97-
];
71+
return array_map(static function ($migration) {
72+
return (string)$migration->getVersion();
9873
}, $migrationsList->getItems());
9974
}
10075
}

Resources/config/services.xml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,12 @@
143143

144144
<service id="doctrine_migrations.migrations_collector" class="Doctrine\Bundle\MigrationsBundle\Collector\MigrationsCollector">
145145
<argument type="service" id="doctrine.migrations.dependency_factory"/>
146-
<tag name="data_collector" template="@DoctrineMigrations/Collector/migrations.html.twig" id="doctrine_migrations" priority="249"/>
146+
<tag name="data_collector" template="@DoctrineMigrations/Collector/migrations.html.twig" id="doctrine_migrations" priority="249" />
147+
</service>
148+
149+
<service id="doctrine_migrations.migrations_extension" class="Doctrine\Bundle\MigrationsBundle\Twig\MigrationsExtension">
150+
<argument type="service" id="doctrine.migrations.dependency_factory"/>
151+
<tag name="twig.extension" />
147152
</service>
148153
</services>
149154

Lines changed: 74 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,62 @@
11
{% extends '@WebProfiler/Profiler/layout.html.twig' %}
22

3+
{% import _self as helper %}
4+
35
{% block toolbar %}
4-
{% set executed_migrations = collector.data.executed_migrations|length %}
5-
{% set executed_unavailable_migrations = collector.data.executed_unavailable_migrations|length %}
6-
{% set available_migrations = collector.data.available_migrations|length %}
6+
{% set unavailable_migrations = collector.data.unavailable_migrations|length %}
77
{% set new_migrations = collector.data.new_migrations|length %}
8-
{% set status_color = executed_unavailable_migrations > 0 ? 'yellow' : '' %}
9-
{% set status_color = new_migrations > 0 ? 'red' : status_color %}
8+
{% if unavailable_migrations > 0 or new_migrations > 0 %}
9+
{% set executed_migrations = collector.data.executed_migrations|length %}
10+
{% set available_migrations = collector.data.available_migrations|length %}
11+
{% set status_color = unavailable_migrations > 0 ? 'yellow' : '' %}
12+
{% set status_color = new_migrations > 0 ? 'red' : status_color %}
1013

11-
{% set icon %}
12-
{{ include('@DoctrineMigrations/Collector/icon.svg') }}
13-
<span class="sf-toolbar-value">{{ executed_migrations }}</span>
14-
<span class="sf-toolbar-label">/</span>
15-
<span class="sf-toolbar-value">{{ available_migrations }}</span>
16-
{% endset %}
14+
{% set icon %}
15+
{{ include('@DoctrineMigrations/Collector/icon.svg') }}
16+
<span class="sf-toolbar-value">{{ new_migrations + unavailable_migrations }}</span>
17+
{% endset %}
1718

18-
{% set text %}
19-
<div class="sf-toolbar-info-piece">
20-
<b>Current</b>
21-
<span>{{ collector.data.executed_migrations|last.version|split('\\')|last }}</span>
22-
</div>
23-
<div class="sf-toolbar-info-piece">
24-
<b>Executed</b>
25-
<span class="sf-toolbar-status">{{ executed_migrations }}</span>
26-
</div>
27-
<div class="sf-toolbar-info-piece">
28-
<b>Executed Unavailable</b>
29-
<span class="sf-toolbar-status {{ executed_unavailable_migrations > 0 ? 'sf-toolbar-status-yellow' }}">{{ executed_unavailable_migrations }}</span>
30-
</div>
31-
<div class="sf-toolbar-info-piece">
32-
<b>Available</b>
33-
<span class="sf-toolbar-status">{{ available_migrations }}</span>
34-
</div>
35-
<div class="sf-toolbar-info-piece">
36-
<b>New</b>
37-
<span class="sf-toolbar-status {{ new_migrations > 0 ? 'sf-toolbar-status-red' }}">{{ new_migrations }}</span>
38-
</div>
39-
{% endset %}
19+
{% set text %}
20+
<div class="sf-toolbar-info-piece">
21+
<b>Current</b>
22+
<span>{{ collector.data.executed_migrations|last|split('\\')|last }}</span>
23+
</div>
24+
<div class="sf-toolbar-info-piece">
25+
<b>Executed</b>
26+
<span class="sf-toolbar-status">{{ executed_migrations }}</span>
27+
</div>
28+
<div class="sf-toolbar-info-piece">
29+
<b>Executed Unavailable</b>
30+
<span class="sf-toolbar-status {{ unavailable_migrations > 0 ? 'sf-toolbar-status-yellow' }}">{{ unavailable_migrations }}</span>
31+
</div>
32+
<div class="sf-toolbar-info-piece">
33+
<b>Available</b>
34+
<span class="sf-toolbar-status">{{ available_migrations }}</span>
35+
</div>
36+
<div class="sf-toolbar-info-piece">
37+
<b>New</b>
38+
<span class="sf-toolbar-status {{ new_migrations > 0 ? 'sf-toolbar-status-red' }}">{{ new_migrations }}</span>
39+
</div>
40+
{% endset %}
4041

41-
{{ include('@WebProfiler/Profiler/toolbar_item.html.twig', { link: profiler_url, status: status_color }) }}
42+
{{ include('@WebProfiler/Profiler/toolbar_item.html.twig', { link: profiler_url, status: status_color }) }}
43+
{% endif %}
4244
{% endblock %}
4345

4446

4547
{% block menu %}
46-
{% set executed_unavailable_migrations = collector.data.executed_unavailable_migrations|length %}
48+
{% set unavailable_migrations = collector.data.unavailable_migrations|length %}
4749
{% set new_migrations = collector.data.new_migrations|length %}
48-
{% set label = executed_unavailable_migrations > 0 ? 'label-status-warning' : '' %}
50+
{% set label = unavailable_migrations > 0 ? 'label-status-warning' : '' %}
4951
{% set label = new_migrations > 0 ? 'label-status-error' : label %}
5052
<span class="label {{ label }}">
5153
<span class="icon">{{ include('@DoctrineMigrations/Collector/icon.svg') }}</span>
5254
<strong>Migrations</strong>
53-
<span class="count">
54-
<span>{{ collector.data.executed_migrations|length }} / {{ collector.data.available_migrations|length }}</span>
55-
</span>
55+
{% if unavailable_migrations > 0 or new_migrations > 0 %}
56+
<span class="count">
57+
<span>{{ new_migrations + unavailable_migrations }}</span>
58+
</span>
59+
{% endif %}
5660
</span>
5761
{% endblock %}
5862

@@ -64,7 +68,7 @@
6468
<span class="label">Executed</span>
6569
</div>
6670
<div class="metric">
67-
<span class="value">{{ collector.data.executed_unavailable_migrations|length }}</span>
71+
<span class="value">{{ collector.data.unavailable_migrations|length }}</span>
6872
<span class="label">Executed Unavailable</span>
6973
</div>
7074
<div class="metric">
@@ -122,7 +126,7 @@
122126
<th colspan="2" class="colored font-normal">Migration Namespaces</th>
123127
</tr>
124128
</thead>
125-
{% for namespace,directory in collector.data.namespaces %}
129+
{% for namespace, directory in collector.data.namespaces %}
126130
<tr>
127131
<td class="font-normal">{{ namespace }}</td>
128132
<td class="font-normal">{{ directory }}</td>
@@ -141,52 +145,37 @@
141145
<th class="colored font-normal">Execution time</th>
142146
</tr>
143147
</thead>
144-
{% for migration in collector.data.new_migrations %}
145-
<tr>
146-
<td class="font-normal">
147-
{% set version = migration.version|split('\\') %}
148-
{% set file = collector.data.namespaces[version|first] ~ '/' ~ version|last ~ '.php' %}
149-
<a href="{{ file|file_link(1) }}" title="{{ file }}">
150-
{{ migration.version }}
151-
</a>
152-
</td>
153-
<td class="font-normal">{{ migration.description }}</td>
154-
<td class="font-normal"><span class="label status-error">NOT EXECUTED</span></td>
155-
<td class="font-normal">n/a</td>
156-
<td class="font-normal">n/a</td>
157-
</tr>
148+
{% for name in collector.data.new_migrations %}
149+
{{ helper.render_migration(name, collector.data) }}
158150
{% endfor %}
159151

160-
{% set unavailable = [] %}
161-
{% for migration in collector.data.executed_unavailable_migrations %}
162-
{% set unavailable = unavailable|merge([migration.version]) %}
163-
{% endfor %}
164-
165-
{% for migration in collector.data.executed_migrations|reverse %}
166-
{% set is_unavailable = migration.version in unavailable %}
167-
<tr>
168-
<td class="font-normal">
169-
{% if is_unavailable %}
170-
{{ migration.version }}
171-
{% else %}
172-
{% set version = migration.version|split('\\') %}
173-
{% set file = collector.data.namespaces[version|first] ~ '/' ~ version|last ~ '.php' %}
174-
<a href="{{ file|file_link(1) }}" title="{{ file }}">
175-
{{ migration.version }}
176-
</a>
177-
{% endif %}
178-
</td>
179-
<td class="font-normal">{{ migration.description }}</td>
180-
<td class="font-normal">
181-
{% if is_unavailable %}
182-
<span class="label status-warning">UNAVAILABLE</span>
183-
{% else %}
184-
<span class="label status-success">EXECUTED</span>
185-
{% endif %}
186-
</td>
187-
<td class="font-normal">{{ migration.executed_at|date }}</td>
188-
<td class="font-normal">{{ migration.execution_time }}</td>
189-
</tr>
152+
{% for name in collector.data.executed_migrations|reverse %}
153+
{{ helper.render_migration(name, collector.data) }}
190154
{% endfor %}
191155
</table>
192156
{% endblock %}
157+
158+
{% macro render_migration(name, data) %}
159+
{% set migration = migration_info(name) %}
160+
<tr>
161+
<td class="font-normal">
162+
{% if migration.file %}
163+
<a href="{{ migration.file|file_link(1) }}" title="{{ migration.file }}">{{ name }}</a>
164+
{% else %}
165+
{{ name }}
166+
{% endif %}
167+
</td>
168+
<td class="font-normal">{{ migration.description }}</td>
169+
<td class="font-normal">
170+
{% if name in data.new_migrations %}
171+
<span class="label status-error">NOT EXECUTED</span>
172+
{% elseif name in data.unavailable_migrations %}
173+
<span class="label status-warning">UNAVAILABLE</span>
174+
{% else %}
175+
<span class="label status-success">EXECUTED</span>
176+
{% endif %}
177+
</td>
178+
<td class="font-normal">{{ migration.executed_at ? migration.executed_at|date : 'n/a' }}</td>
179+
<td class="font-normal">{{ migration.execution_time|default('n/a') }}</td>
180+
</tr>
181+
{% endmacro %}

Twig/MigrationsExtension.php

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Doctrine\Bundle\MigrationsBundle\Twig;
6+
7+
use Doctrine\Migrations\DependencyFactory;
8+
use Doctrine\Migrations\Version\Version;
9+
use Twig\Extension\AbstractExtension;
10+
use Twig\TwigFunction;
11+
12+
class MigrationsExtension extends AbstractExtension
13+
{
14+
private $dependencyFactory;
15+
private $executedMigrations;
16+
private $availableMigrations;
17+
18+
public function __construct(DependencyFactory $dependecyFactory)
19+
{
20+
$this->dependencyFactory = $dependecyFactory;
21+
}
22+
23+
/**
24+
* @uses \Doctrine\Bundle\MigrationsBundle\Twig\MigrationsExtension::getMigrationInfo()
25+
*/
26+
public function getFunctions(): array
27+
{
28+
return [
29+
new TwigFunction('migration_info', [$this, 'getMigrationInfo']),
30+
];
31+
}
32+
33+
public function getMigrationInfo(string $name): array
34+
{
35+
$version = new Version($name);
36+
37+
if (null === $this->executedMigrations) {
38+
$this->executedMigrations = $this->dependencyFactory->getMetadataStorage()->getExecutedMigrations();
39+
$this->availableMigrations = $this->dependencyFactory->getMigrationPlanCalculator()->getMigrations();
40+
}
41+
42+
$executedMigration = $this->executedMigrations->hasMigration($version)
43+
? $this->executedMigrations->getMigration($version) : null;
44+
$availableMigration = $this->availableMigrations->hasMigration($version)
45+
? $this->availableMigrations->getMigration($version) : null;
46+
47+
return [
48+
'description' => $availableMigration ? $availableMigration->getMigration()->getDescription() : '',
49+
'executed_at' => $executedMigration ? $executedMigration->getExecutedAt() : null,
50+
'execution_time' => $executedMigration ? $executedMigration->getExecutionTime() : null,
51+
'file' => $availableMigration ? (new \ReflectionClass($availableMigration->getMigration()))->getFileName() : null,
52+
];
53+
}
54+
}

0 commit comments

Comments
 (0)