diff --git a/qa.routing.yml b/qa.routing.yml index 997060a..2aec23d 100644 --- a/qa.routing.yml +++ b/qa.routing.yml @@ -9,7 +9,8 @@ qa.reports: qa.reports.checks: path: '/admin/reports/qa/list' defaults: - _controller: '\Drupal\qa\Controller\CheckListController::report' + _form: 'Drupal\qa\Form\ReportForm' + # _controller: '\Drupal\qa\Controller\CheckListController::report' _title: 'QA Checks' requirements: _permission: 'access site reports' diff --git a/src/Form/ReportForm.php b/src/Form/ReportForm.php new file mode 100644 index 0000000..7fc8717 --- /dev/null +++ b/src/Form/ReportForm.php @@ -0,0 +1,231 @@ +moduleHandler = $mh; + $this->translation = $translation; + } + + public static function create(ContainerInterface $container) { + $mh = $container->get('module_handler'); + $translation = $container->get('string_translation'); + return new static($mh, $translation); + } + + /** + * {@inheritdoc} + */ + public function getFormId() { + return 'qa_report'; + } + + /** + * {@inheritdoc} + */ + public function buildForm(array $form, FormStateInterface $form_state) { + $packages = Exportable::getClasses(__DIR__ . "/../..", BasePackage::class); + ksort($packages); + + $session = $this->getRequest()->getSession(); + foreach ($packages as $package_name => $package) { + $open = FALSE; + $form[$package_name] = array( + '#type' => 'details', + '#title' => Xss::filterAdmin($package->title), + '#description' => Xss::filterAdmin($package->description), + '#collapsible' => TRUE, + ); + $controls = $package->getClasses($package->dir, BaseControl::class); + foreach ($controls as $control_name => $control) { + $default_value = $session->get($control_name); + if ($default_value) { + $open = TRUE; + } + $deps = array(); + $met = TRUE; + foreach ($control->getDependencies() as $dep_name) { + if ($this->moduleHandler->moduleExists($dep_name)) { + $deps[] = $this->t('@module (available)', [ + '@module' => $dep_name, + ]); + } + else { + $deps[] = $this->t('@module (unavailable)', [ + '@module' => $dep_name, + ]); + $met = FALSE; + } + } + $form[$package_name][$control_name] = [ + '#type' => 'checkbox', + '#default_value' => $met ? $default_value : 0, + '#title' => Xss::filterAdmin($control->title), + '#description' => Xss::filterAdmin($control->description), + '#disabled' => !$met, + ]; + $form[$package_name][$control_name .'-dependencies'] = [ + '#value' => $this->t('Depends on: !dependencies', [ + '!dependencies' => implode(', ', $deps), + ]), + '#prefix' => '
', + '#suffix' => '
', + ]; + } + $form[$package_name]['#open'] = $open; + } + + $form['actions'] = [ + '#type' => 'actions', + ]; + $form['actions']['submit'] = [ + '#type' => 'submit', + '#value' => $this->t('Run checked controls'), + ]; + + return $form; + } + + /** + * {@inheritdoc} + */ + public function validateForm(array &$form, FormStateInterface $form_state) { +// if (mb_strlen($form_state->getValue('message')) < 10) { +// $form_state->setErrorByName('name', $this->t('Message should be at least 10 characters.')); +// } + } + + + /** + * {@inheritdoc} + */ + public function submitForm(array &$form, FormStateInterface $formState) { + $controls = array(); + $session = $this->getRequest()->getSession(); + foreach ($formState->getValues() as $item => $value) { + if (class_exists($item) && is_subclass_of($item, BaseControl::class)) { + if ($value) { + $controls[$item] = $value; + } + $session->set($item, $value); + } + elseif ($value === 1) { + $args = ['%control' => $item]; + $this->messenger() + ->addError($this->t('Requested invalid control %control', $args)); + $this->logger('qa') + ->error('Requested invalid control %control', $args); + } + } + + $this->messenger() + ->addStatus($this->t('Prepare to run these controls: @controls', [ + '@controls' => implode(', ', array_keys($controls)), + ])); + $batch = [ + 'operations' => [], + 'title' => $this->t('QA Controls running'), + 'init_message' => $this->t('QA Controls initializing'), + 'progress_message' => $this->t('current: @current, Remaining: @remaining, Total: @total'), + 'error_message' => $this->t('Error in QA Control'), + 'finished' => [ReportForm::class, 'runFinished'], + // 'file' => '', // only if outside module file + ]; + + foreach ($controls as $item => $value) { + $batch['operations'][] = [[$this, 'runPass'], [$item]]; + } + batch_set($batch); + } + + /** + * Batch conclusion callback. + * + * @param bool $success + * @param array $results + * @param array $operations + * + * @return \Symfony\Component\HttpFoundation\RedirectResponse + */ + public static function runFinished(bool $success, array $results, array $operations) { + unset($results['#message']); + if ($success) { + $message = \Drupal::translation()->formatPlural(count($results), + 'One control pass ran.', + '@count control passes ran.' + ); + } + else { + $message = t('Finished with an error.'); + } + \Drupal::messenger()->addMessage($message); + $_SESSION['qa_results'] = $results; + return new RedirectResponse( + Url::fromRoute('qa.reports.results', [], ['absolute' => TRUE])->toString() + ); + } + + /** + * Batch progress step. + * + * @return void + */ + public function runPass(string $className, array &$context) { + $nameArg = array('@class' => $className); + + $control = new $className(); + if (!is_object($control)) { + $this->messenger() + ->addError($this->t('Cannot obtain an instance for @class', $nameArg)); + $context['results']['#message'] = $this->t('Control @class failed to run.', $nameArg); + $context['message'] = $this->t('Control @class failed to run.', $nameArg); + $context['results'][$className] = 'wow'; + } + else { + $this->messenger() + ->addStatus($this->t('Running a control instance for @class', $nameArg)); + $pass = $control->run(); + if (!$pass->status) { + $context['success'] = FALSE; + } + $context['results']['#message'][] = $this->t('Control @class ran', $nameArg); + $context['message'] = [ + '#theme' => 'item_list', + '#items' => $context['results']['#message'], + ]; + $context['results'][$className] = $pass; + } + } + +} diff --git a/src/Plugin/Qa/Control/I18n/Package.php b/src/Plugin/Qa/Control/I18n/Package.php index 92e44d6..c6420c0 100644 --- a/src/Plugin/Qa/Control/I18n/Package.php +++ b/src/Plugin/Qa/Control/I18n/Package.php @@ -2,7 +2,7 @@ declare(strict_types = 1); -namespace Drupal\qa\I18n; +namespace Drupal\qa\Plugin\Qa\Control\I18n; use Drupal\qa\BasePackage; diff --git a/src/Plugin/Qa/Control/I18n/Variables.php b/src/Plugin/Qa/Control/I18n/Variables.php index 7f26721..47c5c58 100644 --- a/src/Plugin/Qa/Control/I18n/Variables.php +++ b/src/Plugin/Qa/Control/I18n/Variables.php @@ -1,6 +1,6 @@