# Question
Title: Does removing fields also removes submitted values?
I just removed each fields of a form in order to update them. Sadly, I'm afraid it also removes all the associated values submitted, because when I navigate to the 'Result' tab, values are missing.

Is there any way to recover this?
How could I fetch the whole submissions despite the fact that some fields does not exists anymore?

EDIT: I've root access to the MySQL database (currently searching inside it)

Some unsuccessful attempts:

```
-- Enable to fetch submitted data associated to a submission identified by its node id

SELECT * FROM webform_submissions
JOIN webform_submissions.nid = webform_submitted_data.nid
WHERE webform_submissions.nid = 42;

> Empty set (0.00 sec)

```

```
-- Verify that node id actually exists: it does

SELECT * FROM webform_submissions WHERE nid = 42 LIMIT 1;

> +------+--------+-------+----------+------------+---------------+
> | sid  | nid    | uid   | is_draft | submitted  | remote_addr   |
> +------+--------+-------+----------+------------+---------------+
> | 2538 | 42     | 26261 |        0 | 1613557280 | IP.ADD.RE.SS  |
> +------+--------+-------+----------+------------+---------------+

```

```
-- Verify that some submitted data related to this node id are present

SELECT * FROM webform_submitted_data
WHERE nid = 42;

> Empty set (0.00 sec)
-- Has it been deleted ?

```

Assumption: it has been deleted and I'm in a bad trouble !

# Answer
As webform elements are deleted, all related submission data is deleted.
> 0 votes

---
Tags: webforms
---


# Question
Title: How can I conditionally create a user account based on field in registration?
Here is the scenario: Prospective employees (PE) who need to access this Drupal site for onboarding resources will be sent an access code from someone in HR (to prevent random people from creating accounts).

The PE goes to Drupal site and "registers" for a user account and they enter the access code into a field.

Only approve the account if the access code is correct. If it is correct, approve account and set role to prospect. If it is not correct, block account (until that user registers with correct access code or alternately, someone in HR manually approves it).

What should the account settings be for who can register account? How to test access value and approve/grant role or block based on registration field? Is there a hook or class to extend?

# Answer
> 1 votes
1. Create a new field on the user object, `field_registration_code`.
2. Set the form field to show on the registration page.
3. Use hook\_form\_alter() to hide the field when not registering, if the code is not to be used in the future. Don't hide the form field on the 'manage form' tab, else it will not be rendered on the registration page.
4. Create a service with the following method:

```
/**
 * Validates a registration code.
 *
 * This function checks if the submitted  code is a valid
 * registration code, and if it is, invalidates the code, and
 * returns TRUE. If the access code is invalid, it returns FALSE.
 *
 * @param string $registrationCode
 *   The code to be validate.
 *
 * @return bool
 *   TRUE if the code was valid, FALSE otherwise.
 */
 public function validateRegistrationCode(string $registrationCode): bool;

```
5. Implement hook\_ENTITY\_TYPE\_insert(), implemented as hook\_user\_insert(). This is called after the user entity has been saved. You can use that hook to check if the given code is validated, and if not, block the account. It can then be activated by an admin through the admin interface.

```
function HOOK_user_insert(EntityInterface $user) {
  if ($this->myService->validateRegistrationCode($entity->field_registration_code->value)) {
    // Add roles to user here.
  }
  else {
    $user->block()->save();
  }
}

```

---
Tags: users
---


# Question
Title: How to do file downloading in a controller function?
I asked the question about downloading of files upon submitting a form.

Now I want to clarify how to do it in the case of controller function. That is, some controller is called and its function is being executed.

In the form submit function file downloading starts upon executing the `$form_state->setResponse($response);`

How to start it in the controller function ?

I tried to use `$response->send();` but it sends a file with wrong data and another size.

# Answer
> 15 votes
Never send the response with `$response->send()`. Instead return the response:

```
use Symfony\Component\HttpFoundation\Response;

public function myController() {
    $response = new Response();
    // prepare $response
    return $response;
  }

```

BTW, this is a standard Symfony Controller. The fact that you also can return the main content in a render array is because Drupal has added an event subscriber, which converts the main content to a response with the themed html page.

---

This works for all responses, in your case for example for a binary file response:

*Drupal\system\FileDownloadController::download():*

```
  public function download(Request $request, $scheme = 'private') {
    $target = $request->query->get('file');
    // Merge remaining path arguments into relative file path.
    $uri = $scheme . '://' . $target;

    if (file_stream_wrapper_valid_scheme($scheme) && file_exists($uri)) {
      // Let other modules provide headers and controls access to the file.
      $headers = $this->moduleHandler()->invokeAll('file_download', [$uri]);

      foreach ($headers as $result) {
        if ($result == -1) {
          throw new AccessDeniedHttpException();
        }
      }

      if (count($headers)) {
        // \Drupal\Core\EventSubscriber\FinishResponseSubscriber::onRespond()
        // sets response as not cacheable if the Cache-Control header is not
        // already modified. We pass in FALSE for non-private schemes for the
        // $public parameter to make sure we don't change the headers.
        return new BinaryFileResponse($uri, 200, $headers, $scheme !== 'private');
      }

      throw new AccessDeniedHttpException();
    }

    throw new NotFoundHttpException();
  }

```

# Answer
> 10 votes
My way in Drupal 8 controller;

```
use Symfony\Component\HttpFoundation\BinaryFileResponse;

$uri = 'public://' . $fileName;

$headers = array(
        'Content-Type'     => 'application/pdf',
        'Content-Disposition' => 'attachment;filename="'.$fileName.'"');

return new BinaryFileResponse($uri, 200, $headers, true);

```

# Answer
> 2 votes
Piggybacking on Tien Wang's answer, here is an example using a file entity:

```
$headers = array(
  'Content-Type' => $file->getMimeType(),
  'Content-Disposition' => 'attachment;filename="'.$file->getFilename().'"',
  'Content-Length' => $file->getSize(),
  'Content-Description' => ' File Transfer'
);

return new BinaryFileResponse($file->getFileUri(), 200, $headers, true);

```

---
Tags: 8, files
---


title: Can we alter a form using view data?

text:
# Question
Title: Can we alter a form using view data?
I is possible to:

1. Hook on `views_pre_view` (which is executed before `form_alter`)
2. Query `view data` (execute the view query filtering according to URL parameters) and collect some data
3. Hook on `form_alter`
4. Replace some selects using data collected on item 2?

I'm asking because if I `$view->execute()` inside `views_pre_view` (to filter and use view data) it will internally call `form_alter` and generate the form before I'm able to collect the data to pre-populate my selects. And I'm not sure if it's possible to re-generate a form that was already generated.

I also tried `views_pre_execute` but this one is always executed after `form_alter`.

Cheers!

# Answer
> 0 votes
The only way I found for now was to, inside `views_pre_view`, deep clone the `$view` object using `$view = unserialize(serialize($_view))`, so when Drupal passes again on `form_alter` the form would be untouched and I can just recreate some selects.

---
Tags: views, forms, hooks
---


# Question
Title: Unable to install Pathauto, pathauto.settings already exists in active configuration
After upgrade from 8.7.10 to 8.9.13, i updated the pathauto module from ftp and trying to install from drupal admin but it showing an error like "Unable to install Pathauto, pathauto.settings already exists in active configuration."

Based on the post https://www.drupal.org/forum/support/post-installation/2016-01-29/already-exists-in-active-configuration-issue i deleted the pathauto.settings row from config table and cleared the cache and trying to install the module , but still showing the same error. Please help me.

Thanks in advance.

# Answer
**Before trying to do whatever I suggest below first of all have a full backup of the site.**

It seems pathauto module is not uninstalled properly.

To solve your problem you can just delete the `pathauto.settings` from config using drush.

Use the below command to delete the conflicting config.

`drush cdel pathauto.settings`

It will delete the existing pathauto configuration.Then you can install the pathauto module.

You should consider using composer for the module management.
> 1 votes

# Answer
You can use the following Drush command.

```
drush ev "\Drupal::service('config.manager')->uninstall('module', 'pathauto');"

```

After running it, you should be able to re-install the module.
> -1 votes

---
Tags: 8, upgrading
---


# Question
Title: How to get block id on block add & edit form?
Blocks are plugin in Drupal-8, I need to add a form element in the block add form & all the block edit forms. I am able to add the new form element in the form by form alter. But i need to get the block id on submit(custom submit handler). For block add forms block id has to be new block created & for block edit form, the existing block id.

How can i get the block id?

# Answer
Have a lookt at Extend Block Class and my answer there about the block\_class module.

It does exactly the same to add configurable CSS classes to blocks.
> 0 votes

# Answer
Place this cistom block(php code) to seven theme under Breadcrumbs for page /admin/structure/block/manage/\*

```
<?php
/**
* Cistom admin block for get number block numberID on edit entity.block.edit_form
*/
if( \Drupal::routeMatch()->getRouteName() == 'entity.block.edit_form' ) {
    $blockMachineName = \Drupal::token()->replace('[current-page:url:args:last]');
    $blockLoad = \Drupal\block\Entity\Block::load($blockMachineName); //dump($blockLoad);
    if($blockLoad) { //dump($blockLoad->get('id'));
        $blockIdStr = str_ireplace('block_content:', '', $blockLoad->get('settings')['id']); //print "blockIdStr: {$blockIdStr}";
        $query = \Drupal::database()->select('block_content', 'bc')->fields('bc', ['id'])->condition('bc.uuid', $blockIdStr);
        $blockIdNum = $result = $query->execute()->fetchField(); //print " blockIdNum: {$blockIdNum}"; //drupal_set_message("id: {$blockIdNum}");
        print "<b>BlockIDs</b> Str: {$blockIdStr} Num: {$blockIdNum}";
    }
}
?>

```
> 0 votes

---
Tags: 8, blocks
---


# Question
Title: Webform template suggestion doesn't work
Is there a way to suggest a template in webform 3.x?

I have tried this:

```
$vars['theme_hook_suggestions'][] = 'webform__form__mywebform';

```

But it does not work.

# Answer
1. Apply the latest patch from here: https://www.drupal.org/node/1891220
2. In your theme's template.php, in `YOURTHEME_preprocess_webform_form()`, add:

`$path_parts = explode('/', drupal_get_path_alias());`

`$path = implode('__', str_replace(array('-', ' ', '+', '.'), '_', $path_parts));`

`$hook = $vars['theme_hook_original'];`

`$vars['theme_hook_suggestions'][] = "{$hook}__{$path}";`
> 1 votes

# Answer
To override the template of webform you just need to name it like :

```
webform-form-[nid].tpl.php

```

No need to write the code for this.
> 0 votes

# Answer
The reason is this part in webform\_theme() function:

```
'webform_form' => array(
      'render element' => 'form',
      'template' => 'templates/webform-form',
      'pattern' => 'webform_form_[0-9]+',
    ),

```

It will ignore any suggestions if they do not match the pattern. So looks like only webform-form-\[nid\].tpl.php are working...

What I did (I needed only one special template for some specific webforms), I made a custom numeric suggestion with leading zero (just to be sure it's not NID).

In hook\_preprocess\_webform\_form:

```
if ($my_custom_conditions) {
 $vars['theme_hook_suggestions'][] = 'webform_form_01';
}

```

Drupal does not ignore webform-from-01.tpl.php since it matches the pattern and it won't conflict with other webforms, because of leading zero.

Hope it saves anyone's time :)
> 0 votes

---
Tags: 7, webforms, theming
---


# Question
Title: Permanent Deleting of files still doesn't work for me (make_unused_managed_files_temporary = true)
`make_unused_managed_files_temporary` didn't work for me.

I am using Drupal backend for the REST API frontend application.

Thats how the File input looks (because I am not sure if that setting is for that File elements, but guess so).

I read some informations about permanent files deleting, because I would like to delete files permanent from the file system and also database.

I was set the `make_unused_managed_files_temporary` to `true` and debuging, this is really true in the code.

I also found the configuration in `Backend / File system` \- Delete temporary files after (6 hours), so this is on.

I am checking also the database `file_managed` before and after (and after 6 hours) file deletion for the flags like `status` that indicates `isTemporary()` method. But after uploading file, saving... then editing, and removing file, the file is still in the database as a status 1.

I am also checking DB table `file_usage` where there is still the item with `count=1` too, that should be not true (because of deletion).

And files maybe should move to /tmp folder, but that doesnt. I am working on Drupal 8.5.6 and 8.7.2 on production, but the behaviour is the same. I am doing something wrong? Is there some cron to be configured? Or another futher settings?

Edit 1: I think it is not a Media, but simply file widget - `/core/module/file`

Edit 2: The main problem is that, when I delete file, it stay in the database as a permanent flag (`status=1`), and also it has a count of usage 1 (`file_usage=1`). When I manually update database to set `status=0` and `count=0`, the cron works OK. Why the file usage and count stay on?

# Answer
> -2 votes
I just made a solution that works for me even the Drupal or config doesn't works properly. In my plugin I hooked up the `hook_cron()` for logging these unused files to proceed them next.

* SQL SELECT; query to fetch all `file_managed` `fid`'s. You can select only `status=1`, as permanent files, but I got all,
* PHP loop all id's and making a `Drupal\file\FileInterface` entity reference `$file = File::load($item->fid)` to check all the file references `$references = file_get_file_references($file)`. When the `$references` is `empty()` this file is unused. Save all that `fid` id's into array `$fids`,
* SQL UPDATE; build update query to null these rows: `UPDATE file_managed SET status=0 WHERE fid IN($fids)` and `UPDATE file_usage SET count=0 WHERE fid IN ($fids)`.

Finaly after next cron run the default `function file_cron() {...` will properly delete these files.

---
Tags: 8, files
---


# Question
Title: Phone international error in submit form
I installed the module (international phone) on drupal 8.6 and I display it on my form. when sending data it gives me an error message and blocks sending data.

The website encountered an unexpected error. Please try again later. Error: Class 'libphonenumber\PhoneNumberUtil' not found in Drupal\phone\_international\Helpers\ValidatingService-\>isValidNumber() (line 24 of modules/phone\_international/src/Helpers/ValidatingService.php). Drupal\phone\_international\Helpers\ValidatingService-\>isValidNumber('+212670998765') (Line: 74) Drupal\phone\_international\Plugin\Field\FieldWidget\PhoneInternationalDefaultWidget-\>phoneValidate(Array, Object, Array) call\_user\_func\_array(Array, Array) (Line: 282) Drupal\Core\Form\FormValidator-\>doValidateForm(Array, Object) (Line: 238) Drupal\Core\Form\FormValidator-\>doValidateForm(Array, Object) (Line: 238) Drupal\Core\Form\FormValidator-\>doValidateForm(Array, Object) (Line: 238) Drupal\Core\Form\FormValidator-\>doValidateForm(Array, Object) (Line: 238) Drupal\Core\Form\FormValidator-\>doValidateForm(Array, Object, 'node\_candidat\_edit\_form') (Line: 118) Drupal\Core\Form\FormValidator-\>validateForm('node\_candidat\_edit\_form', Array, Object) (Line: 575) Drupal\Core\Form\FormBuilder-\>processForm('node\_candidat\_edit\_form', Array, Object) (Line: 318) Drupal\Core\Form\FormBuilder-\>buildForm('node\_candidat\_edit\_form', Object) (Line: 93) Drupal\Core\Controller\FormController-\>getContentResult(Object, Object) call\_user\_func\_array(Array, Array) (Line: 123) Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber-\>Drupal\Core\EventSubscriber{closure}() (Line: 582) Drupal\Core\Render\Renderer-\>executeInRenderContext(Object, Object) (Line: 124) Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber-\>wrapControllerExecutionInRenderContext(Array, Array) (Line: 97) Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber-\>Drupal\Core\EventSubscriber{closure}() (Line: 151) Symfony\Component\HttpKernel\HttpKernel-\>handleRaw(Object, 1) (Line: 68) Symfony\Component\HttpKernel\HttpKernel-\>handle(Object, 1, 1) (Line: 57) Drupal\Core\StackMiddleware\Session-\>handle(Object, 1, 1) (Line: 47) Drupal\Core\StackMiddleware\KernelPreHandle-\>handle(Object, 1, 1) (Line: 99) Drupal\page\_cache\StackMiddleware\PageCache-\>pass(Object, 1, 1) (Line: 78) Drupal\page\_cache\StackMiddleware\PageCache-\>handle(Object, 1, 1) (Line: 47) Drupal\Core\StackMiddleware\ReverseProxyMiddleware-\>handle(Object, 1, 1) (Line: 52) Drupal\Core\StackMiddleware\NegotiationMiddleware-\>handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel-\>handle(Object, 1, 1) (Line: 693) Drupal\Core\DrupalKernel-\>handle(Object) (Line: 19)

# Answer
The error suggests that you haven't followed the installation instructions on the module page:

> Since the module requires an external library, Composer must be used.
>
> ```
> composer require "drupal/phone_international"
>
> ```
> 2 votes

---
Tags: webforms
---


# Question
Title: How to do a Library Override in my theme for dialog.ajax.js
I’m trying to do a libraries-override to the dialog.ajax.js file appearing in /core/misc/dialog/. (Want to replace it with a js file from my theme, let's say at mytheme/js/dialog.ajax.js)

In my theme’s \*info.yml file, I tried

```
libraries-override:
  drupal.dialog.ajax:
    js:
      assets/js/dialog.ajax.js: false

```

as another post suggested (just to try and disable it). Didn't work.

My confusion comes from not knowing how to correctly target the /core/misc/dialog/dialog.ajax.js file within my override, and then correctly target my mytheme/js/dialog.ajax.js as a replacement.

I reviewed the documentation, but it's still quite unclear. Any tips? Thanks!

# Answer
Looks like you're just missing the `core/` prefix:

```
libraries-override:
  core/drupal.dialog.ajax:
    js:
      assets/js/dialog.ajax.js: false

```
> 1 votes

---
Tags: 8
---


# Question
Title: Are Drush vbo-execute actions supported?
I've been trying to find an efficient back-end way to delete large numbers of nodes based on some filter criteria to implement data retention policies. I have read that it's possible to perform actions provided by views bulk operations on results from a view via drush - such as in the answer in the screenshot below (in response to this question).

This seems like a very powerful concept because you can use the selection power of views and do operations on large amounts of data from the server side. I tried to do this on my Drupal 9 site. One discrepancy I noticed is that when I go to add the VBO field, I do not have an option for "Bulk Operations: Content" like is suggested in the above screenshot, rather only the one from the "Global" Category:

I tried using that field anyway, and selected the "Delete selected entities/translations" option and saved the view.

When I try to execute the action from the view using the drush command
`drush vbo-execute my_view_id action::views_bulk_operations_delete_item`

I get the following error:

```
In ViewsBulkOperationsActionManager.php line 169:

  The "action::delete_action" plugin does not exist.

```

I cannot seem to find this error in any other forum posts, or any documentation from VBO as to how to identify what actions are available. Is this capability for VBO not available for Drupal 9, or is there some knowledge base I have missed that details how to specify the action?

# Answer
After much searching to no avail, I decided to dig into the VBO codebase. It turns out that I was using the wrong action id (the 2nd argument to the drush command after the view id). Whatever action id was being used in the post I referenced is not the right one (either it was custom or VBO has since changed the convention for action id's). I discovered this by finding the file that implemented the action (delete) that I wanted, which happened to be in `/drupal_root/modules/contrib/views_bulk_operations/src/Plugin/Action/EntityDeleteAction.php`. This file has an annotation block that specifies the action id to use:

```
namespace Drupal\views_bulk_operations\Plugin\Action;

use Drupal\views_bulk_operations\Action\ViewsBulkOperationsActionBase;
use Drupal\Core\Entity\TranslatableInterface;
use Drupal\Core\Session\AccountInterface;

/**
 * Delete entity action with default confirmation form.
 *
 * @Action(
 *   id = "views_bulk_operations_delete_entity",
 *   label = @Translation("Delete selected entities / translations"),
 *   type = "",
 *   confirm = TRUE,
 * )
 */
class EntityDeleteAction extends ViewsBulkOperationsActionBase {
...
}

```

running `drush vbo-execute my_delete_view views_bulk_operations_delete_entity` did the trick! No idea why there doesn't appear to be any documentation about this (at least that I can find), but I'm glad I finally figured it out and hopefully this helps someone else having the same trouble.
> 2 votes

---
Tags: views, drush, 9
---


# Question
Title: How can I invalidate cached field access grants for anonymous users?
We have a Drupal 8 application that uses an event subscriber class to validate IP addresses against a table of white-listed addresses on kernel requests, and adds that value to a session variable. Basically, anonymous users with authenticated IPs can access privileged content on the site. I can use `hook_node_access` and `hook_block_access` to control access when appropriate, but `hook_entity_field_access` only fires once after rebuilding the caches, and not for each session, so field access seems more difficult to control this way. I've thought about injecting a service into my event subscriber and adding the necessary logic there for field access control, but I'm wondering if there's something easier that I'm missing about invalidating cache tags that would cause that hook to fire for each session.

# Answer
> 2 votes
I was able to use `hook_entity_field_access` and return an `AccessResult $result->addCacheContexts(['session', 'user.roles.anonymous'])`

---
Tags: 8, hooks, caching, event-subscribers
---


# Question
Title: Change value on validate form when I create or edit a block
I need change a value to element on form validation.

I have this code:

```
/**
 * Implements hook_form_FORM_alter().
 */
function MY_MODULE_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  if ($form_id == 'block_content_MY_BLOCK_form' || $form_id == 'block_content_MY_BLOCK_edit_form') {
    $form['#validate'][] = '_custom_validate';
  }
}

```

I want change the value of field field\_test. This field is plain text.

```
function _custom_validate($form, FormStateInterface $form_state) {
  $form_state->setValueForElement($form['field_test'], 'changed');
}

```

But when I saved this block, the field field\_test doesn't change its value.

What I am doing wrong?

# Answer
Please insert the validate method inside the #element\_validate function and then change the element value.

```
/**
 * Implements hook_form_FORM_alter().
 */
function MY_MODULE_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  if ($form_id == 'block_content_MY_BLOCK_form' ||  $form_id =='block_content_MY_BLOCK_edit_form') {
       $form['field_test']['widget'][0]['#element_validate'][] = '_custom_validate';
      }
    }

function _custom_validate(&$element, FormStateInterface $form_state, &$complete_form) {
  $form_state->setValueForElement($element,['value' => 'See the change']);
}

```
> 10 votes

# Answer
Use setValue function to change textfield value.

```
function MY_MODULE_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  if ($form_id == 'block_content_MY_BLOCK_form' || $form_id == 'block_content_MY_BLOCK_edit_form') {
    $form['#validate'][] = '_custom_validate';
  }
}

function _custom_validate(&$form, FormStateInterface $form_state) {
  $form_state->setValue('field_test', 'changed');
}

```
> 1 votes

# Answer
Your code looks like it should work, according to the docs for setValueForElement(). I couldn't get it to work that way, either.

There's what eventually worked:

```
$title = t(
  '@user enrolled in @class',
  ['@user' => $userName, '@class' => $classTitle]
);
$formState->setValue('title', [['value'=>(string) $title]]);

```

If the field has other attributes, like a format name for a rich text field, you might have to add the attributes, too:

```
$formState->setValue('field_notes', [['value'=>'Dogs are great!', 'format'=>'skilling']]);

```

Something else that might help. In hook\_alter, my code hides the field that will have its value computed. However, the field needs a value to keep Drupal happy:

```
// Hide the title. Compute it from other elements.
$form['title']['#type'] = 'hidden' ;
// Need to give the field a default value, for Drupal's validation code
// to get to the point where a value for the field can be computed.
$form['title']['widget'][0]['value']['#default_value'] = 'Dogs are the best!';

```
> 0 votes

# Answer
It is a bit off-topic, but related to the question.

How to add a css class to specific element when validating it.

First of all you need to add `#element_validate` to the form element, for example in your `buildForm()` method. Something like that:

```
$form['foo'] = [
  // ...
  '#element_validate' => ['::markAsWrongWhenEmpty']
]

```

Then inside your custom validation callback just add desired css class:

```
public static markAsWrongWhenEmpty(&$element, FormStateInterface $form_state, &$complete_form) {
  if (empty($element['#value'])) {
    $form_state->setErrorByName('foo', 'error_message');
    $element['#attributes']['class'][] = 'error';
  }
}

```

Based on the great answer #5501
> 0 votes

---
Tags: 8, forms, blocks
---


# Question
Title: How can I insert fields from custom content to custom form?
I have a problem with form. I had to create a custom content with fields. User can put variables into those fields and save to database, for example "Anna" into column `field_student_name` in table `node__field_student_name`. I see this connection where every field from this content type is saved under particular node.

Now I need to create a form with fields, which values will go to the same database tables, for example in this form I have a form field where I put "Tom", and this value is saved in table `node__field_student_name` in column `field_student_name` (the same as Anna in custom content).

At this moment I see two main potential ways to accomplish this task:

1. insert form from custom content to my new form with entity.form\_builder

I added this two lines info code:

```
$node = \Drupal\node\Entity\Node::create(['type' => 'my_students']);
$form = \Drupal::service('entity.form_builder')->getForm($node);
return $form

```

And this works fine, but I need only part of those fields :( And I don't wanna see section for admin like "add new revision" etc. Moreover, "Submit" button is on the top of the page

2. Create a form and in submit function do something like

$node-\>set('title', 'titile1')

but I prefer way #1. Besides that, I don't know how to do it with way #2. I don't know how can i put variables from $form\['student\]' into `field_student_name` column in `node__field_student_name` table. Moreover i am not sure if it is ok and if nodes id etc will be added in correct way.

To sum up, I think way #1 is better and easier but I don't have such a big knowledge to do this and maybe here are more advanced, helpful people who can help me.

EDIT

I've create new mode student\_user in student content type:

**core.entity\_view\_mode.node.student\_user.yml**

```
langcode: en
status: true
dependencies:
  module:
    - node
id: node.student_user
label: student
targetEntityType: node
cache: true

```

**core.entity\_view\_display.node.student.student\_user.yml**

```
langcode: en
status: true
dependencies:
  config:
    - core.entity_view_mode.node.student_user
    - field.field.node.student.field_name
    - node.type.student
  module:
    - options
    - user
id: node.student.student_user
targetEntityType: node
bundle: student
mode: student_user
content:
  field_name:
    weight: 103
    label: above
    settings:
      thousand_separator: ''
      prefix_suffix: true
    third_party_settings: {  }
    type: list_default
    region: content
hidden:
  links: true

```

and here i tried with **routing**

student.student\_user: path: '/test' defaults: \_entity\_view: 'node.student\_user' \_title: 'Students' requirements: \_permission: 'access content' \_entity\_access: 'node.view'

I received an error

```
RuntimeException: Failed to find entity of type node in route named student.student_user

```

And then i tried with form

i added **core.entity\_form\_display.node.student.student\_form.yml** and **core.entity\_form\_mode.node.student\_form.yml**

and then i tried return it in **controller**

```
<?php

namespace Drupal\student\Controller;

use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Controller\ControllerBase;
use Drupal\node\NodeInterface;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Url;
use Drupal\Core\Link;
use Drupal\Core\Routing;

class TestController extends ControllerBase {

  function test() {

    $node = \Drupal\node\Entity\Node::create(['type' => 'student']);

    $form = \Drupal::service('entity.form_builder')->getForm($node, 'student_form');

    return $form;
  }
}
?>

```

error

```
Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException: The "node" entity type did not specify a "student_form" form class.

```

# Answer
> 0 votes
An entity can have multiple form modes, so you can exclude some fields in different form modes and leave fields that you want to display.

So, you can create form mode "custom\_form\_mode", go to manage fields, choose "custom\_form\_mode" and arrange fields.

In the custom code, you can use the code that you mention in #1, but with an extra argument in the `getForm` method, which is `$operation`, and that one is the form mode that you want to use to display form.

```
$node = \Drupal\node\Entity\Node::create(['type' => 'my_students']);
$form = \Drupal::service('entity.form_builder')->getForm($node, 'custom_form_mode');
return $form

```

---
Tags: 8, nodes
---


# Question
Title: Display status message after submitting modal popup form
Ok so i have a custom entity and want to display a custom delete form. Have created the Route and everything works except for Drupal messenger displaying status message after submission, even after a manual refresh.

The weird thing is, if i add a ksm() output to hook\_entity\_delete() which is called after the entity is deleted, the status message does display.

I have added a '?destination=' parameter to the end of the link the initiates the popup, and after submit, the redirect is successful.

Here is my class, which i can get to popup in a dialog window, with the form and successful deletion and window close.

Just to clarify, trying to get the status message to display on the form from where the modal popup was initiated from, not to get the message in an additional popup.

Any ideas?

```
class TrEntryDeleteForm extends ConfirmFormBase {

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state, EntityInterface $na_entry = NULL) {

    $entry_id = $na_entry->id();

    $form['title'] = [
      '#markup' => t("<p>Title</p>"),
    ];

    $form['description'] = [
      '#markup' => t("<p class='text-center'>This action can't be undone</p>"),
    ];

    $form['entry_id'] = [
      '#type' => 'hidden',
      '#default_value' => $entry_id,
      '#required' => TRUE,
    ];

    $form['actions'] = [
      '#type' => 'actions',
    ];

    $form['actions']['cancel'] = [
      '#type' => 'submit',
      '#value' => $this->t('Cancel'),
      '#attributes' => [
        'class' => [
          'use-ajax',
          'cancel',
        ],
      ],
      '#ajax' => [
        'callback' => [$this, 'closeModalForm'],
        'event' => 'click',
      ],
    ];

    $form['actions']['submit'] = [
      '#type' => 'submit',
      '#value' => $this->t('Delete'),
    ];

    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {

    $entry_entity = \Drupal::entityTypeManager()->getStorage('entry')->load($entry_id);
    $entry_entity->delete();

    \Drupal::messenger()->addStatus(
      t('@msg', ['@msg' => 'Entity deleted.'])
    );
  }

  /**
   * {@inheritdoc}
   */
  public function getQuestion() {

  }

  /**
   * {@inheritdoc}
   */
  public function getCancelUrl() {
    // TODO: Implement getCancelUrl() method.
  }

}

```

# Answer
After redirection the \Drupal::messenger() may not work. So try with the Drupal **OpenModalDialogCommand**

```
use Drupal\Core\Ajax\OpenModalDialogCommand;

/**
* {@inheritdoc}
*/
  public function submitForm(array &$form, FormStateInterface $form_state){

    $entry_entity = \Drupal::entityTypeManager()->getStorage('entry')->load($entry_id);
    $entry_entity->delete();

    $response = new AjaxResponse();
    $response->addCommand(new OpenModalDialogCommand("Success", 'Entity deleted.', ['width' => 800]));
    return $response;
  }

```
> 1 votes

---
Tags: 8, modal-dialogs, status-messages
---


# Question
Title: Is there a way to manually run cron with Drush?
I want to be able to accomplish this: http://mywebsite.com/admin/reports/status/run-cron

But it should be done through the Drush interface.

Can any one help me out ?

# Answer
You can try `drush core-cron`

> $ drush help core-cron
> Run all cron hooks in all active modules for specified site.
> Aliases: cron
> 63 votes

# Answer
You can use `drush core-cron` or just `drush cron`

If you wish to use drush to run cron from a crontab, it's best to run cron as the web server user, and supply it with additional arguments to make up the lack of a terminal and supply environment variables.

The drush documentation explains it best either at docs/cron.html or run `drush topic docs-cron`.

Personally I use server wide site aliases so I omit `--root` and `--uri` and use `@some.site` instead for a single site. If you have defined group aliases, you can run cron on the whole group by using `@some.group`. More information on site aliases if you are interested, otherwise `drush docs-aliases`.
> 26 votes

# Answer
You could use **drush core-cron** command that would run the cron . For more detailing about the commands that drush provides us is there on https://drushcommands.com/
> 9 votes

# Answer
You can use `--quiet`

The `--quiet` flag will suppress these and other progress messages, again avoiding an unnecessary email message.
> 0 votes

---
Tags: drush, cron
---


title: Expose custom entity to views

text:
# Question
Title: Expose custom entity to views
I've created an entity in a Drupal 8 custom module. Right now it's just an entity with base fields.

I want to expose these base fields to views.

I have the entity appearing on the views wizard page, but when I create the view, there are no base fields available for me to add, and the default field that views puts in there shows up as broken/missing.

I've tried referencing the comments module for examples, and have tried defining various views plugins, but I'm not having much luck.

I have `baseFieldDefinitions($entity_type)` defined in my entity controller. What else is required to expose this entity and its fields to views?

# Answer
> 11 votes
You need to implement hook\_views\_data() just like in Drupal 7. See comment.views.inc.

# Answer
> 11 votes
This is now possible via a class annotation; per the documentation for the hook mentioned in the other answer:

> To provide views data for an entity, instead of implementing this hook, create a class implementing \Drupal\views\EntityViewsDataInterface and reference this in the "views" annotation in the entity class. The return value of the getViewsData() method on the interface is the same as this hook.

# Answer
> 3 votes
You should extend `EntityViewsData` and you'll have the integration of your entity.

Example:

```
use Drupal\views\EntityViewsData;

class CustomEntityViewsData extends EntityViewsData {
  public function getViewsData() {
    $data = parent::getViewsData();
    return $data;
  }
}

```

# Answer
> 2 votes
If you use Drupal Console's Content entity generator it will automatically include Views integration.

# Answer
> 1 votes
This is an example of a custom entity with views integration:

```
/**
 * Defines the logbook entity.
 *
 * @ingroup logbook
 *
 * @ContentEntityType(
 *   id = "logbook",
 *   label = @Translation("Logbook"),
 *   base_table = "logbook",
 *   data_table = "logbook_field_data",
 *   fieldable = TRUE,
 *   entity_keys = {
 *     "id" = "id",
 *     "uuid" = "uuid",
 *     "owner" = "uid",
 *     "uid" = "uid",
 *   },
 *   handlers = {
 *     "views_data" = "Drupal\views\EntityViewsData",
 *     "access" = "Drupal\logbook\LogbookAccessControlHandler",
 *   },
 *   field_ui_base_route="entity.logbook.settings"
 * )
 */

```

# Answer
> 0 votes
you need implement \Drupal\views\EntityViewsData and add it in entity aanotation

---
Tags: views, entities, 8
---


# Question
Title: How to get the row added by ajax in the right place?
I have a table form created from a custom entity:

```
  public function buildForm(array $form, FormStateInterface $form_state, $contract = NULL)
  {

    $form['subscriptions'] = [
      '#type'       => 'table',
    ];
    $form['subscriptions']['#header'] = [some stuff here];
//  here is the query to retrieve data from entity...
    $results = db_query($query);
    foreach ($results as $key => $value) {
      $myKey = $key * 10;
      $form['subscriptions'][$myKey]['somefield'] = ['#markup' => $value->designation];
      $form['subscriptions'][$myKey]['anotherfield'] = [
        '#type'          => 'number',
        '#default_value' => $value->$sTemp,
      ];
      $form['subscriptions'][$myKey]['addRow'] = [
        '#type'  => 'submit',
        '#name'  => $myKey,
        '#value' => '+',
        '#ajax'  => [
          'callback' => '::ajaxAddRow',
          'wrapper'  => 'my_form_wrapper',
        ],
      ];
    }

    $form['#prefix'] = '<div id="my_form_wrapper">';
    $form['#suffix'] = '</div>';

    $form['submit'] = [
     '#type'  => 'submit',
     '#name'  => 'submit',
     '#value' => $this->t('Submit'),
    ];
  return $form;
  }

```

The ajax callback:

```
  public function ajaxAddRow(array &$form, FormStateInterface $form_state)
  {
    $myKey = $form_state->getTriggeringElement()['#name'];
    $form['subscriptions'][$myKey + 5] = $form['subscriptions'][$myKey];
    return $form;
  }

```

The submitForm:

```
  public function submitForm(array &$form, FormStateInterface $form_state)
  {
    if ($form_state->getTriggeringElement()['#name'] == 'submit') {
        do some stuff then exit the form
    }
    else {
      $form_state->setRebuild();
    }
  }

```

When I click on '+' in some row, the form is displayed again with a copy of the row added to the table.
But the copy is added at the end of the table.
How can I have the copy added just after the original one?

# Answer
> 0 votes
I finally made it work this way:

```
  public function ajaxAddRow(array &$form, FormStateInterface $form_state)
  {
    $myKey = $form_state->getTriggeringElement()['#name'];
    $formBis = [];
    foreach ($form as $key => $value) {
      switch ($key) {
        case 'subscriptions':
          foreach ($form['subscriptions'] as $key2 => $value2) {
            $formBis['subscriptions'][$key2] = $form['subscriptions'][$key2];
            if (is_numeric($key2)) {
              if ($key2 == $myKey) {           << Here is the row to be copied
                $keyfornewrow = $key2 + 5;
                $formBis['subscriptions'][$keyfornewrow] = $form['subscriptions'][$key2];
                foreach ($formBis['subscriptions'][$keyfornewrow] as $key3 => $value3) {
                    << some code here to initialize content of copied row >>
                }
              }
            }
          }
          break;
        default:
          $formBis[$key] = $form[$key];
      }
    }
    return $formBis;
  }

```

---
Tags: 8, forms, ajax
---


# Question
Title: How to access a selected label instead of value
I have a select list of states:

```
AL|Alabama
AK|Alaska
AZ|Arizona
AR|Arkansas

```

In code to access the selected state value I can run code like this:

```
...
$entity->get('field_state')->value;
...

```

I get the values like AL or AK. How can I get the labels like Alabama or Alaska?

# Answer
Not sure if there is a better way but I got the value by getting the allowed values first.

```
$allowed_values = $state->getFieldDefinition('field_state')->getFieldStorageDefinition()->getSetting('allowed_values');
$state_value = $state->get('field_state')->value;
$info['state_name'] = $allowed_values[$state_value];

```
> 25 votes

# Answer
The proper way is to use **options\_allowed\_values()** function. Because the field might not have "allowed\_values" setting and options can be provided through the "allowed\_values\_function".

**Live examples:**

**Case #1:** You have an entity object and want to get a label of the value of the field with options.

```
$field_name = 'field_state';

/** @var \Drupal\Core\Field\FieldStorageDefinitionInterface $field_definition */
$field_definition = $entity->{$field_name}->getFieldDefinition()->getFieldStorageDefinition();

// This is a list (array) of options for the field definition:
// [{option1_key} => {option1_value}, {option2_key} => {option2_value}, ...]
$field_allowed_options = options_allowed_values($field_definition, $entity);

// If the field is NOT multiple.
/** @var string|\Drupal\Component\Render\MarkupInterface $field_value_label */
$field_value_label = $field_allowed_options[$entity->{$field_name}->value];

// If the field is multiple.
$field_value = array_column($entity->{$field_name}->getValue(), 'value', 'value');
/** @var string[]|\Drupal\Component\Render\MarkupInterface[] $field_value_labels */
$field_value_labels = array_intersect_key($field_allowed_options, $field_value);

```

**Case #2:** You don't have an entity object but you want to get a list of all allowed options of the field of the entity.

```
$entity_type_id = 'node';
$field_name = 'field_state';

$entity_fields_definitions = \Drupal::service('entity_field.manager')->getFieldStorageDefinitions($entity_type_id);

/** @var \Drupal\Core\Field\FieldStorageDefinitionInterface $field_definition */
$field_definition = $entity_fields_definitions[$field_name];
$field_allowed_options = options_allowed_values($field_definition);

```
> 5 votes

# Answer
This might help as well:

```
$node->field_state->getFieldDefinition()->getSetting('allowed_values');

```
> 3 votes

# Answer
On Drupal 8 you can use the `view()` method which will render the field, so you can use its markup:

```
$rendered_state_field = $entity->get('field_state')->view(['label' => 'hidden']);

```

then, the path to the label of the selected value should be:

```
$rendered_state_field[0]['#markup']

```

If you want to use it in a twig, then you can simply pass `$rendered_state_field` as a variable.
> 1 votes

# Answer
drupal 7 way:

```
$jid = $row->job_id_181;
if($jid)
{
    $jobNode = node_load($params['jid']);
    $key = $jobNode->field_job_location['und'][0]['value'];//2
    if($key)
    {
        $field = field_info_field('field_job_location');
        $label = $field['settings']['allowed_values'][$key];
        echo $label;
    }

}

```

Hope it helps some one in future.
> -1 votes

---
Tags: 8
---


title: Multiple forms on one page

text:
# Question
Title: Multiple forms on one page
I try to input several forms into one page via Controller. With code which is under, I see those forms but after submit one of them, nothing happens. Any of data is send to database. Has anyone idea how to fix this?

```
<?php

namespace Drupal\Core\Entity\ContentEntityForm;
namespace Drupal\student\Controller;
use Drupal\node\Entity\Node;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Controller\ControllerBase;
use Drupal\node\NodeInterface;
use Drupal\node\Entity;
use Drupal\node\NodeForm;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Url;
use Drupal\Core\Link;
use Drupal\Core\Routing;
use Drupal\Core\Entity\ContentEntityForm;

class SFormController extends ControllerBase {

  function new_form() {

    $build = [];

    foreach ($stud as $id => $name) {

      $node = \Drupal\node\Entity\Node::create(['type' => 'student']);
      $form = \Drupal::service('entity.form_builder')->getForm($node, 'student_form');

      $build[] = $form;
    }
    return $build;
  }
}

?>

```

# Answer
> 1 votes
You need to make the form ID dynamic, so that it is different for each instance on the page. As you're extending EntityForm, you'll have to extend it, then register your form on the node class, and finally call your form class.

1. Extend the entity form:

```
class MyEntityForm extends EntityForm {
  public function getFormId() {
    // The dynamic form ID allows for the form to be
    // reused on a page.
    return parent::getFormId() . '-' . $this->getEntity()->id();
  }
}

```

2. Register your form class on the node entity type:

```
/**
 * Implements hook_entity_type_alter().
 */
function HOOK_entity_type_alter(array &$entity_types) {
  $node = &$entity_types['node'];
  $node->setFormClass('my_form_type', 'Drupal\[MODULE]\Form\MyEntityForm');
}

```
3. Call your form from your controller:

```
  $form = \Drupal::service('entity.form_builder')->getForm($node, 'my_form_type');

```

---
Tags: 8, forms
---


# Question
Title: Override specific configuration keys in settings.local.php
I'm trying to learn the Drupal 8 configuration override system based on the documentation here:

https://www.drupal.org/docs/drupal-apis/configuration-api/configuration-override-system

As a simple test, I have disabled the Shield module and exported config. Here's a diff:

```
diff --git a/config/sync/shield.settings.yml b/config/sync/shield.settings.yml
index 3f7482f18..d9f019ca4 100644
--- a/config/sync/shield.settings.yml
+++ b/config/sync/shield.settings.yml
@@ -1,4 +1,4 @@
-shield_enable: true
+shield_enable: false
 credential_provider: shield
 credentials:
   shield:

```

Now, in my `settings.local.php` I have attempted to override this config key:

```
/**
 * Disable Shield (HTTP Basic Authentication).
 */
$config['shield']['shield_enable'] = FALSE;

```

This approach does not seem to work.

Do I need to do anything else to override the configuration?

**NOTE:** This is a contrived example. I could use configuration splits to disable HTTP basic auth in the production environment, even if it's enabled in the active database configuration. In fact, I am hoping this approach will allow me to use environment variables to provide environment-specific values for authentication tokens, API keys and other secrets that may change in sandbox and production environments, but details are irrelevant to the question.

# Answer
> 3 votes
The key for `$config` is the config name, not the module. This should work:

```
$config['shield.settings']['shield_enable'] = FALSE;

```

---
Tags: 8, configuration
---


# Question
Title: Custom migrate source plugin, extends FieldableEntity class, has migrate status of [error] No migrations found. Why?
I'm writing a migrate source plugin for migrating D7 entityform (entityform module) submissions. If anyone has done this or knows an existing plugin, please let me know.

I am trying to extend the `FieldableEntity` base class from `Drupal\migrate_drupal\Plugin\migrate\source\d7\FieldableEntity;` because I want to use its `getFields()` and `getFieldValues()` methods when I override `prepareRow()` to include custom fields from my D7 entityform.

My problem is that when my source plugin extends `FieldableEntity`, drush reports `[error] No migrations found.` for my migration. Importantly, however, if my source plugin instead uses the `SqlBase` class from `Drupal\migrate\Plugin\migrate\source\SqlBase`, then drush can import all of my entityforms from D7 into D9 contact forms no problem. So it would seem that I am missing something when I try to implement `FieldableEntity` preventing it from retrieving data for the migration.

Here is my plugin, which shows up fine in `drush ms`:

```
<?php

namespace Drupal\mymodule_migrate\Plugin\migrate\source;

use Drupal\migrate\Row;
use Drupal\migrate_drupal\Plugin\migrate\source\d7\FieldableEntity;

/**
 * The 'mymodule_migrate_entityform' source plugin.
 *
 * @MigrateSource(
 *   id = "mymodule_migrate_entityform",
 *   source_module = "mymodule_migrate"
 * )
 */
class Entityform extends FieldableEntity {

  /**
   * {@inheritdoc}
   */
  public function query() {
    $query = $this->select('entityform', 'e')
      ->fields('e', [
        'entityform_id',
        'type',
        'created',
        'changed',
        'uid'
      ]);
    return $query;
  }

  /**
   * {@inheritdoc}
   */
  public function fields() {
    return array(
      'entityform_id' => $this->t('The ID of the entityform submission.'),
      'type' => $this->t('The entityform type.'),
      'created' => $this->t('The time that the entityform was submitted.'),
      'changed' => $this->t('Last updated time.'),
      'uid' => $this->t('The {users}.uid who submitted the entityform. If set to 0, this entityform was submitted by an anonymous user.'),
    );
  }

  /**
   * {@inheritdoc}
   */
  public function getIds() {
    $ids['entityform_id']['type'] = 'integer';
    $ids['entityform_id']['alias'] = 'e';
    return $ids;
  }

  /**
   * {@inheritdoc}
   */
  public function prepareRow(Row $row) {
    $entityform_id = $row->getSourceProperty('entityform_id');
    // Get Field API field values.
    foreach ($this->getFields('entityform', 'BUNDLE_MACHINE_NAME') as $field_name => $field) {
      $row->setSourceProperty($field_name, $this->getFieldValues('entityform', $field_name, $entityform_id));
    }
    return parent::prepareRow($row);
  }

}

```

I use this yml migration definition. My migrate destination is D8/D9 contact\_message entity.

```
id: mymodule_contact_message
label: D8 Contact message migration from D7 entityform submission
source:
  plugin: mymodule_migrate_entityform
process:
  id: entityform_id
  langcode:
    plugin: default_value
    source: language
    default_value: "und"
  created: created
  changed: changed
destination:
  plugin: entity:contact_message
  default_bundle: MY_DESTINATION_BUNDLE

```

As stated above, all of this works great when I use `SqlBase` in my plugin. But with `FieldableEntity` drush comes back with `[error] No migrations found.`

# Answer
> 2 votes
I resolved my problem when I identified a mistake in my `@MigrateSource` annotation on my plugin. I had included my own custom migration module in the `source_module` entry of the plugin annotation. Here is what I did wrong:

```
/**
 * The 'mymodule_migrate_entityform' source plugin.
 *
 * @MigrateSource(
 *   id = "mymodule_migrate_entityform",
 *   source_module = "mymodule_migrate"
 * )
 */

```

Well I looked at the api docs on `source_module`

> Identifies the system providing the data the source plugin will read.

> The source plugin itself determines how the value is used. For example, Migrate Drupal's source plugins expect source\_module to be the name of a module that must be installed and enabled in the source database.

It didn't work because `source_module` was set to my D9 custom migration module, which is obviously not on the D7 source, so the migration just silently gets removed from the list of migrations.

So I simply deleted the annotation line. My working plugin annotation looks like this now, and the plugin extends `FieldableEntity` and works as I had hoped it would.

```
/**
 * The 'mymodule_migrate_entityform' source plugin.
 *
 * @MigrateSource(
 *   id = "mymodule_migrate_entityform"
 * )
 */

```

I hope my plugin here will prove useful to someone migrating from D7 entityform to D8/9 core contact module (with contact\_storage contrib module). It works.

---
Tags: entities, migrations
---


# Question
Title: Upload External File to Drupal File System
# **Situation**

---

I would like to be able to upload files programmatically from an external source to the drupal file system. I was thinking of making a `RESTful API` that allows me to save external files into my site's public file path. The file is an excel file as well if that changes anything.

# **Problem**

---

Currently, I am thinking of just using an `S3` bucket to store the external files. Then within my site, I would simply run a `GET REQUEST` and programmatically save the file. I was just hoping there was a way to simply POST a file in drupal without me having to use Amazon's S3.

Parameters:

---

* Drupal Version 8.8
* Drupal Site BackEnd= PHP 7.3
* External App FrontEnd = Vue.js
* External App BackEnd = .NET Core
* Required File Type: .xlxs
* Secondary File Types: .csv, .docx, .json, .jpeg, .mp4, .txt

### **TL;DR**

---

How can I make it so another site/app can upload files to my site? (using `JavaScript`)

> **Notice:** *I understand StackOverflow is only meant for help with code issues but I would greatly appreciate some help getting started and if not at least some very useful links that are credible. Some of the research I have found is not useful seeing that I am on Drupal 8.8*

# Answer
Take a look at foldershare and foldershare\_rest modules, they provide entire data management pipeline on a Drupal site, along with a ready to use rest client cum command line utility. Here are couple videos that show the module's capabilities

1. Managing data via REST client for automation and power users (5 mins)
2. Managing data on SeedMeLab for users(3mins)

Disclosure: I am the maintainer for these modules.
> 0 votes

---
Tags: 8, files, http-request
---


# Question
Title: How to automatically add http prefix to links in a form?
I am trying to come up with a solution to fix the D8 Link module to allow URLs like example.com (the most common use case, imho). I was thinking it would be simple enough to modify the submit value during a custom validate function; but regardless of what I set the value to it still validates on the original value.

In a form alter I have done this:

```
$form['field_linktest']['widget'][0]['#element_validate'][] = '_fix_link_field_value';

```

and then in that validate function I set the url uri value:

```
function _fix_link_field_value(&$element, FormStateInterface $form_state, &$complete_form) {
  $url = $form_state->getValue('field_linktest');
  $url[0]['uri'] = 'http://example.com';
  $form_state->setValue('field_linktest', $url);
}

```

But I still get the error: Manually entered paths should start with one of the following characters: / ? #

# Answer
Thanks to those who provided answers; I couldn't quite get those to work, but they got me to my answer. My final solution ended up being this:

```
function my_module_form_alter(&$form, $form_state, $form_id) {
  // add a global validator to fix stupid Link fields - add to all Link fields
  // only worry about entity forms
  if (isset($form['#entity_type'])) {
    $bundle = $form_state->getFormObject()->getEntity()->bundle();
    $entity_type = $form['#entity_type'];
    $entityFieldManager = \Drupal::service('entity_field.manager');
    $fields = $entityFieldManager->getFieldDefinitions($entity_type, $bundle);
    foreach ($fields as $field) {
      if ($field->getType() == 'link') {
        $field_name = $field->getName();
        $form[$field_name]['widget'][0]['#element_validate'][] = '_fix_link_field_value';
        array_unshift($form[$field_name]['widget'][0]['uri']['#element_validate'][0], '_fix_link_field_value');
        $form[$field_name]["widget"][0]["uri"]["#description"] = t('This must be an external URL such as http://example.com, https://example.com, example.com, www.example.com.');
      }
    }
  }
}

```

and then the validator/fixer:

```
function _fix_link_field_value(&$element, FormStateInterface $form_state, &$complete_form) {
  $url = $form_state->getValue($element['#parents'][0]);
  $urlOriginal = $url[0]['uri'];
  if (!$urlOriginal) return;

  if (!stristr($url[0]['uri'], '//')) {
    $url[0]['uri'] = 'http://' . $url[0]['uri'];
  }
  if (filter_var($url[0]['uri'], FILTER_VALIDATE_URL) === FALSE) {
    $form_state->setErrorByName($element['#parents'][0], t('%url is not a valid URL format. This must be in a format like
      http://example.com, https://example.com, example.com, www.example.com.',
      ['%url' => $urlOriginal])
    );
  }
  else {
    $form_state->setValue($element['#parents'][0], $url);
  }
}

```

The array\_unshift isn't right but doing an unset() didn't seem to cut it. I am sure all this is doing is preventing the original validator from running; which is good as the error message it generates is stupid. Not sure why 5 years into D8 they still don't have this fixed.

Also, this will need an extra loop if you are dealing with multi-valued fields.
> 0 votes

---
Tags: 8, entities, forms
---


# Question
Title: How do I find out which base fields are available for an entity type?
If I have an entity type id as a string, how I can tell which base fields are defined for that entity type?

For example, how do I programatically check that an entity type has the "changed" field?

# Answer
How to get the base fields for an entity type id:

```
$base_fields = \Drupal::entityManager()->getBaseFieldDefinitions($entity_type_id);

```

You get an array. The keys are the field names. Example how to loop through this array:

```
foreach ( $base_fields as $field_name => $definition ) {
  echo "$field_name: ", $definition->getDescription(), "\n";
}

```

**Edit:**

The method has moved to the service `EntityFieldManager`:

```
$base_fields = \Drupal::service('entity_field.manager')
  ->getBaseFieldDefinitions($entity_type_id);

```
> 6 votes

# Answer
The easiest way is through the entity type manager service, by getting the entity type definition and class:

```
$entity_type = 'node';
$container = \Drupal::getContainer();
/** @var \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager */
$entity_type_manager = $container->get('entity_type.manager');
$entity_type_definition = $entity_type_manager->getDefinition($entity_type);
$entity_type_class = $entity_type_definition->getClass();
$fields = call_user_func([$entity_type_class, 'baseFieldDefinitions'], $entity_type_definition);
if (!empty($fields['changed'])) {
  // Do something.
}

```
> 0 votes

# Answer
If you know the class of the entity type then:

```
$fields = Foo::baseFieldDefinitions(\Drupal::entityTypeManager()->getDefinition('foo'));

```
> 0 votes

# Answer
Here's an example for `drush`, sample `$entity_type_id` is `user` but could be `node` etc..

```
drush ev 'var_export(array_keys(\Drupal::service("entity_field.manager")->getBaseFieldDefinitions("user")))'

```
> 0 votes

---
Tags: entities, 8
---


title: VBO hook_entity_update

text:
# Question
Title: VBO hook_entity_update
I would like to perform the following mass action via VBO: send a mail to author of a node.

This mail is configured and sent in a hook\_entity\_update function.

The beginning of the function is the following :

```
if (is_null($entity)) return;
if (!isset($entity)) return;

$nid = \Drupal::routeMatch()->getRawParameter('node');
if ($nid) {
 $type = $node->bundle();
 if ($type != 'membre') {
   return;
 }
}
else if ($nid == null) {
 return;
}

...

$mailManager->mail($module, $key, $to_trsf, $langcode, $params, NULL, $send);

```

test 1: If I update manually the node, the mail is sent.

test 2: If I update the node through a VBO, the mail is not sent because the nid is null, so the "return" statement is done.

Is there a possibility to retrieve the nid of a node when the hook is fired throught a VBO action?

# Answer
> 3 votes
Your problem is that you are using `routeMatch()` to get the node id, which won't be returned when using VBO.

You said you're using `hook_entity_update()`:

```
function hook_ENTITY_TYPE_update(Drupal\Core\Entity\EntityInterface $entity)

```

This code assumes that the entity you are running `hook_entity_update()` for is the node entity.

Since the hook provides the `$entity` object, you can get the node id like this:

`$nid = $entity->id()`

---
Tags: 8, views, emails, entities
---


# Question
Title: Missing proxy classes when container compiles custom ExtensionPass
# Context

I try to find a way to integrate Webpack Encore into Drupal. Since we can't use Symfony Bundles in Drupal I want to port the bundle to a custom Drupal module.

# What I have done so far

To register an alter services I use a custom compiler pass described here

So my Service Provider looks like that:

```
class WebpackEncoreServiceProvider extends ServiceProviderBase
{
    /**
     * {@inheritdoc}
     */
    public function register(ContainerBuilder $container) {
        $container->addCompilerPass(new WebpackEncoreExtensionPass());
    }
}

```

My custom extension pass looks like that:

```
class WebpackEncoreExtensionPass implements CompilerPassInterface
{
    /**
     * {@inheritdoc}
     */
    public function process(ContainerBuilder $container)
    {
        //get the parameters from mymodule.services.yml
        $configs = Yaml::parseFile(\dirname(__DIR__).'/../webpack_encore.services.yml');
        $config = $configs['parameters']['webpack_encore'];
        // Drupal does not load configs from files like Symfony does.
        $container->prependExtensionConfig('webpack_encore', ['output_path' => $config['output_path']]);
        $extension = new WebpackEncoreExtension();
        $extension->load([$config], $container);
        $container->registerExtension($extension);
        $container->loadFromExtension($extension->getAlias());
//      var_dump($container->getDefinitions());die();
        $container->compile();
    }
}

```

# Problem

The container is not build a states that there are missing proxy classes. This output is from the browser and it runs in circles:

```
User warning: Missing proxy class 'Symfony\Component\ProxyClass\HttpKernel\HttpKernel' for lazy service 'http_kernel.basic'. Use the following command to generate the proxy class: php core/scripts/generate-proxy-class.php 'Symfony\Component\HttpKernel\HttpKernel' "[namespace_root_path]" in Drupal\Core\DependencyInjection\Compiler\ProxyServicesPass->process() (line 61 of /var/www/html/mws_bundles/dietpet.vet/web/core/lib/Drupal/Core/DependencyInjection/Compiler/ProxyServicesPass.php).
Drupal\Core\DependencyInjection\Compiler\ProxyServicesPass->process(Object) (Line: 94)
Symfony\Component\DependencyInjection\Compiler\Compiler->compile(Object) (Line: 762)
Symfony\Component\DependencyInjection\ContainerBuilder->compile() (Line: 34)
Drupal\webpack_encore\Compiler\WebpackEncoreExtensionPass->process(Object) (Line: 94)
Symfony\Component\DependencyInjection\Compiler\Compiler->compile(Object) (Line: 762)
Symfony\Component\DependencyInjection\ContainerBuilder->compile() (Line: 1293)
Drupal\Core\DrupalKernel->compileContainer() (Line: 898)
Drupal\Core\DrupalKernel->initializeContainer() (Line: 471)
Drupal\Core\DrupalKernel->boot() (Line: 705)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
User warning: Missing proxy class 'Drupal\Core\ProxyClass\StackMiddleware\KernelPreHandle' for lazy service 'http_middleware.kernel_pre_handle'. Use the following command to generate the proxy class: php core/scripts/generate-proxy-class.php 'Drupal\Core\StackMiddleware\KernelPreHandle' "core/lib/Drupal/Core" in Drupal\Core\DependencyInjection\Compiler\ProxyServicesPass->process() (line 61 of /var/www/html/mws_bundles/dietpet.vet/web/core/lib/Drupal/Core/DependencyInjection/Compiler/ProxyServicesPass.php).
Drupal\Core\DependencyInjection\Compiler\ProxyServicesPass->process(Object) (Line: 94)
Symfony\Component\DependencyInjection\Compiler\Compiler->compile(Object) (Line: 762)
Symfony\Component\DependencyInjection\ContainerBuilder->compile() (Line: 34)
Drupal\webpack_encore\Compiler\WebpackEncoreExtensionPass->process(Object) (Line: 94)
Symfony\Component\DependencyInjection\Compiler\Compiler->compile(Object) (Line: 762)
Symfony\Component\DependencyInjection\ContainerBuilder->compile() (Line: 1293)
Drupal\Core\DrupalKernel->compileContainer() (Line: 898)
Drupal\Core\DrupalKernel->initializeContainer() (Line: 471)
Drupal\Core\DrupalKernel->boot() (Line: 705)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
User warning: Missing proxy class 'Drupal\Core\ProxyClass\StackMiddleware\Session' for lazy service 'http_middleware.session'. Use the following command to generate the proxy class: php core/scripts/generate-proxy-class.php 'Drupal\Core\StackMiddleware\Session' "core/lib/Drupal/Core" in Drupal\Core\DependencyInjection\Compiler\ProxyServicesPass->process() (line 61 of /var/www/html/mws_bundles/dietpet.vet/web/core/lib/Drupal/Core/DependencyInjection/Compiler/ProxyServicesPass.php).
Drupal\Core\DependencyInjection\Compiler\ProxyServicesPass->process(Object) (Line: 94)
Symfony\Component\DependencyInjection\Compiler\Compiler->compile(Object) (Line: 762)
Symfony\Component\DependencyInjection\ContainerBuilder->compile() (Line: 34)
Drupal\webpack_encore\Compiler\WebpackEncoreExtensionPass->process(Object) (Line: 94)
Symfony\Component\DependencyInjection\Compiler\Compiler->compile(Object) (Line: 762)
Symfony\Component\DependencyInjection\ContainerBuilder->compile() (Line: 1293)
Drupal\Core\DrupalKernel->compileContainer() (Line: 898)
Drupal\Core\DrupalKernel->initializeContainer() (Line: 471)
Drupal\Core\DrupalKernel->boot() (Line: 705)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)

```

I tried the commands mentioned on the console but this also runs in circles and does not generate the proxy classes.

What I wonder is this command:

```
php core/scripts/generate-proxy-class.php 'Symfony\Component\HttpKernel\HttpKernel' "[namespace_root_path]"

```

Shouldn't there be a real path?

How can I solve this problem?

Should this be considered a bug? If yes where can I file a bug report?

# Answer
> 0 votes
I found the answer. I had to remove `$container->compile();` cause this is done by drupal in a later step.

---
Tags: dependency-injection, symfony-services
---


# Question
Title: displaying taxonomy term as a header in a view
I have a view that displays 3 latest articles from a certain taxonomy term. The issue im having is I need to display the taxonomy term as a Header. I dont see the \[field\_myterm\] under **Header** \> **Global : Text area.**. I also need this taxonomy term translated when I switch languages.

# Answer
> 0 votes
You should probably try to create a Taxonomy term View and not a Content View. Then, you could add a relationship (Taxonomy term : content with term) to fetch your node fields (or rendered entities). Add a taxonomy term filter to select your certain taxonomy term. Add a sort criteria based on descending post date (relationship with content). Display only 3 items. Finally, the taxonomy term name will become your View title and I guess you're done.

# Answer
> 0 votes
You can add the taxonomy term field in the list of fields that are shown for each node, and then use that field to group the results. It will give you a common header for the 3 nodes. It is not a view header, but with some CSS nobody will note it.

# Answer
> 0 votes
Have you tried the "Use replacement tokens from the first row"

You could create a hidden field and then you should see the twig token under "replacement patterns"

---
Tags: 7, views, taxonomy-terms
---


# Question
Title: How do I keep data without using sessions
Is there a way to store data for separate users in Drupal without using sessions. I have previously used Drupal varibales. But it didin't work because the variable gets updated for every user (So whenever I access the variable it shows the last users details). I can't use sessions because I have a horizontally scaled server, so when the server is changed the sessions will be deleted.

Is there a way to do this exactly as the sessions but without sessions? I need to save users data in the browser temporarily.

# Answer
> 0 votes
If you don't need your data server side, you could use cookies, using user\_cookie\_save. Or store your variables in window.localStorage (it's HTML5, see here for browser support) in your own javascript code/behavior, like :

```
function storePersistentValue() {

  //Check whether local storage is available or not

  if (window.localStorage) {

    window.localStorage.MyKey = "HTML 5 features";

  }

}

function getPersistentValue() {

  //Check whether local storage is available or not

  if (window.localStorage) {

    var text = window.localStorage.MyKey;

  }

}

```

# Answer
> 0 votes
You can use the user.data service to store user-specific data, that should persist across servers. This data is stored in the `{users_data}` table of the DB.

---
Tags: 8, sessions
---


title: How can I render form elements?

text:
# Question
Title: How can I render form elements?
In Drupal 6, I am using the following code.

```
$rows[] = array(
  array('data' => drupal_render($form['collected'])),
  array(
    'data'=> drupal_render($form['count']) . drupal_render($form['submit']),
    'colspan' => 3
  )
);

```

In Drupal 8, I am trying to use the following code, but I see the HTML markup of `$form['count']`.

```
$rows[] = [
  ['data' => \Drupal::service('renderer')->render(($form['collected'])],
  [
    'data' => \Drupal::service('renderer')->render($form['count']) . \Drupal::service('renderer')->render($form['submit']),
    'colspan' => 3,
  ]
];

```

# Answer
In Drupal 8+, you do not need to use a separate theming function as was required in Drupal 6. You can put the form element directly into the table without rendering, and Drupal will handle that on the back-end. It's much simpler:

```
$row = [];
$row[] = [
  'data' => [
    'something' => $form['something'],
    'something_else' => $form['something_else'],
  ],
];

$rows[] = $row;

```
> 0 votes

---
Tags: 8, forms
---


# Question
Title: Entityqueue - Get field values from the queue
First off, i'm very new to Drupal. Kindly help me and forgive if im being a noob.

Im using the module - **Entityqueue** https://www.drupal.org/project/entityqueue

Im created a view block for a entity queue that gets specific blog articles.

The problem im facing is that, this view only gets the blog title, and not the other custom fields within each blog.

Is there anyway to get the custom fields also ?

Thank you for your support.

EDIT: Please see below for screnshot of what i've done.

**Entityqueue**

**View Block**

If i select fields below, it doesn't get the custom field that are in the blog article.

# Answer
I have found a solution.

After you create the entity queue, go to view and create/edit a view block.

Select **Relationship** as **Content queue**, now you can get the fields in the fields section.

Hope this helps.
> 1 votes

---
Tags: views, entities, blocks
---


# Question
Title: Views taxonomy for multiple content types
I have three different content types: News, Events and Resources. They all use the same set of taxonomy so that all content is tagged with the same categories.

I want to build a view with the taxonomy terms exposed so that they can be searched by users.

However, I seem to have to add each as a separate field, which looks quite messy.

I've tried a grouped filter, however, no results are found when I know they exist.

# Answer
You can achieve this by using views :

1. Create a new view with show content of type ALL -\> continue and edit
2. Under format select show fields
3. Under filter criteria select Content: Has taxonomy term and select selection type Drop down later check Expose this filter to visitors, to allow them to change it and click apply

Result : You can have an exposed filter with taxonomy term that filters the contents irrespective of content type
> 6 votes

# Answer
Did you create a new field referencing the terms per content type or did you add an existing field to each content type?

If you create the field once and add it to many content types, it works in views. As long as you have no content type filters in the view.
> 0 votes

# Answer
I found that there is a bug in the views filter that it won't show content from multiple content types using the same taxonomy tag unless the content is tagged as "published" regardless of how the view is configured for the published flag.
> 0 votes

---
Tags: taxonomy-terms, views
---


# Question
Title: Filter by text of a field of an entity displayed in a view
I have following content types: "Person" and "Publication" and I'm showing the publications using a view on a page, showing title, year, venue and authors. The authors in "Publication" are referenced to "Person" via entity reference.

I added filter criteria so the users visiting the page can search publications based on title, author etc. The problem now is, that the field for searching by author only accepts the author's entity ID. But I want the user to search by a part of the author's name (either the entity title or a specific field in the "Person" entity).

What would be the best way to do this? I tried different ways via contextual filters, relationships and entity reference on the view, but neither of them worked for me, or I made something wrong. Any help would be appreciated!

# Answer
Entity Reference Fields only store the entity ID. To pull other information about the referenced entity into the Views you need to add the Relationship for the ER field.

It will be called something like **Content referenced from field\_person**.

Once you add that Relationship you unlock new Fields and Filters inside Views that relate to the Person entity.

You can now add (Content) Title Filter that uses the Relationship and it will filter text within the Title Field of the Person Content Type.

Without the Relationship the Title Field/Filter will show information about the Publication, the base type chosen for that particular View.

The same goes for other Fields/Filters. If you make them use the Relationship they will pull information from People CT.

Fields/Filters that only exist on People CT will have the Relationship prefilled, as a requirement (because that data isn't accessible in that View without the Relationship).
> 2 votes

---
Tags: views, nodes
---


# Question
Title: Is there anyway create relationship for filter criteria which has vocabularies( state, city and location)?
list of available Vocabularies in my content type.

* Country(Term: US)
* State (Terms: CA , CO, DE.. etc)
* City (Terms:Fremont, Irwin, Los Angeles, Monument etc..)
* Location(Terms: All loacations)

I'm trying to create a view for published content result which uses above vocabularies. I need to expose filters to the users where I added above vocabulary fields. How to create a relationship to select particular state-\>city-\> location (For ex: State(CA)-\>City(Fremont)-\>location(xxx-fremont))

Below is the example filter. Please help. Thank you!

# Answer
> 0 votes
The **Relationship** option in Views tracks entity references, so to use that option, you have to create Entity References among your terms. In taxonomy terms, the parent and grandparent are entity references.

Generally speaking, Views can only use a data structure that already exists in the database, or can be built from other structures in the database; it can't create a structure "out of thin air."

**One approach: Using parents and grandparents**

To use parents and grandparents, you would have to delete your current terms and re-structure them like this:

* Grandparent: Country
* Parent: State
* Child: City

You can do this by setting the parent when you create each term:

* Countries have no parent
* States have a country as parent
* Cities have a state as parent

Since there are no rules that enforce this structure unless you code the rules yourself, you have to be careful to make sure you set things correctly.

If you take this approach, you can add relationships to get the parent / grandparent under **Relationships** in Views, but making the filters by country / state / city will be a pain.

**Alternative approach that will make it easier to add the filters but that is harder to maintain**

Keep the vocabularies independent. Add an entity reference field (term reference) to the **State** term type called **Country** and let users select a country.

Add two more entity reference fields (term reference) to the **City** term type called **State** and **Country**.

Then you have to set the correct country for each state, and state and country for each city.

Then, in your View, you can simply show a list of cities, and the filters for Country, State, and City will work for cities as you expect.

Note, however, that if a country or state has no cities, no entries will appear. This is because we set this View to only show the list of cities to make setting up the filters easier.

---
Tags: 8, views, taxonomy-terms
---


title: Webform import via Webform Share

text:
# Question
Title: Webform import via Webform Share
Question: How can I import a Webform via the https://drupal.org/project/webform\_share API?

What do I know/current state: The API shows a graphical UI to do it, but I'd need a way to do it via an exported function, if any (e.g. a function call like webform\_share\_import($formspec)).

Reason/scenario: Because I want to install some forms in the .install of a module.

# Answer
> 1 votes
Found: there's not an exported API, but an implementation of a regular form hook for the UI, which does all the magic (webform\_share.module:123).

# Answer
> 0 votes
See this issue.

In the comments, it shows that there is a function called `_webform_share_eval()` in the webform\_share.module file.

```
function _webform_share_eval($str) {
  eval($str);
  return empty($webform) ? FALSE : $webform;
}

```

It's very simple to use this to import a webform and save a node.

```
// Create the node
$node = new stdClass();
$node->type = 'webform';
$node->title = 'Contact Us';
$node->status = 1;
node_object_prepare($node);

// Import the webform
$node->language = 'und';
$node->webform = _webform_share_eval(file_get_contents(drupal_get_path('module', 'mymodule') . '/webform.txt'));
node_save($node);

```

# Answer
> 0 votes
For Drupal 8/9 and Webform 6, there is now a Webform Share submodule in Webform itself.

This can be used to use webforms in decoupled situations.

There is a video tutorial here.

Basic config info for global sharing of webforms:

First, go to `/admin/structure/webform/config` and *Enable form sharing* under **Form share settings**.

Then go to `/admin/structure/webform`, click the more info triangle, select **Share**, and then choose from among the three options to embed your webform.

---
Tags: webforms, installation, importing-exporting
---


# Question
Title: How can I embed a webform in an Ionic React app?
Webform has a Share submodule that can be used in decoupled situations.

There is a video tutorial here.

However, I'm having trouble getting my webform embedded in my Ionic React app.

What I have done

1. Went to `/admin/structure/webform/config` and selected *Enable form sharing* under **Form share settings**.
2. Went to `/admin/structure/webform`, clicked the more info triangle, selected **Share**.

I now have the option to choose from JavaScript, Resizing iframe, and Fixed iframe, but all of these use `document.write`, which won't work with Ionic because the document has already been written.

# Answer
Here is specifically how to do this in Ionic + React.

First, Webform share uses the iframe-resizer library, which has an official react component.

So install the library into your app:

`npm install iframe-resizer-react`

Then add a component such as **WebformContact.tsx** (this example uses TypeScript):

```
import * as React from 'react';
import {
  IonContent, IonPage,
} from '@ionic/react';
import IframeResizer from 'iframe-resizer-react';

const styleWebformIframeEmbed: React.CSSProperties = {
  width: '1px',
  minWidth: '100%',
};

const WebformContact = () => (
  <IonPage>
    <IonContent>
      <IframeResizer
        src="https://example.com/webform/MY-WEBFORM-MACHINENAME/share/iframe-resizer/4.2.10"
        title="MY WEBFORM TITLE"
        frameBorder="0"
        allowFullScreen
        style={styleWebformIframeEmbed}
      />
    </IonContent>
  </IonPage>
);
export default WebformContact;

```

Note that you need to install the same version of `iframe-resizer` in both webform (drupal) + your ionic app.

Also note that if your site is `https`, you should be sure to specify that in the `src` tag; when React is hosted by Ionic, it will be run from http://localhost (Android) or http://capacitor (iOS), so if you do not specify `https` for the server, you will get a difficult to understand error:

> iframeResizer.js:822 Failed to execute 'postMessage' on 'DOMWindow': The target origin provided

But really what this means is that you are trying to access an https server in an iframe with http. So specify https!
> 1 votes

---
Tags: webforms
---


# Question
Title: How can I reference an entity field in a template file?
I am trying to theme the node add/edit form for a custom content type (for example, *Album*). I implemented `hook_form_alter()` in the theme.

```
function mytheme_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {
  switch ($form_id) {
    case "node_album_form":
      $form['#theme'] = ['node_album_edit_form'];
      break;
  }
}

```

That correctly intercepts the node add/edit form and passes it to my theme hook which also finds the correct template.

```
function mytheme_theme() {
  return [
    'node_album_form' => [
      'template' => 'node_album_edit_form',
      'path' => \Drupal::theme()->getActiveTheme()->getPath() . '/scss/templates/album',
      'render element' => 'form'
    ],
  ];
}

```

In *node\_album\_edit\_form.html.twig*, I can confirm that changes there alter only the album add/edit form and that I can remove elements with `{{ form|without('advanced', 'footer', 'actions') }}`, for example.

What I cannot do is placing the form fields where I want them because I'm not using the right reference to the field.

```
<div class='myfancydiv album-title-field'>{{ field_album_title }}</div>
<div class='myfancydiv album-artist-field'>{{ field_artist }}</div>

```

I tried any of the following, but they didn't work.

* `{{ field_album_title }}`
* `{{ form.field_album_title }}`
* `{{ album_title }}`

How can I reference an entity field in a template file?

# Answer
Change your hook\_theme code to:

```
function mytheme_theme() {
  return [
    'node_album_edit_form' => [
      'path' => \Drupal::theme()->getActiveTheme()->getPath() . '/scss/templates/album',
      'render element' => 'form'
    ],
  ];
}

```

and in your template file

```
{{ form.field_album_title }}

```
> 0 votes

---
Tags: 8, theming, forms
---


title: Full phrase search

text:
# Question
Title: Full phrase search
Now I'm using "Search\_api" module and when I input, for example, "test case" - it's output all articles which consists both of this words separately. But I want to make search with exact phrase "test case". How can I do it? Maybe there is another module, or I can rework this one?

# Answer
You can create a custom view to override/bypass the default Drupal search form.

In the view, setup an exposed filter for the search phrase (appearing in either a specific field or combined set of fields), with the operator set to "CONTAINS ALL WORDS." For a breakdown of the differences between "Contains" and "Contains Any Word", see https://www.drupal.org/node/1744880

One thing to consider when setting up this search form and exposing it is user intent- how likely is the user searching the site going to know exact phrasing? You might want to use "Contains any word".

For an example of building a custom search form with multiple field search via views, see this "Views Exposed Filters Multiple Field Search" blog post.
> 0 votes

# Answer
Stepwise answer is as follows -

1. Go to your view
2. Go to your exposed filter field - which is showing filter on the page
3. Select "Contains all Words" operator

please have look on this link Using views exposed filter
> -1 votes

---
Tags: 7, search
---


title: Get the vocabulary ID by term or node

text:
# Question
Title: Get the vocabulary ID by term or node
I am going to check whether a term belongs to a designated vocabulary.

Which function is used to get vocabulary by term or node?

# Answer
> 15 votes
In Drupal 6, if you know the taxonomy term ID, you can get the vocabulary ID by using the following code:

```
$term = taxonomy_get_term($tid);
$vid = $term->vid;

```

If you have a node ID, then you can use the following code to get the vocabulary ID of all the taxonomy terms associated with the node using the following code:

```
$node = node_load($nid);
$vids = array();

if (!empty($node->taxonomy)) {
  foreach ($node->taxonomy as $tid => $term) {
    $vids[] = $term->vid;
  }
}

```

In Drupal 7, the code would be the following:

```
$term = taxonomy_term_load($tid);
$vid = $term->vid;

```

In Drupal 7, the node property `$node->taxonomy` doesn't exist anymore. Instead, there is `$node->field_<vocabulary_name>`, which is an array with two different structures.

* tags
* other taxonomy terms

Using field\_get\_items(), you would get the taxonomy terms in the language they would be displayed, or in the language whose code is passed as argument to the function.

```
$items = field_get_items('node', $node, $field_name);

```

`$node` contains the node object, and `$field_name` the name of the taxonomy term field.

`$items` contains a simplified array, compared to the array contained in `$node->field_<vocabulary_name>`.

# Answer
> 1 votes
For Drupal 7 the above code should be like this:

```
 $tid = 18;
 $vid = db_query('SELECT vid FROM {taxonomy_term_data} WHERE tid = :tid',
                  array(':tid' => $tid)
                )->fetchField();
 echo $vid;

```

See more examples at db\_query() drupal 7 function.

# Answer
> 0 votes
Solved by the code below:

```
$tid = 18;
$result = db_query("SELECT vid FROM {term_data} WHERE tid = %d", $tid);
$vid = db_result($result);
echo $vid;

```

# Answer
> 0 votes
In Drupal 8 :

First load the term using termId as follows :

```
use Drupal\taxonomy\Entity\Term;
$term = Term::load($termId);
$vocabularyId = $term->getVocabularyId();

```

---
Tags: taxonomy-terms
---


# Question
Title: Custom normalizer throws error once enabled
I wrote a custom normalizer last year to alter link output (using https://www.mediacurrent.com/blog/using-normalizers-alter-rest-json-structure-drupal-8/ as reference) for use with JSON:API output, which worked like a charm. However, at the moment I get a big error (see below) when I've enabled the module.

The error:

```
TypeError: Adaptor Drupal\jsonapi_extras\Plugin\ResourceFieldEnhancerBase returned invalid output data: [] in Drupal\jsonapi_extras\Plugin\ResourceFieldEnhancerBase->undoTransform() (line 66 of /vendor/e0ipso/shaper/src/DataAdaptor/DataAdaptorTransformerTrait.php).
Drupal\jsonapi_extras\Plugin\ResourceFieldEnhancerBase->undoTransform(Array, Object) (Line: 65)
Drupal\jsonapi_extras\Normalizer\ResourceIdentifierNormalizer->normalize(Object, 'api_json', Array) (Line: 143)
Symfony\Component\Serializer\Serializer->normalize(Object, 'api_json', Array) (Line: 62)
Drupal\jsonapi\Serializer\Serializer->normalize(Object, 'api_json', Array) (Line: 26)
Drupal\jsonapi\Normalizer\DataNormalizer->Drupal\jsonapi\Normalizer\{closure}(Object)
array_map(Object, Array) (Line: 27)
Drupal\jsonapi\Normalizer\DataNormalizer->normalize(Object, 'api_json', Array) (Line: 143)
Symfony\Component\Serializer\Serializer->normalize(Object, 'api_json', Array) (Line: 62)
Drupal\jsonapi\Serializer\Serializer->normalize(Object, 'api_json', Array) (Line: 26)
Drupal\jsonapi\Normalizer\RelationshipNormalizer->normalize(Object, 'api_json', Array) (Line: 143)
Symfony\Component\Serializer\Serializer->normalize(Object, 'api_json', Array) (Line: 62)
Drupal\jsonapi\Serializer\Serializer->normalize(Object, 'api_json', Array) (Line: 187)
Drupal\jsonapi\Normalizer\ResourceObjectNormalizer->serializeField(Object, Array, 'api_json') (Line: 121)
Drupal\jsonapi\Normalizer\ResourceObjectNormalizer->getNormalization(Array, Object, 'api_json', Array) (Line: 73)
Drupal\jsonapi\Normalizer\ResourceObjectNormalizer->normalize(Object, 'api_json', Array) (Line: 38)
Drupal\jsonapi_extras\Normalizer\JsonApiNormalizerDecoratorBase->normalize(Object, 'api_json', Array) (Line: 24)
Drupal\jsonapi_extras\Normalizer\ResourceObjectNormalizer->normalize(Object, 'api_json', Array) (Line: 143)
Symfony\Component\Serializer\Serializer->normalize(Object, 'api_json', Array) (Line: 62)
Drupal\jsonapi\Serializer\Serializer->normalize(Object, 'api_json', Array) (Line: 26)
Drupal\jsonapi\Normalizer\DataNormalizer->Drupal\jsonapi\Normalizer\{closure}(Object)
array_map(Object, Array) (Line: 27)
Drupal\jsonapi\Normalizer\DataNormalizer->normalize(Object, 'api_json', Array) (Line: 143)
Symfony\Component\Serializer\Serializer->normalize(Object, 'api_json', Array) (Line: 62)
Drupal\jsonapi\Serializer\Serializer->normalize(Object, 'api_json', Array) (Line: 193)
Drupal\jsonapi\Normalizer\JsonApiDocumentTopLevelNormalizer->normalize(Object, 'api_json', Array) (Line: 143)
Symfony\Component\Serializer\Serializer->normalize(Object, 'api_json', Array) (Line: 62)
Drupal\jsonapi\Serializer\Serializer->normalize(Object, 'api_json', Array) (Line: 120)
Drupal\jsonapi\EventSubscriber\ResourceResponseSubscriber->renderResponseBody(Object, Object, Object, 'api_json') (Line: 85)
Drupal\jsonapi\EventSubscriber\ResourceResponseSubscriber->onResponse(Object, 'kernel.response', Object)
call_user_func(Array, Object, 'kernel.response', Object) (Line: 111)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch('kernel.response', Object) (Line: 191)
Symfony\Component\HttpKernel\HttpKernel->filterResponse(Object, Object, 1) (Line: 173)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 68)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 57)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 52)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 708)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)

```

My services.yml

```
services:
  custom_normalizer.typed_data:
    class: Drupal\custom_normalizer\Normalizer\LinkNormalizer
    tags:
      - { name: normalizer, priority: 10 }

```

The LinkNormalizer file:

```
<?php

namespace Drupal\custom_normalizer\Normalizer;

use Drupal\Core\Url;
use Drupal\link\Plugin\Field\FieldType\LinkItem;
use Drupal\serialization\Normalizer\NormalizerBase;

/**
 * Converts typed data objects to arrays.
 */
class LinkNormalizer extends NormalizerBase
{
    /**
     * The interface or class that this Normalizer supports.
     *
     * @var string
     */
    protected $supportedInterfaceOrClass = 'Drupal\Core\TypedData\TypedDataInterface';

    /**
     * {@inheritdoc}
     */
    public function normalize($object, $format = null, array $context = array())
    {
        $value = $object->getValue();
        $parent = $object->getParent();
        if ($parent instanceof LinkItem) {
            $internalLink = $parent->get('uri')->getValue();
            $link = Url::fromUri($internalLink, array('absolute' => false))->toString();
            $object->getParent()->get('options')->setValue(['url' => $link]);
        }
        return $value;
    }
}

```

If anyone has an idea what I'm doing wrong (or what has changed), that would be great. I haven't found anything useful yet.

Stephan

# Answer
Your normalizer is basically a null function:

```
$value = $object->getValue();

```

You return typed data values without applying any changes.

You are only doing this to get hold of a different object, the parent field. This is not what the method is supposed to do according to the interface. The result is unpredictable. Instead try to target the normalization process of the field or entity directly.
> 0 votes

---
Tags: 8
---


# Question
Title: How can I access webform submission values from webform-confirmation.html.twig
I have a webform with Inline confirmation, AJAX enabled and saving of submissions disabled.

Is it possible to access the submitted values from the `webform-confirmation.html.twig` template?

I know that I can do this by adding token values to the Confirmation message in the WebForm UI. But I prefer to solve this by modifying the template.

My motivation for doing this is that I need to add a javascript snippet after the user has submitted the form. And I want to do it at the template level because I have a larger number of forms where I need to add the javascript snippet.

Cheers

Stian

# Answer
You can access submissions using 'webform\_submission' variable. I know the webform-confirmation template file doesn't mention that variable but, if you look closely to the controller you see there additional variable being passed to this template.

N.B on your form setting make sure to set confirmation type to be "age (redirects to new page and displays the confirmation message)"

And always the latest one on the array is your last submission.
> 1 votes

# Answer
webform\_confirmation is a hook\_theme so you can preprocess it yourmodule\_preprocess\_webform\_confirmation , get webform\_submission related ( $variables\['webform\_submission'\] ) and create any variable you need into this preprocess. YOu will find all the variable here : template\_preprocess\_webform\_confirmation() in webform module.
> 0 votes

---
Tags: theming, webforms
---


title: Newbie Taxonomy and Content Question

text:
# Question
Title: Newbie Taxonomy and Content Question
I'm new to Drupal (having used Perch CMS and PHP for years). Forgive me if I bumble the terminology a bit. I've been furiously going over documentation and tutorials. Sorry in advanced for being verbose.

Using Drupal 9 with a Bootstrap 5 template I'm developing - I'm looking to create a page that has a listing of downloadable PDFs that are categorized into groups and subgroups - these will eventually be placed in nested accordions on a page:

**DOCUMENT LIBRARY**

== Category A

==== Sub Category AA

====== Content: Has title, image and file link

==== Sub Category AB

====== Content: Has title, image and file link

== Category B

==== Sub Category BA

====== Content: Has title, image and file link

====== Content: Has title, image and file link

==== Sub Category BB

***What I've done so far:*** I've setup a vocabulary tree that matches the structure I need. I also created a content type that meets the needs of each content item and have added taxonomy to the content form display. Created a view that show the content type.

***What I need to do:*** Cycle through the taxonomy tree structure to create the accordions, showing the taxonomy term name and then nest each content item that matches the taxonomy term.

***What I need from the community:*** Make sure I'm going down the right path and that I'm not misusing Drupal in this way. Also, any tips and/or things I should search for would be helpful. I'm pretty comfortable with theming (twig).

# Answer
One way to implement this, assuming that you will show the entire document library as a block.

I'll build this in reverse order because in Drupal, there is no "tree" structure; philosophically, Drupal adopts a "tag" (multivalue) structure, so you have to nudge the tags into a tree structure.

This can seem like a disadvantage coming from a tree-based system, but it's one of Drupal's strengths because tags allow for multiple parents.

So first, for each sub category, create a view mode called "Show documents".

View mode creation path: `/admin/structure/taxonomy/manage/MY_VOCAB_MACHINE_NAME/overview/display`, scroll down and choose "Manage view modes" under "Custom settings."

After adding the view mode, go back to `/admin/structure/taxonomy/manage/MY_VOCAB_MACHINE_NAME/overview/display`, check the box for "Use custom display settings for the following view modes" and press Save.

Now you can edit this view mode to get the display of content you want.

For that, I would create a view. This view should use a contextual filter to get the current taxonomy term, and then it should use fields to list the title, image, and file link. The display mode should be block.

After you create the view, enable the Layout Builder module. This will allow you to completely customize the layout per view mode.

Now, you can go back to the view mode page and attach the block showing the content to the term. Depending on how you implement the accordions, you should be able to adjust the CSS classes in Layout Build and the Views UI (for the block) to get what you want. Using a view mode will also let you target a theme template specifically to that view mode.

Finally, you can make another view (block) of the sub categories, this time grouping them by parent. And then set the view to show the display mode of the sub categories to the view mode that you created earlier, which will automatically bring in all the accordions.

This is not the only way to do this; another way is to use the *embed* feature of views, which lets you embed one view inside another.
> 0 votes

---
Tags: views, theming, taxonomy-terms
---