Skip to content

Commit

Permalink
Render application templates
Browse files Browse the repository at this point in the history
  • Loading branch information
Dominic Tubach committed Feb 22, 2024
1 parent cb8e8a5 commit 1b9cf2a
Show file tree
Hide file tree
Showing 10 changed files with 285 additions and 20 deletions.
16 changes: 16 additions & 0 deletions civiremote_funding.module
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,31 @@

declare(strict_types=1);

use Drupal\civiremote_funding\Api\FundingApi;
use Drupal\civiremote_funding\Breadcrumb\BreadcrumbRouteAnalyzer;
use Drupal\civiremote_funding\File\FundingFileDownloadHook;
use Drupal\civiremote_funding\File\FundingFileManager;
use Drupal\civiremote_funding\Install\DashboardBlockInstaller;
use Drupal\civiremote_funding\Views\ApplicationProcessDropButton;
use Drupal\civiremote_funding\ViewTranslator;
use Drupal\Core\Breadcrumb\Breadcrumb;
use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\file\FileInterface;
use Drupal\views\Plugin\views\field\Dropbutton;
use Drupal\views\ViewExecutable;

function civiremote_funding_views_pre_build(ViewExecutable $view): void {
if (!in_array($view->id(), ['civiremote_funding_application_list', 'civiremote_funding_combined_application_process_list'], TRUE)) {
return;
}

if (($view->field['dropbutton'] ?? NULL) instanceof Dropbutton) {
/** @var \Drupal\civiremote_funding\Api\FundingApi $fundingApi */
$fundingApi = \Drupal::service(FundingApi::class);
$view->field['dropbutton'] = new ApplicationProcessDropButton($fundingApi, $view->field['dropbutton']);
}
}

/**
* Implements hook_rebuild().
Expand Down
14 changes: 14 additions & 0 deletions civiremote_funding.routing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,20 @@ civiremote_funding.application_history:
requirements:
_permission: 'civiremote_funding: access'

civiremote_funding.application_template_render:
path: '/civiremote/funding/application/{applicationProcessId}/template/{templateId}/render'
defaults:
_controller: 'Drupal\civiremote_funding\Controller\ApplicationTemplateRenderController:render'
options:
no_cache: TRUE
parameters:
applicationProcessId:
type: int
templateId:
type: int
requirements:
_permission: 'civiremote_funding: access'

civiremote_funding.case:
path: '/civiremote/funding/case/{fundingCaseId}'
defaults:
Expand Down
4 changes: 4 additions & 0 deletions civiremote_funding.services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,10 @@ services:
class: Drupal\civiremote_funding\Controller\ApplicationHistoryController
public: true

Drupal\civiremote_funding\Controller\ApplicationTemplateRenderController:
class: Drupal\civiremote_funding\Controller\ApplicationTemplateRenderController
public: true

Drupal\civiremote_funding\Controller\TransferContractDownloadController:
class: Drupal\civiremote_funding\Controller\TransferContractDownloadController
public: true
Expand Down
3 changes: 3 additions & 0 deletions phpcs.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@
<!-- Don't enforce phpdoc type hint because it (might) only duplicate a PHP type hint -->
<exclude name="Drupal.Commenting.FunctionComment.ParamMissingDefinition"/>

<!-- Don't enforce short single line comment -->
<exclude name="Drupal.Commenting.DocComment.ShortSingleLine"/>

<!-- False positive with license header -->
<exclude name="Drupal.Commenting.FileComment.NamespaceNoFileDoc"/>

Expand Down
43 changes: 43 additions & 0 deletions src/Api/DTO/ApplicationProcessTemplate.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

/*
* Copyright (C) 2023 SYSTOPIA GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

declare(strict_types=1);

namespace Drupal\civiremote_funding\Api\DTO;

/**
* @phpstan-type templateT array{
* id: int,
* label: string,
* }
*
* @phpstan-extends AbstractDTO<templateT>
*
* @codeCoverageIgnore
*/
final class ApplicationProcessTemplate extends AbstractDTO {

public function getId(): int {
return $this->values['id'];
}

public function getLabel(): string {
return $this->values['label'];
}

}
26 changes: 26 additions & 0 deletions src/Api/FundingApi.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

use Drupal\civiremote_funding\Access\RemoteContactIdProviderInterface;
use Drupal\civiremote_funding\Api\DTO\ApplicationProcessActivity;
use Drupal\civiremote_funding\Api\DTO\ApplicationProcessTemplate;
use Drupal\civiremote_funding\Api\DTO\FundingCase;
use Drupal\civiremote_funding\Api\DTO\FundingCaseInfo;
use Drupal\civiremote_funding\Api\DTO\FundingCaseType;
Expand Down Expand Up @@ -183,6 +184,31 @@ public function getApplicationActivities(int $applicationProcessId): array {
return ApplicationProcessActivity::allFromArrays($result['values']);
}

public function getApplicationTemplateRenderUri(int $applicationProcessId, int $templateId): string {
$result = $this->apiClient->executeV4('RemoteFundingApplicationProcess', 'getTemplateRenderUri', [
'remoteContactId' => $this->remoteContactIdProvider->getRemoteContactId(),
'applicationProcessId' => $applicationProcessId,
'templateId' => $templateId,
]);

// @phpstan-ignore-next-line
return $result['values']['renderUri'];
}

/**
* @phpstan-return list<ApplicationProcessTemplate>
*
* @throws \Drupal\civiremote_funding\Api\Exception\ApiCallFailedException
*/
public function getApplicationTemplates(int $applicationProcessId): array {
$result = $this->apiClient->executeV4('RemoteFundingApplicationProcess', 'getTemplates', [
'remoteContactId' => $this->remoteContactIdProvider->getRemoteContactId(),
'applicationProcessId' => $applicationProcessId,
]);

return ApplicationProcessTemplate::allFromArrays($result['values']);
}

/**
* @phpstan-return array<string, \Drupal\civiremote_funding\Api\DTO\Option>
* Options with option ID as key.
Expand Down
53 changes: 53 additions & 0 deletions src/Controller/ApplicationTemplateRenderController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php

/*
* Copyright (C) 2024 SYSTOPIA GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

declare(strict_types=1);

namespace Drupal\civiremote_funding\Controller;

use Drupal\civiremote_funding\Api\FundingApi;
use Drupal\civiremote_funding\RemotePage\RemotePageProxy;
use Drupal\Core\Controller\ControllerBase;
use Symfony\Component\HttpFoundation\Response;

final class ApplicationTemplateRenderController extends ControllerBase {

private FundingApi $fundingApi;

private RemotePageProxy $remotePageProxy;

public function __construct(
FundingApi $fundingApi,
RemotePageProxy $remotePageProxy
) {
$this->fundingApi = $fundingApi;
$this->remotePageProxy = $remotePageProxy;
}

public function render(int $applicationProcessId, int $templateId): Response {
$uri = $this->getDownloadUri($applicationProcessId, $templateId);

return $this->remotePageProxy->get($uri);
}

private function getDownloadUri(int $applicationProcessId, int $templateId): string {
return $this->fundingApi->getApplicationTemplateRenderUri($applicationProcessId, $templateId);
}

}
5 changes: 4 additions & 1 deletion src/RemotePage/RemotePageClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@
*/
class RemotePageClient {

private const DEFAULT_TIMEOUT = 3.0;
private const DEFAULT_CONNECT_TIMEOUT = 3.0;

private const DEFAULT_TIMEOUT = 7.0;

private string $apiKey;

Expand Down Expand Up @@ -83,6 +85,7 @@ public function __construct(
public function request(string $method, string $uri, array $options = []): ResponseInterface {
// @phpstan-ignore-next-line
$options['headers'] = array_merge($options['headers'] ?? [], $this->buildHeaders());
$options['connect_timeout'] ??= self::DEFAULT_CONNECT_TIMEOUT;
$options['timeout'] ??= self::DEFAULT_TIMEOUT;
$options['http_errors'] ??= FALSE;

Expand Down
99 changes: 99 additions & 0 deletions src/Views/ApplicationProcessDropButton.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
<?php

/*
* Copyright (C) 2024 SYSTOPIA GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

declare(strict_types=1);

namespace Drupal\civiremote_funding\Views;

use Drupal\civiremote_funding\Api\FundingApi;
use Drupal\Core\Url;
use Drupal\views\Plugin\views\field\Dropbutton;
use Drupal\views\ResultRow;

/**
* Acts like a decorator (a real decorator is not possible) to add application
* process document creation links.
*/
final class ApplicationProcessDropButton extends Dropbutton {

private FundingApi $fundingApi;

private ?int $applicationProcessId = NULL;

public function __construct(FundingApi $fundingApi, Dropbutton $dropbutton) {
$this->fundingApi = $fundingApi;
parent::__construct($dropbutton->configuration, $dropbutton->getPluginId(), $dropbutton->getPluginDefinition());
// @phpstan-ignore-next-line
if (NULL !== $dropbutton->view) {
$this->init($dropbutton->view, $dropbutton->view->getDisplay(), $dropbutton->options);
}
}

/**
* {@inheritDoc}
*/
public function render(ResultRow $values) {
// @phpstan-ignore-next-line
foreach ($values as $key => $value) {
if (str_ends_with($key, '_application_process_id')) {
$this->applicationProcessId = $value;

break;
}
}

try {
return parent::render($values);
}
finally {
$this->applicationProcessId = NULL;
}
}

/**
* {@inheritDoc}
*
* @phpstan-return array<mixed>
*
* @throws \Drupal\civiremote_funding\Api\Exception\ApiCallFailedException
*/
protected function getLinks(): array {
$links = parent::getLinks();
if (NULL === $this->applicationProcessId) {
// Should not happen.
return $links;
}

foreach ($this->fundingApi->getApplicationTemplates($this->applicationProcessId) as $template) {
$links[] = [
'url' => Url::fromRoute('civiremote_funding.application_template_render', [
'applicationProcessId' => $this->applicationProcessId,
'templateId' => $template->getId(),
]),
'title' => $this->t('Create: @label', ['@label' => $template->getLabel()]),
'attributes' => [
'target' => '_blank',
],
];
}

return $links;
}

}
Loading

0 comments on commit 1b9cf2a

Please sign in to comment.