drupalorg-1.0.x-dev/src/Controller/ProjectBrowserController.php
src/Controller/ProjectBrowserController.php
<?php
namespace Drupal\drupalorg\Controller;
use Composer\Semver\Semver;
use Drupal\Component\Utility\Xss;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Site\Settings;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
/**
* Controller to manage functionality related to Project Browser.
*/
class ProjectBrowserController extends ControllerBase {
/**
* This is what drupal.org understands as "Active" modules.
*
* @var array
*/
const ACTIVE_VALUES = [
'Under active development',
'Maintenance fixes only',
];
/**
* This is what drupal.org understands as "Maintained" modules.
*
* @var array
*/
const MAINTAINED_VALUES = [
'Actively maintained',
'Minimally maintained',
'Seeking co-maintainer(s)',
];
/**
* This is what drupal.org understands as "Not active" modules.
*
* @var array
*/
const NOT_ACTIVE_VALUES = [
'No further development',
'Obsolete',
];
/**
* This is what drupal.org understands as "Not maintained" modules.
*
* @var array
*/
const NOT_MAINTAINED_VALUES = [
'Seeking new maintainer',
'Unsupported',
];
/**
* Return the UUIDs of the relevant filters for the Project Browser plugin.
*
* @param \Symfony\Component\HttpFoundation\Request $request
* The current request.
*
* @return \Symfony\Component\HttpFoundation\JsonResponse
* JsonResponse with the data that Project Browser plugin needs.
*/
public function filtersUuids(Request $request): JsonResponse {
$data = [
'active' => $this->filter('development_status', self::ACTIVE_VALUES),
'maintained' => $this->filter('maintenance_status', self::MAINTAINED_VALUES),
'not-active' => $this->filter('development_status', self::NOT_ACTIVE_VALUES),
'not-maintained' => $this->filter('maintenance_status', self::NOT_MAINTAINED_VALUES),
];
$version = $request->query->get('drupal_version');
if ($version) {
$data['drupal_version'] = $this->checkVersion($version);
}
return new JsonResponse($data);
}
/**
* Return if a version of Drupal supports the Project Browser endpoints.
*
* @param string $version
* Version of Drupal to check in semver format.
*
* @return array
* Data indicating whether a version of Drupal can query this endpoint.
*/
protected function checkVersion(string $version): array {
// Array of Semver constraints that will not be allowed.
$unsupported_versions = Settings::get('drupalorg_project_browser_unsupported_drupal_versions');
if (empty($version)) {
$supported = FALSE;
$message = $this->t('The Drupal version parameter is required.');
}
elseif (empty($unsupported_versions)) {
$supported = FALSE;
$message = $this->t('Unsupported versions have not been setup on the site.');
}
else {
$supported = TRUE;
$message = $this->t('Supported version.');
foreach ($unsupported_versions as $constraint => $explanation) {
try {
// If there are multiple matches, only the first unsupported rule
// will show.
if ($supported && Semver::satisfies($version, $constraint)) {
$message = $this->t('Unsupported version:') . ' ' . Xss::filter($explanation);
$supported = FALSE;
}
}
catch (\Throwable $e) {
$message = $e->getMessage();
}
}
}
return [
'supported' => $supported,
'message' => $message,
];
}
/**
* Filter out UUIDs of a vocabulary where the terms belong to the allow list.
*
* @param string $vid
* Vocabulary name.
* @param array $allow_list
* List of labels to filter.
*
* @return array
* List of UUIDs filtered.
*/
protected function filter(string $vid, array $allow_list) {
$data = [];
$terms = $this->entityTypeManager()->getStorage('taxonomy_term')->loadTree($vid, 0, NULL, TRUE);
foreach ($terms as $term) {
/** @var \Drupal\taxonomy\Entity\Term $term */
if (in_array($term->label(), $allow_list)) {
$data[] = $term->uuid();
}
}
return $data;
}
}
