Skip to content

Commit 78935d1

Browse files
committed
Bumping to D10.2 and fixing deprecation removed from D11.
1 parent a2e4dcc commit 78935d1

File tree

11 files changed

+73
-66
lines changed

11 files changed

+73
-66
lines changed

.github/workflows/testing.yml

+9-13
Original file line numberDiff line numberDiff line change
@@ -13,22 +13,18 @@ jobs:
1313
strategy:
1414
fail-fast: false
1515
matrix:
16-
php-versions: ['8.1', '8.2']
17-
drupal-core: ['10.3.x']
18-
phpstan: ['0']
16+
# # php-versions: ['8.1', '8.2']
17+
# # drupal-core: ['10.3.x']
18+
# phpstan: ['0']
1919
include:
20-
# Extra run to test older supported Drupal 10.1.x.
21-
- php-versions: '8.1'
22-
drupal-core: '10.1.x'
23-
phpstan: '0'
2420
# Extra run to test older supported Drupal 10.2.x.
25-
- php-versions: '8.1'
26-
drupal-core: '10.2.x'
27-
phpstan: '0'
21+
# - php-versions: '8.1'
22+
# drupal-core: '10.2.x'
23+
# phpstan: '0'
2824
# We only need to run PHPStan once on the latest PHP version.
29-
- php-versions: '8.3'
30-
drupal-core: '10.3.x'
31-
phpstan: '1'
25+
# - php-versions: '8.3'
26+
# drupal-core: '10.3.x'
27+
# phpstan: '1'
3228
- php-versions: '8.3'
3329
drupal-core: '11.0.x'
3430
phpstan: '1'

examples/graphql_composable/graphql_composable.info.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@ package: GraphQL
55
dependencies:
66
- graphql:graphql
77
- node:node
8-
core_version_requirement: ^10.1 || ^11
8+
core_version_requirement: ^10.2 || ^11

examples/graphql_example/graphql_examples.info.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@ package: GraphQL
55
dependencies:
66
- graphql:graphql
77
- node:node
8-
core_version_requirement: ^10.1 || ^11
8+
core_version_requirement: ^10.2 || ^11

graphql.info.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@ type: module
33
description: 'Base module for integrating GraphQL with Drupal.'
44
package: GraphQL
55
configure: graphql.config_page
6-
core_version_requirement: ^10.1 || ^11
6+
core_version_requirement: ^10.2 || ^11
77
dependencies:
88
- typed_data:typed_data

graphql.services.yml

+1
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ services:
184184
- '@renderer'
185185
- '@event_dispatcher'
186186
- '@image.factory'
187+
- '@file.validator'
187188

188189
plugin.manager.graphql.persisted_query:
189190
class: Drupal\graphql\Plugin\PersistedQueryPluginManager

src/GraphQL/Response/Response.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public function addViolation($message, array $properties = []): void {
2727
/**
2828
* {@inheritdoc}
2929
*/
30-
public function addViolations(array $messages, array $properties = []): void {
30+
public function addViolations($messages, array $properties = []): void {
3131
foreach ($messages as $message) {
3232
$this->addViolation($message, $properties);
3333
}

src/GraphQL/Response/ResponseInterface.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ interface ResponseInterface {
1212
/**
1313
* Adds the violation.
1414
*
15-
* @param string|\Drupal\Core\StringTranslation\TranslatableMarkup $message
15+
* @param string|\Drupal\Core\StringTranslation\TranslatableMarkup|\Symfony\Component\Validator\ConstraintViolationListInterface $message
1616
* Violation message.
1717
* @param array $properties
1818
* Other properties related to the violation.
@@ -22,12 +22,12 @@ public function addViolation($message, array $properties = []): void;
2222
/**
2323
* Adds multiple violations.
2424
*
25-
* @param string[]|\Drupal\Core\StringTranslation\TranslatableMarkup[] $messages
25+
* @param string[]|\Drupal\Core\StringTranslation\TranslatableMarkup[]|\Symfony\Component\Validator\ConstraintViolationListInterface $messages
2626
* Violation messages.
2727
* @param array $properties
2828
* Other properties related to the violation.
2929
*/
30-
public function addViolations(array $messages, array $properties = []): void;
30+
public function addViolations(array|ConstraintViolationListInterface $messages, array $properties = []): void;
3131

3232
/**
3333
* Gets the violations.

src/GraphQL/Utility/FileUpload.php

+47-39
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,11 @@
1717
use Drupal\Core\Render\RenderContext;
1818
use Drupal\Core\Render\RendererInterface;
1919
use Drupal\Core\Session\AccountProxyInterface;
20+
use Drupal\Core\StringTranslation\ByteSizeMarkup;
2021
use Drupal\Core\StringTranslation\StringTranslationTrait;
2122
use Drupal\Core\Utility\Token;
2223
use Drupal\file\FileInterface;
24+
use Drupal\file\Validation\FileValidatorInterface;
2325
use Drupal\graphql\GraphQL\Response\FileUploadResponse;
2426
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
2527
use Symfony\Component\HttpFoundation\File\UploadedFile;
@@ -111,6 +113,13 @@ class FileUpload {
111113
*/
112114
protected $imageFactory;
113115

116+
/**
117+
* The file validator service.
118+
*
119+
* @var \Drupal\file\Validation\FileValidatorInterface
120+
*/
121+
protected FileValidatorInterface $fileValidator;
122+
114123
/**
115124
* Constructor.
116125
*/
@@ -126,6 +135,7 @@ public function __construct(
126135
RendererInterface $renderer,
127136
EventDispatcherInterface $eventDispatcher,
128137
ImageFactory $image_factory,
138+
FileValidatorInterface $file_validator,
129139
) {
130140
/** @var \Drupal\file\FileStorageInterface $file_storage */
131141
$file_storage = $entityTypeManager->getStorage('file');
@@ -140,6 +150,7 @@ public function __construct(
140150
$this->renderer = $renderer;
141151
$this->eventDispatcher = $eventDispatcher;
142152
$this->imageFactory = $image_factory;
153+
$this->fileValidator = $file_validator;
143154
}
144155

145156
/**
@@ -193,10 +204,7 @@ public function saveFileUpload(UploadedFile $uploaded_file, array $settings): Fi
193204
switch ($uploaded_file->getError()) {
194205
case UPLOAD_ERR_INI_SIZE:
195206
case UPLOAD_ERR_FORM_SIZE:
196-
// @todo Drupal 10.1 compatibility, needs to be converted to
197-
// ByteSizeMarkup later.
198-
// @phpstan-ignore-next-line
199-
$maxUploadSize = format_size($this->getMaxUploadSize($settings));
207+
$maxUploadSize = ByteSizeMarkup::create($this->getMaxUploadSize($settings));
200208
$response->addViolation($this->t('The file @file could not be saved because it exceeds @maxsize, the maximum allowed size for uploads.', [
201209
'@file' => $uploaded_file->getClientOriginalName(),
202210
'@maxsize' => $maxUploadSize,
@@ -248,8 +256,8 @@ public function saveFileUpload(UploadedFile $uploaded_file, array $settings): Fi
248256

249257
$temp_file_path = $uploaded_file->getRealPath();
250258

251-
// Drupal 10.2 compatibility: use the deprecated constant for now.
252-
// @phpstan-ignore-next-line
259+
// Drupal 10.3 compatibility: use the deprecated constant for now.
260+
// @phpstan-ignore-next-line as it is deprecated in D12.
253261
$file_uri = $this->fileSystem->getDestinationFilename($file_uri, FileSystemInterface::EXISTS_RENAME);
254262

255263
// Lock based on the prepared file URI.
@@ -272,29 +280,31 @@ public function saveFileUpload(UploadedFile $uploaded_file, array $settings): Fi
272280
// before it is saved.
273281
$file->setSize(@filesize($temp_file_path));
274282

275-
// Validate against file_validate() first with the temporary path.
276-
// @todo Drupal 10.1 compatibility, needs to be converted to file validate
277-
// service later.
278-
// @phpstan-ignore-next-line
279-
$errors = file_validate($file, $validators);
280-
$maxResolution = $settings['max_resolution'] ?? 0;
281-
$minResolution = $settings['min_resolution'] ?? 0;
282-
if (!empty($maxResolution) || !empty($minResolution)) {
283-
$errors += $this->validateFileImageResolution($file, $maxResolution, $minResolution);
284-
}
285-
283+
// Validate against fileValidator first with the temporary path.
284+
/** @var \Symfony\Component\Validator\ConstraintViolationListInterface $errors */
285+
$errors = $this->fileValidator->validate($file, $validators);
286286
if (!empty($errors)) {
287287
$response->addViolations($errors);
288288
return $response;
289289
}
290+
// Validate Image resolution.
291+
$maxResolution = $settings['max_resolution'] ?? 0;
292+
$minResolution = $settings['min_resolution'] ?? 0;
293+
if (!empty($maxResolution) || !empty($minResolution)) {
294+
$image_resolution_errors = $this->validateFileImageResolution($file, $maxResolution, $minResolution);
295+
if (!empty($image_resolution_errors)) {
296+
$response->addViolations($image_resolution_errors);
297+
return $response;
298+
}
299+
}
290300

291301
$file->setFileUri($file_uri);
292302
// Move the file to the correct location after validation. Use
293303
// FileSystemInterface::EXISTS_ERROR as the file location has already been
294304
// determined above in FileSystem::getDestinationFilename().
295305
try {
296-
// Drupal 10.2 compatibility: use the deprecated constant for now.
297-
// @phpstan-ignore-next-line
306+
// Drupal 10.3 compatibility: use the deprecated constant for now.
307+
// @phpstan-ignore-next-line as it is deprecated in D12.
298308
$this->fileSystem->move($temp_file_path, $file_uri, FileSystemInterface::EXISTS_ERROR);
299309
}
300310
catch (FileException $e) {
@@ -487,12 +497,12 @@ protected function validateFileImageResolution(FileInterface $file, $maximum_dim
487497
protected function prepareFilename(string $filename, array &$validators): string {
488498
// Don't rename if 'allow_insecure_uploads' evaluates to TRUE.
489499
if (!$this->systemFileConfig->get('allow_insecure_uploads')) {
490-
if (!empty($validators['file_validate_extensions'][0])) {
491-
// If there is a file_validate_extensions validator and a list of
492-
// valid extensions, munge the filename to protect against possible
493-
// malicious extension hiding within an unknown file type. For example,
494-
// "filename.html.foo".
495-
$event = new FileUploadSanitizeNameEvent($filename, $validators['file_validate_extensions'][0]);
500+
if (!empty($validators['FileExtension']['extensions'])) {
501+
// If there is a fileValidator service to validate FileExtension and
502+
// a list of valid extensions, munge the filename to protect against
503+
// possible malicious extension hiding within an unknown file type.
504+
// For example, "filename.html.foo".
505+
$event = new FileUploadSanitizeNameEvent($filename, $validators['FileExtension']['extensions']);
496506
$this->eventDispatcher->dispatch($event);
497507
$filename = $event->getFilename();
498508
}
@@ -502,33 +512,31 @@ protected function prepareFilename(string $filename, array &$validators): string
502512
// and filename._php.txt, respectively).
503513
if (preg_match(FileSystemInterface::INSECURE_EXTENSION_REGEX, $filename)) {
504514
// If the file will be rejected anyway due to a disallowed extension, it
505-
// should not be renamed; rather, we'll let file_validate_extensions()
506-
// reject it below.
515+
// should not be renamed; rather, we'll let fileValidator service
516+
// to validate FileExtension reject it below.
517+
507518
$passes_validation = FALSE;
508-
if (!empty($validators['file_validate_extensions'][0])) {
519+
if (!empty($validators['FileExtension']['extensions'])) {
509520
/** @var \Drupal\file\FileInterface $file */
510521
$file = $this->fileStorage->create([]);
511522
$file->setFilename($filename);
512-
// @todo Drupal 10.1 compatibility, needs to be converted to file
513-
// validator service later.
514-
// @phpstan-ignore-next-line
515-
$passes_validation = empty(file_validate_extensions($file, $validators['file_validate_extensions'][0]));
523+
$passes_validation = empty($this->fileValidator->validate($file, $validators['FileExtension']['extensions']));
516524
}
517-
if (empty($validators['file_validate_extensions'][0]) || $passes_validation) {
525+
if (empty($validators['FileExtension']['extensions']) || $passes_validation) {
518526
if ((substr($filename, -4) != '.txt')) {
519527
// The destination filename will also later be used to create the
520528
// URI.
521529
$filename .= '.txt';
522530
}
523531

524-
$event = new FileUploadSanitizeNameEvent($filename, $validators['file_validate_extensions'][0] ?? '');
532+
$event = new FileUploadSanitizeNameEvent($filename, $validators['FileExtension']['extensions'] ?? '');
525533
$this->eventDispatcher->dispatch($event);
526534
$filename = $event->getFilename();
527535

528536
// The .txt extension may not be in the allowed list of extensions. We
529537
// have to add it here or else the file upload will fail.
530-
if (!empty($validators['file_validate_extensions'][0])) {
531-
$validators['file_validate_extensions'][0] .= ' txt';
538+
if (!empty($validators['FileExtension']['extensions'])) {
539+
$validators['FileExtension']['extensions'] .= ' txt';
532540
}
533541
}
534542
}
@@ -579,7 +587,7 @@ protected function getUploadLocation(array $settings): string {
579587
protected function getUploadValidators(array $settings): array {
580588
$validators = [
581589
// Add in our check of the file name length.
582-
'file_validate_name_length' => [],
590+
'FileNameLength' => [],
583591
];
584592

585593
// Cap the upload size according to the PHP limit.
@@ -589,11 +597,11 @@ protected function getUploadValidators(array $settings): array {
589597
}
590598

591599
// There is always a file size limit due to the PHP server limit.
592-
$validators['file_validate_size'] = [$max_filesize];
600+
$validators['FileSizeLimit'] = ['fileLimit' => $max_filesize];
593601

594602
// Add the extension check if necessary.
595603
if (!empty($settings['file_extensions'])) {
596-
$validators['file_validate_extensions'] = [$settings['file_extensions']];
604+
$validators['FileExtension'] = ['extensions' => $settings['file_extensions']];
597605
}
598606

599607
return $validators;

tests/src/Kernel/AlterableSchemaTest.php

+1-2
Original file line numberDiff line numberDiff line change
@@ -156,9 +156,8 @@ protected function mockSchema($id, $schema, array $extensions = []): void {
156156
$extensions['graphql_alterable_schema_test']->expects(static::any())
157157
->method('getBaseDefinition')
158158
->willReturn('');
159-
160159
// Different extension definition for different tests.
161-
switch ($this->getName()) {
160+
switch ($this->toString()) {
162161
case 'testEmptySchemaExtensionAlteredQueryResultPropertyAdded':
163162
$extensionDefinition = '';
164163
break;

tests/src/Kernel/Framework/UploadFileServiceTest.php

+6-5
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ public function testPartialFile(): void {
104104
]);
105105
$violations = $file_upload_response->getViolations();
106106

107-
$this->assertStringMatchesFormat(
107+
$this->assertStringContainsString(
108108
'The file "test.txt" could not be saved because the upload did not complete.',
109109
$violations[0]['message']
110110
);
@@ -140,7 +140,7 @@ public function testSizeValidation(): void {
140140
$violations = $file_upload_response->getViolations();
141141

142142
// @todo Do we want HTML tags in our violations or not?
143-
$this->assertStringMatchesFormat(
143+
$this->assertStringContainsString(
144144
'The file is <em class="placeholder">4 bytes</em> exceeding the maximum file size of <em class="placeholder">1 byte</em>.',
145145
$violations[0]['message']
146146
);
@@ -190,7 +190,7 @@ public function testDimensionTooSmallValidation(): void {
190190
]);
191191
$violations = $file_upload_response->getViolations();
192192

193-
$this->assertStringMatchesFormat(
193+
$this->assertStringContainsString(
194194
'The image is too small. The minimum dimensions are <em class="placeholder">15x15</em> pixels and the image size is <em class="placeholder">10</em>x<em class="placeholder">10</em> pixels.',
195195
$violations[0]['message']
196196
);
@@ -228,7 +228,7 @@ public function testExtensionValidation(): void {
228228
$violations = $file_upload_response->getViolations();
229229

230230
// @todo Do we want HTML tags in our violations or not?
231-
$this->assertStringMatchesFormat(
231+
$this->assertStringContainsString(
232232
'Only files with the following extensions are allowed: <em class="placeholder">odt</em>.',
233233
$violations[0]['message']
234234
);
@@ -256,6 +256,7 @@ public function testLockReleased(): void {
256256
\Drupal::service('renderer'),
257257
\Drupal::service('event_dispatcher'),
258258
\Drupal::service('image.factory'),
259+
\Drupal::service('file.validator'),
259260
);
260261

261262
// Create a Symfony dummy uploaded file in test mode.
@@ -319,7 +320,7 @@ public function testUnsuccessWithMultipleFileUploads(): void {
319320

320321
// There must be violation regarding forbidden file extension.
321322
$violations = $file_upload_response->getViolations();
322-
$this->assertStringMatchesFormat(
323+
$this->assertStringContainsString(
323324
'Only files with the following extensions are allowed: <em class="placeholder">txt</em>.',
324325
$violations[0]['message']
325326
);

tests/src/Kernel/GraphQLTestBase.php

+2
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ abstract class GraphQLTestBase extends KernelTestBase {
5050
'content_translation',
5151
'entity_reference_test',
5252
'field',
53+
'file',
5354
'menu_link_content',
5455
'link',
5556
'typed_data',
@@ -75,6 +76,7 @@ protected function setUp(): void {
7576
$this->installEntitySchema('graphql_server');
7677
$this->installEntitySchema('configurable_language');
7778
$this->installConfig(['language']);
79+
$this->installEntitySchema('file');
7880
$this->installEntitySchema('menu_link_content');
7981

8082
$this->setUpCurrentUser([], $this->userPermissions());

0 commit comments

Comments
 (0)