Drupal StackExchange

How to build multivalue form elements using Form API

5 days 17 hours ago

With the 'field collections' module at the form level, you can create a fieldset (or 'field group') that will accept multiple sets of values.

Is there a way to do this with the Form API directly (or with the help 'field collections' or 'field group' module) programmatically. I can make the form fieldset easy enough, but I'm not sure how to set multiple values for this set. In fact, I'm not really sure how you define multiple values for any field with the Form API.

UPDATE: Just to be clear I want to create the form, not the entity itself (at least not yet). I want to use the Form API to accomplish this to make my own $form – just the form.

Joe

Webform mail formatting broken after moving to symfony-mailer-lite from swiftmailer

5 days 17 hours ago

In march 2024 we left swiftmailer and switched to symfony-mailer-lite.

Everything looked well until we found that the font for mails which had no template specified in our theme had a default font like times new roman instead of arial.

We then took the mail template from the old swiftmailer and put it in our theme thought this will fix it.

It did fix it for the font but not for the formatting. Before any Element title was bold and styled in the mails now only plain text.

So now I wonder if there is something else we missed.

Here are two mails, the first is from february and contains all the style info. The second is from now.

<html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"><style type="text/css"> table tr td { font-family: Arial; font-size: 12px; } </style> </head> <body> <div> <table width="800px" cellpadding="0" cellspacing="0"> <tr> <td> <div style="padding: 0px 0px 0px 0px;"> <p>Gesendet am: Fr., 26.04.2024 - 19:35</p> <p>Gesendet von: admin</p> <p>Gesendete Eingaben:</p> <b>Anrede</b><br>Familie<br><br><b>Vorname</b><br>Dixisset<br><br><b>Nachname</b><br>Loremipsum<br><br><b>Straße</b><br>Dixisset<br><br><b>Hausnummer</b><br>Oratione<br><br><b>PLZ</b><br>Loremipsum<br><br><b>Ort</b><br>Loremipsum<br><br><b>E-Mail</b><br><a href="mailto:test@test.com">test@test.com</a><br><br><b>Telefonnummer</b><br>Oratione<br><br><b>Betreff</b><br>Loremipsum<br><br><b>Ihr Anliegen</b><br>Quae cum dixisset, finem ille. Quamquam non negatis nos intellegere quid sit voluptas, sed quid ille dicat. Progredientibus autem aetatibus sensim tardeve potius quasi nosmet ipsos cognoscimus. Gloriosa ostentatio in constituendo summo bono. Qui-vere falsone, quaerere mittimus-dicitur oculis se privasse; Duarum enim vitarum nobis erunt instituta capienda. Comprehensum, quod cognitum non habet? Qui enim existimabit posse se miserum esse beatus non erit. Causa autem fuit huc veniendi ut quosdam hinc libros promerem. Nunc omni virtuti vitium contrario nomine opponitur.<br><br><b>Weitergabe von personenbezogenen Daten</b><br>Ich bin nicht damit einverstanden, dass meine in diesem Formular erhobenen personenbezogenen Daten zum Zweck der Beantwortung meiner Anfrage an andere Behörden der Landesverwaltung, Bundes- oder kommunale Behörden weitergeleitet werden. Wir weisen vorsorglich darauf hin, dass Ihre Anfrage u. U. nicht beantwortet werden kann, wenn Sie hiermit nicht einverstanden sind.<br><br> </div> </td> </tr> </table> </div> </body> </html>

The current one:

<!-- THEME DEBUG --><!-- THEME HOOK: 'symfony_mailer_lite_email' --><!-- FILE NAME SUGGESTIONS: * symfony-mailer-lite-email--webform--kontakt-e-mail.html.twig * symfony-mailer-lite-email--webform.html.twig x symfony-mailer-lite-email.html.twig --><!-- BEGIN OUTPUT from 'themes/custom/hw_radix_standard/templates/mail/symfony-mailer-lite-email.html.twig' --><html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"><style type="text/css"> table tr td { font-family: Arial; font-size: 12px; } </style> </head> <body> <div flags="63"> <table width="800px" cellpadding="0" cellspacing="0"> <tr> <td> <div style="padding: 0px 0px 0px 0px;"> <b>symfony-mailer-lite-email</b> <!-- THEME DEBUG --> <!-- THEME HOOK: 'webform_email_message_html' --> <!-- FILE NAME SUGGESTIONS: * webform-email-message-html--kontakt--email--e-mail.html.twig * webform-email-message-html--kontakt--email.html.twig * webform-email-message-html--kontakt.html.twig x webform-email-message-html.html.twig --> <!-- BEGIN OUTPUT from 'modules/contrib/webform/templates/webform-email-message-html.html.twig' --> <b>webform-email-message-html</b> <p>Gesendet am: Fr., 26.04.2024 - 13:44</p> <p>Gesendet von: admin</p> <p>Gesendete Eingaben:</p> <p> Anrede<br>Frau</p> <p> Vorname<br>Dixisset</p> <p> Nachname<br>Dixisset</p> <p> Straße<br>Oratione</p> <p> Hausnummer<br>Oratione</p> <p> PLZ<br>Oratione</p> <p> Ort<br>Loremipsum</p> <p> E-Mail<br><a href="mailto:test@test.com">test@test.com</a></p> <p> Telefonnummer<br>Oratione</p> <p> Betreff<br>Loremipsum</p> <p> Ihr Anliegen<br>Quae cum dixisset, finem ille. Quamquam non negatis nos intellegere quid sit voluptas, sed quid ille dicat. Progredientibus autem aetatibus sensim tardeve potius quasi nosmet ipsos cognoscimus. Gloriosa ostentatio in constituendo summo bono. Qui-vere falsone, quaerere mittimus-dicitur oculis se privasse; Duarum enim vitarum nobis erunt instituta capienda. Comprehensum, quod cognitum non habet? Qui enim existimabit posse se miserum esse beatus non erit. Causa autem fuit huc veniendi ut quosdam hinc libros promerem. Nunc omni virtuti vitium contrario nomine opponitur.</p> <p> Weitergabe von personenbezogenen Daten<br>Ich bin damit einverstanden, dass meine in diesem Formular erhobenen personenbezogenen Daten zum Zweck der Beantwortung meiner Anfrage an andere Behörden der Landesverwaltung, Bundes- oder kommunale Behörden weitergeleitet werden. </p> <!-- END OUTPUT from 'modules/contrib/webform/templates/webform-email-message-html.html.twig' --> </div> </td> </tr> </table> </div> </body> </html> <!-- END OUTPUT from 'themes/custom/hw_radix_standard/templates/mail/symfony-mailer-lite-email.html.twig' -->

We did not have any special template with all the styles for the mail body.
So I wonder where this information did come from before. Any changes in webform module, core or is symfony-mailer just dropping it?

Found this issue in symfony-mailer-lite https://git.drupalcode.org/project/symfony_mailer_lite/-/commit/623c53acc21bd1d82fad41bec7cfd8eacd1e7546 and changed the config to not use the default content in the message settings of symfony-mailer-lite - but no change to the behaviour. Somehow the HTML of message.body from webform gehts stripped.

macbert

PHPUnit Test run Error with ConfigFactory

5 days 18 hours ago

I'm running an error with the following test I wrote including some config. I don't know if my test is even properly written so any advice in improving that code is welcomed. Since my test is not finish yet, dont mind the self::assertTrue(TRUE);

Here is my Test :

namespace Drupal\mymodule\Tests\Service; use Drupal\Component\Serialization\Json; use Drupal\Core\DependencyInjection\ContainerBuilder; use Drupal\Core\Url; use Drupal\Tests\UnitTestCase; use Drupal\mymodule\Service\MyClass; /** * MyClass Test. * * @group mymodule */ class MyClassTest extends UnitTestCase { private $params; protected $configFactory; protected $loggerFactory; protected $container; protected $myClass; /** * Set Up. */ public function setUp() { parent::setUp(); $this->configFactory = $this ->getConfigFactoryStub([ 'mymodule.settings' => [ 'api' => [ 'hostname' => 'https://example.com', 'periodbars_uri' => '/api/v2.0/articles', 'api_key' => 'aaabbbcccdddeeefffzzz', ], ], ]); $this->container = new ContainerBuilder(); $this->container ->set('config.factory', $this->configFactory); \Drupal::setContainer($this->container); $this->loggerFactory = $this ->getMockBuilder('Drupal\Core\Logger\LoggerChannelFactoryInterface') ->disableOriginalConstructor() ->getMock(); $this->params = [ 'criteria' => [ 'id' => '1', ], ]; $this->myClass = new MyClass($this->configFactory, $this->loggerFactory); } /** * Test API Accor Fetcher. */ public function testMyClass() { $params = Json::encode($this->params); $url = 'https://example.com/api/v2.0/articles'; $this->myClass->myClassRequest($url, $params, 'FR'); self::assertTrue(TRUE); } }

And here is the class I test :

namespace Drupal\mymodule\Service; use Drupal\Core\Config\ConfigFactoryInterface; use Drupal\Core\Logger\LoggerChannelFactoryInterface; use Psr\Http\Message\ResponseInterface; use GuzzleHttp\Client; use GuzzleHttp\Psr7\Request; use GuzzleHttp\Pool; use GuzzleHttp\Exception\ClientException; use GuzzleHttp\Exception\ServerException; use Drupal\Core\Url; /** * Provides all the functions to call MyClass Webservices. */ class MyClass { protected $configFactory; protected $loggerFactory; /** * AccorWebService constructor. * * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory * Config Factory. * @param \Drupal\Core\Logger\LoggerChannelFactoryInterface $logger_factory * Logger Factory. */ public function __construct(ConfigFactoryInterface $config_factory, LoggerChannelFactoryInterface $logger_factory) { $this->configFactory = $config_factory; $this->loggerFactory = $logger_factory; } /** * The Guzzle Request. * * @param string $url * The url of the webservice to call. * @param string $params * The params to be sent to the webservice formatted in JSON. * @param string $langcode * The langcode to call the webservice. * * @return \Psr\Http\Message\StreamInterface|null * The response from the webservice. */ public function myClassRequest($url, $params, $langcode = 'FR') { $api_key = $this->configFactory->get('mymodule.settings')->get('api.api_key'); $headers = [ 'apikey' => $api_key, 'Content-Type' => 'application/json', 'Accept-Language' => $langcode, ]; $client = new Client(); $response = NULL; try { $request = $client->request('POST', $url, [ 'headers' => $headers, 'body' => $params, ]); $response = $request->getBody(); } catch (ClientException $e) { $this->loggerFactory->get('mymodule') ->error($e->getMessage()); } catch (ServerException $se) { $this->loggerFactory->get('mymodule') ->error($se->getMessage()); } return $response; }

When I run the Test in PHPStorm, I get Call to a member function get() on null on the line where the code is : $api_key = $this->configFactory->get('mymodule.settings')->get('api.api_key');

pbonnefoi

Domain Access: Edit admin/domain/content/ display settings, filters etc

5 days 19 hours ago

I am using Drupal Commerce and Domain Access module and I wonder where I could be able to edit how page admin/domain/content is displayed. I would expect to find a View page which is utilised by this module to show content and to allow to add filters and fields.

I have got a multi-domain site with thousands of products and I need to filter content by manufacturer or other field and to assign all products with desirable keywoord to selected domains.

Am I missing anything? I have not found any corresponding View. Thank you for an answer

liam dupin

Add CSS classes to theme function

5 days 20 hours ago

I'm implementing hook_theme() in a custom module.

function monitor_chart_theme() { return array( 'chart_monitor' => array( 'template' => 'monitor_chart', 'variables' => array( 'container' => null, 'theme' => null, 'classes' => null, 'chart' => null, ), ), ); }

On the template file, I would like to add additional CSS classes the theme function gets in its parameters. I declared a preprocess function with the following code.

function monitor_chart_preprocess_chart_monitor(&$vars) { if ($vars['classes']) { foreach ($vars['classes'] as $class) { $vars['classes_array'][] = $class; } } }

The template file contains the following code.

<div id="<?php print $container; ?>" class="<?php print $classes; ?>"></div>

If I don't use the preprocess function, the class attribute of <div> contains just 'chart-monitor', the name of the theme function.

Is there a more elegant way to pass extra variables to a template file?

arrubiu

Twig cache files on load-balanced setup

5 days 22 hours ago

The Twig cache key (twig_cache_prefix) is based the modify timestamp of the Twig template file and a randomly generated key. This gives a problem with a load-balanced Drupal setup where every host has it own copy of the Drupal source files, with different timestamps for the same template files across the hosts.

In this setup each Drupal instance keep generating a new prefix for every other request (when the balancer is in round-robin mode).

Is there a workaround for this?

Lennert

A little question about Webform Views Integration

5 days 22 hours ago

Have set up the Webform module with Webform Views Integration. Created an additional view for webform submissions via cloning and alteration of 'Embed:Default', applied there a function from Views Aggregator Plus' armory to count the values in the fields. Then integrated that view into the submissions' table with considerable ease, gaining a dropdown that contains two views: default (Submissions) and custom (Quantity). How to switch them to get Quantity as default submissions' view?

Dre

Specify which Migrate entries need to be updated using prepareRow

5 days 23 hours ago

I have made a Migration that i run with Cron. My highwater field is the date changed, which is present in the XML (source) document. Then I do this in my cron function:

$result = $migration->prepareUpdate(); $result = $migration->processImport();

Problem is is this will update ALL nodes from the XML. I would like to only update those that have been changed, according to their modifiedAt date. If I just do:

$result = $migration->processImport();

Then nothing at all updates. I think processImport() would work if it were just about importing new items, but I also need to update any existing items that have changed. The ones that don't need updating can be skipped, of course. Is there another method I could call here? Is there a way I need to set up some kind of prepareRow to mark items as needing updating?

blablazo

How do I create an instance of an entity with all its fields attached?

6 days ago

I am trying to create an instance of 'commerce_customer_profile' entity with all the extra fields of the customers address.

I am doing this inside a FeedsProcessor that will import users and their addresses from Magento.

I don't want to have to create a fake $form_state array and then use field_attach_submit() as it doesn't seem right to me.

The only other way I have found so far is:

$billing_profile = commerce_customer_profile_new('billing', $entity->uid); commerce_customer_profile_save($billing_profile); $full_billing_profile = commerce_customer_profile_load($billing_profile->profile_id);

$entity is the current user being created.

Which will then give me an empty instance of the new entity ready to populate and save but again it doesn't feel right.

Any help appreciated.

jbloomfield