class FileExampleSubmitHandlerHelper
A submit handler helper class for the file_example module.
Hierarchy
- class \Drupal\file_example\FileExampleSubmitHandlerHelper uses \Drupal\file_example\stringTranslationTrait
Expanded class hierarchy of FileExampleSubmitHandlerHelper
1 file declares its use of FileExampleSubmitHandlerHelper
- FileExampleReadWriteForm.php in modules/
file_example/ src/ Form/ FileExampleReadWriteForm.php
1 string reference to 'FileExampleSubmitHandlerHelper'
- file_example.services.yml in modules/
file_example/ file_example.services.yml - modules/file_example/file_example.services.yml
1 service uses FileExampleSubmitHandlerHelper
File
-
modules/
file_example/ src/ FileExampleSubmitHandlerHelper.php, line 18
Namespace
Drupal\file_exampleView source
class FileExampleSubmitHandlerHelper {
use stringTranslationTrait, DumperTrait;
/**
* Constructs a new FileExampleReadWriteForm page.
*
* @param \Drupal\file_example\FileExampleStateHelper $stateHelper
* The file example state helper.
* @param \Drupal\file_example\FileExampleFileHelper $fileHelper
* The file example file helper.
* @param \Drupal\file_example\FileExampleSessionHelperWrapper $sessionHelperWrapper
* The file example session helper wrapper.
* @param \Drupal\Core\Messenger\MessengerInterface $messenger
* The messenger.
* @param \Drupal\file\FileRepositoryInterface $fileRepository
* The file repository.
* @param \Drupal\Core\File\FileSystemInterface $fileSystem
* The file system.
* @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $eventDispatcher
* The event dispatcher.
*
* @see https://php.watch/versions/8.0/constructor-property-promotion
*/
public function __construct(FileExampleStateHelper $stateHelper, FileExampleFileHelper $fileHelper, FileExampleSessionHelperWrapper $sessionHelperWrapper, MessengerInterface $messenger, FileRepositoryInterface $fileRepository, FileSystemInterface $fileSystem, EventDispatcherInterface $eventDispatcher) {
}
/**
* Submit handler to write a managed file.
*
* A "managed file" is a file that Drupal tracks as a file entity. It's the
* standard way Drupal manages files in file fields and elsewhere.
*
* The key functions used here are:
* - file_save_data(), which takes a buffer and saves it to a named file and
* also creates a tracking record in the database and returns a file object.
* In this function we use FileSystemInterface::EXISTS_RENAME (the default)
* as the argument, which means that if there's an existing file, create a
* new non-colliding filename and use it.
* - file_create_url(), which converts a URI in the form public://junk.txt or
* private://something/test.txt into a URL like
* http://example.com/sites/default/files/junk.txt.
* * @param array $form
* An associative array containing the structure of the form.
*
* @param array &$form
* The form array.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The current state of the form.
*/
public function handleManagedFile(array &$form, FormStateInterface $form_state) {
$form_values = $form_state->getValues();
$data = $form_values['write_contents'];
$uri = !empty($form_values['destination']) ? $form_values['destination'] : NULL;
// Managed operations work with a file object.
$file_object = $this->fileRepository
->writeData($data, $uri, FileSystemInterface::EXISTS_RENAME);
if (!empty($file_object)) {
$url = $this->fileHelper
->getExternalUrl($file_object);
$this->stateHelper
->setDefaultFile($file_object->getFileUri());
$file_data = $file_object->toArray();
if ($url) {
$this->messenger
->addMessage($this->t('Saved managed file: %file to destination %destination (accessible via <a href=":url">this URL</a>, actual uri=<span id="uri">@uri</span>)', [
'%file' => print_r($file_data, TRUE),
'%destination' => $uri,
'@uri' => $file_object->getFileUri(),
':url' => $url->toString(),
]));
}
else {
// This Uri is not routable, so we cannot give a link to it.
$this->messenger
->addMessage($this->t('Saved managed file: %file to destination %destination (no URL, since this stream type does not support it)', [
'%file' => print_r($file_data, TRUE),
'%destination' => $uri,
'@uri' => $file_object->getFileUri(),
]));
}
}
else {
$this->messenger
->addMessage($this->t('Failed to save the managed file'), 'error');
}
}
/**
* Submit handler to write an unmanaged file.
*
* An unmanaged file is a file that Drupal does not track. A standard
* operating system file, in other words.
*
* The key functions used here are:
* - FileSystemInterface::saveData(), which takes a buffer and saves it to a
* named file, but does not create any kind of tracking record in the
* database. This example uses FileSystemInterface::EXISTS_REPLACE for the
* third argument, meaning that if there's an existing file at this
* location, it should be replaced.
* - file_create_url(), which converts a URI in the form public://junk.txt or
* private://something/test.txt into a URL like
* http://example.com/sites/default/files/junk.txt.
* * @param array $form
* An associative array containing the structure of the form.
*
* @param array &$form
* The form array.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The current state of the form.
*/
public function handleUnmanagedFile(array &$form, FormStateInterface $form_state) {
$form_values = $form_state->getValues();
$data = $form_values['write_contents'];
$destination = !empty($form_values['destination']) ? $form_values['destination'] : NULL;
// With the unmanaged file we just get a filename back.
$filename = $this->fileSystem
->saveData($data, $destination, FileSystemInterface::EXISTS_REPLACE);
if ($filename) {
$url = $this->fileHelper
->getExternalUrl($filename);
$this->stateHelper
->setDefaultFile($filename);
if ($url) {
$this->messenger
->addMessage($this->t('Saved file as %filename (accessible via <a href=":url">this URL</a>, uri=<span id="uri">@uri</span>)', [
'%filename' => $filename,
'@uri' => $filename,
':url' => $url->toString(),
]));
}
else {
$this->messenger
->addMessage($this->t('Saved file as %filename (not accessible externally)', [
'%filename' => $filename,
'@uri' => $filename,
]));
}
}
else {
$this->messenger
->addMessage($this->t('Failed to save the file'), 'error');
}
}
/**
* Submit handler to write an unmanaged file using plain PHP functions.
*
* The key functions used here are:
* - FileSystemInterface::saveData(), which takes a buffer and saves it to a
* named file, but does not create any kind of tracking record in the
* database.
* - file_create_url(), which converts a URI in the form public://junk.txt or
* private://something/test.txt into a URL like
* http://example.com/sites/default/files/junk.txt.
* - drupal_tempnam() generates a temporary filename for use.
*
* @param array $form
* An associative array containing the structure of the form.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The current state of the form.
*/
public function handleUnmanagedPhp(array &$form, FormStateInterface $form_state) {
$form_values = $form_state->getValues();
$data = $form_values['write_contents'];
$destination = !empty($form_values['destination']) ? $form_values['destination'] : NULL;
if (empty($destination)) {
// If no destination has been provided, use a generated name.
$destination = $this->fileSystem
->tempnam('public://', 'file');
}
// With all traditional PHP functions we can use the stream wrapper notation
// for a file as well.
$fp = fopen($destination, 'w');
// To demonstrate the fact that everything is based on streams, we'll do
// multiple 5-character writes to put this to the file. We could easily
// (and far more conveniently) write it in a single statement with
// fwrite($fp, $data).
$length = strlen($data);
$write_size = 5;
for ($i = 0; $i < $length; $i += $write_size) {
$result = fwrite($fp, substr($data, $i, $write_size));
if ($result === FALSE) {
$this->messenger
->addMessage($this->t('Failed writing to the file %file', [
'%file' => $destination,
]), 'error');
fclose($fp);
return;
}
}
$url = $this->fileHelper
->getExternalUrl($destination);
$this->stateHelper
->setDefaultFile($destination);
if ($url) {
$this->messenger
->addMessage($this->t('Saved file as %filename (accessible via <a href=":url">this URL</a>, uri=<span id="uri">@uri</span>)', [
'%filename' => $destination,
'@uri' => $destination,
':url' => $url->toString(),
]));
}
else {
$this->messenger
->addMessage($this->t('Saved file as %filename (not accessible externally)', [
'%filename' => $destination,
'@uri' => $destination,
]));
}
}
/**
* Submit handler for reading a stream wrapper.
*
* Drupal now has full support for PHP's stream wrappers, which means that
* instead of the traditional use of all the file functions
* ($fp = fopen("/tmp/some_file.txt");) far more sophisticated and generalized
* (and extensible) things can be opened as if they were files. Drupal itself
* provides the public:// and private:// schemes for handling public and
* private files. PHP provides file:// (the default) and http://, so that a
* URL can be read or written (as in a POST) as if it were a file. In
* addition, new schemes can be provided for custom applications. The Stream
* Wrapper Example, if installed, impleents a custom 'session' scheme that
* you can test with this example.
*
* Here we take the stream wrapper provided in the form. We grab the
* contents with file_get_contents(). Notice that's it's as simple as that:
* file_get_contents("http://example.com") or
* file_get_contents("public://somefile.txt") just works. Although it's
* not necessary, we use FileSystemInterface::saveData() to save this file
* locally and then find a local URL for it by using file_create_url().
*
* @param array $form
* An associative array containing the structure of the form.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The current state of the form.
*/
public function handleFileRead(array &$form, FormStateInterface $form_state) {
$form_values = $form_state->getValues();
$uri = $form_values['fileops_file'];
if (empty($uri) or !is_file($uri)) {
$this->messenger
->addMessage($this->t('The file "%uri" does not exist', [
'%uri' => $uri,
]), 'error');
return;
}
$filename = $this->fileSystem
->basename($uri);
// To ensure that the filename is valid, strip off any potential file
// portion from the stream wrapper. If the filename includes a malicious
// file extension, it will be neutralized by the event subscriber of the
// FileUploadSanitizeNameEvent. This process helps to maintain the security
// of the system and prevent any potential harm from malicious files.
$event = new FileUploadSanitizeNameEvent($filename, 'txt');
$this->eventDispatcher
->dispatch($event);
$dirname = $this->fileSystem
->dirname($uri);
if (str_ends_with($dirname, '/')) {
$filename = $dirname . $event->getFilename();
}
else {
$filename = $dirname . '/' . $event->getFilename();
}
$buffer = file_get_contents($filename);
if ($buffer) {
$sourcename = $this->fileSystem
->saveData($buffer, 'public://' . $event->getFilename());
if ($sourcename) {
$url = $this->fileHelper
->getExternalUrl($sourcename);
$this->stateHelper
->setDefaultFile($sourcename);
if ($url) {
$this->messenger
->addMessage($this->t('The file was read and copied to %filename which is accessible at <a href=":url">this URL</a>', [
'%filename' => $sourcename,
':url' => $url->toString(),
]));
}
else {
$this->messenger
->addMessage($this->t('The file was read and copied to %filename (not accessible externally)', [
'%filename' => $sourcename,
]));
}
}
else {
$this->messenger
->addMessage($this->t('Failed to save the file'));
}
}
else {
// We failed to get the contents of the requested file.
$this->messenger
->addMessage($this->t('Failed to retrieve the file %file', [
'%file' => $uri,
]));
}
}
/**
* Submit handler to delete a file.
*
* @param array $form
* An associative array containing the structure of the form.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The current state of the form.
*/
public function handleFileDelete(array &$form, FormStateInterface $form_state) {
$form_values = $form_state->getValues();
$uri = $form_values['fileops_file'];
// Since we don't know if the file is managed or not, look in the database
// to see. Normally, code would be working with either managed or unmanaged
// files, so this is not a typical situation.
$file_object = $this->fileHelper
->getManagedFile($uri);
// If a managed file, use file_delete().
if (!empty($file_object)) {
// While file_delete should return FALSE on failure,
// it can currently throw an exception on certain cache states.
try {
// This no longer returns a result code. If things go bad,
// it will throw an exception:
$file_object->delete();
$this->messenger
->addMessage($this->t('Successfully deleted managed file %uri', [
'%uri' => $uri,
]));
$this->stateHelper
->setDefaultFile($uri);
} catch (\Exception $e) {
$this->messenger
->addMessage($this->t('Failed deleting managed file %uri. Result was %result', [
'%uri' => $uri,
'%result' => print_r($e->getMessage(), TRUE),
]), 'error');
}
}
else {
$result = $this->fileSystem
->delete($uri);
if ($result !== TRUE) {
$this->messenger
->addError($this->t('Failed deleting unmanaged file %uri', [
'%uri' => $uri,
]));
}
else {
$this->messenger
->addMessage($this->t('Successfully deleted unmanaged file %uri', [
'%uri' => $uri,
]));
$this->stateHelper
->setDefaultFile($uri);
}
}
}
/**
* Submit handler to check existence of a file.
*/
public function handleFileExists(array &$form, FormStateInterface $form_state) {
$form_values = $form_state->getValues();
$uri = $form_values['fileops_file'];
if (is_file($uri)) {
$this->messenger
->addMessage($this->t('The file %uri exists.', [
'%uri' => $uri,
]));
}
else {
$this->messenger
->addMessage($this->t('The file %uri does not exist.', [
'%uri' => $uri,
]));
}
}
/**
* Submit handler for directory creation.
*
* Here we create a directory and set proper permissions on it using
* FileSystemInterface::prepareDirectory().
*/
public function handleDirectoryCreate(array &$form, FormStateInterface $form_state) {
$form_values = $form_state->getValues();
$directory = $form_values['directory_name'];
// The options passed to FileSystemInterface::prepareDirectory() are a
// bitmask, so we can specify
// either FileSystemInterface::MODIFY_PERMISSIONS
// (set permissions on the directory),
// FileSystemInterface::CREATE_DIRECTORY,
// or both together:
// FileSystemInterface::MODIFY_PERMISSIONS |
// FileSystemInterface::CREATE_DIRECTORY.
// FileSystemInterface::MODIFY_PERMISSIONS
// will set the permissions of the directory by default to 0755,
// or to the value of the variable
// 'file_chmod_directory'.
if (!$this->fileSystem
->prepareDirectory($directory, FileSystemInterface::MODIFY_PERMISSIONS | FileSystemInterface::CREATE_DIRECTORY)) {
$this->messenger
->addMessage($this->t('Failed to create %directory.', [
'%directory' => $directory,
]), 'error');
}
else {
$this->messenger
->addMessage($this->t('Directory %directory is ready for use.', [
'%directory' => $directory,
]));
$this->stateHelper
->setDefaultDirectory($directory);
}
}
/**
* Submit handler for directory deletion.
*
* @see \Drupal\Core\File\FileSystemInterface::deleteRecursive()
*/
public function handleDirectoryDelete(array &$form, FormStateInterface $form_state) {
$form_values = $form_state->getValues();
$directory = $form_values['directory_name'];
$result = $this->fileSystem
->deleteRecursive($directory);
if (!$result) {
$this->messenger
->addMessage($this->t('Failed to delete %directory.', [
'%directory' => $directory,
]), 'error');
}
else {
$this->messenger
->addMessage($this->t('Recursively deleted directory %directory.', [
'%directory' => $directory,
]));
$this->stateHelper
->setDefaultDirectory($directory);
}
}
/**
* Submit handler to test directory existence.
*
* This actually just checks to see if the directory is writable.
*
* @param array $form
* FormAPI form.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* FormAPI form state.
*/
public function handleDirectoryExists(array &$form, FormStateInterface $form_state) {
$form_values = $form_state->getValues();
$directory = $form_values['directory_name'];
$result = is_dir($directory);
if (!$result) {
$this->messenger
->addMessage($this->t('Directory %directory does not exist.', [
'%directory' => $directory,
]));
}
else {
$this->messenger
->addMessage($this->t('Directory %directory exists.', [
'%directory' => $directory,
]));
}
}
/**
* Utility submit function to show the contents of $_SESSION.
*/
public function handleShowSession(array &$form, FormStateInterface $form_state) {
$dumper = $this->dumper();
if ($dumper instanceof DevelDumperInterface) {
// If the devel module is installed, use its nicer message format.
$dumper->dump($this->sessionHelperWrapper
->getStoredData(), $this->t('Entire $_SESSION["file_example"]'));
}
else {
$this->messenger
->addMessage(sprintf('<pre>%s</pre>', print_r($this->sessionHelperWrapper
->getStoredData(), TRUE)));
}
}
/**
* Utility submit function to reset the demo.
*
* @param array $form
* FormAPI form.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* FormAPI form state.
*
* @todo Note this does NOT clear any managed file references in Drupal's DB.
* It might be a good idea to add this.
* https://www.drupal.org/project/examples/issues/2985471
*/
public function handleResetSession(array &$form, FormStateInterface $form_state) {
$this->stateHelper
->deleteDefaultState();
$this->sessionHelperWrapper
->clearStoredData();
$this->messenger
->addMessage('Session reset.');
}
}
Members
Title Sort descending | Modifiers | Object type | Summary |
---|---|---|---|
FileExampleSubmitHandlerHelper::handleDirectoryCreate | public | function | Submit handler for directory creation. |
FileExampleSubmitHandlerHelper::handleDirectoryDelete | public | function | Submit handler for directory deletion. |
FileExampleSubmitHandlerHelper::handleDirectoryExists | public | function | Submit handler to test directory existence. |
FileExampleSubmitHandlerHelper::handleFileDelete | public | function | Submit handler to delete a file. |
FileExampleSubmitHandlerHelper::handleFileExists | public | function | Submit handler to check existence of a file. |
FileExampleSubmitHandlerHelper::handleFileRead | public | function | Submit handler for reading a stream wrapper. |
FileExampleSubmitHandlerHelper::handleManagedFile | public | function | Submit handler to write a managed file. |
FileExampleSubmitHandlerHelper::handleResetSession | public | function | Utility submit function to reset the demo. |
FileExampleSubmitHandlerHelper::handleShowSession | public | function | Utility submit function to show the contents of $_SESSION. |
FileExampleSubmitHandlerHelper::handleUnmanagedFile | public | function | Submit handler to write an unmanaged file. |
FileExampleSubmitHandlerHelper::handleUnmanagedPhp | public | function | Submit handler to write an unmanaged file using plain PHP functions. |
FileExampleSubmitHandlerHelper::__construct | public | function | Constructs a new FileExampleReadWriteForm page. |