Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
W
webform_rest
Manage
Activity
Members
Labels
Plan
Wiki
Custom issue tracker
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Model registry
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
project
webform_rest
Merge requests
!9
Issue
#2899902
: Send/Upload files?
Code
Review changes
Check out branch
Download
Patches
Plain diff
Open
Issue
#2899902
: Send/Upload files?
issue/webform_rest-2899902:2899902-sendupload-files
into
4.x
Overview
9
Commits
13
Pipelines
0
Changes
10
8 unresolved threads
Hide all comments
Open
mohamed nabawy
requested to merge
issue/webform_rest-2899902:2899902-sendupload-files
into
4.x
1 year ago
Overview
9
Commits
13
Pipelines
0
Changes
10
8 unresolved threads
Hide all comments
Expand
0
0
Merge request reports
Compare
4.x
version 10
35f8cdec
1 year ago
version 9
2c18cecd
1 year ago
version 8
cca28e0e
1 year ago
version 7
07cf1f10
1 year ago
version 6
d5ca6331
1 year ago
version 5
9ee4456c
1 year ago
version 4
1dca99b7
1 year ago
version 3
846e29f8
1 year ago
version 2
69be8459
1 year ago
version 1
a3811675
1 year ago
4.x (HEAD)
and
latest version
latest version
2f0c5e5d
13 commits,
3 months ago
version 10
35f8cdec
12 commits,
1 year ago
version 9
2c18cecd
11 commits,
1 year ago
version 8
cca28e0e
10 commits,
1 year ago
version 7
07cf1f10
9 commits,
1 year ago
version 6
d5ca6331
7 commits,
1 year ago
version 5
9ee4456c
6 commits,
1 year ago
version 4
1dca99b7
4 commits,
1 year ago
version 3
846e29f8
3 commits,
1 year ago
version 2
69be8459
2 commits,
1 year ago
version 1
a3811675
1 commit,
1 year ago
10 files
+
918
−
0
Inline
Compare changes
Side-by-side
Inline
Show whitespace changes
Show one file at a time
Files
10
Search (e.g. *.vue) (Ctrl+P)
src/Plugin/rest/resource/WebformFileUploadResource.php
0 → 100644
+
222
−
0
Options
<?php
namespace
Drupal\webform_rest\Plugin\rest\resource
;
use
Drupal\Component\Utility\Bytes
;
use
Drupal\Component\Utility\Environment
;
use
Drupal\Core\File\FileSystemInterface
;
use
Drupal\file\Entity\File
;
use
Drupal\file\Plugin\rest\resource\FileUploadResource
;
use
Drupal\rest\ModifiedResourceResponse
;
use
Drupal\webform\Entity\Webform
;
use
Drupal\webform\Entity\WebformSubmission
;
use
Drupal\webform\WebformSubmissionForm
;
use
Symfony\Component\HttpFoundation\Request
;
use
Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException
;
use
Symfony\Component\HttpKernel\Exception\BadRequestHttpException
;
use
Symfony\Component\HttpKernel\Exception\HttpException
;
/**
* Creates a resource for webform file uploads.
*
* @RestResource(
* id = "webform_rest_file_upload",
* label = @Translation("Webform File Upload"),
* serialization_class = "Drupal\file\Entity\File",
* uri_paths = {
* "create" = "/webform_rest/{webform_id}/upload/{field_name}"
* },
* config_dependencies = {
* "module" = {
* "file"
* }
* }
* )
*/
class
WebformFileUploadResource
extends
FileUploadResource
{
/**
* Creates a file from an endpoint.
*
* @param \Symfony\Component\HttpFoundation\Request $request
* The current request.
* @param string $webform_id
* The webform ID.
* @param string $field_name
* The field name.
* @param string $placeholder
* An unused placeholder to maintain compatibility with the parent method.
*
* @return \Drupal\rest\ResourceResponseInterface
* The HTTP response object.
*
* @throws \Symfony\Component\HttpKernel\Exception\HttpException
* Throws HttpException in case of error.
*/
public
function
post
(
Request
$request
,
$webform_id
,
$field_name
,
$placeholder
=
''
)
{
// Check for a valid webform.
$webform
=
Webform
::
load
(
$webform_id
);
if
(
!
$webform
)
{
throw
new
BadRequestHttpException
(
'Invalid webform_id value.'
);
}
// Check if the user has access to the webform.
if
(
!
$webform
->
access
(
'submission_create'
))
{
throw
new
AccessDeniedHttpException
(
'You do not have access to this webform.'
);
}
// Check if the webform is open.
$is_open
=
WebformSubmissionForm
::
isOpen
(
$webform
);
if
(
$is_open
===
TRUE
)
{
$filename
=
$this
->
validateAndParseContentDispositionHeader
(
$request
);
$element
=
$webform
->
getElement
(
$field_name
);
if
(
$element
===
NULL
)
{
throw
new
BadRequestHttpException
(
'Invalid webform field.'
);
}
$webform_submission
=
WebformSubmission
::
create
([
'webform_id'
=>
$webform
->
id
()]);
// Prepare upload location and validators for the element
$element_plugin
=
$this
->
getElementPlugin
(
$element
);
$element_plugin
->
prepare
(
$element
,
$webform_submission
);
$destination
=
$element
[
'#upload_location'
];
// Check the destination file path is writable.
if
(
!
$this
->
fileSystem
->
prepareDirectory
(
$destination
,
FileSystemInterface
::
CREATE_DIRECTORY
))
{
throw
new
HttpException
(
500
,
'Destination file path is not writable'
);
}
$validators
=
$this
->
getElementValidators
(
$element
);
$prepared_filename
=
$this
->
prepareFilename
(
$filename
,
$validators
);
// Create the file.
if
(
substr
(
$destination
,
-
1
)
===
'/'
)
{
$file_uri
=
"
{
$destination
}{
$prepared_filename
}
"
;
}
else
{
$file_uri
=
"
{
$destination
}
/
{
$prepared_filename
}
"
;
}
$temp_file_path
=
$this
->
streamUploadData
();
// This will take care of altering $file_uri if a file already exists.
$file_uri
=
$this
->
fileSystem
->
getDestinationFilename
(
$file_uri
,
FileSystemInterface
::
EXISTS_RENAME
);
// Lock based on the prepared file URI.
$lock_id
=
$this
->
generateLockIdFromFileUri
(
$file_uri
);
if
(
!
$this
->
lock
->
acquire
(
$lock_id
))
{
throw
new
HttpException
(
503
,
sprintf
(
'File "%s" is already locked for writing'
),
NULL
,
[
'Retry-After'
=>
1
]);
}
// Begin building file entity.
$file
=
File
::
create
([]);
$file
->
setOwnerId
(
$this
->
currentUser
->
id
());
$file
->
setFilename
(
$prepared_filename
);
$file
->
setMimeType
(
$this
->
mimeTypeGuesser
->
guessMimeType
(
$prepared_filename
));
// set temp path so any file validation implementers can check the file.
$file
->
setFileUri
(
$temp_file_path
);
// Set the size. This is done in File::preSave() but we validate the file
// before it is saved.
$file
->
setSize
(
@
filesize
(
$temp_file_path
));
// Validate the file entity against entity-level validation and
// field-level validators.
$this
->
validate
(
$file
,
$validators
);
// Move the file to the correct location after validation. Use
// FILE_EXISTS_ERROR as the file location has already been determined
// above in file_unmanaged_prepare().
if
(
!
$this
->
fileSystem
->
move
(
$temp_file_path
,
$file_uri
,
FileSystemInterface
::
EXISTS_ERROR
))
{
throw
new
HttpException
(
500
,
'Temporary file could not be moved to file location'
);
}
// set real path after move.
$file
->
setFileUri
(
$file_uri
);
$file
->
save
();
$this
->
lock
->
release
(
$lock_id
);
// 201 Created responses return the newly created entity in the response
// body. These responses are not cacheable, so we add no cacheability
// metadata here.
return
new
ModifiedResourceResponse
(
$file
,
201
);
}
else
{
throw
new
AccessDeniedHttpException
(
'This webform is closed, or too many submissions have been made.'
);
}
}
/**
* Retrieves the upload validators for an element.
*
* This is copied from \Drupal\file\Plugin\Field\FieldType\FileItem as there
* is no entity instance available here that a FileItem would exist for.
*
* @param array $element
* The element for which to get validators.
*
* @return array
* An array suitable for passing to file_save_upload() or the file field
* element's '#upload_validators' property.
*
* @see \Drupal\file\Plugin\rest\resource\FileUploadResource::getUploadValidators()
*/
protected
function
getElementValidators
(
array
$element
)
{
$validators
=
[
// Add in our check of the file name length.
'file_validate_name_length'
=>
[],
];
// Cap the upload size according to the PHP limit.
if
(
version_compare
(
\Drupal
::
VERSION
,
'9.1'
,
'<'
))
{
$max_filesize
=
Bytes
::
toInt
(
Environment
::
getUploadMaxSize
());
}
else
{
$max_filesize
=
Bytes
::
toNumber
(
Environment
::
getUploadMaxSize
());
}
if
(
!
empty
(
$element
[
"#max_filesize"
]))
{
if
(
version_compare
(
\Drupal
::
VERSION
,
'9.1'
,
'<'
))
{
$max_elem_filesize
=
Bytes
::
toInt
(
$element
[
'#max_filesize'
]
*
1024
*
1024
);
}
else
{
$max_elem_filesize
=
Bytes
::
toNumber
(
$element
[
'#max_filesize'
]
*
1024
*
1024
);
}
$max_filesize
=
min
(
$max_filesize
,
$max_elem_filesize
);
}
// There is always a file size limit due to the PHP server limit.
$validators
[
'file_validate_size'
]
=
[
$max_filesize
];
// Add the extension check if necessary.
if
(
!
empty
(
$element
[
'#file_extensions'
]))
{
$validators
[
'file_validate_extensions'
]
=
[
$element
[
'#file_extensions'
]];
}
return
$validators
;
}
/**
* Loads the webform element plugin for the provided element.
*
* @param array $element
* The element for which to get the plugin.
*
* @return \Drupal\Core\Render\Element\ElementInterface
* The element plugin.
*/
protected
function
getElementPlugin
(
array
$element
)
{
/** @var \Drupal\Core\Render\ElementInfoManager $plugin_manager */
$plugin_manager
=
\Drupal
::
service
(
'plugin.manager.webform.element'
);
$plugin_definition
=
$plugin_manager
->
getDefinition
(
$element
[
'#type'
]);
$element_plugin
=
$plugin_manager
->
createInstance
(
$element
[
'#type'
],
$plugin_definition
);
return
$element_plugin
;
}
}
Loading