protected function UpgradeStatusForm::buildProjectList in Upgrade Status 8.2
Same name and namespace in other branches
- 8.3 src/Form/UpgradeStatusForm.php \Drupal\upgrade_status\Form\UpgradeStatusForm::buildProjectList()
- 8 src/Form/UpgradeStatusForm.php \Drupal\upgrade_status\Form\UpgradeStatusForm::buildProjectList()
Builds a list and status summary of projects.
Parameters
\Drupal\Core\Extension\Extension[] $projects: Array of extensions representing projects.
bool $isContrib: (Optional) Whether the list to be produced is for contributed projects.
Return value
array Build array.
1 call to UpgradeStatusForm::buildProjectList()
- UpgradeStatusForm::buildForm in src/
Form/ UpgradeStatusForm.php - Form constructor.
File
- src/
Form/ UpgradeStatusForm.php, line 292
Class
Namespace
Drupal\upgrade_status\FormCode
protected function buildProjectList(array $projects, bool $isContrib = FALSE) {
$counters = [
'not-scanned' => 0,
'no-known-error' => 0,
'known-errors' => 0,
'known-warnings' => 0,
'known-error-projects' => 0,
'known-warning-projects' => 0,
];
$header = [
'project' => [
'data' => $this
->t('Project'),
'class' => 'project-label',
],
];
if ($isContrib) {
$header['update'] = [
'data' => $this
->t('Available update'),
'class' => 'update-info',
];
}
$header['status'] = [
'data' => $this
->t('Status'),
'class' => 'status-info',
];
$build['uninstalled'] = $build['installed'] = [
'#type' => 'tableselect',
'#header' => $header,
'#weight' => 20,
'#options' => [],
];
$build['uninstalled']['#weight'] = '40';
$update_check_for_uninstalled = $this
->config('update.settings')
->get('check.disabled_extensions');
foreach ($projects as $name => $extension) {
// Always use a fresh service. An injected service could get stale results
// because scan result saving happens in different HTTP requests for most
// cases (when analysis was successful).
$scan_result = \Drupal::service('keyvalue')
->get('upgrade_status_scan_results')
->get($name);
$info = $extension->info;
$label = $info['name'] . (!empty($info['version']) ? ' ' . $info['version'] : '');
$state = empty($extension->status) ? 'uninstalled' : 'installed';
$update_cell = [
'class' => 'update-info',
'data' => $isContrib ? $this
->t('Up to date') : '',
];
$label_cell = [
'data' => [
'label' => [
'#type' => 'html_tag',
'#tag' => 'label',
'#value' => $label,
'#attributes' => [
'for' => 'edit-' . ($isContrib ? 'contrib' : 'custom') . '-data-data-' . str_replace('_', '-', $name),
],
],
],
'class' => 'project-label',
];
if ($isContrib) {
$projectUpdateData = $this->releaseStore
->get($name);
if (!isset($projectUpdateData['releases']) || is_null($projectUpdateData['releases'])) {
$update_cell = [
'class' => 'update-info',
'data' => $update_check_for_uninstalled ? $this
->t('Not available') : $this
->t('Not checked'),
];
}
else {
$latestRelease = reset($projectUpdateData['releases']);
$latestVersion = $latestRelease['version'];
if ($info['version'] !== $latestVersion) {
$link = $projectUpdateData['link'] . '/releases/' . $latestVersion;
$update_cell = [
'class' => 'update-info',
'data' => [
'#type' => 'link',
'#title' => $latestVersion,
'#url' => Url::fromUri($link),
],
];
}
}
}
// If this project was not found in our keyvalue storage, it is not yet scanned, report that.
if (empty($scan_result)) {
$build[$state]['#options'][$name] = [
'#attributes' => [
'class' => [
'not-scanned',
'project-' . $name,
],
],
'project' => $label_cell,
'update' => $update_cell,
'status' => [
'class' => 'status-info',
'data' => $this
->t('Not scanned'),
],
];
$counters['not-scanned']++;
continue;
}
// Unpack JSON of deprecations to display results.
$report = json_decode($scan_result, TRUE);
if (!empty($report['plans'])) {
$label_cell['data']['plans'] = [
'#type' => 'markup',
'#markup' => '<div>' . $report['plans'] . '</div>',
];
}
if (isset($report['data']['totals'])) {
$project_error_count = $report['data']['totals']['file_errors'];
}
else {
$project_error_count = 0;
}
// If this project had no known issues found, report that.
if ($project_error_count === 0) {
$build[$state]['#options'][$name] = [
'#attributes' => [
'class' => [
'no-known-error',
'project-' . $name,
],
],
'project' => $label_cell,
'update' => $update_cell,
'status' => [
'class' => 'status-info',
'data' => $this
->t('No known errors'),
],
];
$counters['no-known-error']++;
continue;
}
// Finally this project had errors found, display them.
$error_label = [];
$error_class = 'known-warnings';
if (!empty($report['data']['totals']['upgrade_status_split']['error'])) {
$counters['known-errors'] += $report['data']['totals']['upgrade_status_split']['error'];
$counters['known-error-projects']++;
$error_class = 'known-errors';
$error_label[] = $this
->formatPlural($report['data']['totals']['upgrade_status_split']['error'], '@count error', '@count errors');
}
if (!empty($report['data']['totals']['upgrade_status_split']['warning'])) {
$counters['known-warnings'] += $report['data']['totals']['upgrade_status_split']['warning'];
$counters['known-warning-projects']++;
$error_label[] = $this
->formatPlural($report['data']['totals']['upgrade_status_split']['warning'], '@count warning', '@count warnings');
}
// If the project was declared Drupal 9 compatible (info and composer
// files), than use that to visually display it as such. We still list
// errors but they may be false positives or results of workaround code.
if (!empty($report['data']['totals']['upgrade_status_split']['declared_ready'])) {
$error_class = 'no-known-error';
}
$build[$state]['#options'][$name] = [
'#attributes' => [
'class' => [
$error_class,
'project-' . $name,
],
],
'project' => $label_cell,
'update' => $update_cell,
'status' => [
'class' => 'status-info',
'data' => [
'#type' => 'link',
'#title' => join(', ', $error_label),
'#url' => Url::fromRoute('upgrade_status.project', [
'type' => $extension
->getType(),
'project_machine_name' => $name,
]),
'#attributes' => [
'class' => [
'use-ajax',
],
'data-dialog-type' => 'modal',
'data-dialog-options' => Json::encode([
'width' => 1024,
'height' => 568,
]),
],
],
],
];
}
if (!$isContrib) {
// If the list is not for contrib, remove the update placeholder.
$states = [
'installed',
'uninstalled',
];
foreach ($states as $state) {
foreach ($build[$state]['#options'] as $name => &$row) {
if (is_array($row)) {
unset($row['update']);
}
}
}
}
if (empty($build['uninstalled']['#options'])) {
unset($build['uninstalled']);
}
else {
// Add a specific intro section to uninstalled extensions.
$check_info = '';
if ($isContrib) {
// Contrib extensions that are uninstalled may not get available updates info.
$enable_check = Url::fromRoute('update.settings', [], [
'query' => $this->destination
->getAsArray(),
])
->toString();
if (!empty($update_check_for_uninstalled)) {
$check_info = ' ' . $this
->t('Available update checking for uninstalled extensions is enabled.');
}
else {
$check_info = ' ' . $this
->t('Available update checking for uninstalled extensions is disabled. (<a href="@enable">Enable</a>)', [
'@enable' => $enable_check,
]);
}
}
$build['uninstalled_intro'] = [
'#weight' => 30,
[
'#type' => 'markup',
'#markup' => '<h3>' . $this
->t('Uninstalled extensions') . '</h3>',
],
[
'#type' => 'markup',
'#markup' => '<div>' . $this
->t('Consider if you need these uninstalled extensions at all. A limited set of checks may also be run on uninstalled extensions.') . $check_info . '</div>',
],
];
}
if (empty($build['installed']['#options'])) {
unset($build['installed']);
}
$summary = [];
if ($counters['known-errors'] > 0) {
$summary[] = [
'type' => $this
->formatPlural($counters['known-errors'], '1 error', '@count errors'),
'class' => 'error',
'message' => $this
->formatPlural($counters['known-error-projects'], 'Found in one project.', 'Found in @count projects.'),
];
}
if ($counters['known-warnings'] > 0) {
$summary[] = [
'type' => $this
->formatPlural($counters['known-warnings'], '1 warning', '@count warnings'),
'class' => 'warning',
'message' => $this
->formatPlural($counters['known-warning-projects'], 'Found in one project.', 'Found in @count projects.'),
];
}
if ($counters['no-known-error'] > 0) {
$summary[] = [
'type' => $this
->formatPlural($counters['no-known-error'], '1 checked', '@count checked'),
'class' => 'checked',
'message' => $this
->t('No known errors found.'),
];
}
if ($counters['not-scanned'] > 0) {
$summary[] = [
'type' => $this
->formatPlural($counters['not-scanned'], '1 not scanned', '@count not scanned'),
'class' => 'not-scanned',
'message' => $this
->t('Scan to find errors.'),
];
}
$build['summary'] = [
'#theme' => 'upgrade_status_summary_counter',
'#summary' => $summary,
];
return $build;
}