Skip to content

Instantly share code, notes, and snippets.

@jorislucius
Last active September 1, 2020 13:10
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jorislucius/f8f8b96fd60a63a7a65524f8651d4ed3 to your computer and use it in GitHub Desktop.
Save jorislucius/f8f8b96fd60a63a7a65524f8651d4ed3 to your computer and use it in GitHub Desktop.
Multiple files upload in a custom Drupal form programmatically | Native, clean example Drupal code | Also see https://www.lucius.digital/en/blog/multiple-files-upload-custom-drupal-form-programmatically-native-clean-example-drupal-code
<?php
namespace Drupal\ol_messages\Form;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Component\Utility\Html;
use Drupal\Component\Utility\Xss;
use Drupal\file\Entity\File;
use Drupal\ol_file\Entity\OlFile;
use Drupal\ol_main\Services\OlFiles;
use Drupal\ol_members\Services\OlMembers;
use Drupal\ol_messages\Services\OlMessages;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Class MessageForm.
*/
class MessageForm extends FormBase {
/**
* @var $messages
*/
protected $messages;
/**
* @var $files
*/
protected $files;
/**
* @var $members
*/
protected $members;
/**
* Class constructor.
*/
public function __construct(OlMessages $messages, OlFiles $files, OlMembers $members) {
$this->messages = $messages;
$this->files = $files;
$this->members = $members;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('olmessages.messages'),
$container->get('olmain.files'),
$container->get('olmembers.members')
);
}
/**
* {@inheritdoc}
*/
public function getFormId() {
return 'message_form';
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state, $op = null, $id = null) {
// Defaults.
$name = '';
$body = '';
$button_text = t('Submit');
$hdd_file_location = $this->buildFileLocaton('message');
// Handle edit vars.
if ($op == 'edit'){
$message_data = $this->getMessageData($id);
$name = $message_data->name;
$body = $message_data->body;
$button_text = t('Update Message');
}
// Build form.
$form['message_id'] = [
'#type' => 'hidden',
'#default_value' => $id,
'#weight' => '0',
];
$form['name'] = [
'#type' => 'textfield',
'#weight' => '10',
'#default_value' => $name,
'#required' => true,
'#attributes' => array('placeholder' => t('Add a title...'), 'maxlength' => '150'),
];
$form['body'] = [
'#type' => 'text_format',
'#format' => 'ol_rich_text',
'#weight' => '20',
'#default_value' => $body,
'#required' => true,
];
$form['files'] = array(
'#title' => t('Attach files'),
'#type' => 'managed_file',
'#required' => FALSE,
'#upload_location' => 'private://'.$hdd_file_location,
'#multiple' => TRUE,
'#upload_validators' => array(
'file_validate_extensions' => $this->getAllowedFileExtensions(),
),
'#weight' => '30',
);
$form['submit'] = [
'#type' => 'submit',
'#weight' => '100',
'#attributes' => array('class' => array('btn btn-success')),
'#value' => $button_text,
];
return $form;
}
/**
* {@inheritdoc}
*/
public function validateForm(array &$form, FormStateInterface $form_state) {
if (strlen($form_state->getValue('name')) > 128) {
// Set an error for the form element with a key of "name".
$form_state->setErrorByName('name', $this->t('Message not saved yet: title can\'t be more than 128 characters.'));
}
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
// Get data.
$id = Html::escape($form_state->getValue('message_id'));
$name = Xss::filter($form_state->getValue('name'));
$body = $form_state->getValue('body')['value'];
$body = check_markup($body,'ol_rich_text');
$files = $form_state->getValue('files');
// Existing, update message.
if(is_numeric($id)){
$this->messages->updateMessage($id, $name, $body);
}
// New, save message.
elseif(empty($id)){
$id = $this->messages->saveMessage($name, $body);
}
if(!empty($files)) {
$this->saveFiles($files, $id);
}
}
/**
* @param $files
* @param $entity_id
* @throws \Drupal\Core\Entity\EntityStorageException
*/
private function saveFiles($files, $entity_id){
// Needed for end-user message.
$filenames = array();
// Loop through uploaded files.
foreach ($files as $fid) {
$file = File::load($fid);
$file->setPermanent();
$file->save();
$name = $file->getFilename();
$filenames [] = $name;
// Create ol_file entity
$ol_file = OlFile::create([
'name' => $name,
'file_id' => $fid,
'entity_id' => $entity_id,
]);
$ol_file->save();
}
// Build message for end-user.
// Count uploaded files.
$files_count = count($filenames);
// If there is 1 file uploaded.
$filename = ($files_count == 1) ? $filenames[0] : '';
// If there are multiple files uploaded
$filenames_imploded = ($files_count > 1) ? implode(', ', $filenames) : '';
// Build message, based on file count.
if ($filename){
$message = t('One file uploaded successfully: ') .$filename;
} elseif ($filenames_imploded) {
$message = t('@files_count files uploaded successfully: ',
array('@files_count' => $files_count)) .$filenames_imploded;
}
// Add message.
\Drupal::messenger()->addMessage($message);
}
/**
* @param $id
* @return mixed
*/
private function getMessageData($id){
$query = \Drupal::database()->select('ol_message', 'mess');
$query->addField('mess', 'body');
$query->addField('mess', 'name');
$query->condition('mess.id', $id);
return $query->execute()->fetchObject();
}
/**
* @param $entity_type
* @return string
*/
public function buildFileLocaton($entity_type){
// Build file location
return $entity_type.'/'.date('Y_W');
}
/**
* @return array
*/
private function getAllowedFileExtensions(){
return array('jpg jpeg gif png txt doc docx zip xls xlsx pdf ppt pps odt ods odp');
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment