Account created on 4 June 2012, over 12 years ago
  • Drupal Developer at Gizra 
#

Merge Requests

More

Recent comments

🇷🇸Serbia miksha

I tested 11.x locally and it still has the same issue that my patch in #20 fixes. I created a new MR against 11.x and combined changes from both #13 & #20 patches. For me this fixes the AJAX error when translator role user has permissions like defined in issue description under Steps to reproduce but at the same time has no edit permissions.

🇷🇸Serbia miksha

I checked MR44 in combination with 4x-dev and core 10.3.2 trying to set autocomplete reference field to be controlled (both visibility and required option) by another radio buttons field and it wasn't working. What worked for me was module version alpha5 and patch in #159.

🇷🇸Serbia miksha

@solideogloria Thanks. It makes sense.

🇷🇸Serbia miksha

For the batch process issue that is explained in #15 I am suggesting another approach that doesn't require us to include JS in all site pages (which in turn also requires core.once).

We are using status message (visible to both anonymous and authenticated user) to show link to exported file and we can use this message on the redirected page to dynamically load our library only on required pages.

I am attaching a patch for this. I tested it locally and works for both anonymous and authenticated users.

🇷🇸Serbia miksha

I am sorry but I do not seem to understand the new logic. For example if I check `Automatically generate the label and hide the label field` and `title` field is required. And then also I check `Preserve already created node titles.` I end up with `Integrity constraint violation: 1048 Column 'title' cannot be null` because code inside `auto_entitylabel_entity_presave` for `$entity->isNew()` skips the next check.

The way I understand option `Preserve already created node titles.` is e.g. I set title to use date token. Then on first node save I get title and I want to preserve it on the next node update. But I want to set titles automatically with the same pattern and hide title field from user for consistency of title naming and I set `Automatically generate the label and hide the label field`. So with these options set I end up with SQL error. And this option to preserve already created titles is only visible with option that sets title automatically and hides title field.

Therefore I don't understand if code comment:

// Handle the case where the automatic label is optional.
// Check to see if isTitlePreserved is set. If the autolabel is
// optional AND the user has filled this title in then the
// the autolabel should not be set.

fits with the code checks below.

Also what I think happens is that `Preserve already created node titles.` checkbox (which is visible only in combination with `Automatically generate the label and hide the label field`) doesn't seem to be set to unchecked when being hidden if we switch options.

🇷🇸Serbia miksha

Thanks for your comment Scott. To explain the background for this need. For some node types we have complex structure made up from different paragraphs. Such node type can have text field, followed by slider, then grid of cards, then again another text paragraph etc. - basically a fluid structure. For such pages it's easiest to let FootnotesFilter process() to render individual footnotes groups per each text field automatically. Especially that this is rendered as part of the text field and inherits the styling etc. On the other hand we have some pages we want to specifically order structure and put footnotes always in the same place. In such case, hiding individual footnote groups is ideal in combination with rendering the block with all the footnotes grouped. This is the case where node type structure is not fluid and we don't use Paragraphs or have combination of standard fields with Paragraphs.

Regardless of our use case, original module doesn't allow different behavior per node type which seems a bit limiting to me.

Now it's late for me but I will consider your suggestions, and also when I have time I will try to spend some time converting patch into MR and covering tests. But this makes sense only if you or others too see some sense in my reasoning for this feature request.

Thanks again for the nice module.

🇷🇸Serbia miksha

Here's the patch for the proposed changes.

🇷🇸Serbia miksha

Patch against 11.x that is targeting class "layout-region--main". Previous one was bad.

🇷🇸Serbia miksha

Patch against 11.x that is targeting class

layout-region--main

.

🇷🇸Serbia miksha

Extended patch to cover both default editor and source editor against 10.x where node-add exists is in this comment.

🇷🇸Serbia miksha

Last patch in https://www.drupal.org/project/claro/issues/3400204#comment-15655237 🐛 Long string breaks the layout Needs review covers only SOURCE editor. It can be extended to cover default editor too.

🇷🇸Serbia miksha

I needed to add around 3000 characters as I wanted to add `connect-src` for all google supported domains defined at https://www.google.com/supported_domains and in the end I opted to disable `connect-src` form field on seckit config page,

/**
 * Implements hook_form_FORM_ID_alter().
 *
 * Check CspEventSubscriber.php.
 */
function your_module_form_seckit_settings_form_alter(array &$form, FormStateInterface $form_state, string $form_id) {
  if (isset($form['seckit_xss']['csp']['connect-src'])) {
    $form['seckit_xss']['csp']['connect-src']['#attributes']['disabled'] = 'disabled';
  }
}

and implement onResponse event subscriber:


namespace Drupal\your_module\EventSubscriber;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\ResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;

/**
 * CSP Event Subscriber.
 */
class CspEventSubscriber implements EventSubscriberInterface {

  /**
   * Adds custom CSP headers.a
   */
  public function onResponse(ResponseEvent $event) {
    $response = $event->getResponse();
    $headers = $response->headers;

    // CSP connect-src directive entries.
    $connect_src = [
      '*.google.com', '*.google.ad', '*.google.ae', '*.google.com.af', '*.google.com.ag', '*.google.al', '*.google.am',
      '*.google.co.ao', '*.google.com.ar', '*.google.as', '*.google.at', '*.google.com.au', '*.google.az', '*.google.ba',
      '*.google.com.bd', '*.google.be', '*.google.bf', '*.google.bg', '*.google.com.bh', '*.google.bi', '*.google.bj',
      '*.google.com.bn', '*.google.com.bo', '*.google.com.br', '*.google.bs', '*.google.bt', '*.google.co.bw', '*.google.by',
      '*.google.com.bz', '*.google.ca', '*.google.cd', '*.google.cf', '*.google.cg', '*.google.ch', '*.google.ci',
      '*.google.co.ck', '*.google.cl', '*.google.cm', '*.google.cn', '*.google.com.co', '*.google.co.cr', '*.google.com.cu',
      '*.google.cv', '*.google.com.cy', '*.google.cz', '*.google.de', '*.google.dj', '*.google.dk', '*.google.dm',
      '*.google.com.do', '*.google.dz', '*.google.com.ec', '*.google.ee', '*.google.com.eg', '*.google.es', '*.google.com.et',
      '*.google.fi', '*.google.com.fj', '*.google.fm', '*.google.fr', '*.google.ga', '*.google.ge', '*.google.gg',
      '*.google.com.gh', '*.google.com.gi', '*.google.gl', '*.google.gm', '*.google.gr', '*.google.com.gt', '*.google.gy',
      '*.google.com.hk', '*.google.hn', '*.google.hr', '*.google.ht', '*.google.hu', '*.google.co.id', '*.google.ie',
      '*.google.co.il', '*.google.im', '*.google.co.in', '*.google.iq', '*.google.is', '*.google.it', '*.google.je',
      '*.google.com.jm', '*.google.jo', '*.google.co.jp', '*.google.co.ke', '*.google.com.kh', '*.google.ki', '*.google.kg',
      '*.google.co.kr', '*.google.com.kw', '*.google.kz', '*.google.la', '*.google.com.lb', '*.google.li', '*.google.lk',
      '*.google.co.ls', '*.google.lt', '*.google.lu', '*.google.lv', '*.google.com.ly', '*.google.co.ma', '*.google.md',
      '*.google.me', '*.google.mg', '*.google.mk', '*.google.ml', '*.google.com.mm', '*.google.mn', '*.google.com.mt',
      '*.google.mu', '*.google.mv', '*.google.mw', '*.google.com.mx', '*.google.com.my', '*.google.co.mz', '*.google.com.na',
      '*.google.com.ng', '*.google.com.ni', '*.google.ne', '*.google.nl', '*.google.no', '*.google.com.np', '*.google.nr',
      '*.google.nu', '*.google.co.nz', '*.google.com.om', '*.google.com.pa', '*.google.com.pe', '*.google.com.pg',
      '*.google.com.ph', '*.google.com.pk', '*.google.pl', '*.google.pn', '*.google.com.pr', '*.google.ps', '*.google.pt',
      '*.google.com.py', '*.google.com.qa', '*.google.ro', '*.google.ru', '*.google.rw', '*.google.com.sa', '*.google.com.sb',
      '*.google.sc', '*.google.se', '*.google.com.sg', '*.google.sh', '*.google.si', '*.google.sk', '*.google.com.sl',
      '*.google.sn', '*.google.so', '*.google.sm', '*.google.sr', '*.google.st', '*.google.com.sv', '*.google.td',
      '*.google.tg', '*.google.co.th', '*.google.com.tj', '*.google.tl', '*.google.tm', '*.google.tn', '*.google.to',
      '*.google.com.tr', '*.google.tt', '*.google.com.tw', '*.google.co.tz', '*.google.com.ua', '*.google.co.ug',
      '*.google.co.uk', '*.google.com.uy', '*.google.co.uz', '*.google.com.vc', '*.google.co.ve', '*.google.co.vi',
      '*.google.com.vn', '*.google.vu', '*.google.ws', '*.google.rs', '*.google.co.za', '*.google.co.zm', '*.google.co.zw',
      '*.google.cat', '*.staticflickr.com', '*.flickr.com', 'maps.google.com', 'analytics.google.com', '*.analytics.google.com',
    ];

    // Create the CSP directive.
    $connect_src_directive = "connect-src 'self' " . implode(' ', $connect_src);

    // Check if a Content-Security-Policy header already exists.
    if ($headers->has('Content-Security-Policy')) {
      // Get the existing CSP header.
      $existing_csp = $headers->get('Content-Security-Policy');

      // Append the new connect-src directive to the existing CSP header.
      $new_csp = $existing_csp . '; ' . $connect_src_directive;

      // Set the updated CSP header.
      $headers->set('Content-Security-Policy', $new_csp);
    }
    else {
      // Set the new CSP header if none exists.
      $headers->set('Content-Security-Policy', $connect_src_directive);
    }
  }

  /**
   * {@inheritdoc}
   */
  public static function getSubscribedEvents() {
    return [
      KernelEvents::RESPONSE => 'onResponse',
    ];
  }

}

and you also of course need to add service entry:

services:
  your_module.event_subscriber:
    class: Drupal\your_module\EventSubscriber\CspEventSubscriber
    tags:
      - { name: event_subscriber }

Keep in mind that HTTP header max size for Apache server is 8190 bytes so you shouldn't make your HTTP header bigger than what HTTP server supports.

🇷🇸Serbia miksha

As this module initially had only one service provider (Azure) and was later extended to support Alttext.AI I would rather go with updating requirement message to something more generic because message about missing Azure configuration is now a bit misleading. Also not sure if module gracefully handles missing provider configuration. But to me more sense is to inform site developer that this module needs config to be set than to allow enabling module without proper config.

🇷🇸Serbia miksha

I made a patch proposal fix for this issue.

🇷🇸Serbia miksha

Previous patch has bad code that sets $title to $title in case if $alternative _title is empty but $title can be undefined.

🇷🇸Serbia miksha

I have a translator role that doesn't have edit permissions. I also encountered the same when adding/updating translations with this role that AJAX error happens with message that user needs edit permission for entity type where media field is calling media library in order to change field value. I made a patch for this but not sure if it's the right approach or if it covers all situations but what I tested and works is that user with just `translate any entity` and without `edit` permissions is able to either create new translation and also update media field. Editing existing translation and updating media field also works. Solution also covers translating entities other than nodes e.g. taxonomies with media field etc.

🇷🇸Serbia miksha

If you use patch #134 from https://www.drupal.org/project/drupal/issues/2983456 Expose triggering update of media metadata + thumbnail to end users Needs work and enable file translation for media image at "/admin/config/regional/content-language" and also set "translatable elements" in the bottom of "/admin/structure/media/manage/image/fields/media.image.field_media_image" then thumbnail translation works. Patch that is attached here is already included in patch #134 I mentioned above.

🇷🇸Serbia miksha

My event subscriber actually wouldn't work because in `SearchBuilder.php` we already set `$query_limit` based on `$query_option` but inside `PrepareSearchQueryEvent` we don't have any original information from `$query_options` as we only pass `$elasticSearchQuery` and `$indexName`. If e.g. I want to check if query limit is set inside my event subscriber while `Display all items` is chosen in the view, I would get result that it is set and its value is 10. This isn't something I can use inside event subscriber therefore I would suggest that `getSearchQueryOptions()` needs to be changed and we either pass original query so it is accessible in an event subscriber or some other solution to pass relevant information from original query that is changed inside `getSearchQueryOptions()`.

🇷🇸Serbia miksha

I opted for Event subscriber solution without patching module:

// File my_module/src/EventSubscriber/SearchQueryAlterSubscriber.php

<?php

namespace Drupal\my_module\EventSubscriber;

use Drupal\elasticsearch_connector\Event\PrepareSearchQueryEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

/**
 * Event subscriber to alter search query config from ES connector.
 */
class SearchQueryAlterSubscriber implements EventSubscriberInterface {

  /**
   * {@inheritdoc}
   */
  public static function getSubscribedEvents() {
    return [
      PrepareSearchQueryEvent::PREPARE_QUERY => ['onPrepareSearchQuery', 100],
    ];
  }

  /**
   * Sets the query limit to 1000.
   *
   * @param \Drupal\elasticsearch_connector\Event\PrepareSearchQueryEvent $event
   *   The event.
   */
  public function onPrepareSearchQuery(PrepareSearchQueryEvent $event) {
    // Get the Elasticsearch query from the event.
    /** @var \Drupal\elasticsearch_connector\Event\PrepareSearchQueryEvent $elastic_search_query */
    $elastic_search_query = $event->getElasticSearchQuery();
    $elastic_search_query['query_limit'] = 1000;

    // Set the altered query back to the event.
    $event->setElasticSearchQuery($elastic_search_query);
  }

}

// File my_module/my_module.services.yml

services:
  my_module.search_query_alter:
    class: Drupal\my_module\EventSubscriber\SearchQueryAlterSubscriber
    tags:
      - { name: event_subscriber }
🇷🇸Serbia miksha

I just realized this happens only on Firefox (I use 106.0.1 (64-bit) on Ubuntu Linux). So on page reload (f5) if there are selected items they stay selected. Only of ctrl+f5 they get cleared. I tested in Firefox private window too.

Production build 0.71.5 2024