Een hart voor de Drupal Community

Bij make it fly geloven we sterk in Drupal en Open Source software in het algemeen. We maken dagelijks gebruik van vele open source componenten en de vele Drupal modules die beschikbaar zijn. We dragen actief ons steentje bij aan de community door zelf patches, modules en documentatie te voorzien, daarnaast zijn enkele teamleden ook actief in de Drupal User Group vzw.

Een overzicht van onze bijdragen aan de Drupal community vind je terug op onze Drupal.org pagina. Naast het actief meerwerken aan de Drupal community, zetten we ook andere ontwikkelaars op weg door vragen te beantwoorden op Drupal Answers.

  1. Time-out in ContextUploader

    Brecht Ceyssens

    The only thing I want to prevent are timeouts and errors in our logs. These are caused by uploadAndMatchContextSync because it uses the wait method to check status of the (slow?) matching process on Smartling side.

    That's why I would split the functionality up in 2 steps/queues but keep all existing logic, that way we give Smartling the time it needs to finish processing without failing on our side:

    1. trigger uploadAndMatchContext, retrieve the processUid and create a new item in a separate queue
      • queue worker uses DelayedRequeueException instead of waiting in the PHP process itself
      • when process is finished, fetch all information using uploadAndMatchContext again and log messages
      • trigger (improved) uploadContextMissingResources

    The major difference it that the waiting part is not done in PHP but in a queue with the correct exceptions, that won't block the queue. Processing of other queue items will continue while waiting for slow ones.

    Part of my comment here https://www.drupal.org/project/tmgmt_smartling/issues/3546398 is related to this topic as well:

    I think uploading all of these assets one by one also makes the process incredibly slow. Why not use Guzzle http client instead of curl commands directly after which you could easily execute async upload commands for all of those assets: https://docs.guzzlephp.org/en/stable/quickstart.html#concurrent-requests

  2. Long translatable string in user interface translations

    Randal

    Problem/Motivation

    Upon installing this module, the config item "notifications_widget.settings:excluded_entities" adds a long unbroken translatable string to the user interface translation.

    There are two problems with this:

    1. The user interface translation table gets stretched out, the left column being incredibly long leaving nearly no space for the content input on both Claro and Gin
    2. Config should not be translatable in the user interface translation, the translation is luckily not used anywhere, but it still shouldn't be in there.

    Steps to reproduce

    1. Install the module
    2. Visit the user interface translation page
    3. If the string isn't on the first page, look for the default value by searching for: "block,block_content_type"

    Proposed resolution

    We should change the data type from "text" (which is translatable) to "string" (which isn't).

    Data model changes

    (Ha, I get to use this heading for once) The "excluded_entities"-key in the "notifications_widget.settings"-config should be a non-translatable data type.

  3. JQuery downgrade

    Fons

    Hello thank you for the information.

    I just did a quick scan and I don't see any dependencies that are stated in the Sticky module (except for using the latest version of the Sticky library).

    {
        "type": "package",
        "package": {
            "name": "garand/sticky",
            "version": "1.0.4",
            "type": "drupal-library",
            "source": {
                "url": "https://github.com/garand/sticky.git",
                "type": "git",
                "reference": "1.0.4"
            }
        }
    },
    
  4. .is-active-li jumps from first to last item on touching the scroll

    Fons

    After a lot of debugging I think I found the issue.

    When I set

    options.headingsOffset = 1;

    in the tocbot-init.js file just before tocbot.init() everything works great. Looks like it gets passed as text instead of a number and Tocbot doesn't throw an error and just doesn't work well then.

    I'll dig deeper and look for a patch but if anyone else has this issue in the meantime this information could be helpful.

  5. .is-active-li jumps from first to last item on touching the scroll

    Fons

    Tested with some older Tocbot libraries but all three instances have the same issue.

    I have already debugged so much that I don't know where to look anymore to be honest.

    Will look into the tocbot-init.js once more. If I don't find anything there I think a fresh pair of eyes/someone smarter than me is needed.

  6. .is-active-li jumps from first to last item on touching the scroll

    Fons

    Problem/Motivation

    I've noticed a problem with Tocbot when using it in Drupal 11.3, I first thought it were my settings or theme specific css but that doesn't seem to be the case.

    I could reproduce this in three different environments, with different theming and tocbot settings:

    • My own environment
    • A clean Drupal 11 install
    • A clean Drupal 11 install with the umami profile installed

    I also tested this with tocbot from CDN and tocbot installed locally with composer (latest version).

    I've recorded 3 videos to illustrate.

    Steps to reproduce

    Install Tocbot, set it up as you would and touch the scroll.

  7. Support core mail as well

    Sven Decabooter

    Problem/Motivation

    This module requires the symfony_mailer module. Refactor the logic so it supports core mail by default. Only if symfony_mailer module exist, build the email that way. Or provide a configuration page to select the email sending method.

  8. Track advancedqueue events issue

    Sven Decabooter

    Problem/Motivation

    Keep track of the process in #3255444: Events on job states, to make sure this module uses the events that will eventually be added to the advancedqueue module.

  9. Cron keep processing the same (old) items

    Brecht Ceyssens

    Here an example of translation submissions that are fetched in tmgmt_smartling_cron.

    {"response":{"statusCode":200,"headers":{"Content-Type":@"0":"application\/json;charset=utf-8","Date":@"0":"Fri, 12 Sep 2025 12:31:04 GMT","Server":@"0":"Apache-Coyote\/1.1","set-cookie":@"0":"_csrf=IzDlPv20Y1Uo1Y1iDIcnvWeV; Path=\/","Vary":@"0":"Accept-Encoding","X-Application-Context":@"0":"api-gateway:aws,redis:8443","X-Content-Type-Options":@"0":"nosniff","X-Frame-Options":@"0":"DENY","X-SL-RequestId":@"0":"2ab19f80-e5e6-4731-8f4a-5f2528811308","X-XSS-Protection":@"0":"1; mode=block","1":"1; mode=block","transfer-encoding":@"0":"chunked","Connection":@"0":"keep-alive"},"body":"{\"response\":{\"code\":\"SUCCESS\",\"data\":{\"items\":[{\"translationRequestUid\":\"67d3ed0b5adb\",\"percentComplete\":100,\"lastErrorMessage\":null,\"state\":\"Completed\",\"projectId\":\"60ab0f659\",\"bucketName\":\"66d7fbbb9e401\",\"version\":1058,\"translationSubmissionUid\":\"2ec5a5e47526\",\"targetAssetKey\":@\"tmgmt_job_id\":\"12786\",\"customTranslationData\":@\"batch_uid\":\"25kbxi9abdba\",\"batch_execute_on_job\":\"13320\",\"targetLocaleId\":\"fr-BE\",\"localeLastModifiedDate\":\"2025-09-01T10:18:52Z\",\"submitterName\":\"cron\",\"lastExportedDate\":\"2025-09-12T12:16:08Z\",\"submittedDate\":null,\"createdDate\":\"2025-08-25T08:31:03Z\",\"modifiedDate\":\"2025-09-12T12:16:08Z\"},{\"translationRequestUid\":\"67d3ed0b5adb\",\"percentComplete\":100,\"lastErrorMessage\":null,\"state\":\"Translated\",\"projectId\":\"60ab0f659\",\"bucketName\":\"66d7fbbb9e401\",\"version\":10,\"translationSubmissionUid\":\"fd58627cb484\",\"targetAssetKey\":@\"tmgmt_job_id\":\"12783\",\"customTranslationData\":@\"batch_uid\":\"25kbxi9abdba\",\"batch_execute_on_job\":\"13320\",\"targetLocaleId\":\"fr-BE\",\"localeLastModifiedDate\":\"2025-09-01T10:18:52Z\",\"submitterName\":\"cron\",\"lastExportedDate\":\"2025-05-27T06:55:11Z\",\"submittedDate\":\"2025-08-25T08:31:05.000Z\",\"createdDate\":\"2025-05-27T06:52:05Z\",\"modifiedDate\":\"2025-09-01T10:18:53Z\"}]}}}"}}
    

    We haven't digged deeper, but we see that the file_id is not set and there are no other related entries in the logs. Do you have an idea what this could cause?

  10. Smartling failed to create an audit log record

    Brecht Ceyssens

    @loparev where are these audit logs used for anyway? Is it necessary for Smartling's handling? I suppose it belongs to https://help.smartling.com/hc/en-us/articles/26782577087771--Introductio... but I can't seem to find it in the Smartling backend nor in the API documentation.

  11. Time-out in ContextUploader

    Brecht Ceyssens

    To prevent locking the process: isn't it possible to do the upload, capture the processUuid from contexts/upload-and-match-async and put that in another queue so we can use DelayedRequeueException to "wait" for the process to finish?

  12. Managed file storage

    Brecht Ceyssens

    @loparev, we noticed not all API endpoint are documented here: https://api-reference.smartling.com Missing resources, logs, audit log, ... Where you look for documentation?

  13. Managed file storage

    Brecht Ceyssens

    We noticed that disk usage keeps growing for tmgmt_* folders. Aside from tests there are 3 places where managed files are written to disk and their usage is not updated or set. This will result in files that will never be automatically cleaned by Drupal.

    Drupal has 2 seperate settings to control this functionality: - Set file to temporary when usage becomes 0 file.settings.yml: make_unused_managed_files_temporary - Timeframe after which temporary files can be deleted system.file.yml: temporary_maximum_age

    There are 2 ways we can solve the issue:

    1. usage is set correctly for all of these files
    2. do not store files which are needed afterwards

    For example: context upload. I don't think we need to keep the files stored locally, isn't it possible to generate the HTML and send it directly to Smartling API?

    You can also briefly explain what the uploadContextMissingResources method in ContextUploader.php should do? If I understand the code correctly, we send context HTML and Smartling ask for missing resources (assets) which we upload afterwards? If that's the case, I also think it's not needed to save these files to disk in another folder which is not cleaned automatically.

    I think uploading all of these assets one by one also makes the process incredibly slow. Why not use Guzzle http client instead of curl commands directly after which you could easily execute async upload commands for all of those assets: https://docs.guzzlephp.org/en/stable/quickstart.html#concurrent-requests

    Let me know how you think about it, we can help writing the code. I can also split this ticket as it contains multiple different subjects.

  14. Smartling failed to create an audit log record

    Brecht Ceyssens

    We often see these type of errors in the logs. I'm trying to capture more information about the request, hoping to send that tomorrow.

    As they are internal server errors on Smartling side, I'm not sure if we can do something about them. Maybe you can see what's going wrong based on the project ID in the URL?

    Guzzle:RequestException: Server error: `POST https://api.smartling.com/audit-log-api/v2/projects/60ab0f659/logs` resulted in a `500 Internal Server Error` response: {"response":{"code":"GENERAL_ERROR","errors":[{"key":"error","message":"Request Timeout after 30000ms","details":null}]} (truncated...) .
    
    Guzzle:RequestException: Server error: `POST https://api.smartling.com/audit-log-api/v2/projects/60ab0f659/logs` resulted in a `500 Internal Server Error` response: {"response":{"code":"GENERAL_ERROR","errors":[{"key":"error","message":"[cluster_block_exception] blocked by: [FORBIDDEN (truncated...)
    
  15. Time-out in ContextUploader

    Brecht Ceyssens

    @loparev,

    We've read the code and understand that this is the flow that needs to be followed, but what's the benefit of waiting on the Smartling matching process to finish? In our case we already increased the timeout to 30 seconds, and even then it's sometimes not enough.

    Is there other functionality depending on these processes to finish correctly? Or is it only a log that needs to happen on Drupal side?

  16. Do not perform API calls during config sync

    Brecht Ceyssens

    @loparev, yes the method is called from tmgmt_smartling_tmgmt_translator_update. Our project also has an integration with Lokalise (https://www.drupal.org/project/tmgmt_lokalise) which doesn't have an update hook in place. But we also don't receive messages from the getSupportedRemoteLanguages function when updating the configuration.

    Where do you think the config syncing check should happen? We can start a patch on tmgmt itself when we agree on a solution.

  17. Optional use of Drupal cron

    Brecht Ceyssens

    @loparev, looks like our messages crosses while writing. Installing another module just to disable cron for this module just feels wrong, if you think it's OK we prefer to keep our existing queue_info_alter hook.

  18. Optional use of Drupal cron

    Brecht Ceyssens

    This ticket is related to https://www.drupal.org/project/tmgmt_smartling/issues/3125696 We already use the drush commands but we don't want cron to interfere with these separate drush commands.

  19. Exclude for context upload improvements

    Brecht Ceyssens

    Patch attached for reviewing. It removes the hardcoded entity type list and replaces with automatic entity type excludes when entity type:

    • has no canonical
    • canonical is the same as edit page
    • is not translatable

    Cleaned the config from still included (not excluded) items. We also added to ability to exclude an entire entity type. Comes in handy when there are a lot of bundles, or they keep growing during development.

    The only thing still missing might be an update hook to save all existing providers to apply new rules.

  20. Exclude for context upload improvements

    Brecht Ceyssens

    We're in constant active development for one client where entity types and bundles keep growing. During initial setup the massive 200+ item list is a pain to configure for multiple providers and it now hard to maintain as well. It would be nice to improve this functionality to keep context upload as performant as it should be.

  21. User context switching not working

    Brecht Ceyssens

    @loparev if you agree, the user switching part can be removed completely.

    The only additional thing that needs to happen is to properly check the job and job item statuses to prevent requests that will result in a 403 anyway. Attached patch is based on logic from Drupal\tmgmt_content\Access\KeyAccessCheck. There's one other place where the queue is injected (SendContextActionApproveForm.php) but it isn't used yet, so didn't touch that code.

Sven Decabooter - Drupal Developer

"Onze teamleden bouwen zelf ook mee aan ons geliefde Drupal, en daar zijn we trots op"

Sven Decabooter
Drupal developer

Betrouwbare technologie, naadloze prestaties. Dat zijn onze Drupal-oplossingen.