I've added custom integration to the "Third party" according to the logic described here: WebformThirdPartySettingsManager and used as example third_party_settings/webform.honeypot.inc,

but I've used in my form "managed_file" form element. When I try to upload a file I get this error:

A fatal error occurred: The database connection is not serializable. This probably means you are serializing an object that has an indirect reference to the database connection. Adjust your code so that is not necessary

Fix exactly will be the same as in http://cgit.drupalcode.org/yamlform/commit/?id=d42d0e0
But what we should do with public function afterBuild, should it be refactored to the static, and also in the interface too? How we deal then with $this->t() -> t() ?

For now I've added workaround to my code:

function _webform_file_download_form() {
...
  if (isset($form['#after_build'][0][0]) && $form['#after_build'][0][0] instanceof WebformThirdPartySettingsManager) {
    unset($form['#after_build'][0]);
  }
}

Thanks for the great module!

Comments

vlad.dancer created an issue. See original summary.

vlad.dancer’s picture

Issue summary: View changes
jrockowitz’s picture

@vlad.dancer We would need an example of the issue so that we can work on fixing it.

vlad.dancer’s picture

Sure.

# ./file_download/config/schema/file_download.webform.schema.yml
webform.settings.third_party.file_download:
  type: mapping
  label: 'Webform file_download third party settings'
  mapping:
    file_download:
      type: boolean
      label: 'Enable file download'
    file:
      type: integer
      label: 'File ID'
// ./webform/file_download.webform.inc
function _webform_file_download_form(array &$form, FormStateInterface $form_state, $enabled, $file_id, $label) {
  $form['third_party_settings']['file_download'] = [
    '#type' => 'details',
    '#title' => t('File Download'),
    '#open' => TRUE,
    '#description' => t("Allow users to download file right after submission"),
  ];
  $form['third_party_settings']['file_download']['file_download'] = [
    '#type' => 'checkbox',
    '#title' => t('Enable file download'),
    '#default_value' => $enabled,
    '#return_value' => TRUE,
  ];

  $webform = $form_state->getFormObject()->getEntity();

  $form['third_party_settings']['file_download']['file'] = [
    '#type' => 'managed_file',
    '#title' => 'Upload downloadable file',
    '#upload_location' => _webform_file_download_location($webform->id()),
    '#description' => 'This file user only see after success submission, only user that did a submission will download this file',
  ];

  if (!empty($file_id) && $file = File::load($file_id)) {
    $form['third_party_settings']['file_download']['file']['#default_value'] = [$file->id()];
  }

  $form['#validate'][] = '_webform_file_download_form_validate';

  // Workaround for https://www.drupal.org/node/2782989.
  if (isset($form['#after_build'][0][0]) && $form['#after_build'][0][0] instanceof WebformThirdPartySettingsManager) {
    unset($form['#after_build'][0]);
  }
}

function _webform_file_download_location($webform_id) {
  $upload_location = 'private://file_download/' . $webform_id;

  // Make sure the upload location exists and is writable.
  file_prepare_directory($upload_location, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS);
  return $upload_location;
}

function _webform_file_download_form_validate(&$form, FormStateInterface $form_state) {
  $third_party_settings = $form_state->getValue('third_party_settings');

  if (!empty($third_party_settings['file_download']['file'][0])) {
    $file =& $third_party_settings['file_download']['file'];
    $file = $file[0];

    $form_state->setValue('third_party_settings', $third_party_settings);
  }

  $webform = $form_state->getFormObject()->getEntity();

  if (!empty($file) && $loaded = File::load($file)) {
    $file_usage = \Drupal::service('file.usage');
    $file_usage->delete($loaded, 'webform', 'file_download', $webform->id(), 0);
    $file_usage->add($loaded, 'webform', 'file_download', $webform->id());
  }
}

/**
 * Implements hook_form_FORM_ID_alter().
 */
function file_download_form_webform_third_party_settings_form_alter(&$form, FormStateInterface $form_state) {
  /** @var \Drupal\webform\WebformInterface $webform */
  $webform = $form_state->getFormObject()->getEntity();

  $enabled = $webform->getThirdPartySetting('file_download', 'file_download');
  $settings = $webform->getThirdPartySettings('file_download');

  _webform_file_download_form(
    $form,
    $form_state,
    $enabled,
    $settings['file'],
    t('@label webform', ['@label' => $webform->label()])
  );
}


frogdog_tech’s picture

Title: Can't add trird_party integration when there is managed_file on the page » Can't add third_party integration when there is managed_file on the page

update title

jrockowitz’s picture

@vlad.dancer I can't determine where #after_build is being set from.

I did just tweak third party settings. @see #2875841: Hide third party tab (at least optionally).

vlad.dancer’s picture

@jrockowitz

WebformThirdPartySettingsManager->buildForm()

> I did just tweak third party settings
I hope I will not rector my code...

jrockowitz’s picture

Status: Active » Needs review

The latest dev release no longer has the WebformThirdPartySettingsManager::buildForm method because of #2875841: Hide third party tab (at least optionally).

Switch to the latest dev release or just applying the patch might solve your problems.

jrockowitz’s picture

BTW, there was a minor API change in #2875841: Hide third party tab (at least optionally).

You will need to change file_download_form_webform_third_party_settings_form_alter() to file_download_webform_third_party_settings_form_alter()

vlad.dancer’s picture

Status: Needs review » Closed (outdated)

Thanks for example. I'm going to close this issue.