Skip to content

Commit 0bbc9a8

Browse files
committed
Issue #5: Mostly working Control/Pass system. Individual controls not yet ported.
1 parent cb8d3e1 commit 0bbc9a8

11 files changed

+242
-10
lines changed

qa.routing.yml

+2-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ qa.reports:
99
qa.reports.checks:
1010
path: '/admin/reports/qa/list'
1111
defaults:
12-
_controller: '\Drupal\qa\Controller\CheckListController::report'
12+
_form: 'Drupal\qa\Form\ReportForm'
13+
# _controller: '\Drupal\qa\Controller\CheckListController::report'
1314
_title: 'QA Checks'
1415
requirements:
1516
_permission: 'access site reports'

src/Form/ReportForm.php

+231
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,231 @@
1+
<?php
2+
3+
namespace Drupal\qa\Form;
4+
5+
use Drupal\Component\Utility\Xss;
6+
use Drupal\Core\Extension\ModuleHandlerInterface;
7+
use Drupal\Core\Form\FormBase;
8+
use Drupal\Core\Form\FormStateInterface;
9+
use Drupal\Core\StringTranslation\TranslationInterface;
10+
use Drupal\Core\Url;
11+
use Drupal\qa\BasePackage;
12+
use Drupal\qa\Exportable;
13+
use Drupal\qa\Plugin\Qa\Control\BaseControl;
14+
use Symfony\Component\DependencyInjection\ContainerInterface;
15+
use Symfony\Component\HttpFoundation\RedirectResponse;
16+
use Symfony\Component\HttpFoundation\RequestStack;
17+
18+
/**
19+
* Provides a QA form.
20+
*/
21+
class ReportForm extends FormBase {
22+
23+
/**
24+
* @var \Drupal\Core\Extension\ModuleHandlerInterface
25+
*/
26+
protected $moduleHandler;
27+
28+
/**
29+
* @var \Drupal\Core\StringTranslation\TranslationInterface
30+
*/
31+
protected $translation;
32+
33+
public function __construct(
34+
ModuleHandlerInterface $mh,
35+
TranslationInterface $translation
36+
) {
37+
$this->moduleHandler = $mh;
38+
$this->translation = $translation;
39+
}
40+
41+
public static function create(ContainerInterface $container) {
42+
$mh = $container->get('module_handler');
43+
$translation = $container->get('string_translation');
44+
return new static($mh, $translation);
45+
}
46+
47+
/**
48+
* {@inheritdoc}
49+
*/
50+
public function getFormId() {
51+
return 'qa_report';
52+
}
53+
54+
/**
55+
* {@inheritdoc}
56+
*/
57+
public function buildForm(array $form, FormStateInterface $form_state) {
58+
$packages = Exportable::getClasses(__DIR__ . "/../..", BasePackage::class);
59+
ksort($packages);
60+
61+
$session = $this->getRequest()->getSession();
62+
foreach ($packages as $package_name => $package) {
63+
$open = FALSE;
64+
$form[$package_name] = array(
65+
'#type' => 'details',
66+
'#title' => Xss::filterAdmin($package->title),
67+
'#description' => Xss::filterAdmin($package->description),
68+
'#collapsible' => TRUE,
69+
);
70+
$controls = $package->getClasses($package->dir, BaseControl::class);
71+
foreach ($controls as $control_name => $control) {
72+
$default_value = $session->get($control_name);
73+
if ($default_value) {
74+
$open = TRUE;
75+
}
76+
$deps = array();
77+
$met = TRUE;
78+
foreach ($control->getDependencies() as $dep_name) {
79+
if ($this->moduleHandler->moduleExists($dep_name)) {
80+
$deps[] = $this->t('@module (<span class="admin-enabled">available</span>)', [
81+
'@module' => $dep_name,
82+
]);
83+
}
84+
else {
85+
$deps[] = $this->t('@module (<span class="admin-disabled">unavailable</span>)', [
86+
'@module' => $dep_name,
87+
]);
88+
$met = FALSE;
89+
}
90+
}
91+
$form[$package_name][$control_name] = [
92+
'#type' => 'checkbox',
93+
'#default_value' => $met ? $default_value : 0,
94+
'#title' => Xss::filterAdmin($control->title),
95+
'#description' => Xss::filterAdmin($control->description),
96+
'#disabled' => !$met,
97+
];
98+
$form[$package_name][$control_name .'-dependencies'] = [
99+
'#value' => $this->t('Depends on: !dependencies', [
100+
'!dependencies' => implode(', ', $deps),
101+
]),
102+
'#prefix' => '<div class="admin-dependencies">',
103+
'#suffix' => '</div>',
104+
];
105+
}
106+
$form[$package_name]['#open'] = $open;
107+
}
108+
109+
$form['actions'] = [
110+
'#type' => 'actions',
111+
];
112+
$form['actions']['submit'] = [
113+
'#type' => 'submit',
114+
'#value' => $this->t('Run checked controls'),
115+
];
116+
117+
return $form;
118+
}
119+
120+
/**
121+
* {@inheritdoc}
122+
*/
123+
public function validateForm(array &$form, FormStateInterface $form_state) {
124+
// if (mb_strlen($form_state->getValue('message')) < 10) {
125+
// $form_state->setErrorByName('name', $this->t('Message should be at least 10 characters.'));
126+
// }
127+
}
128+
129+
130+
/**
131+
* {@inheritdoc}
132+
*/
133+
public function submitForm(array &$form, FormStateInterface $formState) {
134+
$controls = array();
135+
$session = $this->getRequest()->getSession();
136+
foreach ($formState->getValues() as $item => $value) {
137+
if (class_exists($item) && is_subclass_of($item, BaseControl::class)) {
138+
if ($value) {
139+
$controls[$item] = $value;
140+
}
141+
$session->set($item, $value);
142+
}
143+
elseif ($value === 1) {
144+
$args = ['%control' => $item];
145+
$this->messenger()
146+
->addError($this->t('Requested invalid control %control', $args));
147+
$this->logger('qa')
148+
->error('Requested invalid control %control', $args);
149+
}
150+
}
151+
152+
$this->messenger()
153+
->addStatus($this->t('Prepare to run these controls: @controls', [
154+
'@controls' => implode(', ', array_keys($controls)),
155+
]));
156+
$batch = [
157+
'operations' => [],
158+
'title' => $this->t('QA Controls running'),
159+
'init_message' => $this->t('QA Controls initializing'),
160+
'progress_message' => $this->t('current: @current, Remaining: @remaining, Total: @total'),
161+
'error_message' => $this->t('Error in QA Control'),
162+
'finished' => [ReportForm::class, 'runFinished'],
163+
// 'file' => '', // only if outside module file
164+
];
165+
166+
foreach ($controls as $item => $value) {
167+
$batch['operations'][] = [[$this, 'runPass'], [$item]];
168+
}
169+
batch_set($batch);
170+
}
171+
172+
/**
173+
* Batch conclusion callback.
174+
*
175+
* @param bool $success
176+
* @param array $results
177+
* @param array $operations
178+
*
179+
* @return \Symfony\Component\HttpFoundation\RedirectResponse
180+
*/
181+
public static function runFinished(bool $success, array $results, array $operations) {
182+
unset($results['#message']);
183+
if ($success) {
184+
$message = \Drupal::translation()->formatPlural(count($results),
185+
'One control pass ran.',
186+
'@count control passes ran.'
187+
);
188+
}
189+
else {
190+
$message = t('Finished with an error.');
191+
}
192+
\Drupal::messenger()->addMessage($message);
193+
$_SESSION['qa_results'] = $results;
194+
return new RedirectResponse(
195+
Url::fromRoute('qa.reports.results', [], ['absolute' => TRUE])->toString()
196+
);
197+
}
198+
199+
/**
200+
* Batch progress step.
201+
*
202+
* @return void
203+
*/
204+
public function runPass(string $className, array &$context) {
205+
$nameArg = array('@class' => $className);
206+
207+
$control = new $className();
208+
if (!is_object($control)) {
209+
$this->messenger()
210+
->addError($this->t('Cannot obtain an instance for @class', $nameArg));
211+
$context['results']['#message'] = $this->t('Control @class failed to run.', $nameArg);
212+
$context['message'] = $this->t('Control @class failed to run.', $nameArg);
213+
$context['results'][$className] = 'wow';
214+
}
215+
else {
216+
$this->messenger()
217+
->addStatus($this->t('Running a control instance for @class', $nameArg));
218+
$pass = $control->run();
219+
if (!$pass->status) {
220+
$context['success'] = FALSE;
221+
}
222+
$context['results']['#message'][] = $this->t('Control @class ran', $nameArg);
223+
$context['message'] = [
224+
'#theme' => 'item_list',
225+
'#items' => $context['results']['#message'],
226+
];
227+
$context['results'][$className] = $pass;
228+
}
229+
}
230+
231+
}

src/Plugin/Qa/Control/I18n/Package.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
declare(strict_types = 1);
44

5-
namespace Drupal\qa\I18n;
5+
namespace Drupal\qa\Plugin\Qa\Control\I18n;
66

77
use Drupal\qa\BasePackage;
88

src/Plugin/Qa/Control/I18n/Variables.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?php
22

3-
namespace Drupal\qa\I18n;
3+
namespace Drupal\qa\Plugin\Qa\Control\I18n;
44

55
use Drupal\qa\Pass;
66
use Drupal\qa\Plugin\Qa\Control\BaseControl;

src/Plugin/Qa/Control/Taxonomy/Freetagging.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?php
22

3-
namespace Drupal\qa\Taxonomy;
3+
namespace Drupal\qa\Plugin\Qa\Control\Taxonomy;
44

55
use Drupal\Core\PrivateKey;
66
use Drupal\qa\Pass;

src/Plugin/Qa/Control/Taxonomy/Package.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
declare(strict_types = 1);
44

5-
namespace Drupal\qa\Taxonomy;
5+
namespace Drupal\qa\Plugin\Qa\Control\Taxonomy;
66

77
use Drupal\qa\BasePackage;
88

src/Plugin/Qa/Control/Views/Overrides.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?php
22

3-
namespace Drupal\qa\Views;
3+
namespace Drupal\qa\Plugin\Qa\Control\Views;
44

55
use Drupal\qa\Pass;
66

src/Plugin/Qa/Control/Views/Package.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
declare(strict_types = 1);
44

5-
namespace Drupal\qa\Views;
5+
namespace Drupal\qa\Plugin\Qa\Control\Views;
66

77
use Drupal\qa\BasePackage;
88

src/Plugin/Qa/Control/Views/Php.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?php
22

3-
namespace Drupal\qa\Views;
3+
namespace Drupal\qa\Plugin\Qa\Control\Views;
44

55
use Drupal\qa\Pass;
66

src/Plugin/Qa/Control/Views/Views.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?php
22

3-
namespace Drupal\qa\Views;
3+
namespace Drupal\qa\Plugin\Qa\Control\Views;
44

55
use Drupal\qa\Plugin\Qa\Control\BaseControl;
66

src/Workflows/ContentModerationReportBase.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?php
22

3-
namespace Drupal\magpjm\Workflows;
3+
namespace Drupal\qa\Workflows;
44

55
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
66
use Drupal\Core\StringTranslation\StringTranslationTrait;

0 commit comments

Comments
 (0)