Sindelfingen
Account created on 15 July 2006, over 18 years ago
#

Recent comments

🇩🇪Germany drubb Sindelfingen

Here's a Gist demonstrating how this can be achieved using a JavaScript mutation observer. Details may vary: https://gist.github.com/drubb/8ef8366a10b24bbddb2ca57e4a7bc075

🇩🇪Germany drubb Sindelfingen

Here's a Gist demonstrating how this can be achieved using a JavaScript mutation observer. Details may vary: https://gist.github.com/drubb/8ef8366a10b24bbddb2ca57e4a7bc075

🇩🇪Germany drubb Sindelfingen

Ok, I've now switched the application to Media Thumbnails SVG:

https://www.drupal.org/project/media_thumbnails_svg

It has a bit more PHP code, but not much more, due to its nature as plugin.

The project with the most code written by me would be https://www.drupal.org/project/media_thumbnails ,
but this project already has been opted in for security coverage.

🇩🇪Germany drubb Sindelfingen

Thanks for taking a look. Yes, there are related projects where most commits are by me:

https://www.drupal.org/project/media_thumbnails
https://www.drupal.org/project/media_thumbnails_pdf
https://www.drupal.org/project/media_thumbnails_svg

The first two have been opted in by a new co-maintainer recently.

🇩🇪Germany drubb Sindelfingen

Hi ananya,

thanks for your contribution! I appreciate it, however it's not that simple:

The FileExists class was introduced in Drupal 10.3, but this module's 2.x branch has to support Drupal 9.3 upwards.
The clean way to solve this is introducing a new major branch 3.x supporting Drupal 10.3 upwards, or maybe some
11.x / 12.x version.

I don't want to implement this currently, because new features would then need to be backported. As Drupal 12 is still way to go,
there's no urgency to solve this. So I'll postpone this issue for now.

🇩🇪Germany drubb Sindelfingen

The issue mentioned above in meyfa/php-svg has been fixed in release 0.12, however there's only minor improvement in quality.
SVG support is very limited in PHP-GD, especially for CSS. We can't do better here.
Closing this issue for now.

🇩🇪Germany drubb Sindelfingen

Fair point. There's now a new stable release fixing this issue. Closing this, as I don't expect additional deprecations for D11.

🇩🇪Germany drubb Sindelfingen

Thanks for your contribution. There's now a new stable release fixing the issues.

🇩🇪Germany drubb Sindelfingen

Hey Andrii,

thanks for your offer, you're welcome. I've just granted you maintainership for this module.
As there are now three maintainers for Media Thumbnails, we should coordinate things using
the issue queue, so feel free to open new issues and assign them to Quentin or me directly.

Have a good time!

Regards, Boris

🇩🇪Germany drubb Sindelfingen

This bug is really hard to understand for site builders.
For me, the workaround in #45 works, but this should
definitely be fixed in core!

🇩🇪Germany drubb Sindelfingen

Ah, I see: once the MR gets merged, there will be a local instance of this plugin in composer/Plugin, which can be added to the composer repositories, allowing to require the plugin.
Ok, perspectively it might make sense to host it on packagist.org, just like the other core-xxx plugins.

🇩🇪Germany drubb Sindelfingen

composer require drupal/core-composer-unpack

Where is this package hosted? Can't find it on packagist.org?

🇩🇪Germany drubb Sindelfingen

Yes, I also think it's not ECA's fault. BTW, using Drush 12.5.3.0 here.

🇩🇪Germany drubb Sindelfingen

The question is, does this filter make any sense at all in conjunction with CKEditor fields? I think it's primarily meant for use with plain text fields, as CKEditor does this conversion already. I can't think of a use case for fields powered by CKE, so maybe we need a hint not to use it, or prevent usage at all for CKE fields. At least it should fail silently and not destroy the markup given by CKE.

🇩🇪Germany drubb Sindelfingen

Did a quick test to look at this filter in isolation, by calling the _filter_autop() function directly. This is broken indeed:

$output = _filter_autop('<p><a href="https://google.de"><drupal-media/></a></p>')

Result:

<p><a href="https://google.de"></p>\n
  <drupal-media/></a></p>
🇩🇪Germany drubb Sindelfingen

MR !99 works for me, all files are loaded locally:

Not sure how library versions should be handled. I don't like pinning stuff, so tested with Tagify 4.26.6, despite
the query parm saying 4.26.0

Setting to RTBC.

🇩🇪Germany drubb Sindelfingen

Reopening this ticket, as there's still an issue related to the local fallback for libraries.

I've installed yaireo/tagify in the /libraries folder as suggested. Looking at my browser's devtools
I noticed most library files being fetched locally now, with one exception: tagify.min.js still fetched
from the CDN (Cloudflare):

I've taken a look at the library's source code on GitHub. Seems tagify.min.js has been removed
in release 4.25.0 in favor of an already minified tagify.js.
So the script can't be found locally and is still fetched from the CDN. Don't know why Cloudflare
delivers this non-existent file.
Switching from tagify.min.js to tagify.js should solve the issue.

🇩🇪Germany drubb Sindelfingen

It depends on what you want to achieve. This module (media_thumbnails) is just a plugin manager and does not have special requirements. There are however contributed modules to generate thumbnails from various file types. They might need special tools to do this. Here are some examples:

  • media_thumbnails_pdf needs ImageMagick to generate a thumbnail from a PDF
  • media_thumbnails_video needs ffmpeg to extract a thumbnail from a video file
  • media_thumbnails_svg supports multiple tools, but the resulting quality might differ

What about shared hosting? Besides saving costs, the main reason to use it is not needing to manage the operating system yourself. It's not less capable by default, but it depends on the provider which features will be available. For example, there are shared hosters that support tools like ImageMagick, while others don't. It's the same for features like ssh access, Composer, OpCache or a memory limit high enough for Drupal - you can get them with shared hosting, but not every provider supports them.

The alternative might be using a managed server, because this offers more resources and usually a bit more flexibility in terms of installed tools, but of course at a higher cost.

Does this answer your question?

🇩🇪Germany drubb Sindelfingen

What's the benefit compared to access handlers, e.g. for routes, entities or fields?

🇩🇪Germany drubb Sindelfingen

I'll need to take a closer look, but for now:

We'll need to handle all ways of deletion, not just manual ones (using the form).
When deleting any translation (or the origin), we need to load all existing translations and check
if the file id of the thumbnail is used in any other translation - in this case, the
file must not be deleted. This would be the case, if a media file (and thus its thumbnail)
is reused in multiple translations.

🇩🇪Germany drubb Sindelfingen

Hey Sven,

just to clarify:

The attached PDF in the translation is the same file as in the original? Or is it a translated file, with a different name?

🇩🇪Germany drubb Sindelfingen

I did something similar like in #28 or #54. While the image is correctly displayed and linked, there are still additional empty links before and after the image. Something like

<p><a></a></p>
<p><a>Rendered image</a></p>
<p><a></a></p>

It's weird!

🇩🇪Germany drubb Sindelfingen

Here's a workaround I'm using now to disable logging and thus prevent errors:

      $email
        ->to($message['to'])
        ->subject($message['subject'])
        ->html($message['html'])
        ->text($message['body']);

      // Disable logging, it's verbose and throws exceptions
      // on transport shutdown.
      $this->logger = new NullLogger();
      $this->getMailer()->send($email);
      return TRUE;
    } catch (\Exception|TransportExceptionInterface $e) {
      return FALSE;
    }
🇩🇪Germany drubb Sindelfingen

This was my thought, too. However, I have no idea how to do this. Logging is part of the smtp mail transport class of Symfony Mailer, not done in Drupal. This class has a constructor where it initializes a logger, at that time with the correct database connection. One might be able to patch it, but...

Logging the transport stop is done in the destructor of the same class, at this point the logger property is missing the database connection (null).

The destructor calls a stop() method, where logging is done (and fails).

🇩🇪Germany drubb Sindelfingen

The stack trace in PhpStorm starts with the __destruct function of SmtpTransport.php, there the connection seems to be missing already:

DbLog.php:61, Drupal\dblog\Logger\DbLog->log()
LoggerChannel.php:127, Drupal\Core\Logger\LoggerChannel->log()
LoggerTrait.php:127, Drupal\Core\Logger\LoggerChannel->debug()
SmtpTransport.php:297, Symfony\Component\Mailer\Transport\Smtp\SmtpTransport->stop()
SmtpTransport.php:390, Symfony\Component\Mailer\Transport\Smtp\SmtpTransport->__destruct()

🇩🇪Germany drubb Sindelfingen

This is how the connection object looks in DbLog.php, right before the insert statement:

Drupal\mysql\Driver\Database\mysql\Connection Object
(
    [target:protected] => default
    [key:protected] => default
    [logger:protected] => 
    [transactionLayers:protected] => Array
        (
        )

    [driverClasses:protected] => Array
        (
        )

    [statementWrapperClass:protected] => Drupal\Core\Database\StatementWrapperIterator
    [transactionalDDLSupport:protected] => 
    [connection:protected] => 
    [connectionOptions:protected] => Array
        (
            [database] => drupal10
            [username] => drupal10
            [password] => drupal10
            [prefix] => 
            [host] => database
            [port] => 3306
            [namespace] => Drupal\mysql\Driver\Database\mysql
            [driver] => mysql
            [init_commands] => Array
                (
                    [isolation_level] => SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED
                    [sql_mode] => SET sql_mode = 'ANSI,TRADITIONAL'
                )

            [autoload] => core/modules/mysql/src/Driver/Database/mysql/
            [pdo] => Array
                (
                    [3] => 2
                    [1000] => 1
                    [1005] => 1
                    [20] => 1
                    [1013] => 
                    [17] => 1
                )

        )

    [schema:protected] => 
    [prefix:protected] => 
    [tablePlaceholderReplacements:protected] => Array
        (
            [0] => "
            [1] => "
        )

    [prefixes:protected] => Array
        (
        )

    [prefixSearch:protected] => Array
        (
        )

    [prefixReplace:protected] => Array
        (
        )

    [unprefixedTablesMap:protected] => Array
        (
        )

    [escapedTables:protected] => Array
        (
            [config] => config
            [key_value] => key_value
            [key_value_expire] => key_value_expire
            [path_alias] => path_alias
            [config_pages] => config_pages
            [crop_field_data] => crop_field_data
            [menu_tree] => menu_tree
            [sessions] => sessions
            [users_field_data] => users_field_data
        )

    [escapedFields:protected] => Array
        (
            [] => 
            [collection] => "collection"
            [name] => "name"
            [config.name] => "config"."name"
            [uid] => "uid"
            [type] => "type"
            [message] => "message"
            [variables] => "variables"
            [severity] => "severity"
            [link] => "link"
            [location] => "location"
            [referer] => "referer"
            [hostname] => "hostname"
            [timestamp] => "timestamp"
            [base_table.status] => "base_table"."status"
            [base_table.path] => "base_table"."path"
            [base_table.langcode] => "base_table"."langcode"
            [base_table.alias] => "base_table"."alias"
            [base_table.id] => "base_table"."id"
            [config_pages.type] => "config_pages"."type"
            [config_pages.context] => "config_pages"."context"
            [cfd.uri] => "cfd"."uri"
            [cfd.type] => "cfd"."type"
            [cfd.cid] => "cfd"."cid"
            [menu_name] => "menu_name"
            [expanded] => "expanded"
            [has_children] => "has_children"
            [enabled] => "enabled"
            [parent] => "parent"
            [id] => "id"
            [menu_tree.id] => "menu_tree"."id"
            [sid] => "sid"
            [session] => "session"
            [access] => "access"
        )

    [escapedAliases:protected] => Array
        (
            [name] => "name"
            [config] => "config"
            [path] => "path"
            [alias] => "alias"
            [base_table] => "base_table"
            [id] => "id"
            [langcode] => "langcode"
            [base_table_id] => "base_table_id"
            [config_pages] => "config_pages"
            [type] => "type"
            [cid] => "cid"
            [cfd] => "cfd"
            [menu_tree] => "menu_tree"
            [expression] => "expression"
            [sessions] => "sessions"
        )

    [rootTransactionEndCallbacks:protected] => Array
        (
        )

    [identifierQuotes:protected] => Array
        (
            [0] => "
            [1] => "
        )

    [enabledEvents:Drupal\Core\Database\Connection:private] => Array
        (
        )

    [transactionManager:protected] => Drupal\mysql\Driver\Database\mysql\TransactionManager Object
        (
            [stack:Drupal\Core\Database\Transaction\TransactionManagerBase:private] => Array
                (
                )

            [voidedItems:Drupal\Core\Database\Transaction\TransactionManagerBase:private] => Array
                (
                )

            [postTransactionCallbacks:Drupal\Core\Database\Transaction\TransactionManagerBase:private] => Array
                (
                )

            [connection:protected] => Drupal\mysql\Driver\Database\mysql\Connection Object
 *RECURSION*
        )

    [needsCleanup:protected] => 
    [serverVersion:Drupal\mysql\Driver\Database\mysql\Connection:private] => 
)
🇩🇪Germany drubb Sindelfingen

Had a quick test: with xdebug disabled, it also happens. The error message is a bit shorter:

Fatal error: Uncaught TypeError: Drupal\Core\Database\StatementWrapperIterator::__construct(): Argument #2 ($clientConnection) must be of type object, null given, called in /app/web/core/lib/Drupal/Core/Database/Connection.php on line 557 and defined in /app/web/core/lib/Drupal/Core/Database/StatementWrapperIterator.php:54 Stack trace: #0 /app/web/core/lib/Drupal/Core/Database/Connection.php(557): Drupal\Core\Database\StatementWrapperIterator->__construct(Object(Drupal\mysql\Driver\Database\mysql\Connection), NULL, 'INSERT INTO "wa...', Array, false) #1 /app/web/core/modules/mysql/src/Driver/Database/mysql/Insert.php(42): Drupal\Core\Database\Connection->prepareStatement('INSERT INTO "wa...', Array) #2 /app/web/core/modules/dblog/src/Logger/DbLog.php(78): Drupal\mysql\Driver\Database\mysql\Insert->execute() #3 /app/web/core/lib/Drupal/Core/Logger/LoggerChannel.php(127): Drupal\dblog\Logger\DbLog->log(7, 'Email transport...', Array) #4 /app/vendor/psr/log/src/LoggerTrait.php(127): Drupal\Core\Logger\LoggerChannel->log(7, 'Email transport...', Array) #5 /app/vendor/symfony/mailer/Transport/Smtp/SmtpTransport.php(297): Drupal\Core\Logger\LoggerChannel->debug('Email transport...') #6 /app/vendor/symfony/mailer/Transport/Smtp/SmtpTransport.php(390): Symfony\Component\Mailer\Transport\Smtp\SmtpTransport->stop() #7 [internal function]: Symfony\Component\Mailer\Transport\Smtp\SmtpTransport->__destruct() #8 {main} thrown in /app/web/core/lib/Drupal/Core/Database/StatementWrapperIterator.php on line 54
🇩🇪Germany drubb Sindelfingen

You can use Drupal's Third Party Settings API to add additional fields to config entities. Here's a blog post with an example:
https://kevinquillen.com/using-thirdpartysettings-api-drupal

🇩🇪Germany drubb Sindelfingen

Just to summarize the current situation in other words, hopefully not getting it wrong:

Route Access is allowed, if ALL access checks return AccessResult::allowed(). It’s denied if ANY access check does NOT return AccessResult::allowed().

Entity Access is allowed, if ANY access check returns AccessResult:allowed() and NO access check returns AccessResult::forbidden(). It’s denied if NO access check returns AccessResult::allowed() or ANY access check returns AccessResult::forbidden().

🇩🇪Germany drubb Sindelfingen

IMHO this is a core Views issue. Views should hide the checkbox and prevent linking to entities that don't have a canonical route / url.
I'm not sure what has been changed from Drupal 10.1 to 10.2. Maybe this failed silently before, and now throws an error.
I guess there's nothing Workflows or EVA can do to fix this.

🇩🇪Germany drubb Sindelfingen

Did you check the columns (Views fields) 'From State' and 'To State'? There's a checkbox, something like 'Link label to the referenced entity', this MUST be unchecked!

🇩🇪Germany drubb Sindelfingen

Check the View that is rendered here, obviously. If it renders workflow states, they should NOT be linked to the workflow state entity, as workflow states don't have canonical urls.

🇩🇪Germany drubb Sindelfingen

Just to clarify: you've upgraded Drupal core, but presumably not the D8 version. So from 10.1.7 to 10.2.1, right?

🇩🇪Germany drubb Sindelfingen

Are there any code examples for converting plugin managers / annotation classes?

🇩🇪Germany drubb Sindelfingen

Just to get this right: the annotation classes and plugin managers will be kept unchanged for now?
Is this only about changing plugin implementations from annotations to attributes? Or is there some core magic in the background?

🇩🇪Germany drubb Sindelfingen

Guess I answered the question myself:

There's indeed a separate field type for media references, 'Media with contextual modifications'. Does this mean the module can't be used on a site with existing media references? Or is there some way to convert them?

🇩🇪Germany drubb Sindelfingen

I guess I have the same issue, I'll try to make it a bit clearer:

When editing an entity containing media references e.g. for image media, there's a pencil symbol to edit the media and choose e.g. a focal point. The media edit form will be opened in a modal. However, this modal will contain the default edit form for the media element, not a contextual form as expected. The modal title will be e.g. 'Edit image xyz', not 'Override media item in context of...'. This means, the focal point settings will be global for all references to this media element, not contextual (bound to the parent entity) as expected.

There's a missing piece somewhere. The form display settings for the reference field in the parent entity allow to choose between 'Media library' and 'Media library extra', the latter is chosen. Are we missing something? Does e.g. the reference field need to use a special field type?

🇩🇪Germany drubb Sindelfingen

I've just published a new dev version that should fix the problem. Please try it out!

🇩🇪Germany drubb Sindelfingen

Found the culprit: it was some custom code implementing a search api subscriber and requiring a small code change in order to work with Symfony 6.

Before:

$query = \Drupal::request()->query;
$f = (array) $query->get('f');

After:

$query = \Drupal::request()->query;
$f = $query->all()['f'] ?? [];

So it's not caused by Facets module, closing this issue.

Production build 0.71.5 2024