class UploadController in Plupload integration 8
Same name and namespace in other branches
- 2.0.x src/UploadController.php \Drupal\plupload\UploadController
Plupload upload handling route.
Hierarchy
- class \Drupal\plupload\UploadController implements ContainerInjectionInterface
Expanded class hierarchy of UploadController
File
- src/
UploadController.php, line 15
Namespace
Drupal\pluploadView source
class UploadController implements ContainerInjectionInterface {
/**
* The current request.
*
* @var \Symfony\Component\HttpFoundation\Request
* The HTTP request object.
*/
protected $request;
/**
* Stores temporary folder URI.
*
* This is configurable via the configuration variable. It was added for HA
* environments where temporary location may need to be a shared across all
* servers.
*
* @var string
*/
protected $temporaryUploadLocation;
/**
* Filename of a file that is being uploaded.
*
* @var string
*/
protected $filename;
/**
* HTAccess writer service.
*
* @var object
*/
protected $htaccessWriter;
/**
* File System service.
*
* @var object
*/
protected $fileSystem;
/**
* Constructs plupload upload controller route controller.
*
* @param \Symfony\Component\HttpFoundation\Request $request
* Request object.
*/
public function __construct(Request $request) {
$this->request = $request;
$this->temporaryUploadLocation = \Drupal::config('plupload.settings')
->get('temporary_uri');
$this->htaccessWriter = \Drupal::service('file.htaccess_writer');
$this->fileSystem = \Drupal::service('file_system');
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static($container
->get('request_stack')
->getCurrentRequest());
}
/**
* Handles Plupload uploads.
*/
public function handleUploads() {
// @todo: Implement file_validate_size();
try {
$this
->prepareTemporaryUploadDestination();
$this
->handleUpload();
} catch (UploadException $e) {
return $e
->getErrorResponse();
}
// Return JSON-RPC response.
return new JsonResponse([
'jsonrpc' => '2.0',
'result' => NULL,
'id' => 'id',
], 200);
}
/**
* Prepares temporary destination folder for uploaded files.
*
* @throws \Drupal\plupload\UploadException
*/
protected function prepareTemporaryUploadDestination() {
$writable = $this->fileSystem
->prepareDirectory($this->temporaryUploadLocation, FileSystemInterface::CREATE_DIRECTORY);
if (!$writable) {
throw new UploadException(UploadException::DESTINATION_FOLDER_ERROR);
}
// Try to make sure this is private via htaccess.
$this->htaccessWriter
->write($this->temporaryUploadLocation, TRUE);
}
/**
* Reads, checks and return filename of a file being uploaded.
*
* @throws \Drupal\plupload\UploadException
*/
protected function getFilename() {
if (empty($this->filename)) {
try {
// @todo this should probably bo OO.
$this->filename = _plupload_fix_temporary_filename($this->request->request
->get('name'));
} catch (InvalidArgumentException $e) {
throw new UploadException(UploadException::FILENAME_ERROR);
}
// Check the file name for security reasons; it must contain letters,
// numbers and underscores followed by a (single) ".tmp" extension.
// Since this check is more stringent than the one performed in
// plupload_element_value(), we do not need to run the checks performed
// in that function here. This is fortunate, because it would be
// difficult for us to get the correct list of allowed extensions
// to pass in to file_munge_filename() from this point in the code
// (outside the form API).
if (!preg_match('/^\\w+\\.tmp$/', $this->filename)) {
throw new UploadException(UploadException::FILENAME_ERROR);
}
}
return $this->filename;
}
/**
* Handles multipart uploads.
*
* @throws \Drupal\plupload\UploadException
*/
protected function handleUpload() {
/* @var $multipart_file \Symfony\Component\HttpFoundation\File\UploadedFile */
$is_multipart = strpos($this->request->headers
->get('Content-Type'), 'multipart') !== FALSE;
// If this is a multipart upload there needs to be a file on the server.
if ($is_multipart) {
$multipart_file = $this->request->files
->get('file', []);
// TODO: Not sure if this is the best check now.
// Originally it was:
// if (empty($multipart_file['tmp_name']) ||
// !is_uploaded_file($multipart_file['tmp_name'])) {.
if (!$multipart_file
->getPathname() || !is_uploaded_file($multipart_file
->getPathname())) {
throw new UploadException(UploadException::MOVE_ERROR);
}
}
// Open temp file.
if (!($out = fopen($this->temporaryUploadLocation . $this
->getFilename(), $this->request->request
->get('chunk', 0) ? 'ab' : 'wb'))) {
throw new UploadException(UploadException::OUTPUT_ERROR);
}
// Read binary input stream.
$input_uri = $is_multipart ? $multipart_file
->getRealPath() : 'php://input';
if (!($in = fopen($input_uri, 'rb'))) {
throw new UploadException(UploadException::INPUT_ERROR);
}
// Append input stream to temp file.
while ($buff = fread($in, 4096)) {
fwrite($out, $buff);
}
// Be nice and keep everything nice and clean.
fclose($in);
fclose($out);
if ($is_multipart) {
$this->fileSystem
->unlink($multipart_file
->getRealPath());
}
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
UploadController:: |
protected | property | Filename of a file that is being uploaded. | |
UploadController:: |
protected | property | File System service. | |
UploadController:: |
protected | property | HTAccess writer service. | |
UploadController:: |
protected | property | The current request. | |
UploadController:: |
protected | property | Stores temporary folder URI. | |
UploadController:: |
public static | function |
Instantiates a new instance of this class. Overrides ContainerInjectionInterface:: |
|
UploadController:: |
protected | function | Reads, checks and return filename of a file being uploaded. | |
UploadController:: |
protected | function | Handles multipart uploads. | |
UploadController:: |
public | function | Handles Plupload uploads. | |
UploadController:: |
protected | function | Prepares temporary destination folder for uploaded files. | |
UploadController:: |
public | function | Constructs plupload upload controller route controller. |